@contractspec/example.saas-boilerplate 0.0.0-canary-20260113170453

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 (226) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +188 -0
  2. package/.turbo/turbo-build.log +189 -0
  3. package/CHANGELOG.md +440 -0
  4. package/LICENSE +21 -0
  5. package/README.md +155 -0
  6. package/dist/billing/billing.entity.d.ts +61 -0
  7. package/dist/billing/billing.entity.d.ts.map +1 -0
  8. package/dist/billing/billing.entity.js +122 -0
  9. package/dist/billing/billing.entity.js.map +1 -0
  10. package/dist/billing/billing.enum.d.ts +16 -0
  11. package/dist/billing/billing.enum.d.ts.map +1 -0
  12. package/dist/billing/billing.enum.js +27 -0
  13. package/dist/billing/billing.enum.js.map +1 -0
  14. package/dist/billing/billing.event.d.ts +86 -0
  15. package/dist/billing/billing.event.d.ts.map +1 -0
  16. package/dist/billing/billing.event.js +153 -0
  17. package/dist/billing/billing.event.js.map +1 -0
  18. package/dist/billing/billing.handler.d.ts +82 -0
  19. package/dist/billing/billing.handler.d.ts.map +1 -0
  20. package/dist/billing/billing.handler.js +58 -0
  21. package/dist/billing/billing.handler.js.map +1 -0
  22. package/dist/billing/billing.operations.d.ts +166 -0
  23. package/dist/billing/billing.operations.d.ts.map +1 -0
  24. package/dist/billing/billing.operations.js +181 -0
  25. package/dist/billing/billing.operations.js.map +1 -0
  26. package/dist/billing/billing.presentation.d.ts +14 -0
  27. package/dist/billing/billing.presentation.d.ts.map +1 -0
  28. package/dist/billing/billing.presentation.js +59 -0
  29. package/dist/billing/billing.presentation.js.map +1 -0
  30. package/dist/billing/billing.schema.d.ts +201 -0
  31. package/dist/billing/billing.schema.d.ts.map +1 -0
  32. package/dist/billing/billing.schema.js +214 -0
  33. package/dist/billing/billing.schema.js.map +1 -0
  34. package/dist/billing/index.d.ts +8 -0
  35. package/dist/billing/index.js +9 -0
  36. package/dist/dashboard/dashboard.presentation.d.ts +14 -0
  37. package/dist/dashboard/dashboard.presentation.d.ts.map +1 -0
  38. package/dist/dashboard/dashboard.presentation.js +55 -0
  39. package/dist/dashboard/dashboard.presentation.js.map +1 -0
  40. package/dist/dashboard/index.d.ts +2 -0
  41. package/dist/dashboard/index.js +3 -0
  42. package/dist/docs/index.d.ts +1 -0
  43. package/dist/docs/index.js +1 -0
  44. package/dist/docs/saas-boilerplate.docblock.d.ts +1 -0
  45. package/dist/docs/saas-boilerplate.docblock.js +100 -0
  46. package/dist/docs/saas-boilerplate.docblock.js.map +1 -0
  47. package/dist/example.d.ts +7 -0
  48. package/dist/example.d.ts.map +1 -0
  49. package/dist/example.js +53 -0
  50. package/dist/example.js.map +1 -0
  51. package/dist/handlers/index.d.ts +4 -0
  52. package/dist/handlers/index.js +5 -0
  53. package/dist/handlers/saas.handlers.d.ts +68 -0
  54. package/dist/handlers/saas.handlers.d.ts.map +1 -0
  55. package/dist/handlers/saas.handlers.js +148 -0
  56. package/dist/handlers/saas.handlers.js.map +1 -0
  57. package/dist/index.d.ts +54 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +81 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/presentations/index.d.ts +17 -0
  62. package/dist/presentations/index.d.ts.map +1 -0
  63. package/dist/presentations/index.js +17 -0
  64. package/dist/presentations/index.js.map +1 -0
  65. package/dist/project/index.d.ts +8 -0
  66. package/dist/project/index.js +9 -0
  67. package/dist/project/project.entity.d.ts +40 -0
  68. package/dist/project/project.entity.d.ts.map +1 -0
  69. package/dist/project/project.entity.js +85 -0
  70. package/dist/project/project.entity.js.map +1 -0
  71. package/dist/project/project.enum.d.ts +16 -0
  72. package/dist/project/project.enum.d.ts.map +1 -0
  73. package/dist/project/project.enum.js +26 -0
  74. package/dist/project/project.enum.js.map +1 -0
  75. package/dist/project/project.event.d.ts +92 -0
  76. package/dist/project/project.event.d.ts.map +1 -0
  77. package/dist/project/project.event.js +165 -0
  78. package/dist/project/project.event.js.map +1 -0
  79. package/dist/project/project.handler.d.ts +72 -0
  80. package/dist/project/project.handler.d.ts.map +1 -0
  81. package/dist/project/project.handler.js +82 -0
  82. package/dist/project/project.handler.js.map +1 -0
  83. package/dist/project/project.operations.d.ts +419 -0
  84. package/dist/project/project.operations.d.ts.map +1 -0
  85. package/dist/project/project.operations.js +260 -0
  86. package/dist/project/project.operations.js.map +1 -0
  87. package/dist/project/project.presentation.d.ts +14 -0
  88. package/dist/project/project.presentation.d.ts.map +1 -0
  89. package/dist/project/project.presentation.js +65 -0
  90. package/dist/project/project.presentation.js.map +1 -0
  91. package/dist/project/project.schema.d.ts +235 -0
  92. package/dist/project/project.schema.d.ts.map +1 -0
  93. package/dist/project/project.schema.js +215 -0
  94. package/dist/project/project.schema.js.map +1 -0
  95. package/dist/saas-boilerplate.feature.d.ts +12 -0
  96. package/dist/saas-boilerplate.feature.d.ts.map +1 -0
  97. package/dist/saas-boilerplate.feature.js +208 -0
  98. package/dist/saas-boilerplate.feature.js.map +1 -0
  99. package/dist/seeders/index.d.ts +10 -0
  100. package/dist/seeders/index.d.ts.map +1 -0
  101. package/dist/seeders/index.js +19 -0
  102. package/dist/seeders/index.js.map +1 -0
  103. package/dist/settings/index.d.ts +3 -0
  104. package/dist/settings/index.js +4 -0
  105. package/dist/settings/settings.entity.d.ts +37 -0
  106. package/dist/settings/settings.entity.d.ts.map +1 -0
  107. package/dist/settings/settings.entity.js +78 -0
  108. package/dist/settings/settings.entity.js.map +1 -0
  109. package/dist/settings/settings.enum.d.ts +10 -0
  110. package/dist/settings/settings.enum.d.ts.map +1 -0
  111. package/dist/settings/settings.enum.js +21 -0
  112. package/dist/settings/settings.enum.js.map +1 -0
  113. package/dist/shared/mock-data.d.ts +86 -0
  114. package/dist/shared/mock-data.d.ts.map +1 -0
  115. package/dist/shared/mock-data.js +138 -0
  116. package/dist/shared/mock-data.js.map +1 -0
  117. package/dist/shared/overlay-types.d.ts +34 -0
  118. package/dist/shared/overlay-types.d.ts.map +1 -0
  119. package/dist/shared/overlay-types.js +0 -0
  120. package/dist/tests/operations.test-spec.d.ts +10 -0
  121. package/dist/tests/operations.test-spec.d.ts.map +1 -0
  122. package/dist/tests/operations.test-spec.js +123 -0
  123. package/dist/tests/operations.test-spec.js.map +1 -0
  124. package/dist/ui/SaasDashboard.d.ts +7 -0
  125. package/dist/ui/SaasDashboard.d.ts.map +1 -0
  126. package/dist/ui/SaasDashboard.js +298 -0
  127. package/dist/ui/SaasDashboard.js.map +1 -0
  128. package/dist/ui/SaasProjectList.d.ts +14 -0
  129. package/dist/ui/SaasProjectList.d.ts.map +1 -0
  130. package/dist/ui/SaasProjectList.js +76 -0
  131. package/dist/ui/SaasProjectList.js.map +1 -0
  132. package/dist/ui/SaasSettingsPanel.d.ts +7 -0
  133. package/dist/ui/SaasSettingsPanel.d.ts.map +1 -0
  134. package/dist/ui/SaasSettingsPanel.js +138 -0
  135. package/dist/ui/SaasSettingsPanel.js.map +1 -0
  136. package/dist/ui/hooks/index.d.ts +3 -0
  137. package/dist/ui/hooks/index.js +6 -0
  138. package/dist/ui/hooks/useProjectList.d.ts +34 -0
  139. package/dist/ui/hooks/useProjectList.d.ts.map +1 -0
  140. package/dist/ui/hooks/useProjectList.js +75 -0
  141. package/dist/ui/hooks/useProjectList.js.map +1 -0
  142. package/dist/ui/hooks/useProjectMutations.d.ts +28 -0
  143. package/dist/ui/hooks/useProjectMutations.d.ts.map +1 -0
  144. package/dist/ui/hooks/useProjectMutations.js +146 -0
  145. package/dist/ui/hooks/useProjectMutations.js.map +1 -0
  146. package/dist/ui/index.d.ts +14 -0
  147. package/dist/ui/index.js +15 -0
  148. package/dist/ui/modals/CreateProjectModal.d.ts +23 -0
  149. package/dist/ui/modals/CreateProjectModal.d.ts.map +1 -0
  150. package/dist/ui/modals/CreateProjectModal.js +139 -0
  151. package/dist/ui/modals/CreateProjectModal.js.map +1 -0
  152. package/dist/ui/modals/ProjectActionsModal.d.ts +38 -0
  153. package/dist/ui/modals/ProjectActionsModal.d.ts.map +1 -0
  154. package/dist/ui/modals/ProjectActionsModal.js +292 -0
  155. package/dist/ui/modals/ProjectActionsModal.js.map +1 -0
  156. package/dist/ui/modals/index.d.ts +3 -0
  157. package/dist/ui/modals/index.js +4 -0
  158. package/dist/ui/overlays/demo-overlays.d.ts +19 -0
  159. package/dist/ui/overlays/demo-overlays.d.ts.map +1 -0
  160. package/dist/ui/overlays/demo-overlays.js +70 -0
  161. package/dist/ui/overlays/demo-overlays.js.map +1 -0
  162. package/dist/ui/overlays/index.d.ts +2 -0
  163. package/dist/ui/overlays/index.js +3 -0
  164. package/dist/ui/renderers/index.d.ts +3 -0
  165. package/dist/ui/renderers/index.js +4 -0
  166. package/dist/ui/renderers/project-list.markdown.d.ts +31 -0
  167. package/dist/ui/renderers/project-list.markdown.d.ts.map +1 -0
  168. package/dist/ui/renderers/project-list.markdown.js +148 -0
  169. package/dist/ui/renderers/project-list.markdown.js.map +1 -0
  170. package/dist/ui/renderers/project-list.renderer.d.ts +9 -0
  171. package/dist/ui/renderers/project-list.renderer.d.ts.map +1 -0
  172. package/dist/ui/renderers/project-list.renderer.js +17 -0
  173. package/dist/ui/renderers/project-list.renderer.js.map +1 -0
  174. package/example.ts +1 -0
  175. package/package.json +135 -0
  176. package/src/billing/billing.entity.ts +158 -0
  177. package/src/billing/billing.enum.ts +23 -0
  178. package/src/billing/billing.event.ts +108 -0
  179. package/src/billing/billing.handler.ts +137 -0
  180. package/src/billing/billing.operations.ts +187 -0
  181. package/src/billing/billing.presentation.ts +56 -0
  182. package/src/billing/billing.schema.ts +133 -0
  183. package/src/billing/index.ts +64 -0
  184. package/src/dashboard/dashboard.presentation.ts +56 -0
  185. package/src/dashboard/index.ts +8 -0
  186. package/src/docs/index.ts +1 -0
  187. package/src/docs/saas-boilerplate.docblock.ts +98 -0
  188. package/src/example.ts +38 -0
  189. package/src/handlers/index.ts +23 -0
  190. package/src/handlers/saas.handlers.ts +300 -0
  191. package/src/index.ts +76 -0
  192. package/src/presentations/index.ts +36 -0
  193. package/src/project/index.ts +66 -0
  194. package/src/project/project.entity.ts +93 -0
  195. package/src/project/project.enum.ts +22 -0
  196. package/src/project/project.event.ts +128 -0
  197. package/src/project/project.handler.ts +168 -0
  198. package/src/project/project.operations.ts +272 -0
  199. package/src/project/project.presentation.ts +58 -0
  200. package/src/project/project.schema.ts +147 -0
  201. package/src/saas-boilerplate.feature.ts +113 -0
  202. package/src/seeders/index.ts +28 -0
  203. package/src/settings/index.ts +9 -0
  204. package/src/settings/settings.entity.ts +89 -0
  205. package/src/settings/settings.enum.ts +11 -0
  206. package/src/shared/mock-data.ts +110 -0
  207. package/src/shared/overlay-types.ts +39 -0
  208. package/src/tests/operations.test-spec.ts +109 -0
  209. package/src/ui/SaasDashboard.tsx +325 -0
  210. package/src/ui/SaasProjectList.tsx +113 -0
  211. package/src/ui/SaasSettingsPanel.tsx +96 -0
  212. package/src/ui/hooks/index.ts +10 -0
  213. package/src/ui/hooks/useProjectList.ts +95 -0
  214. package/src/ui/hooks/useProjectMutations.ts +166 -0
  215. package/src/ui/index.ts +18 -0
  216. package/src/ui/modals/CreateProjectModal.tsx +176 -0
  217. package/src/ui/modals/ProjectActionsModal.tsx +346 -0
  218. package/src/ui/modals/index.ts +2 -0
  219. package/src/ui/overlays/demo-overlays.ts +74 -0
  220. package/src/ui/overlays/index.ts +1 -0
  221. package/src/ui/renderers/index.ts +7 -0
  222. package/src/ui/renderers/project-list.markdown.ts +239 -0
  223. package/src/ui/renderers/project-list.renderer.tsx +22 -0
  224. package/tsconfig.json +10 -0
  225. package/tsconfig.tsbuildinfo +1 -0
  226. package/tsdown.config.js +7 -0
@@ -0,0 +1,122 @@
1
+ import { defineEntity, defineEntityEnum, field, index } from "@contractspec/lib.schema";
2
+
3
+ //#region src/billing/billing.entity.ts
4
+ /**
5
+ * Subscription status enum for entities.
6
+ */
7
+ const SubscriptionStatusEnum = defineEntityEnum({
8
+ name: "SubscriptionStatus",
9
+ values: [
10
+ "TRIALING",
11
+ "ACTIVE",
12
+ "PAST_DUE",
13
+ "CANCELED",
14
+ "PAUSED"
15
+ ],
16
+ schema: "saas_app",
17
+ description: "Status of a subscription."
18
+ });
19
+ /**
20
+ * Subscription entity - organization subscription info.
21
+ */
22
+ const SubscriptionEntity = defineEntity({
23
+ name: "Subscription",
24
+ description: "Organization subscription/plan information.",
25
+ schema: "saas_app",
26
+ map: "subscription",
27
+ fields: {
28
+ id: field.id(),
29
+ organizationId: field.foreignKey({ isUnique: true }),
30
+ planId: field.string({ description: "Plan identifier" }),
31
+ planName: field.string({ description: "Plan display name" }),
32
+ status: field.enum("SubscriptionStatus"),
33
+ currentPeriodStart: field.dateTime(),
34
+ currentPeriodEnd: field.dateTime(),
35
+ trialEndsAt: field.dateTime({ isOptional: true }),
36
+ cancelAtPeriodEnd: field.boolean({ default: false }),
37
+ canceledAt: field.dateTime({ isOptional: true }),
38
+ stripeSubscriptionId: field.string({ isOptional: true }),
39
+ stripeCustomerId: field.string({ isOptional: true }),
40
+ metadata: field.json({ isOptional: true }),
41
+ createdAt: field.createdAt(),
42
+ updatedAt: field.updatedAt()
43
+ },
44
+ enums: [SubscriptionStatusEnum]
45
+ });
46
+ /**
47
+ * BillingUsage entity - track feature usage.
48
+ */
49
+ const BillingUsageEntity = defineEntity({
50
+ name: "BillingUsage",
51
+ description: "Track usage of metered features.",
52
+ schema: "saas_app",
53
+ map: "billing_usage",
54
+ fields: {
55
+ id: field.id(),
56
+ organizationId: field.foreignKey(),
57
+ feature: field.string({ description: "Feature being tracked (e.g., \"api_calls\", \"storage_gb\")" }),
58
+ quantity: field.int({ description: "Usage quantity" }),
59
+ unit: field.string({
60
+ isOptional: true,
61
+ description: "Unit of measurement"
62
+ }),
63
+ billingPeriod: field.string({ description: "Billing period (e.g., \"2024-01\")" }),
64
+ recordedAt: field.dateTime({ description: "When usage was recorded" }),
65
+ sourceId: field.string({
66
+ isOptional: true,
67
+ description: "Source of usage (e.g., request ID)"
68
+ }),
69
+ sourceType: field.string({ isOptional: true }),
70
+ metadata: field.json({ isOptional: true })
71
+ },
72
+ indexes: [index.on([
73
+ "organizationId",
74
+ "feature",
75
+ "billingPeriod"
76
+ ]), index.on(["organizationId", "recordedAt"])]
77
+ });
78
+ /**
79
+ * UsageLimit entity - feature usage limits per plan.
80
+ */
81
+ const UsageLimitEntity = defineEntity({
82
+ name: "UsageLimit",
83
+ description: "Usage limits per plan/organization.",
84
+ schema: "saas_app",
85
+ map: "usage_limit",
86
+ fields: {
87
+ id: field.id(),
88
+ planId: field.string({
89
+ isOptional: true,
90
+ description: "Plan this limit applies to"
91
+ }),
92
+ organizationId: field.string({
93
+ isOptional: true,
94
+ description: "Org-specific override"
95
+ }),
96
+ feature: field.string({ description: "Feature being limited" }),
97
+ limit: field.int({ description: "Maximum allowed usage" }),
98
+ resetPeriod: field.string({
99
+ default: "\"monthly\"",
100
+ description: "When limit resets"
101
+ }),
102
+ isSoftLimit: field.boolean({
103
+ default: false,
104
+ description: "Whether to warn vs block"
105
+ }),
106
+ overage: field.boolean({
107
+ default: false,
108
+ description: "Whether overage is allowed"
109
+ }),
110
+ overageRate: field.float({
111
+ isOptional: true,
112
+ description: "Cost per unit over limit"
113
+ }),
114
+ createdAt: field.createdAt(),
115
+ updatedAt: field.updatedAt()
116
+ },
117
+ indexes: [index.unique(["planId", "feature"])]
118
+ });
119
+
120
+ //#endregion
121
+ export { BillingUsageEntity, SubscriptionEntity, SubscriptionStatusEnum, UsageLimitEntity };
122
+ //# sourceMappingURL=billing.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.entity.js","names":[],"sources":["../../src/billing/billing.entity.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Subscription status enum for entities.\n */\nexport const SubscriptionStatusEnum = defineEntityEnum({\n name: 'SubscriptionStatus',\n values: ['TRIALING', 'ACTIVE', 'PAST_DUE', 'CANCELED', 'PAUSED'] as const,\n schema: 'saas_app',\n description: 'Status of a subscription.',\n});\n\n/**\n * Subscription entity - organization subscription info.\n */\nexport const SubscriptionEntity = defineEntity({\n name: 'Subscription',\n description: 'Organization subscription/plan information.',\n schema: 'saas_app',\n map: 'subscription',\n fields: {\n id: field.id(),\n organizationId: field.foreignKey({ isUnique: true }),\n\n // Plan info\n planId: field.string({ description: 'Plan identifier' }),\n planName: field.string({ description: 'Plan display name' }),\n\n // Status\n status: field.enum('SubscriptionStatus'),\n\n // Billing cycle\n currentPeriodStart: field.dateTime(),\n currentPeriodEnd: field.dateTime(),\n\n // Trial\n trialEndsAt: field.dateTime({ isOptional: true }),\n\n // Cancellation\n cancelAtPeriodEnd: field.boolean({ default: false }),\n canceledAt: field.dateTime({ isOptional: true }),\n\n // External reference\n stripeSubscriptionId: field.string({ isOptional: true }),\n stripeCustomerId: field.string({ isOptional: true }),\n\n // Metadata\n metadata: field.json({ isOptional: true }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n },\n enums: [SubscriptionStatusEnum],\n});\n\n/**\n * BillingUsage entity - track feature usage.\n */\nexport const BillingUsageEntity = defineEntity({\n name: 'BillingUsage',\n description: 'Track usage of metered features.',\n schema: 'saas_app',\n map: 'billing_usage',\n fields: {\n id: field.id(),\n organizationId: field.foreignKey(),\n\n // Feature\n feature: field.string({\n description: 'Feature being tracked (e.g., \"api_calls\", \"storage_gb\")',\n }),\n\n // Usage\n quantity: field.int({ description: 'Usage quantity' }),\n unit: field.string({\n isOptional: true,\n description: 'Unit of measurement',\n }),\n\n // Period\n billingPeriod: field.string({\n description: 'Billing period (e.g., \"2024-01\")',\n }),\n\n // Aggregation\n recordedAt: field.dateTime({ description: 'When usage was recorded' }),\n\n // Source\n sourceId: field.string({\n isOptional: true,\n description: 'Source of usage (e.g., request ID)',\n }),\n sourceType: field.string({ isOptional: true }),\n\n // Metadata\n metadata: field.json({ isOptional: true }),\n },\n indexes: [\n index.on(['organizationId', 'feature', 'billingPeriod']),\n index.on(['organizationId', 'recordedAt']),\n ],\n});\n\n/**\n * UsageLimit entity - feature usage limits per plan.\n */\nexport const UsageLimitEntity = defineEntity({\n name: 'UsageLimit',\n description: 'Usage limits per plan/organization.',\n schema: 'saas_app',\n map: 'usage_limit',\n fields: {\n id: field.id(),\n\n // Scope\n planId: field.string({\n isOptional: true,\n description: 'Plan this limit applies to',\n }),\n organizationId: field.string({\n isOptional: true,\n description: 'Org-specific override',\n }),\n\n // Limit\n feature: field.string({ description: 'Feature being limited' }),\n limit: field.int({ description: 'Maximum allowed usage' }),\n resetPeriod: field.string({\n default: '\"monthly\"',\n description: 'When limit resets',\n }),\n\n // Soft/hard limit\n isSoftLimit: field.boolean({\n default: false,\n description: 'Whether to warn vs block',\n }),\n overage: field.boolean({\n default: false,\n description: 'Whether overage is allowed',\n }),\n overageRate: field.float({\n isOptional: true,\n description: 'Cost per unit over limit',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n },\n indexes: [index.unique(['planId', 'feature'])],\n});\n"],"mappings":";;;;;;AAUA,MAAa,yBAAyB,iBAAiB;CACrD,MAAM;CACN,QAAQ;EAAC;EAAY;EAAU;EAAY;EAAY;EAAS;CAChE,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,qBAAqB,aAAa;CAC7C,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,IAAI;EACd,gBAAgB,MAAM,WAAW,EAAE,UAAU,MAAM,CAAC;EAGpD,QAAQ,MAAM,OAAO,EAAE,aAAa,mBAAmB,CAAC;EACxD,UAAU,MAAM,OAAO,EAAE,aAAa,qBAAqB,CAAC;EAG5D,QAAQ,MAAM,KAAK,qBAAqB;EAGxC,oBAAoB,MAAM,UAAU;EACpC,kBAAkB,MAAM,UAAU;EAGlC,aAAa,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC;EAGjD,mBAAmB,MAAM,QAAQ,EAAE,SAAS,OAAO,CAAC;EACpD,YAAY,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC;EAGhD,sBAAsB,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EACxD,kBAAkB,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAGpD,UAAU,MAAM,KAAK,EAAE,YAAY,MAAM,CAAC;EAG1C,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAC7B;CACD,OAAO,CAAC,uBAAuB;CAChC,CAAC;;;;AAKF,MAAa,qBAAqB,aAAa;CAC7C,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,IAAI;EACd,gBAAgB,MAAM,YAAY;EAGlC,SAAS,MAAM,OAAO,EACpB,aAAa,+DACd,CAAC;EAGF,UAAU,MAAM,IAAI,EAAE,aAAa,kBAAkB,CAAC;EACtD,MAAM,MAAM,OAAO;GACjB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,eAAe,MAAM,OAAO,EAC1B,aAAa,sCACd,CAAC;EAGF,YAAY,MAAM,SAAS,EAAE,aAAa,2BAA2B,CAAC;EAGtE,UAAU,MAAM,OAAO;GACrB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,YAAY,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAG9C,UAAU,MAAM,KAAK,EAAE,YAAY,MAAM,CAAC;EAC3C;CACD,SAAS,CACP,MAAM,GAAG;EAAC;EAAkB;EAAW;EAAgB,CAAC,EACxD,MAAM,GAAG,CAAC,kBAAkB,aAAa,CAAC,CAC3C;CACF,CAAC;;;;AAKF,MAAa,mBAAmB,aAAa;CAC3C,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,IAAI;EAGd,QAAQ,MAAM,OAAO;GACnB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,gBAAgB,MAAM,OAAO;GAC3B,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,SAAS,MAAM,OAAO,EAAE,aAAa,yBAAyB,CAAC;EAC/D,OAAO,MAAM,IAAI,EAAE,aAAa,yBAAyB,CAAC;EAC1D,aAAa,MAAM,OAAO;GACxB,SAAS;GACT,aAAa;GACd,CAAC;EAGF,aAAa,MAAM,QAAQ;GACzB,SAAS;GACT,aAAa;GACd,CAAC;EACF,SAAS,MAAM,QAAQ;GACrB,SAAS;GACT,aAAa;GACd,CAAC;EACF,aAAa,MAAM,MAAM;GACvB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAC7B;CACD,SAAS,CAAC,MAAM,OAAO,CAAC,UAAU,UAAU,CAAC,CAAC;CAC/C,CAAC"}
@@ -0,0 +1,16 @@
1
+ import * as _contractspec_lib_schema303 from "@contractspec/lib.schema";
2
+
3
+ //#region src/billing/billing.enum.d.ts
4
+
5
+ /**
6
+ * Subscription status enum for contract schemas.
7
+ * Note: Entity enum is defined separately in billing.entity.ts
8
+ */
9
+ declare const SubscriptionStatusSchemaEnum: _contractspec_lib_schema303.EnumType<[string, string, string, string, string]>;
10
+ /**
11
+ * Feature access reason enum.
12
+ */
13
+ declare const FeatureAccessReasonEnum: _contractspec_lib_schema303.EnumType<[string, string, string, string]>;
14
+ //#endregion
15
+ export { FeatureAccessReasonEnum, SubscriptionStatusSchemaEnum };
16
+ //# sourceMappingURL=billing.enum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.enum.d.ts","names":[],"sources":["../../src/billing/billing.enum.ts"],"sourcesContent":[],"mappings":";;;;;;;AAMA;AAWa,cAXA,4BAgBX,EAVA,2BAAA,CANuC,QAWL,CAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA;;;;cAAvB,yBAKX,2BAAA,CALkC"}
@@ -0,0 +1,27 @@
1
+ import { defineEnum } from "@contractspec/lib.schema";
2
+
3
+ //#region src/billing/billing.enum.ts
4
+ /**
5
+ * Subscription status enum for contract schemas.
6
+ * Note: Entity enum is defined separately in billing.entity.ts
7
+ */
8
+ const SubscriptionStatusSchemaEnum = defineEnum("SubscriptionStatus", [
9
+ "TRIALING",
10
+ "ACTIVE",
11
+ "PAST_DUE",
12
+ "CANCELED",
13
+ "PAUSED"
14
+ ]);
15
+ /**
16
+ * Feature access reason enum.
17
+ */
18
+ const FeatureAccessReasonEnum = defineEnum("FeatureAccessReason", [
19
+ "included",
20
+ "limit_available",
21
+ "limit_reached",
22
+ "not_in_plan"
23
+ ]);
24
+
25
+ //#endregion
26
+ export { FeatureAccessReasonEnum, SubscriptionStatusSchemaEnum };
27
+ //# sourceMappingURL=billing.enum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.enum.js","names":[],"sources":["../../src/billing/billing.enum.ts"],"sourcesContent":["import { defineEnum } from '@contractspec/lib.schema';\n\n/**\n * Subscription status enum for contract schemas.\n * Note: Entity enum is defined separately in billing.entity.ts\n */\nexport const SubscriptionStatusSchemaEnum = defineEnum('SubscriptionStatus', [\n 'TRIALING',\n 'ACTIVE',\n 'PAST_DUE',\n 'CANCELED',\n 'PAUSED',\n]);\n\n/**\n * Feature access reason enum.\n */\nexport const FeatureAccessReasonEnum = defineEnum('FeatureAccessReason', [\n 'included',\n 'limit_available',\n 'limit_reached',\n 'not_in_plan',\n]);\n"],"mappings":";;;;;;;AAMA,MAAa,+BAA+B,WAAW,sBAAsB;CAC3E;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,0BAA0B,WAAW,uBAAuB;CACvE;CACA;CACA;CACA;CACD,CAAC"}
@@ -0,0 +1,86 @@
1
+ import * as _contractspec_lib_contracts20 from "@contractspec/lib.contracts";
2
+ import * as _contractspec_lib_schema305 from "@contractspec/lib.schema";
3
+
4
+ //#region src/billing/billing.event.d.ts
5
+ /**
6
+ * Event: Feature usage has been recorded.
7
+ */
8
+ declare const UsageRecordedEvent: _contractspec_lib_contracts20.EventSpec<_contractspec_lib_schema305.SchemaModel<{
9
+ organizationId: {
10
+ type: _contractspec_lib_schema305.FieldType<string, string>;
11
+ isOptional: false;
12
+ };
13
+ feature: {
14
+ type: _contractspec_lib_schema305.FieldType<string, string>;
15
+ isOptional: false;
16
+ };
17
+ quantity: {
18
+ type: _contractspec_lib_schema305.FieldType<number, number>;
19
+ isOptional: false;
20
+ };
21
+ billingPeriod: {
22
+ type: _contractspec_lib_schema305.FieldType<string, string>;
23
+ isOptional: false;
24
+ };
25
+ recordedAt: {
26
+ type: _contractspec_lib_schema305.FieldType<Date, string>;
27
+ isOptional: false;
28
+ };
29
+ }>>;
30
+ /**
31
+ * Event: Usage limit has been reached for a feature.
32
+ */
33
+ declare const UsageLimitReachedEvent: _contractspec_lib_contracts20.EventSpec<_contractspec_lib_schema305.SchemaModel<{
34
+ organizationId: {
35
+ type: _contractspec_lib_schema305.FieldType<string, string>;
36
+ isOptional: false;
37
+ };
38
+ feature: {
39
+ type: _contractspec_lib_schema305.FieldType<string, string>;
40
+ isOptional: false;
41
+ };
42
+ limit: {
43
+ type: _contractspec_lib_schema305.FieldType<number, number>;
44
+ isOptional: false;
45
+ };
46
+ currentUsage: {
47
+ type: _contractspec_lib_schema305.FieldType<number, number>;
48
+ isOptional: false;
49
+ };
50
+ reachedAt: {
51
+ type: _contractspec_lib_schema305.FieldType<Date, string>;
52
+ isOptional: false;
53
+ };
54
+ }>>;
55
+ /**
56
+ * Event: Subscription status has changed.
57
+ */
58
+ declare const SubscriptionChangedEvent: _contractspec_lib_contracts20.EventSpec<_contractspec_lib_schema305.SchemaModel<{
59
+ organizationId: {
60
+ type: _contractspec_lib_schema305.FieldType<string, string>;
61
+ isOptional: false;
62
+ };
63
+ previousPlan: {
64
+ type: _contractspec_lib_schema305.FieldType<string, string>;
65
+ isOptional: true;
66
+ };
67
+ newPlan: {
68
+ type: _contractspec_lib_schema305.FieldType<string, string>;
69
+ isOptional: false;
70
+ };
71
+ previousStatus: {
72
+ type: _contractspec_lib_schema305.FieldType<string, string>;
73
+ isOptional: true;
74
+ };
75
+ newStatus: {
76
+ type: _contractspec_lib_schema305.FieldType<string, string>;
77
+ isOptional: false;
78
+ };
79
+ changedAt: {
80
+ type: _contractspec_lib_schema305.FieldType<Date, string>;
81
+ isOptional: false;
82
+ };
83
+ }>>;
84
+ //#endregion
85
+ export { SubscriptionChangedEvent, UsageLimitReachedEvent, UsageRecordedEvent };
86
+ //# sourceMappingURL=billing.event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.event.d.ts","names":[],"sources":["../../src/billing/billing.event.ts"],"sourcesContent":[],"mappings":";;;;;;;cAmEa,oBAAkB,6BAAA,CAAA,sCAAA;EAAlB,cAAA,EAAA;IAUX,IAAA,EAAA,2BAAA,CAAA,SAAA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;;;EAV6B,QAAA,EAAA;IAAA,IAAA,uCAAA,CAAA,MAAA,EAAA,MAAA,CAAA;IAelB,UAAA,EAAA,KAAA;EAUX,CAAA;;;;;;+CAViC,KAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAAA,KAAA;EAAA,CAAA;AAenC,CAAA,CAAA,CAAA;;;;cAfa,wBAAsB,6BAAA,CAAA,sCAAA;;UAUjC,2BAAA,CAAA;;;EAKmC,OAAA,EAAA;IAAA,IAAA,uCAAA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;;;;;;;;;;;;;;;cAAxB,0BAAwB,6BAAA,CAAA,sCAAA;;UAUnC,2BAAA,CAAA"}
@@ -0,0 +1,153 @@
1
+ import { defineEvent } from "@contractspec/lib.contracts";
2
+ import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
3
+
4
+ //#region src/billing/billing.event.ts
5
+ /**
6
+ * Payload when feature usage is recorded.
7
+ */
8
+ const UsageRecordedPayload = defineSchemaModel({
9
+ name: "UsageRecordedPayload",
10
+ description: "Payload when feature usage is recorded",
11
+ fields: {
12
+ organizationId: {
13
+ type: ScalarTypeEnum.String_unsecure(),
14
+ isOptional: false
15
+ },
16
+ feature: {
17
+ type: ScalarTypeEnum.String_unsecure(),
18
+ isOptional: false
19
+ },
20
+ quantity: {
21
+ type: ScalarTypeEnum.Int_unsecure(),
22
+ isOptional: false
23
+ },
24
+ billingPeriod: {
25
+ type: ScalarTypeEnum.String_unsecure(),
26
+ isOptional: false
27
+ },
28
+ recordedAt: {
29
+ type: ScalarTypeEnum.DateTime(),
30
+ isOptional: false
31
+ }
32
+ }
33
+ });
34
+ /**
35
+ * Payload when usage limit is reached.
36
+ */
37
+ const UsageLimitReachedPayload = defineSchemaModel({
38
+ name: "UsageLimitReachedPayload",
39
+ description: "Payload when usage limit is reached",
40
+ fields: {
41
+ organizationId: {
42
+ type: ScalarTypeEnum.String_unsecure(),
43
+ isOptional: false
44
+ },
45
+ feature: {
46
+ type: ScalarTypeEnum.String_unsecure(),
47
+ isOptional: false
48
+ },
49
+ limit: {
50
+ type: ScalarTypeEnum.Int_unsecure(),
51
+ isOptional: false
52
+ },
53
+ currentUsage: {
54
+ type: ScalarTypeEnum.Int_unsecure(),
55
+ isOptional: false
56
+ },
57
+ reachedAt: {
58
+ type: ScalarTypeEnum.DateTime(),
59
+ isOptional: false
60
+ }
61
+ }
62
+ });
63
+ /**
64
+ * Payload when subscription status changes.
65
+ */
66
+ const SubscriptionChangedPayload = defineSchemaModel({
67
+ name: "SubscriptionChangedPayload",
68
+ description: "Payload when subscription status changes",
69
+ fields: {
70
+ organizationId: {
71
+ type: ScalarTypeEnum.String_unsecure(),
72
+ isOptional: false
73
+ },
74
+ previousPlan: {
75
+ type: ScalarTypeEnum.String_unsecure(),
76
+ isOptional: true
77
+ },
78
+ newPlan: {
79
+ type: ScalarTypeEnum.String_unsecure(),
80
+ isOptional: false
81
+ },
82
+ previousStatus: {
83
+ type: ScalarTypeEnum.String_unsecure(),
84
+ isOptional: true
85
+ },
86
+ newStatus: {
87
+ type: ScalarTypeEnum.String_unsecure(),
88
+ isOptional: false
89
+ },
90
+ changedAt: {
91
+ type: ScalarTypeEnum.DateTime(),
92
+ isOptional: false
93
+ }
94
+ }
95
+ });
96
+ /**
97
+ * Event: Feature usage has been recorded.
98
+ */
99
+ const UsageRecordedEvent = defineEvent({
100
+ meta: {
101
+ key: "billing.usage.recorded",
102
+ version: "1.0.0",
103
+ description: "Feature usage has been recorded.",
104
+ stability: "stable",
105
+ owners: ["@saas-team"],
106
+ tags: [
107
+ "billing",
108
+ "usage",
109
+ "recorded"
110
+ ]
111
+ },
112
+ payload: UsageRecordedPayload
113
+ });
114
+ /**
115
+ * Event: Usage limit has been reached for a feature.
116
+ */
117
+ const UsageLimitReachedEvent = defineEvent({
118
+ meta: {
119
+ key: "billing.limit.reached",
120
+ version: "1.0.0",
121
+ description: "Usage limit has been reached for a feature.",
122
+ stability: "stable",
123
+ owners: ["@saas-team"],
124
+ tags: [
125
+ "billing",
126
+ "limit",
127
+ "reached"
128
+ ]
129
+ },
130
+ payload: UsageLimitReachedPayload
131
+ });
132
+ /**
133
+ * Event: Subscription status has changed.
134
+ */
135
+ const SubscriptionChangedEvent = defineEvent({
136
+ meta: {
137
+ key: "billing.subscription.changed",
138
+ version: "1.0.0",
139
+ description: "Subscription status has changed.",
140
+ stability: "stable",
141
+ owners: ["@saas-team"],
142
+ tags: [
143
+ "billing",
144
+ "subscription",
145
+ "changed"
146
+ ]
147
+ },
148
+ payload: SubscriptionChangedPayload
149
+ });
150
+
151
+ //#endregion
152
+ export { SubscriptionChangedEvent, UsageLimitReachedEvent, UsageRecordedEvent };
153
+ //# sourceMappingURL=billing.event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.event.js","names":[],"sources":["../../src/billing/billing.event.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\nimport { defineEvent } from '@contractspec/lib.contracts';\n\n/**\n * Payload when feature usage is recorded.\n */\nconst UsageRecordedPayload = defineSchemaModel({\n name: 'UsageRecordedPayload',\n description: 'Payload when feature usage is recorded',\n fields: {\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n feature: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n quantity: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n billingPeriod: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n recordedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * Payload when usage limit is reached.\n */\nconst UsageLimitReachedPayload = defineSchemaModel({\n name: 'UsageLimitReachedPayload',\n description: 'Payload when usage limit is reached',\n fields: {\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n feature: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n currentUsage: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n reachedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * Payload when subscription status changes.\n */\nconst SubscriptionChangedPayload = defineSchemaModel({\n name: 'SubscriptionChangedPayload',\n description: 'Payload when subscription status changes',\n fields: {\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n previousPlan: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n newPlan: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n previousStatus: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n newStatus: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n changedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * Event: Feature usage has been recorded.\n */\nexport const UsageRecordedEvent = defineEvent({\n meta: {\n key: 'billing.usage.recorded',\n version: '1.0.0',\n description: 'Feature usage has been recorded.',\n stability: 'stable',\n owners: ['@saas-team'],\n tags: ['billing', 'usage', 'recorded'],\n },\n payload: UsageRecordedPayload,\n});\n\n/**\n * Event: Usage limit has been reached for a feature.\n */\nexport const UsageLimitReachedEvent = defineEvent({\n meta: {\n key: 'billing.limit.reached',\n version: '1.0.0',\n description: 'Usage limit has been reached for a feature.',\n stability: 'stable',\n owners: ['@saas-team'],\n tags: ['billing', 'limit', 'reached'],\n },\n payload: UsageLimitReachedPayload,\n});\n\n/**\n * Event: Subscription status has changed.\n */\nexport const SubscriptionChangedEvent = defineEvent({\n meta: {\n key: 'billing.subscription.changed',\n version: '1.0.0',\n description: 'Subscription status has changed.',\n stability: 'stable',\n owners: ['@saas-team'],\n tags: ['billing', 'subscription', 'changed'],\n },\n payload: SubscriptionChangedPayload,\n});\n"],"mappings":";;;;;;;AAMA,MAAM,uBAAuB,kBAAkB;CAC7C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,UAAU;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EACpE,eAAe;GACb,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,YAAY;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EACnE;CACF,CAAC;;;;AAKF,MAAM,2BAA2B,kBAAkB;CACjD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EACjE,cAAc;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EACxE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;;;;AAKF,MAAM,6BAA6B,kBAAkB;CACnD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,cAAc;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EAC1E,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,WAAW;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACxE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;;;;AAKF,MAAa,qBAAqB,YAAY;CAC5C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,aAAa;EACb,WAAW;EACX,QAAQ,CAAC,aAAa;EACtB,MAAM;GAAC;GAAW;GAAS;GAAW;EACvC;CACD,SAAS;CACV,CAAC;;;;AAKF,MAAa,yBAAyB,YAAY;CAChD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,aAAa;EACb,WAAW;EACX,QAAQ,CAAC,aAAa;EACtB,MAAM;GAAC;GAAW;GAAS;GAAU;EACtC;CACD,SAAS;CACV,CAAC;;;;AAKF,MAAa,2BAA2B,YAAY;CAClD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,aAAa;EACb,WAAW;EACX,QAAQ,CAAC,aAAa;EACtB,MAAM;GAAC;GAAW;GAAgB;GAAU;EAC7C;CACD,SAAS;CACV,CAAC"}
@@ -0,0 +1,82 @@
1
+ //#region src/billing/billing.handler.d.ts
2
+ interface Subscription {
3
+ id: string;
4
+ organizationId: string;
5
+ planId: string;
6
+ planName: string;
7
+ status: 'ACTIVE' | 'TRIALING' | 'PAST_DUE' | 'CANCELED' | 'UNPAID';
8
+ currentPeriodStart: Date;
9
+ currentPeriodEnd: Date;
10
+ limits: {
11
+ projects: number;
12
+ users: number;
13
+ storage: number;
14
+ apiCalls: number;
15
+ };
16
+ usage: {
17
+ projects: number;
18
+ users: number;
19
+ storage: number;
20
+ apiCalls: number;
21
+ };
22
+ }
23
+ interface UsageSummary {
24
+ organizationId: string;
25
+ period: string;
26
+ apiCalls: {
27
+ total: number;
28
+ limit: number;
29
+ percentUsed: number;
30
+ };
31
+ storage: {
32
+ totalGb: number;
33
+ limitGb: number;
34
+ percentUsed: number;
35
+ };
36
+ activeProjects: number;
37
+ activeUsers: number;
38
+ breakdown: {
39
+ date: string;
40
+ apiCalls: number;
41
+ storageGb: number;
42
+ }[];
43
+ }
44
+ interface RecordUsageInput {
45
+ metric: string;
46
+ quantity: number;
47
+ timestamp?: Date;
48
+ metadata?: Record<string, unknown>;
49
+ }
50
+ interface CheckFeatureAccessInput {
51
+ feature: string;
52
+ }
53
+ interface CheckFeatureAccessOutput {
54
+ allowed: boolean;
55
+ reason?: 'PLAN_LIMIT' | 'FEATURE_NOT_INCLUDED' | 'QUOTA_EXCEEDED' | 'SUBSCRIPTION_INACTIVE';
56
+ currentUsage?: number;
57
+ limit?: number;
58
+ }
59
+ /**
60
+ * Mock handler for GetSubscriptionContract.
61
+ */
62
+ declare function mockGetSubscriptionHandler(): Promise<Subscription>;
63
+ /**
64
+ * Mock handler for GetUsageSummaryContract.
65
+ */
66
+ declare function mockGetUsageSummaryHandler(input: {
67
+ period?: string;
68
+ }): Promise<UsageSummary>;
69
+ /**
70
+ * Mock handler for RecordUsageContract.
71
+ */
72
+ declare function mockRecordUsageHandler(input: RecordUsageInput): Promise<{
73
+ recorded: boolean;
74
+ newTotal: number;
75
+ }>;
76
+ /**
77
+ * Mock handler for CheckFeatureAccessContract.
78
+ */
79
+ declare function mockCheckFeatureAccessHandler(input: CheckFeatureAccessInput): Promise<CheckFeatureAccessOutput>;
80
+ //#endregion
81
+ export { CheckFeatureAccessInput, CheckFeatureAccessOutput, RecordUsageInput, Subscription, UsageSummary, mockCheckFeatureAccessHandler, mockGetSubscriptionHandler, mockGetUsageSummaryHandler, mockRecordUsageHandler };
82
+ //# sourceMappingURL=billing.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.handler.d.ts","names":[],"sources":["../../src/billing/billing.handler.ts"],"sourcesContent":[],"mappings":";UAMiB,YAAA;EAAA,EAAA,EAAA,MAAA;EAsBA,cAAA,EAAY,MAAA;EAsBZ,MAAA,EAAA,MAAA;EAOA,QAAA,EAAA,MAAA;EAIA,MAAA,EAAA,QAAA,GAAA,UAAwB,GAAA,UAAA,GAAA,UAAA,GAAA,QAAA;EAcnB,kBAAA,EA/DA,IA+DA;EAOA,gBAAA,EArEF,IAqEE;EAYA,MAAA,EAAA;IAeA,QAAA,EAAA,MAAA;IACb,KAAA,EAAA,MAAA;IACE,OAAA,EAAA,MAAA;IAAR,QAAA,EAAA,MAAA;EAAO,CAAA;;;;;;;;UAnFO,YAAA;;;;;;;;;;;;;;;;;;;;;UAsBA,gBAAA;;;cAGH;aACD;;UAGI,uBAAA;;;UAIA,wBAAA;;;;;;;;;iBAcK,0BAAA,CAAA,GAA8B,QAAQ;;;;iBAOtC,0BAAA;;IAElB,QAAQ;;;;iBAUU,sBAAA,QACb,mBACN;;;;;;;iBAamB,6BAAA,QACb,0BACN,QAAQ"}
@@ -0,0 +1,58 @@
1
+ import { MOCK_SUBSCRIPTION, MOCK_USAGE_SUMMARY } from "../shared/mock-data.js";
2
+
3
+ //#region src/billing/billing.handler.ts
4
+ /**
5
+ * Mock handlers for Billing contracts.
6
+ */
7
+ /**
8
+ * Mock handler for GetSubscriptionContract.
9
+ */
10
+ async function mockGetSubscriptionHandler() {
11
+ return MOCK_SUBSCRIPTION;
12
+ }
13
+ /**
14
+ * Mock handler for GetUsageSummaryContract.
15
+ */
16
+ async function mockGetUsageSummaryHandler(input) {
17
+ return {
18
+ ...MOCK_USAGE_SUMMARY,
19
+ period: input.period ?? "current_month"
20
+ };
21
+ }
22
+ /**
23
+ * Mock handler for RecordUsageContract.
24
+ */
25
+ async function mockRecordUsageHandler(input) {
26
+ return {
27
+ recorded: true,
28
+ newTotal: MOCK_USAGE_SUMMARY.apiCalls.total + input.quantity
29
+ };
30
+ }
31
+ /**
32
+ * Mock handler for CheckFeatureAccessContract.
33
+ */
34
+ async function mockCheckFeatureAccessHandler(input) {
35
+ const { feature } = input;
36
+ return {
37
+ custom_domains: { allowed: true },
38
+ api_access: {
39
+ allowed: true,
40
+ currentUsage: MOCK_USAGE_SUMMARY.apiCalls.total,
41
+ limit: MOCK_USAGE_SUMMARY.apiCalls.limit
42
+ },
43
+ advanced_analytics: {
44
+ allowed: false,
45
+ reason: "FEATURE_NOT_INCLUDED"
46
+ },
47
+ unlimited_projects: {
48
+ allowed: false,
49
+ reason: "PLAN_LIMIT",
50
+ currentUsage: MOCK_SUBSCRIPTION.usage.projects,
51
+ limit: MOCK_SUBSCRIPTION.limits.projects
52
+ }
53
+ }[feature] ?? { allowed: true };
54
+ }
55
+
56
+ //#endregion
57
+ export { mockCheckFeatureAccessHandler, mockGetSubscriptionHandler, mockGetUsageSummaryHandler, mockRecordUsageHandler };
58
+ //# sourceMappingURL=billing.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.handler.js","names":[],"sources":["../../src/billing/billing.handler.ts"],"sourcesContent":["/**\n * Mock handlers for Billing contracts.\n */\nimport { MOCK_SUBSCRIPTION, MOCK_USAGE_SUMMARY } from '../shared/mock-data';\n\n// Types inferred from contract schemas\nexport interface Subscription {\n id: string;\n organizationId: string;\n planId: string;\n planName: string;\n status: 'ACTIVE' | 'TRIALING' | 'PAST_DUE' | 'CANCELED' | 'UNPAID';\n currentPeriodStart: Date;\n currentPeriodEnd: Date;\n limits: {\n projects: number;\n users: number;\n storage: number;\n apiCalls: number;\n };\n usage: {\n projects: number;\n users: number;\n storage: number;\n apiCalls: number;\n };\n}\n\nexport interface UsageSummary {\n organizationId: string;\n period: string;\n apiCalls: {\n total: number;\n limit: number;\n percentUsed: number;\n };\n storage: {\n totalGb: number;\n limitGb: number;\n percentUsed: number;\n };\n activeProjects: number;\n activeUsers: number;\n breakdown: {\n date: string;\n apiCalls: number;\n storageGb: number;\n }[];\n}\n\nexport interface RecordUsageInput {\n metric: string;\n quantity: number;\n timestamp?: Date;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CheckFeatureAccessInput {\n feature: string;\n}\n\nexport interface CheckFeatureAccessOutput {\n allowed: boolean;\n reason?:\n | 'PLAN_LIMIT'\n | 'FEATURE_NOT_INCLUDED'\n | 'QUOTA_EXCEEDED'\n | 'SUBSCRIPTION_INACTIVE';\n currentUsage?: number;\n limit?: number;\n}\n\n/**\n * Mock handler for GetSubscriptionContract.\n */\nexport async function mockGetSubscriptionHandler(): Promise<Subscription> {\n return MOCK_SUBSCRIPTION;\n}\n\n/**\n * Mock handler for GetUsageSummaryContract.\n */\nexport async function mockGetUsageSummaryHandler(input: {\n period?: string;\n}): Promise<UsageSummary> {\n return {\n ...MOCK_USAGE_SUMMARY,\n period: input.period ?? 'current_month',\n };\n}\n\n/**\n * Mock handler for RecordUsageContract.\n */\nexport async function mockRecordUsageHandler(\n input: RecordUsageInput\n): Promise<{ recorded: boolean; newTotal: number }> {\n const currentUsage = MOCK_USAGE_SUMMARY.apiCalls.total;\n const newTotal = currentUsage + input.quantity;\n\n return {\n recorded: true,\n newTotal,\n };\n}\n\n/**\n * Mock handler for CheckFeatureAccessContract.\n */\nexport async function mockCheckFeatureAccessHandler(\n input: CheckFeatureAccessInput\n): Promise<CheckFeatureAccessOutput> {\n const { feature } = input;\n\n const featureMap: Record<string, CheckFeatureAccessOutput> = {\n custom_domains: {\n allowed: true,\n },\n api_access: {\n allowed: true,\n currentUsage: MOCK_USAGE_SUMMARY.apiCalls.total,\n limit: MOCK_USAGE_SUMMARY.apiCalls.limit,\n },\n advanced_analytics: {\n allowed: false,\n reason: 'FEATURE_NOT_INCLUDED',\n },\n unlimited_projects: {\n allowed: false,\n reason: 'PLAN_LIMIT',\n currentUsage: MOCK_SUBSCRIPTION.usage.projects,\n limit: MOCK_SUBSCRIPTION.limits.projects,\n },\n };\n\n return featureMap[feature] ?? { allowed: true };\n}\n"],"mappings":";;;;;;;;;AA2EA,eAAsB,6BAAoD;AACxE,QAAO;;;;;AAMT,eAAsB,2BAA2B,OAEvB;AACxB,QAAO;EACL,GAAG;EACH,QAAQ,MAAM,UAAU;EACzB;;;;;AAMH,eAAsB,uBACpB,OACkD;AAIlD,QAAO;EACL,UAAU;EACV,UALmB,mBAAmB,SAAS,QACjB,MAAM;EAKrC;;;;;AAMH,eAAsB,8BACpB,OACmC;CACnC,MAAM,EAAE,YAAY;AAuBpB,QArB6D;EAC3D,gBAAgB,EACd,SAAS,MACV;EACD,YAAY;GACV,SAAS;GACT,cAAc,mBAAmB,SAAS;GAC1C,OAAO,mBAAmB,SAAS;GACpC;EACD,oBAAoB;GAClB,SAAS;GACT,QAAQ;GACT;EACD,oBAAoB;GAClB,SAAS;GACT,QAAQ;GACR,cAAc,kBAAkB,MAAM;GACtC,OAAO,kBAAkB,OAAO;GACjC;EACF,CAEiB,YAAY,EAAE,SAAS,MAAM"}