@contractspec/example.saas-boilerplate 1.57.0 → 1.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/.turbo/turbo-build.log +160 -180
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +39 -0
  4. package/dist/billing/billing.entity.d.ts +40 -45
  5. package/dist/billing/billing.entity.d.ts.map +1 -1
  6. package/dist/billing/billing.entity.js +110 -118
  7. package/dist/billing/billing.enum.d.ts +2 -7
  8. package/dist/billing/billing.enum.d.ts.map +1 -1
  9. package/dist/billing/billing.enum.js +17 -24
  10. package/dist/billing/billing.event.d.ts +67 -73
  11. package/dist/billing/billing.event.d.ts.map +1 -1
  12. package/dist/billing/billing.event.js +84 -146
  13. package/dist/billing/billing.handler.d.ts +59 -62
  14. package/dist/billing/billing.handler.d.ts.map +1 -1
  15. package/dist/billing/billing.handler.js +140 -49
  16. package/dist/billing/billing.operations.d.ts +138 -144
  17. package/dist/billing/billing.operations.d.ts.map +1 -1
  18. package/dist/billing/billing.operations.js +273 -175
  19. package/dist/billing/billing.presentation.d.ts +2 -7
  20. package/dist/billing/billing.presentation.d.ts.map +1 -1
  21. package/dist/billing/billing.presentation.js +51 -57
  22. package/dist/billing/billing.schema.d.ts +159 -164
  23. package/dist/billing/billing.schema.d.ts.map +1 -1
  24. package/dist/billing/billing.schema.js +112 -204
  25. package/dist/billing/index.d.ts +11 -8
  26. package/dist/billing/index.d.ts.map +1 -0
  27. package/dist/billing/index.js +689 -9
  28. package/dist/browser/billing/billing.entity.js +113 -0
  29. package/dist/browser/billing/billing.enum.js +19 -0
  30. package/dist/browser/billing/billing.event.js +90 -0
  31. package/dist/browser/billing/billing.handler.js +148 -0
  32. package/dist/browser/billing/billing.operations.js +278 -0
  33. package/dist/browser/billing/billing.presentation.js +52 -0
  34. package/dist/browser/billing/billing.schema.js +121 -0
  35. package/dist/browser/billing/index.js +688 -0
  36. package/dist/browser/dashboard/dashboard.presentation.js +52 -0
  37. package/dist/browser/dashboard/index.js +52 -0
  38. package/dist/browser/docs/index.js +93 -0
  39. package/dist/browser/docs/saas-boilerplate.docblock.js +93 -0
  40. package/dist/browser/example.js +39 -0
  41. package/dist/browser/handlers/index.js +358 -0
  42. package/dist/browser/handlers/saas.handlers.js +134 -0
  43. package/dist/browser/index.js +3340 -0
  44. package/dist/browser/presentations/index.js +290 -0
  45. package/dist/browser/project/index.js +790 -0
  46. package/dist/browser/project/project.entity.js +77 -0
  47. package/dist/browser/project/project.enum.js +18 -0
  48. package/dist/browser/project/project.event.js +103 -0
  49. package/dist/browser/project/project.handler.js +178 -0
  50. package/dist/browser/project/project.operations.js +372 -0
  51. package/dist/browser/project/project.presentation.js +177 -0
  52. package/dist/browser/project/project.schema.js +134 -0
  53. package/dist/browser/saas-boilerplate.feature.js +88 -0
  54. package/dist/browser/seeders/index.js +20 -0
  55. package/dist/browser/settings/index.js +75 -0
  56. package/dist/browser/settings/settings.entity.js +74 -0
  57. package/dist/browser/settings/settings.enum.js +11 -0
  58. package/dist/browser/shared/mock-data.js +104 -0
  59. package/dist/browser/shared/overlay-types.js +0 -0
  60. package/dist/browser/tests/operations.test-spec.js +112 -0
  61. package/dist/browser/ui/SaasDashboard.js +988 -0
  62. package/dist/browser/ui/SaasProjectList.js +162 -0
  63. package/dist/browser/ui/SaasSettingsPanel.js +145 -0
  64. package/dist/browser/ui/hooks/index.js +159 -0
  65. package/dist/browser/ui/hooks/useProjectList.js +66 -0
  66. package/dist/browser/ui/hooks/useProjectMutations.js +91 -0
  67. package/dist/browser/ui/index.js +1808 -0
  68. package/dist/browser/ui/modals/CreateProjectModal.js +153 -0
  69. package/dist/browser/ui/modals/ProjectActionsModal.js +335 -0
  70. package/dist/browser/ui/modals/index.js +487 -0
  71. package/dist/browser/ui/overlays/demo-overlays.js +61 -0
  72. package/dist/browser/ui/overlays/index.js +61 -0
  73. package/dist/browser/ui/renderers/index.js +675 -0
  74. package/dist/browser/ui/renderers/project-list.markdown.js +499 -0
  75. package/dist/browser/ui/renderers/project-list.renderer.js +177 -0
  76. package/dist/dashboard/dashboard.presentation.d.ts +2 -7
  77. package/dist/dashboard/dashboard.presentation.d.ts.map +1 -1
  78. package/dist/dashboard/dashboard.presentation.js +51 -53
  79. package/dist/dashboard/index.d.ts +5 -2
  80. package/dist/dashboard/index.d.ts.map +1 -0
  81. package/dist/dashboard/index.js +53 -3
  82. package/dist/docs/index.d.ts +2 -1
  83. package/dist/docs/index.d.ts.map +1 -0
  84. package/dist/docs/index.js +94 -1
  85. package/dist/docs/saas-boilerplate.docblock.d.ts +2 -1
  86. package/dist/docs/saas-boilerplate.docblock.d.ts.map +1 -0
  87. package/dist/docs/saas-boilerplate.docblock.js +45 -51
  88. package/dist/example.d.ts +2 -6
  89. package/dist/example.d.ts.map +1 -1
  90. package/dist/example.js +38 -50
  91. package/dist/handlers/index.d.ts +7 -4
  92. package/dist/handlers/index.d.ts.map +1 -0
  93. package/dist/handlers/index.js +358 -4
  94. package/dist/handlers/saas.handlers.d.ts +60 -59
  95. package/dist/handlers/saas.handlers.d.ts.map +1 -1
  96. package/dist/handlers/saas.handlers.js +127 -140
  97. package/dist/index.d.ts +15 -45
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +3335 -75
  100. package/dist/node/billing/billing.entity.js +113 -0
  101. package/dist/node/billing/billing.enum.js +19 -0
  102. package/dist/node/billing/billing.event.js +90 -0
  103. package/dist/node/billing/billing.handler.js +148 -0
  104. package/dist/node/billing/billing.operations.js +278 -0
  105. package/dist/node/billing/billing.presentation.js +52 -0
  106. package/dist/node/billing/billing.schema.js +121 -0
  107. package/dist/node/billing/index.js +688 -0
  108. package/dist/node/dashboard/dashboard.presentation.js +52 -0
  109. package/dist/node/dashboard/index.js +52 -0
  110. package/dist/node/docs/index.js +93 -0
  111. package/dist/node/docs/saas-boilerplate.docblock.js +93 -0
  112. package/dist/node/example.js +39 -0
  113. package/dist/node/handlers/index.js +358 -0
  114. package/dist/node/handlers/saas.handlers.js +134 -0
  115. package/dist/node/index.js +3340 -0
  116. package/dist/node/presentations/index.js +290 -0
  117. package/dist/node/project/index.js +790 -0
  118. package/dist/node/project/project.entity.js +77 -0
  119. package/dist/node/project/project.enum.js +18 -0
  120. package/dist/node/project/project.event.js +103 -0
  121. package/dist/node/project/project.handler.js +178 -0
  122. package/dist/node/project/project.operations.js +372 -0
  123. package/dist/node/project/project.presentation.js +177 -0
  124. package/dist/node/project/project.schema.js +134 -0
  125. package/dist/node/saas-boilerplate.feature.js +88 -0
  126. package/dist/node/seeders/index.js +20 -0
  127. package/dist/node/settings/index.js +75 -0
  128. package/dist/node/settings/settings.entity.js +74 -0
  129. package/dist/node/settings/settings.enum.js +11 -0
  130. package/dist/node/shared/mock-data.js +104 -0
  131. package/dist/node/shared/overlay-types.js +0 -0
  132. package/dist/node/tests/operations.test-spec.js +112 -0
  133. package/dist/node/ui/SaasDashboard.js +988 -0
  134. package/dist/node/ui/SaasProjectList.js +162 -0
  135. package/dist/node/ui/SaasSettingsPanel.js +145 -0
  136. package/dist/node/ui/hooks/index.js +159 -0
  137. package/dist/node/ui/hooks/useProjectList.js +66 -0
  138. package/dist/node/ui/hooks/useProjectMutations.js +91 -0
  139. package/dist/node/ui/index.js +1808 -0
  140. package/dist/node/ui/modals/CreateProjectModal.js +153 -0
  141. package/dist/node/ui/modals/ProjectActionsModal.js +335 -0
  142. package/dist/node/ui/modals/index.js +487 -0
  143. package/dist/node/ui/overlays/demo-overlays.js +61 -0
  144. package/dist/node/ui/overlays/index.js +61 -0
  145. package/dist/node/ui/renderers/index.js +675 -0
  146. package/dist/node/ui/renderers/project-list.markdown.js +499 -0
  147. package/dist/node/ui/renderers/project-list.renderer.js +177 -0
  148. package/dist/presentations/index.d.ts +13 -14
  149. package/dist/presentations/index.d.ts.map +1 -1
  150. package/dist/presentations/index.js +289 -15
  151. package/dist/project/index.d.ts +11 -8
  152. package/dist/project/index.d.ts.map +1 -0
  153. package/dist/project/index.js +791 -9
  154. package/dist/project/project.entity.d.ts +23 -28
  155. package/dist/project/project.entity.d.ts.map +1 -1
  156. package/dist/project/project.entity.js +75 -82
  157. package/dist/project/project.enum.d.ts +2 -7
  158. package/dist/project/project.enum.d.ts.map +1 -1
  159. package/dist/project/project.enum.js +16 -23
  160. package/dist/project/project.event.d.ts +69 -75
  161. package/dist/project/project.event.d.ts.map +1 -1
  162. package/dist/project/project.event.js +95 -156
  163. package/dist/project/project.handler.d.ts +44 -47
  164. package/dist/project/project.handler.d.ts.map +1 -1
  165. package/dist/project/project.handler.js +168 -71
  166. package/dist/project/project.operations.d.ts +341 -347
  167. package/dist/project/project.operations.d.ts.map +1 -1
  168. package/dist/project/project.operations.js +366 -253
  169. package/dist/project/project.presentation.d.ts +2 -7
  170. package/dist/project/project.presentation.d.ts.map +1 -1
  171. package/dist/project/project.presentation.js +174 -61
  172. package/dist/project/project.schema.d.ts +191 -196
  173. package/dist/project/project.schema.d.ts.map +1 -1
  174. package/dist/project/project.schema.js +125 -205
  175. package/dist/saas-boilerplate.feature.d.ts +1 -6
  176. package/dist/saas-boilerplate.feature.d.ts.map +1 -1
  177. package/dist/saas-boilerplate.feature.js +87 -206
  178. package/dist/seeders/index.d.ts +4 -8
  179. package/dist/seeders/index.d.ts.map +1 -1
  180. package/dist/seeders/index.js +18 -16
  181. package/dist/settings/index.d.ts +6 -3
  182. package/dist/settings/index.d.ts.map +1 -0
  183. package/dist/settings/index.js +75 -3
  184. package/dist/settings/settings.entity.d.ts +23 -28
  185. package/dist/settings/settings.entity.d.ts.map +1 -1
  186. package/dist/settings/settings.entity.js +72 -75
  187. package/dist/settings/settings.enum.d.ts +1 -6
  188. package/dist/settings/settings.enum.d.ts.map +1 -1
  189. package/dist/settings/settings.enum.js +10 -19
  190. package/dist/shared/mock-data.d.ts +74 -77
  191. package/dist/shared/mock-data.d.ts.map +1 -1
  192. package/dist/shared/mock-data.js +102 -135
  193. package/dist/shared/overlay-types.d.ts +25 -28
  194. package/dist/shared/overlay-types.d.ts.map +1 -1
  195. package/dist/shared/overlay-types.js +1 -0
  196. package/dist/tests/operations.test-spec.d.ts +4 -9
  197. package/dist/tests/operations.test-spec.d.ts.map +1 -1
  198. package/dist/tests/operations.test-spec.js +108 -118
  199. package/dist/ui/SaasDashboard.d.ts +1 -6
  200. package/dist/ui/SaasDashboard.d.ts.map +1 -1
  201. package/dist/ui/SaasDashboard.js +977 -286
  202. package/dist/ui/SaasProjectList.d.ts +4 -11
  203. package/dist/ui/SaasProjectList.d.ts.map +1 -1
  204. package/dist/ui/SaasProjectList.js +159 -72
  205. package/dist/ui/SaasSettingsPanel.d.ts +1 -6
  206. package/dist/ui/SaasSettingsPanel.d.ts.map +1 -1
  207. package/dist/ui/SaasSettingsPanel.js +142 -134
  208. package/dist/ui/hooks/index.d.ts +3 -3
  209. package/dist/ui/hooks/index.d.ts.map +1 -0
  210. package/dist/ui/hooks/index.js +158 -4
  211. package/dist/ui/hooks/useProjectList.d.ts +26 -30
  212. package/dist/ui/hooks/useProjectList.d.ts.map +1 -1
  213. package/dist/ui/hooks/useProjectList.js +63 -71
  214. package/dist/ui/hooks/useProjectMutations.d.ts +20 -24
  215. package/dist/ui/hooks/useProjectMutations.d.ts.map +1 -1
  216. package/dist/ui/hooks/useProjectMutations.js +88 -142
  217. package/dist/ui/index.d.ts +8 -14
  218. package/dist/ui/index.d.ts.map +1 -0
  219. package/dist/ui/index.js +1809 -15
  220. package/dist/ui/modals/CreateProjectModal.d.ts +10 -19
  221. package/dist/ui/modals/CreateProjectModal.d.ts.map +1 -1
  222. package/dist/ui/modals/CreateProjectModal.js +150 -135
  223. package/dist/ui/modals/ProjectActionsModal.d.ts +20 -33
  224. package/dist/ui/modals/ProjectActionsModal.d.ts.map +1 -1
  225. package/dist/ui/modals/ProjectActionsModal.js +333 -289
  226. package/dist/ui/modals/index.d.ts +3 -3
  227. package/dist/ui/modals/index.d.ts.map +1 -0
  228. package/dist/ui/modals/index.js +487 -3
  229. package/dist/ui/overlays/demo-overlays.d.ts +10 -8
  230. package/dist/ui/overlays/demo-overlays.d.ts.map +1 -1
  231. package/dist/ui/overlays/demo-overlays.js +60 -68
  232. package/dist/ui/overlays/index.d.ts +2 -2
  233. package/dist/ui/overlays/index.d.ts.map +1 -0
  234. package/dist/ui/overlays/index.js +62 -3
  235. package/dist/ui/renderers/index.d.ts +3 -3
  236. package/dist/ui/renderers/index.d.ts.map +1 -0
  237. package/dist/ui/renderers/index.js +675 -3
  238. package/dist/ui/renderers/project-list.markdown.d.ts +15 -14
  239. package/dist/ui/renderers/project-list.markdown.d.ts.map +1 -1
  240. package/dist/ui/renderers/project-list.markdown.js +496 -146
  241. package/dist/ui/renderers/project-list.renderer.d.ts +6 -7
  242. package/dist/ui/renderers/project-list.renderer.d.ts.map +1 -1
  243. package/dist/ui/renderers/project-list.renderer.js +176 -15
  244. package/package.json +508 -98
  245. package/tsdown.config.js +1 -2
  246. package/.turbo/turbo-build$colon$bundle.log +0 -180
  247. package/dist/billing/billing.entity.js.map +0 -1
  248. package/dist/billing/billing.enum.js.map +0 -1
  249. package/dist/billing/billing.event.js.map +0 -1
  250. package/dist/billing/billing.handler.js.map +0 -1
  251. package/dist/billing/billing.operations.js.map +0 -1
  252. package/dist/billing/billing.presentation.js.map +0 -1
  253. package/dist/billing/billing.schema.js.map +0 -1
  254. package/dist/dashboard/dashboard.presentation.js.map +0 -1
  255. package/dist/docs/saas-boilerplate.docblock.js.map +0 -1
  256. package/dist/example.js.map +0 -1
  257. package/dist/handlers/saas.handlers.js.map +0 -1
  258. package/dist/index.js.map +0 -1
  259. package/dist/presentations/index.js.map +0 -1
  260. package/dist/project/project.entity.js.map +0 -1
  261. package/dist/project/project.enum.js.map +0 -1
  262. package/dist/project/project.event.js.map +0 -1
  263. package/dist/project/project.handler.js.map +0 -1
  264. package/dist/project/project.operations.js.map +0 -1
  265. package/dist/project/project.presentation.js.map +0 -1
  266. package/dist/project/project.schema.js.map +0 -1
  267. package/dist/saas-boilerplate.feature.js.map +0 -1
  268. package/dist/seeders/index.js.map +0 -1
  269. package/dist/settings/settings.entity.js.map +0 -1
  270. package/dist/settings/settings.enum.js.map +0 -1
  271. package/dist/shared/mock-data.js.map +0 -1
  272. package/dist/tests/operations.test-spec.js.map +0 -1
  273. package/dist/ui/SaasDashboard.js.map +0 -1
  274. package/dist/ui/SaasProjectList.js.map +0 -1
  275. package/dist/ui/SaasSettingsPanel.js.map +0 -1
  276. package/dist/ui/hooks/useProjectList.js.map +0 -1
  277. package/dist/ui/hooks/useProjectMutations.js.map +0 -1
  278. package/dist/ui/modals/CreateProjectModal.js.map +0 -1
  279. package/dist/ui/modals/ProjectActionsModal.js.map +0 -1
  280. package/dist/ui/overlays/demo-overlays.js.map +0 -1
  281. package/dist/ui/renderers/project-list.markdown.js.map +0 -1
  282. package/dist/ui/renderers/project-list.renderer.js.map +0 -1
  283. package/tsconfig.tsbuildinfo +0 -1
@@ -1,5 +1,359 @@
1
- import { mockCheckFeatureAccessHandler, mockGetSubscriptionHandler, mockGetUsageSummaryHandler, mockRecordUsageHandler } from "../billing/billing.handler.js";
2
- import { mockCreateProjectHandler, mockDeleteProjectHandler, mockGetProjectHandler, mockListProjectsHandler, mockUpdateProjectHandler } from "../project/project.handler.js";
3
- import { createSaasHandlers } from "./saas.handlers.js";
1
+ // @bun
2
+ // src/shared/mock-data.ts
3
+ var MOCK_PROJECTS = [
4
+ {
5
+ id: "proj-1",
6
+ name: "Marketing Website",
7
+ description: "Main company website redesign project",
8
+ slug: "marketing-website",
9
+ organizationId: "demo-org",
10
+ createdBy: "user-1",
11
+ status: "ACTIVE",
12
+ isPublic: false,
13
+ tags: ["marketing", "website", "redesign"],
14
+ createdAt: new Date("2024-01-15T10:00:00Z"),
15
+ updatedAt: new Date("2024-03-20T14:30:00Z")
16
+ },
17
+ {
18
+ id: "proj-2",
19
+ name: "Mobile App v2",
20
+ description: "Next generation mobile application",
21
+ slug: "mobile-app-v2",
22
+ organizationId: "demo-org",
23
+ createdBy: "user-2",
24
+ status: "ACTIVE",
25
+ isPublic: false,
26
+ tags: ["mobile", "app", "v2"],
27
+ createdAt: new Date("2024-02-01T09:00:00Z"),
28
+ updatedAt: new Date("2024-04-05T11:15:00Z")
29
+ },
30
+ {
31
+ id: "proj-3",
32
+ name: "API Integration",
33
+ description: "Third-party API integration project",
34
+ slug: "api-integration",
35
+ organizationId: "demo-org",
36
+ createdBy: "user-1",
37
+ status: "DRAFT",
38
+ isPublic: false,
39
+ tags: ["api", "integration"],
40
+ createdAt: new Date("2024-03-10T08:00:00Z"),
41
+ updatedAt: new Date("2024-03-10T08:00:00Z")
42
+ },
43
+ {
44
+ id: "proj-4",
45
+ name: "Analytics Dashboard",
46
+ description: "Internal analytics and reporting dashboard",
47
+ slug: "analytics-dashboard",
48
+ organizationId: "demo-org",
49
+ createdBy: "user-3",
50
+ status: "ARCHIVED",
51
+ isPublic: true,
52
+ tags: ["analytics", "dashboard", "reporting"],
53
+ createdAt: new Date("2023-10-01T12:00:00Z"),
54
+ updatedAt: new Date("2024-02-28T16:45:00Z")
55
+ }
56
+ ];
57
+ var MOCK_SUBSCRIPTION = {
58
+ id: "sub-1",
59
+ organizationId: "demo-org",
60
+ planId: "pro",
61
+ planName: "Professional",
62
+ status: "ACTIVE",
63
+ currentPeriodStart: new Date("2024-04-01T00:00:00Z"),
64
+ currentPeriodEnd: new Date("2024-05-01T00:00:00Z"),
65
+ limits: {
66
+ projects: 25,
67
+ users: 10,
68
+ storage: 50,
69
+ apiCalls: 1e5
70
+ },
71
+ usage: {
72
+ projects: 4,
73
+ users: 5,
74
+ storage: 12.5,
75
+ apiCalls: 45230
76
+ }
77
+ };
78
+ var MOCK_USAGE_SUMMARY = {
79
+ organizationId: "demo-org",
80
+ period: "current_month",
81
+ apiCalls: {
82
+ total: 45230,
83
+ limit: 1e5,
84
+ percentUsed: 45.23
85
+ },
86
+ storage: {
87
+ totalGb: 12.5,
88
+ limitGb: 50,
89
+ percentUsed: 25
90
+ },
91
+ activeProjects: 4,
92
+ activeUsers: 5,
93
+ breakdown: [
94
+ { date: "2024-04-01", apiCalls: 3200, storageGb: 12.1 },
95
+ { date: "2024-04-02", apiCalls: 2800, storageGb: 12.2 },
96
+ { date: "2024-04-03", apiCalls: 4100, storageGb: 12.3 },
97
+ { date: "2024-04-04", apiCalls: 3600, storageGb: 12.4 },
98
+ { date: "2024-04-05", apiCalls: 3800, storageGb: 12.5 }
99
+ ]
100
+ };
4
101
 
5
- export { createSaasHandlers, mockCheckFeatureAccessHandler, mockCreateProjectHandler, mockDeleteProjectHandler, mockGetProjectHandler, mockGetSubscriptionHandler, mockGetUsageSummaryHandler, mockListProjectsHandler, mockRecordUsageHandler, mockUpdateProjectHandler };
102
+ // src/billing/billing.handler.ts
103
+ async function mockGetSubscriptionHandler() {
104
+ return MOCK_SUBSCRIPTION;
105
+ }
106
+ async function mockGetUsageSummaryHandler(input) {
107
+ return {
108
+ ...MOCK_USAGE_SUMMARY,
109
+ period: input.period ?? "current_month"
110
+ };
111
+ }
112
+ async function mockRecordUsageHandler(input) {
113
+ const currentUsage = MOCK_USAGE_SUMMARY.apiCalls.total;
114
+ const newTotal = currentUsage + input.quantity;
115
+ return {
116
+ recorded: true,
117
+ newTotal
118
+ };
119
+ }
120
+ async function mockCheckFeatureAccessHandler(input) {
121
+ const { feature } = input;
122
+ const featureMap = {
123
+ custom_domains: {
124
+ allowed: true
125
+ },
126
+ api_access: {
127
+ allowed: true,
128
+ currentUsage: MOCK_USAGE_SUMMARY.apiCalls.total,
129
+ limit: MOCK_USAGE_SUMMARY.apiCalls.limit
130
+ },
131
+ advanced_analytics: {
132
+ allowed: false,
133
+ reason: "FEATURE_NOT_INCLUDED"
134
+ },
135
+ unlimited_projects: {
136
+ allowed: false,
137
+ reason: "PLAN_LIMIT",
138
+ currentUsage: MOCK_SUBSCRIPTION.usage.projects,
139
+ limit: MOCK_SUBSCRIPTION.limits.projects
140
+ }
141
+ };
142
+ return featureMap[feature] ?? { allowed: true };
143
+ }
144
+
145
+ // src/project/project.handler.ts
146
+ async function mockListProjectsHandler(input) {
147
+ const { status, search, limit = 20, offset = 0 } = input;
148
+ let filtered = [...MOCK_PROJECTS];
149
+ if (status && status !== "all") {
150
+ filtered = filtered.filter((p) => p.status === status);
151
+ }
152
+ if (search) {
153
+ const q = search.toLowerCase();
154
+ filtered = filtered.filter((p) => p.name.toLowerCase().includes(q) || p.description?.toLowerCase().includes(q) || p.tags.some((t) => t.toLowerCase().includes(q)));
155
+ }
156
+ filtered.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());
157
+ const total = filtered.length;
158
+ const projects = filtered.slice(offset, offset + limit);
159
+ return {
160
+ projects,
161
+ total
162
+ };
163
+ }
164
+ async function mockGetProjectHandler(input) {
165
+ const project = MOCK_PROJECTS.find((p) => p.id === input.projectId);
166
+ if (!project) {
167
+ throw new Error("NOT_FOUND");
168
+ }
169
+ return project;
170
+ }
171
+ async function mockCreateProjectHandler(input, context) {
172
+ if (input.slug) {
173
+ const exists = MOCK_PROJECTS.some((p) => p.slug === input.slug);
174
+ if (exists) {
175
+ throw new Error("SLUG_EXISTS");
176
+ }
177
+ }
178
+ const now = new Date;
179
+ return {
180
+ id: `proj-${Date.now()}`,
181
+ name: input.name,
182
+ description: input.description,
183
+ slug: input.slug ?? input.name.toLowerCase().replace(/\s+/g, "-"),
184
+ organizationId: context.organizationId,
185
+ createdBy: context.userId,
186
+ status: "DRAFT",
187
+ isPublic: input.isPublic ?? false,
188
+ tags: input.tags ?? [],
189
+ createdAt: now,
190
+ updatedAt: now
191
+ };
192
+ }
193
+ async function mockUpdateProjectHandler(input) {
194
+ const project = MOCK_PROJECTS.find((p) => p.id === input.projectId);
195
+ if (!project) {
196
+ throw new Error("NOT_FOUND");
197
+ }
198
+ return {
199
+ ...project,
200
+ name: input.name ?? project.name,
201
+ description: input.description ?? project.description,
202
+ slug: input.slug ?? project.slug,
203
+ isPublic: input.isPublic ?? project.isPublic,
204
+ tags: input.tags ?? project.tags,
205
+ status: input.status ?? project.status,
206
+ updatedAt: new Date
207
+ };
208
+ }
209
+ async function mockDeleteProjectHandler(input) {
210
+ const project = MOCK_PROJECTS.find((p) => p.id === input.projectId);
211
+ if (!project) {
212
+ throw new Error("NOT_FOUND");
213
+ }
214
+ return { success: true };
215
+ }
216
+
217
+ // src/handlers/saas.handlers.ts
218
+ import { web } from "@contractspec/lib.runtime-sandbox";
219
+ var { generateId } = web;
220
+ function rowToProject(row) {
221
+ return {
222
+ id: row.id,
223
+ projectId: row.projectId,
224
+ organizationId: row.organizationId,
225
+ name: row.name,
226
+ description: row.description ?? undefined,
227
+ status: row.status,
228
+ tier: row.tier,
229
+ createdAt: new Date(row.createdAt),
230
+ updatedAt: new Date(row.updatedAt)
231
+ };
232
+ }
233
+ function rowToSubscription(row) {
234
+ return {
235
+ id: row.id,
236
+ projectId: row.projectId,
237
+ organizationId: row.organizationId,
238
+ plan: row.plan,
239
+ status: row.status,
240
+ billingCycle: row.billingCycle,
241
+ currentPeriodStart: new Date(row.currentPeriodStart),
242
+ currentPeriodEnd: new Date(row.currentPeriodEnd),
243
+ cancelAtPeriodEnd: Boolean(row.cancelAtPeriodEnd)
244
+ };
245
+ }
246
+ function createSaasHandlers(db) {
247
+ async function listProjects(input) {
248
+ const {
249
+ projectId,
250
+ organizationId,
251
+ status,
252
+ search,
253
+ limit = 20,
254
+ offset = 0
255
+ } = input;
256
+ let whereClause = "WHERE projectId = ?";
257
+ const params = [projectId];
258
+ if (organizationId) {
259
+ whereClause += " AND organizationId = ?";
260
+ params.push(organizationId);
261
+ }
262
+ if (status && status !== "all") {
263
+ whereClause += " AND status = ?";
264
+ params.push(status);
265
+ }
266
+ if (search) {
267
+ whereClause += " AND (name LIKE ? OR description LIKE ?)";
268
+ params.push(`%${search}%`, `%${search}%`);
269
+ }
270
+ const countResult = (await db.query(`SELECT COUNT(*) as count FROM saas_project ${whereClause}`, params)).rows;
271
+ const total = countResult[0]?.count ?? 0;
272
+ const rows = (await db.query(`SELECT * FROM saas_project ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
273
+ return {
274
+ items: rows.map(rowToProject),
275
+ total,
276
+ hasMore: offset + rows.length < total
277
+ };
278
+ }
279
+ async function getProject(id) {
280
+ const rows = (await db.query(`SELECT * FROM saas_project WHERE id = ?`, [id])).rows;
281
+ return rows[0] ? rowToProject(rows[0]) : null;
282
+ }
283
+ async function createProject(input, context) {
284
+ const id = generateId("proj");
285
+ const now = new Date().toISOString();
286
+ await db.execute(`INSERT INTO saas_project (id, projectId, organizationId, name, description, status, tier, createdAt, updatedAt)
287
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
288
+ id,
289
+ context.projectId,
290
+ context.organizationId,
291
+ input.name,
292
+ input.description ?? null,
293
+ "DRAFT",
294
+ input.tier ?? "FREE",
295
+ now,
296
+ now
297
+ ]);
298
+ const rows = (await db.query(`SELECT * FROM saas_project WHERE id = ?`, [id])).rows;
299
+ return rowToProject(rows[0]);
300
+ }
301
+ async function updateProject(input) {
302
+ const now = new Date().toISOString();
303
+ const updates = ["updatedAt = ?"];
304
+ const params = [now];
305
+ if (input.name !== undefined) {
306
+ updates.push("name = ?");
307
+ params.push(input.name);
308
+ }
309
+ if (input.description !== undefined) {
310
+ updates.push("description = ?");
311
+ params.push(input.description);
312
+ }
313
+ if (input.status !== undefined) {
314
+ updates.push("status = ?");
315
+ params.push(input.status);
316
+ }
317
+ params.push(input.id);
318
+ await db.execute(`UPDATE saas_project SET ${updates.join(", ")} WHERE id = ?`, params);
319
+ const rows = (await db.query(`SELECT * FROM saas_project WHERE id = ?`, [input.id])).rows;
320
+ if (!rows[0]) {
321
+ throw new Error("NOT_FOUND");
322
+ }
323
+ return rowToProject(rows[0]);
324
+ }
325
+ async function deleteProject(id) {
326
+ await db.execute(`DELETE FROM saas_project WHERE id = ?`, [id]);
327
+ }
328
+ async function getSubscription(input) {
329
+ let query = `SELECT * FROM saas_subscription WHERE projectId = ?`;
330
+ const params = [input.projectId];
331
+ if (input.organizationId) {
332
+ query += " AND organizationId = ?";
333
+ params.push(input.organizationId);
334
+ }
335
+ query += " LIMIT 1";
336
+ const rows = (await db.query(query, params)).rows;
337
+ return rows[0] ? rowToSubscription(rows[0]) : null;
338
+ }
339
+ return {
340
+ listProjects,
341
+ getProject,
342
+ createProject,
343
+ updateProject,
344
+ deleteProject,
345
+ getSubscription
346
+ };
347
+ }
348
+ export {
349
+ mockUpdateProjectHandler,
350
+ mockRecordUsageHandler,
351
+ mockListProjectsHandler,
352
+ mockGetUsageSummaryHandler,
353
+ mockGetSubscriptionHandler,
354
+ mockGetProjectHandler,
355
+ mockDeleteProjectHandler,
356
+ mockCreateProjectHandler,
357
+ mockCheckFeatureAccessHandler,
358
+ createSaasHandlers
359
+ };
@@ -1,67 +1,68 @@
1
- import { DatabasePort } from "@contractspec/lib.runtime-sandbox";
2
-
3
- //#region src/handlers/saas.handlers.d.ts
4
- interface Project {
5
- id: string;
6
- projectId: string;
7
- organizationId: string;
8
- name: string;
9
- description?: string;
10
- status: 'DRAFT' | 'ACTIVE' | 'ARCHIVED';
11
- tier: 'FREE' | 'PRO' | 'ENTERPRISE';
12
- createdAt: Date;
13
- updatedAt: Date;
1
+ /**
2
+ * Runtime-local SaaS Boilerplate handlers
3
+ *
4
+ * Database-backed handlers for project and billing management.
5
+ */
6
+ import type { DatabasePort } from '@contractspec/lib.runtime-sandbox';
7
+ export interface Project {
8
+ id: string;
9
+ projectId: string;
10
+ organizationId: string;
11
+ name: string;
12
+ description?: string;
13
+ status: 'DRAFT' | 'ACTIVE' | 'ARCHIVED';
14
+ tier: 'FREE' | 'PRO' | 'ENTERPRISE';
15
+ createdAt: Date;
16
+ updatedAt: Date;
14
17
  }
15
- interface Subscription {
16
- id: string;
17
- projectId: string;
18
- organizationId: string;
19
- plan: 'FREE' | 'PRO' | 'ENTERPRISE';
20
- status: 'ACTIVE' | 'PAST_DUE' | 'CANCELED';
21
- billingCycle: 'MONTHLY' | 'YEARLY';
22
- currentPeriodStart: Date;
23
- currentPeriodEnd: Date;
24
- cancelAtPeriodEnd: boolean;
18
+ export interface Subscription {
19
+ id: string;
20
+ projectId: string;
21
+ organizationId: string;
22
+ plan: 'FREE' | 'PRO' | 'ENTERPRISE';
23
+ status: 'ACTIVE' | 'PAST_DUE' | 'CANCELED';
24
+ billingCycle: 'MONTHLY' | 'YEARLY';
25
+ currentPeriodStart: Date;
26
+ currentPeriodEnd: Date;
27
+ cancelAtPeriodEnd: boolean;
25
28
  }
26
- interface ListProjectsInput {
27
- projectId: string;
28
- organizationId?: string;
29
- status?: Project['status'] | 'all';
30
- search?: string;
31
- limit?: number;
32
- offset?: number;
29
+ export interface ListProjectsInput {
30
+ projectId: string;
31
+ organizationId?: string;
32
+ status?: Project['status'] | 'all';
33
+ search?: string;
34
+ limit?: number;
35
+ offset?: number;
33
36
  }
34
- interface ListProjectsOutput {
35
- items: Project[];
36
- total: number;
37
- hasMore: boolean;
37
+ export interface ListProjectsOutput {
38
+ items: Project[];
39
+ total: number;
40
+ hasMore: boolean;
38
41
  }
39
- interface CreateProjectInput {
40
- name: string;
41
- description?: string;
42
- tier?: Project['tier'];
42
+ export interface CreateProjectInput {
43
+ name: string;
44
+ description?: string;
45
+ tier?: Project['tier'];
43
46
  }
44
- interface UpdateProjectInput {
45
- id: string;
46
- name?: string;
47
- description?: string;
48
- status?: Project['status'];
47
+ export interface UpdateProjectInput {
48
+ id: string;
49
+ name?: string;
50
+ description?: string;
51
+ status?: Project['status'];
49
52
  }
50
- declare function createSaasHandlers(db: DatabasePort): {
51
- listProjects: (input: ListProjectsInput) => Promise<ListProjectsOutput>;
52
- getProject: (id: string) => Promise<Project | null>;
53
- createProject: (input: CreateProjectInput, context: {
54
- projectId: string;
55
- organizationId: string;
56
- }) => Promise<Project>;
57
- updateProject: (input: UpdateProjectInput) => Promise<Project>;
58
- deleteProject: (id: string) => Promise<void>;
59
- getSubscription: (input: {
60
- projectId: string;
61
- organizationId?: string;
62
- }) => Promise<Subscription | null>;
53
+ export declare function createSaasHandlers(db: DatabasePort): {
54
+ listProjects: (input: ListProjectsInput) => Promise<ListProjectsOutput>;
55
+ getProject: (id: string) => Promise<Project | null>;
56
+ createProject: (input: CreateProjectInput, context: {
57
+ projectId: string;
58
+ organizationId: string;
59
+ }) => Promise<Project>;
60
+ updateProject: (input: UpdateProjectInput) => Promise<Project>;
61
+ deleteProject: (id: string) => Promise<void>;
62
+ getSubscription: (input: {
63
+ projectId: string;
64
+ organizationId?: string;
65
+ }) => Promise<Subscription | null>;
63
66
  };
64
- type SaasHandlers = ReturnType<typeof createSaasHandlers>;
65
- //#endregion
66
- export { CreateProjectInput, ListProjectsInput, ListProjectsOutput, Project, SaasHandlers, Subscription, UpdateProjectInput, createSaasHandlers };
67
+ export type SaasHandlers = ReturnType<typeof createSaasHandlers>;
67
68
  //# sourceMappingURL=saas.handlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"saas.handlers.d.ts","names":[],"sources":["../../src/handlers/saas.handlers.ts"],"mappings":";;;UAYiB,OAAA;EACf,EAAA;EACA,SAAA;EACA,cAAA;EACA,IAAA;EACA,WAAA;EACA,MAAA;EACA,IAAA;EACA,SAAA,EAAW,IAAA;EACX,SAAA,EAAW,IAAA;AAAA;AAAA,UAGI,YAAA;EACf,EAAA;EACA,SAAA;EACA,cAAA;EACA,IAAA;EACA,MAAA;EACA,YAAA;EACA,kBAAA,EAAoB,IAAA;EACpB,gBAAA,EAAkB,IAAA;EAClB,iBAAA;AAAA;AAAA,UAGe,iBAAA;EACf,SAAA;EACA,cAAA;EACA,MAAA,GAAS,OAAA;EACT,MAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,UAGe,kBAAA;EACf,KAAA,EAAO,OAAA;EACP,KAAA;EACA,OAAA;AAAA;AAAA,UAGe,kBAAA;EACf,IAAA;EACA,WAAA;EACA,IAAA,GAAO,OAAA;AAAA;AAAA,UAGQ,kBAAA;EACf,EAAA;EACA,IAAA;EACA,WAAA;EACA,MAAA,GAAS,OAAA;AAAA;AAAA,iBA2DK,kBAAA,CAAmB,EAAA,EAAI,YAAA;wBAK5B,iBAAA,KACN,OAAA,CAAQ,kBAAA;8BAqD4B,OAAA,CAAQ,OAAA;yBAWtC,kBAAA,EAAkB,OAAA;IACd,SAAA;IAAmB,cAAA;EAAA,MAC7B,OAAA,CAAQ,OAAA;yBA8ByB,kBAAA,KAAqB,OAAA,CAAQ,OAAA;iCAyCvB,OAAA;;IAQxC,SAAA;IACA,cAAA;EAAA,MACE,OAAA,CAAQ,YAAA;AAAA;AAAA,KA0BF,YAAA,GAAe,UAAA,QAAkB,kBAAA"}
1
+ {"version":3,"file":"saas.handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/saas.handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAOtE,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IACxC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,YAAY,CAAC;IACpC,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,YAAY,CAAC;IACpC,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;IAC3C,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAC;IACnC,kBAAkB,EAAE,IAAI,CAAC;IACzB,gBAAgB,EAAE,IAAI,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC5B;AA0DD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY;0BAKxC,iBAAiB,KACvB,OAAO,CAAC,kBAAkB,CAAC;qBAqDA,MAAM,KAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;2BAWrD,kBAAkB,WAChB;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,KACrD,OAAO,CAAC,OAAO,CAAC;2BA8BiB,kBAAkB,KAAG,OAAO,CAAC,OAAO,CAAC;wBAyCxC,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;6BAOjB;QACpC,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,KAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;EAwBjC;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}