@contractspec/example.saas-boilerplate 1.44.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 (142) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +113 -0
  2. package/.turbo/turbo-build.log +114 -0
  3. package/CHANGELOG.md +246 -0
  4. package/LICENSE +21 -0
  5. package/README.md +156 -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 +15 -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 +15 -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 +37 -0
  48. package/dist/example.d.ts.map +1 -0
  49. package/dist/example.js +46 -0
  50. package/dist/example.js.map +1 -0
  51. package/dist/handlers/index.d.ts +3 -0
  52. package/dist/handlers/index.js +4 -0
  53. package/dist/index.d.ts +42 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +69 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/presentations/index.d.ts +17 -0
  58. package/dist/presentations/index.d.ts.map +1 -0
  59. package/dist/presentations/index.js +17 -0
  60. package/dist/presentations/index.js.map +1 -0
  61. package/dist/project/index.d.ts +8 -0
  62. package/dist/project/index.js +9 -0
  63. package/dist/project/project.entity.d.ts +40 -0
  64. package/dist/project/project.entity.d.ts.map +1 -0
  65. package/dist/project/project.entity.js +85 -0
  66. package/dist/project/project.entity.js.map +1 -0
  67. package/dist/project/project.enum.d.ts +16 -0
  68. package/dist/project/project.enum.d.ts.map +1 -0
  69. package/dist/project/project.enum.js +26 -0
  70. package/dist/project/project.enum.js.map +1 -0
  71. package/dist/project/project.event.d.ts +92 -0
  72. package/dist/project/project.event.d.ts.map +1 -0
  73. package/dist/project/project.event.js +165 -0
  74. package/dist/project/project.event.js.map +1 -0
  75. package/dist/project/project.handler.d.ts +72 -0
  76. package/dist/project/project.handler.d.ts.map +1 -0
  77. package/dist/project/project.handler.js +82 -0
  78. package/dist/project/project.handler.js.map +1 -0
  79. package/dist/project/project.operations.d.ts +419 -0
  80. package/dist/project/project.operations.d.ts.map +1 -0
  81. package/dist/project/project.operations.js +260 -0
  82. package/dist/project/project.operations.js.map +1 -0
  83. package/dist/project/project.presentation.d.ts +15 -0
  84. package/dist/project/project.presentation.d.ts.map +1 -0
  85. package/dist/project/project.presentation.js +65 -0
  86. package/dist/project/project.presentation.js.map +1 -0
  87. package/dist/project/project.schema.d.ts +235 -0
  88. package/dist/project/project.schema.d.ts.map +1 -0
  89. package/dist/project/project.schema.js +215 -0
  90. package/dist/project/project.schema.js.map +1 -0
  91. package/dist/saas-boilerplate.feature.d.ts +12 -0
  92. package/dist/saas-boilerplate.feature.d.ts.map +1 -0
  93. package/dist/saas-boilerplate.feature.js +201 -0
  94. package/dist/saas-boilerplate.feature.js.map +1 -0
  95. package/dist/settings/index.d.ts +3 -0
  96. package/dist/settings/index.js +4 -0
  97. package/dist/settings/settings.entity.d.ts +37 -0
  98. package/dist/settings/settings.entity.d.ts.map +1 -0
  99. package/dist/settings/settings.entity.js +78 -0
  100. package/dist/settings/settings.entity.js.map +1 -0
  101. package/dist/settings/settings.enum.d.ts +10 -0
  102. package/dist/settings/settings.enum.d.ts.map +1 -0
  103. package/dist/settings/settings.enum.js +21 -0
  104. package/dist/settings/settings.enum.js.map +1 -0
  105. package/dist/shared/mock-data.d.ts +86 -0
  106. package/dist/shared/mock-data.d.ts.map +1 -0
  107. package/dist/shared/mock-data.js +138 -0
  108. package/dist/shared/mock-data.js.map +1 -0
  109. package/example.ts +1 -0
  110. package/package.json +113 -0
  111. package/src/billing/billing.entity.ts +158 -0
  112. package/src/billing/billing.enum.ts +23 -0
  113. package/src/billing/billing.event.ts +108 -0
  114. package/src/billing/billing.handler.ts +137 -0
  115. package/src/billing/billing.operations.ts +187 -0
  116. package/src/billing/billing.presentation.ts +57 -0
  117. package/src/billing/billing.schema.ts +133 -0
  118. package/src/billing/index.ts +64 -0
  119. package/src/dashboard/dashboard.presentation.ts +57 -0
  120. package/src/dashboard/index.ts +8 -0
  121. package/src/docs/index.ts +1 -0
  122. package/src/docs/saas-boilerplate.docblock.ts +98 -0
  123. package/src/example.ts +31 -0
  124. package/src/handlers/index.ts +20 -0
  125. package/src/index.ts +71 -0
  126. package/src/presentations/index.ts +36 -0
  127. package/src/project/index.ts +66 -0
  128. package/src/project/project.entity.ts +93 -0
  129. package/src/project/project.enum.ts +22 -0
  130. package/src/project/project.event.ts +128 -0
  131. package/src/project/project.handler.ts +168 -0
  132. package/src/project/project.operations.ts +272 -0
  133. package/src/project/project.presentation.ts +59 -0
  134. package/src/project/project.schema.ts +147 -0
  135. package/src/saas-boilerplate.feature.ts +109 -0
  136. package/src/settings/index.ts +9 -0
  137. package/src/settings/settings.entity.ts +89 -0
  138. package/src/settings/settings.enum.ts +11 -0
  139. package/src/shared/mock-data.ts +110 -0
  140. package/tsconfig.json +10 -0
  141. package/tsconfig.tsbuildinfo +1 -0
  142. package/tsdown.config.js +7 -0
@@ -0,0 +1,86 @@
1
+ //#region src/shared/mock-data.d.ts
2
+ /**
3
+ * Shared mock data for saas-boilerplate handlers.
4
+ */
5
+ declare const MOCK_PROJECTS: ({
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ slug: string;
10
+ organizationId: string;
11
+ createdBy: string;
12
+ status: "ACTIVE";
13
+ isPublic: boolean;
14
+ tags: string[];
15
+ createdAt: Date;
16
+ updatedAt: Date;
17
+ } | {
18
+ id: string;
19
+ name: string;
20
+ description: string;
21
+ slug: string;
22
+ organizationId: string;
23
+ createdBy: string;
24
+ status: "DRAFT";
25
+ isPublic: boolean;
26
+ tags: string[];
27
+ createdAt: Date;
28
+ updatedAt: Date;
29
+ } | {
30
+ id: string;
31
+ name: string;
32
+ description: string;
33
+ slug: string;
34
+ organizationId: string;
35
+ createdBy: string;
36
+ status: "ARCHIVED";
37
+ isPublic: boolean;
38
+ tags: string[];
39
+ createdAt: Date;
40
+ updatedAt: Date;
41
+ })[];
42
+ declare const MOCK_SUBSCRIPTION: {
43
+ id: string;
44
+ organizationId: string;
45
+ planId: string;
46
+ planName: string;
47
+ status: "ACTIVE";
48
+ currentPeriodStart: Date;
49
+ currentPeriodEnd: Date;
50
+ limits: {
51
+ projects: number;
52
+ users: number;
53
+ storage: number;
54
+ apiCalls: number;
55
+ };
56
+ usage: {
57
+ projects: number;
58
+ users: number;
59
+ storage: number;
60
+ apiCalls: number;
61
+ };
62
+ };
63
+ declare const MOCK_USAGE_SUMMARY: {
64
+ organizationId: string;
65
+ period: string;
66
+ apiCalls: {
67
+ total: number;
68
+ limit: number;
69
+ percentUsed: number;
70
+ };
71
+ storage: {
72
+ totalGb: number;
73
+ limitGb: number;
74
+ percentUsed: number;
75
+ };
76
+ activeProjects: number;
77
+ activeUsers: number;
78
+ breakdown: {
79
+ date: string;
80
+ apiCalls: number;
81
+ storageGb: number;
82
+ }[];
83
+ };
84
+ //#endregion
85
+ export { MOCK_PROJECTS, MOCK_SUBSCRIPTION, MOCK_USAGE_SUMMARY };
86
+ //# sourceMappingURL=mock-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-data.d.ts","names":[],"sources":["../../src/shared/mock-data.ts"],"sourcesContent":[],"mappings":";;AAMA;;cAAa;;;;;;EAyDA,SAAA,EAAA,MAAA;EAwBA,MAAA,EAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAxBA;;;;;;sBAoBZ;oBAAA;;;;;;;;;;;;;;cAIY"}
@@ -0,0 +1,138 @@
1
+ //#region src/shared/mock-data.ts
2
+ /**
3
+ * Shared mock data for saas-boilerplate handlers.
4
+ */
5
+ const MOCK_PROJECTS = [
6
+ {
7
+ id: "proj-1",
8
+ name: "Marketing Website",
9
+ description: "Main company website redesign project",
10
+ slug: "marketing-website",
11
+ organizationId: "demo-org",
12
+ createdBy: "user-1",
13
+ status: "ACTIVE",
14
+ isPublic: false,
15
+ tags: [
16
+ "marketing",
17
+ "website",
18
+ "redesign"
19
+ ],
20
+ createdAt: /* @__PURE__ */ new Date("2024-01-15T10:00:00Z"),
21
+ updatedAt: /* @__PURE__ */ new Date("2024-03-20T14:30:00Z")
22
+ },
23
+ {
24
+ id: "proj-2",
25
+ name: "Mobile App v2",
26
+ description: "Next generation mobile application",
27
+ slug: "mobile-app-v2",
28
+ organizationId: "demo-org",
29
+ createdBy: "user-2",
30
+ status: "ACTIVE",
31
+ isPublic: false,
32
+ tags: [
33
+ "mobile",
34
+ "app",
35
+ "v2"
36
+ ],
37
+ createdAt: /* @__PURE__ */ new Date("2024-02-01T09:00:00Z"),
38
+ updatedAt: /* @__PURE__ */ new Date("2024-04-05T11:15:00Z")
39
+ },
40
+ {
41
+ id: "proj-3",
42
+ name: "API Integration",
43
+ description: "Third-party API integration project",
44
+ slug: "api-integration",
45
+ organizationId: "demo-org",
46
+ createdBy: "user-1",
47
+ status: "DRAFT",
48
+ isPublic: false,
49
+ tags: ["api", "integration"],
50
+ createdAt: /* @__PURE__ */ new Date("2024-03-10T08:00:00Z"),
51
+ updatedAt: /* @__PURE__ */ new Date("2024-03-10T08:00:00Z")
52
+ },
53
+ {
54
+ id: "proj-4",
55
+ name: "Analytics Dashboard",
56
+ description: "Internal analytics and reporting dashboard",
57
+ slug: "analytics-dashboard",
58
+ organizationId: "demo-org",
59
+ createdBy: "user-3",
60
+ status: "ARCHIVED",
61
+ isPublic: true,
62
+ tags: [
63
+ "analytics",
64
+ "dashboard",
65
+ "reporting"
66
+ ],
67
+ createdAt: /* @__PURE__ */ new Date("2023-10-01T12:00:00Z"),
68
+ updatedAt: /* @__PURE__ */ new Date("2024-02-28T16:45:00Z")
69
+ }
70
+ ];
71
+ const MOCK_SUBSCRIPTION = {
72
+ id: "sub-1",
73
+ organizationId: "demo-org",
74
+ planId: "pro",
75
+ planName: "Professional",
76
+ status: "ACTIVE",
77
+ currentPeriodStart: /* @__PURE__ */ new Date("2024-04-01T00:00:00Z"),
78
+ currentPeriodEnd: /* @__PURE__ */ new Date("2024-05-01T00:00:00Z"),
79
+ limits: {
80
+ projects: 25,
81
+ users: 10,
82
+ storage: 50,
83
+ apiCalls: 1e5
84
+ },
85
+ usage: {
86
+ projects: 4,
87
+ users: 5,
88
+ storage: 12.5,
89
+ apiCalls: 45230
90
+ }
91
+ };
92
+ const MOCK_USAGE_SUMMARY = {
93
+ organizationId: "demo-org",
94
+ period: "current_month",
95
+ apiCalls: {
96
+ total: 45230,
97
+ limit: 1e5,
98
+ percentUsed: 45.23
99
+ },
100
+ storage: {
101
+ totalGb: 12.5,
102
+ limitGb: 50,
103
+ percentUsed: 25
104
+ },
105
+ activeProjects: 4,
106
+ activeUsers: 5,
107
+ breakdown: [
108
+ {
109
+ date: "2024-04-01",
110
+ apiCalls: 3200,
111
+ storageGb: 12.1
112
+ },
113
+ {
114
+ date: "2024-04-02",
115
+ apiCalls: 2800,
116
+ storageGb: 12.2
117
+ },
118
+ {
119
+ date: "2024-04-03",
120
+ apiCalls: 4100,
121
+ storageGb: 12.3
122
+ },
123
+ {
124
+ date: "2024-04-04",
125
+ apiCalls: 3600,
126
+ storageGb: 12.4
127
+ },
128
+ {
129
+ date: "2024-04-05",
130
+ apiCalls: 3800,
131
+ storageGb: 12.5
132
+ }
133
+ ]
134
+ };
135
+
136
+ //#endregion
137
+ export { MOCK_PROJECTS, MOCK_SUBSCRIPTION, MOCK_USAGE_SUMMARY };
138
+ //# sourceMappingURL=mock-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-data.js","names":[],"sources":["../../src/shared/mock-data.ts"],"sourcesContent":["/**\n * Shared mock data for saas-boilerplate handlers.\n */\n\n// ============ Project Mock Data ============\n\nexport const MOCK_PROJECTS = [\n {\n id: 'proj-1',\n name: 'Marketing Website',\n description: 'Main company website redesign project',\n slug: 'marketing-website',\n organizationId: 'demo-org',\n createdBy: 'user-1',\n status: 'ACTIVE' as const,\n isPublic: false,\n tags: ['marketing', 'website', 'redesign'],\n createdAt: new Date('2024-01-15T10:00:00Z'),\n updatedAt: new Date('2024-03-20T14:30:00Z'),\n },\n {\n id: 'proj-2',\n name: 'Mobile App v2',\n description: 'Next generation mobile application',\n slug: 'mobile-app-v2',\n organizationId: 'demo-org',\n createdBy: 'user-2',\n status: 'ACTIVE' as const,\n isPublic: false,\n tags: ['mobile', 'app', 'v2'],\n createdAt: new Date('2024-02-01T09:00:00Z'),\n updatedAt: new Date('2024-04-05T11:15:00Z'),\n },\n {\n id: 'proj-3',\n name: 'API Integration',\n description: 'Third-party API integration project',\n slug: 'api-integration',\n organizationId: 'demo-org',\n createdBy: 'user-1',\n status: 'DRAFT' as const,\n isPublic: false,\n tags: ['api', 'integration'],\n createdAt: new Date('2024-03-10T08:00:00Z'),\n updatedAt: new Date('2024-03-10T08:00:00Z'),\n },\n {\n id: 'proj-4',\n name: 'Analytics Dashboard',\n description: 'Internal analytics and reporting dashboard',\n slug: 'analytics-dashboard',\n organizationId: 'demo-org',\n createdBy: 'user-3',\n status: 'ARCHIVED' as const,\n isPublic: true,\n tags: ['analytics', 'dashboard', 'reporting'],\n createdAt: new Date('2023-10-01T12:00:00Z'),\n updatedAt: new Date('2024-02-28T16:45:00Z'),\n },\n];\n\n// ============ Subscription Mock Data ============\n\nexport const MOCK_SUBSCRIPTION = {\n id: 'sub-1',\n organizationId: 'demo-org',\n planId: 'pro',\n planName: 'Professional',\n status: 'ACTIVE' as const,\n currentPeriodStart: new Date('2024-04-01T00:00:00Z'),\n currentPeriodEnd: new Date('2024-05-01T00:00:00Z'),\n limits: {\n projects: 25,\n users: 10,\n storage: 50, // GB\n apiCalls: 100000,\n },\n usage: {\n projects: 4,\n users: 5,\n storage: 12.5,\n apiCalls: 45230,\n },\n};\n\n// ============ Usage Summary Mock Data ============\n\nexport const MOCK_USAGE_SUMMARY = {\n organizationId: 'demo-org',\n period: 'current_month',\n apiCalls: {\n total: 45230,\n limit: 100000,\n percentUsed: 45.23,\n },\n storage: {\n totalGb: 12.5,\n limitGb: 50,\n percentUsed: 25,\n },\n activeProjects: 4,\n activeUsers: 5,\n breakdown: [\n { date: '2024-04-01', apiCalls: 3200, storageGb: 12.1 },\n { date: '2024-04-02', apiCalls: 2800, storageGb: 12.2 },\n { date: '2024-04-03', apiCalls: 4100, storageGb: 12.3 },\n { date: '2024-04-04', apiCalls: 3600, storageGb: 12.4 },\n { date: '2024-04-05', apiCalls: 3800, storageGb: 12.5 },\n ],\n};\n"],"mappings":";;;;AAMA,MAAa,gBAAgB;CAC3B;EACE,IAAI;EACJ,MAAM;EACN,aAAa;EACb,MAAM;EACN,gBAAgB;EAChB,WAAW;EACX,QAAQ;EACR,UAAU;EACV,MAAM;GAAC;GAAa;GAAW;GAAW;EAC1C,2BAAW,IAAI,KAAK,uBAAuB;EAC3C,2BAAW,IAAI,KAAK,uBAAuB;EAC5C;CACD;EACE,IAAI;EACJ,MAAM;EACN,aAAa;EACb,MAAM;EACN,gBAAgB;EAChB,WAAW;EACX,QAAQ;EACR,UAAU;EACV,MAAM;GAAC;GAAU;GAAO;GAAK;EAC7B,2BAAW,IAAI,KAAK,uBAAuB;EAC3C,2BAAW,IAAI,KAAK,uBAAuB;EAC5C;CACD;EACE,IAAI;EACJ,MAAM;EACN,aAAa;EACb,MAAM;EACN,gBAAgB;EAChB,WAAW;EACX,QAAQ;EACR,UAAU;EACV,MAAM,CAAC,OAAO,cAAc;EAC5B,2BAAW,IAAI,KAAK,uBAAuB;EAC3C,2BAAW,IAAI,KAAK,uBAAuB;EAC5C;CACD;EACE,IAAI;EACJ,MAAM;EACN,aAAa;EACb,MAAM;EACN,gBAAgB;EAChB,WAAW;EACX,QAAQ;EACR,UAAU;EACV,MAAM;GAAC;GAAa;GAAa;GAAY;EAC7C,2BAAW,IAAI,KAAK,uBAAuB;EAC3C,2BAAW,IAAI,KAAK,uBAAuB;EAC5C;CACF;AAID,MAAa,oBAAoB;CAC/B,IAAI;CACJ,gBAAgB;CAChB,QAAQ;CACR,UAAU;CACV,QAAQ;CACR,oCAAoB,IAAI,KAAK,uBAAuB;CACpD,kCAAkB,IAAI,KAAK,uBAAuB;CAClD,QAAQ;EACN,UAAU;EACV,OAAO;EACP,SAAS;EACT,UAAU;EACX;CACD,OAAO;EACL,UAAU;EACV,OAAO;EACP,SAAS;EACT,UAAU;EACX;CACF;AAID,MAAa,qBAAqB;CAChC,gBAAgB;CAChB,QAAQ;CACR,UAAU;EACR,OAAO;EACP,OAAO;EACP,aAAa;EACd;CACD,SAAS;EACP,SAAS;EACT,SAAS;EACT,aAAa;EACd;CACD,gBAAgB;CAChB,aAAa;CACb,WAAW;EACT;GAAE,MAAM;GAAc,UAAU;GAAM,WAAW;GAAM;EACvD;GAAE,MAAM;GAAc,UAAU;GAAM,WAAW;GAAM;EACvD;GAAE,MAAM;GAAc,UAAU;GAAM,WAAW;GAAM;EACvD;GAAE,MAAM;GAAc,UAAU;GAAM,WAAW;GAAM;EACvD;GAAE,MAAM;GAAc,UAAU;GAAM,WAAW;GAAM;EACxD;CACF"}
package/example.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from './src/example';
package/package.json ADDED
@@ -0,0 +1,113 @@
1
+ {
2
+ "name": "@contractspec/example.saas-boilerplate",
3
+ "version": "1.44.0",
4
+ "description": "SaaS Boilerplate - Users, Orgs, Projects, Billing, Settings",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": "./dist/index.js",
10
+ "./billing": "./dist/billing/index.js",
11
+ "./billing/billing.entity": "./dist/billing/billing.entity.js",
12
+ "./billing/billing.enum": "./dist/billing/billing.enum.js",
13
+ "./billing/billing.event": "./dist/billing/billing.event.js",
14
+ "./billing/billing.handler": "./dist/billing/billing.handler.js",
15
+ "./billing/billing.operations": "./dist/billing/billing.operations.js",
16
+ "./billing/billing.presentation": "./dist/billing/billing.presentation.js",
17
+ "./billing/billing.schema": "./dist/billing/billing.schema.js",
18
+ "./dashboard": "./dist/dashboard/index.js",
19
+ "./dashboard/dashboard.presentation": "./dist/dashboard/dashboard.presentation.js",
20
+ "./docs": "./dist/docs/index.js",
21
+ "./docs/saas-boilerplate.docblock": "./dist/docs/saas-boilerplate.docblock.js",
22
+ "./example": "./dist/example.js",
23
+ "./handlers": "./dist/handlers/index.js",
24
+ "./presentations": "./dist/presentations/index.js",
25
+ "./project": "./dist/project/index.js",
26
+ "./project/project.entity": "./dist/project/project.entity.js",
27
+ "./project/project.enum": "./dist/project/project.enum.js",
28
+ "./project/project.event": "./dist/project/project.event.js",
29
+ "./project/project.handler": "./dist/project/project.handler.js",
30
+ "./project/project.operations": "./dist/project/project.operations.js",
31
+ "./project/project.presentation": "./dist/project/project.presentation.js",
32
+ "./project/project.schema": "./dist/project/project.schema.js",
33
+ "./saas-boilerplate.feature": "./dist/saas-boilerplate.feature.js",
34
+ "./settings": "./dist/settings/index.js",
35
+ "./settings/settings.entity": "./dist/settings/settings.entity.js",
36
+ "./settings/settings.enum": "./dist/settings/settings.enum.js",
37
+ "./shared/mock-data": "./dist/shared/mock-data.js",
38
+ "./*": "./*"
39
+ },
40
+ "scripts": {
41
+ "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
42
+ "publish:pkg:canary": "bun publish:pkg --tag canary",
43
+ "build": "bun build:types && bun build:bundle",
44
+ "build:bundle": "tsdown",
45
+ "build:types": "tsc --noEmit",
46
+ "dev": "bun build:bundle --watch",
47
+ "clean": "rimraf dist .turbo",
48
+ "lint": "bun lint:fix",
49
+ "lint:fix": "eslint src --fix",
50
+ "lint:check": "eslint src",
51
+ "test": "bun run"
52
+ },
53
+ "dependencies": {
54
+ "@contractspec/lib.schema": "1.44.0",
55
+ "@contractspec/lib.contracts": "1.44.0",
56
+ "@contractspec/lib.bus": "1.44.0",
57
+ "@contractspec/lib.identity-rbac": "1.44.0",
58
+ "@contractspec/lib.jobs": "1.44.0",
59
+ "@contractspec/module.audit-trail": "1.44.0",
60
+ "@contractspec/module.notifications": "1.44.0",
61
+ "zod": "^4.1.13"
62
+ },
63
+ "devDependencies": {
64
+ "@contractspec/tool.tsdown": "1.44.0",
65
+ "@contractspec/tool.typescript": "1.44.0",
66
+ "tsdown": "^0.18.3",
67
+ "typescript": "^5.9.3"
68
+ },
69
+ "module": "./dist/index.js",
70
+ "publishConfig": {
71
+ "exports": {
72
+ ".": "./dist/index.js",
73
+ "./billing": "./dist/billing/index.js",
74
+ "./billing/billing.contracts": "./dist/billing/billing.operations.js",
75
+ "./billing/billing.entity": "./dist/billing/billing.entity.js",
76
+ "./billing/billing.enum": "./dist/billing/billing.enum.js",
77
+ "./billing/billing.event": "./dist/billing/billing.event.js",
78
+ "./billing/billing.handler": "./dist/billing/billing.handler.js",
79
+ "./billing/billing.presentation": "./dist/billing/billing.presentation.js",
80
+ "./billing/billing.schema": "./dist/billing/billing.schema.js",
81
+ "./dashboard": "./dist/dashboard/index.js",
82
+ "./dashboard/dashboard.presentation": "./dist/dashboard/dashboard.presentation.js",
83
+ "./docs": "./dist/docs/index.js",
84
+ "./docs/saas-boilerplate.docblock": "./dist/docs/saas-boilerplate.docblock.js",
85
+ "./example": "./dist/example.js",
86
+ "./handlers": "./dist/handlers/index.js",
87
+ "./presentations": "./dist/presentations/index.js",
88
+ "./project": "./dist/project/index.js",
89
+ "./project/project.contracts": "./dist/project/project.operations.js",
90
+ "./project/project.entity": "./dist/project/project.entity.js",
91
+ "./project/project.enum": "./dist/project/project.enum.js",
92
+ "./project/project.event": "./dist/project/project.event.js",
93
+ "./project/project.handler": "./dist/project/project.handler.js",
94
+ "./project/project.presentation": "./dist/project/project.presentation.js",
95
+ "./project/project.schema": "./dist/project/project.schema.js",
96
+ "./saas-boilerplate.feature": "./dist/saas-boilerplate.feature.js",
97
+ "./settings": "./dist/settings/index.js",
98
+ "./settings/settings.entity": "./dist/settings/settings.entity.js",
99
+ "./settings/settings.enum": "./dist/settings/settings.enum.js",
100
+ "./shared/mock-data": "./dist/shared/mock-data.js",
101
+ "./*": "./*"
102
+ },
103
+ "registry": "https://registry.npmjs.org/",
104
+ "access": "public"
105
+ },
106
+ "license": "MIT",
107
+ "repository": {
108
+ "type": "git",
109
+ "url": "https://github.com/lssm-tech/contractspec.git",
110
+ "directory": "packages/examples/saas-boilerplate"
111
+ },
112
+ "homepage": "https://contractspec.io"
113
+ }
@@ -0,0 +1,158 @@
1
+ import {
2
+ defineEntity,
3
+ defineEntityEnum,
4
+ field,
5
+ index,
6
+ } from '@contractspec/lib.schema';
7
+
8
+ /**
9
+ * Subscription status enum for entities.
10
+ */
11
+ export const SubscriptionStatusEnum = defineEntityEnum({
12
+ name: 'SubscriptionStatus',
13
+ values: ['TRIALING', 'ACTIVE', 'PAST_DUE', 'CANCELED', 'PAUSED'] as const,
14
+ schema: 'saas_app',
15
+ description: 'Status of a subscription.',
16
+ });
17
+
18
+ /**
19
+ * Subscription entity - organization subscription info.
20
+ */
21
+ export const SubscriptionEntity = defineEntity({
22
+ name: 'Subscription',
23
+ description: 'Organization subscription/plan information.',
24
+ schema: 'saas_app',
25
+ map: 'subscription',
26
+ fields: {
27
+ id: field.id(),
28
+ organizationId: field.foreignKey({ isUnique: true }),
29
+
30
+ // Plan info
31
+ planId: field.string({ description: 'Plan identifier' }),
32
+ planName: field.string({ description: 'Plan display name' }),
33
+
34
+ // Status
35
+ status: field.enum('SubscriptionStatus'),
36
+
37
+ // Billing cycle
38
+ currentPeriodStart: field.dateTime(),
39
+ currentPeriodEnd: field.dateTime(),
40
+
41
+ // Trial
42
+ trialEndsAt: field.dateTime({ isOptional: true }),
43
+
44
+ // Cancellation
45
+ cancelAtPeriodEnd: field.boolean({ default: false }),
46
+ canceledAt: field.dateTime({ isOptional: true }),
47
+
48
+ // External reference
49
+ stripeSubscriptionId: field.string({ isOptional: true }),
50
+ stripeCustomerId: field.string({ isOptional: true }),
51
+
52
+ // Metadata
53
+ metadata: field.json({ isOptional: true }),
54
+
55
+ // Timestamps
56
+ createdAt: field.createdAt(),
57
+ updatedAt: field.updatedAt(),
58
+ },
59
+ enums: [SubscriptionStatusEnum],
60
+ });
61
+
62
+ /**
63
+ * BillingUsage entity - track feature usage.
64
+ */
65
+ export const BillingUsageEntity = defineEntity({
66
+ name: 'BillingUsage',
67
+ description: 'Track usage of metered features.',
68
+ schema: 'saas_app',
69
+ map: 'billing_usage',
70
+ fields: {
71
+ id: field.id(),
72
+ organizationId: field.foreignKey(),
73
+
74
+ // Feature
75
+ feature: field.string({
76
+ description: 'Feature being tracked (e.g., "api_calls", "storage_gb")',
77
+ }),
78
+
79
+ // Usage
80
+ quantity: field.int({ description: 'Usage quantity' }),
81
+ unit: field.string({
82
+ isOptional: true,
83
+ description: 'Unit of measurement',
84
+ }),
85
+
86
+ // Period
87
+ billingPeriod: field.string({
88
+ description: 'Billing period (e.g., "2024-01")',
89
+ }),
90
+
91
+ // Aggregation
92
+ recordedAt: field.dateTime({ description: 'When usage was recorded' }),
93
+
94
+ // Source
95
+ sourceId: field.string({
96
+ isOptional: true,
97
+ description: 'Source of usage (e.g., request ID)',
98
+ }),
99
+ sourceType: field.string({ isOptional: true }),
100
+
101
+ // Metadata
102
+ metadata: field.json({ isOptional: true }),
103
+ },
104
+ indexes: [
105
+ index.on(['organizationId', 'feature', 'billingPeriod']),
106
+ index.on(['organizationId', 'recordedAt']),
107
+ ],
108
+ });
109
+
110
+ /**
111
+ * UsageLimit entity - feature usage limits per plan.
112
+ */
113
+ export const UsageLimitEntity = defineEntity({
114
+ name: 'UsageLimit',
115
+ description: 'Usage limits per plan/organization.',
116
+ schema: 'saas_app',
117
+ map: 'usage_limit',
118
+ fields: {
119
+ id: field.id(),
120
+
121
+ // Scope
122
+ planId: field.string({
123
+ isOptional: true,
124
+ description: 'Plan this limit applies to',
125
+ }),
126
+ organizationId: field.string({
127
+ isOptional: true,
128
+ description: 'Org-specific override',
129
+ }),
130
+
131
+ // Limit
132
+ feature: field.string({ description: 'Feature being limited' }),
133
+ limit: field.int({ description: 'Maximum allowed usage' }),
134
+ resetPeriod: field.string({
135
+ default: '"monthly"',
136
+ description: 'When limit resets',
137
+ }),
138
+
139
+ // Soft/hard limit
140
+ isSoftLimit: field.boolean({
141
+ default: false,
142
+ description: 'Whether to warn vs block',
143
+ }),
144
+ overage: field.boolean({
145
+ default: false,
146
+ description: 'Whether overage is allowed',
147
+ }),
148
+ overageRate: field.float({
149
+ isOptional: true,
150
+ description: 'Cost per unit over limit',
151
+ }),
152
+
153
+ // Timestamps
154
+ createdAt: field.createdAt(),
155
+ updatedAt: field.updatedAt(),
156
+ },
157
+ indexes: [index.unique(['planId', 'feature'])],
158
+ });
@@ -0,0 +1,23 @@
1
+ import { defineEnum } from '@contractspec/lib.schema';
2
+
3
+ /**
4
+ * Subscription status enum for contract schemas.
5
+ * Note: Entity enum is defined separately in billing.entity.ts
6
+ */
7
+ export const SubscriptionStatusSchemaEnum = defineEnum('SubscriptionStatus', [
8
+ 'TRIALING',
9
+ 'ACTIVE',
10
+ 'PAST_DUE',
11
+ 'CANCELED',
12
+ 'PAUSED',
13
+ ]);
14
+
15
+ /**
16
+ * Feature access reason enum.
17
+ */
18
+ export const FeatureAccessReasonEnum = defineEnum('FeatureAccessReason', [
19
+ 'included',
20
+ 'limit_available',
21
+ 'limit_reached',
22
+ 'not_in_plan',
23
+ ]);
@@ -0,0 +1,108 @@
1
+ import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';
2
+ import { defineEvent } from '@contractspec/lib.contracts';
3
+
4
+ /**
5
+ * Payload when feature usage is recorded.
6
+ */
7
+ const UsageRecordedPayload = defineSchemaModel({
8
+ name: 'UsageRecordedPayload',
9
+ description: 'Payload when feature usage is recorded',
10
+ fields: {
11
+ organizationId: {
12
+ type: ScalarTypeEnum.String_unsecure(),
13
+ isOptional: false,
14
+ },
15
+ feature: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
16
+ quantity: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
17
+ billingPeriod: {
18
+ type: ScalarTypeEnum.String_unsecure(),
19
+ isOptional: false,
20
+ },
21
+ recordedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
22
+ },
23
+ });
24
+
25
+ /**
26
+ * Payload when usage limit is reached.
27
+ */
28
+ const UsageLimitReachedPayload = defineSchemaModel({
29
+ name: 'UsageLimitReachedPayload',
30
+ description: 'Payload when usage limit is reached',
31
+ fields: {
32
+ organizationId: {
33
+ type: ScalarTypeEnum.String_unsecure(),
34
+ isOptional: false,
35
+ },
36
+ feature: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
37
+ limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
38
+ currentUsage: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
39
+ reachedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
40
+ },
41
+ });
42
+
43
+ /**
44
+ * Payload when subscription status changes.
45
+ */
46
+ const SubscriptionChangedPayload = defineSchemaModel({
47
+ name: 'SubscriptionChangedPayload',
48
+ description: 'Payload when subscription status changes',
49
+ fields: {
50
+ organizationId: {
51
+ type: ScalarTypeEnum.String_unsecure(),
52
+ isOptional: false,
53
+ },
54
+ previousPlan: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
55
+ newPlan: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
56
+ previousStatus: {
57
+ type: ScalarTypeEnum.String_unsecure(),
58
+ isOptional: true,
59
+ },
60
+ newStatus: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
61
+ changedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
62
+ },
63
+ });
64
+
65
+ /**
66
+ * Event: Feature usage has been recorded.
67
+ */
68
+ export const UsageRecordedEvent = defineEvent({
69
+ meta: {
70
+ key: 'billing.usage.recorded',
71
+ version: 1,
72
+ description: 'Feature usage has been recorded.',
73
+ stability: 'stable',
74
+ owners: ['@saas-team'],
75
+ tags: ['billing', 'usage', 'recorded'],
76
+ },
77
+ payload: UsageRecordedPayload,
78
+ });
79
+
80
+ /**
81
+ * Event: Usage limit has been reached for a feature.
82
+ */
83
+ export const UsageLimitReachedEvent = defineEvent({
84
+ meta: {
85
+ key: 'billing.limit.reached',
86
+ version: 1,
87
+ description: 'Usage limit has been reached for a feature.',
88
+ stability: 'stable',
89
+ owners: ['@saas-team'],
90
+ tags: ['billing', 'limit', 'reached'],
91
+ },
92
+ payload: UsageLimitReachedPayload,
93
+ });
94
+
95
+ /**
96
+ * Event: Subscription status has changed.
97
+ */
98
+ export const SubscriptionChangedEvent = defineEvent({
99
+ meta: {
100
+ key: 'billing.subscription.changed',
101
+ version: 1,
102
+ description: 'Subscription status has changed.',
103
+ stability: 'stable',
104
+ owners: ['@saas-team'],
105
+ tags: ['billing', 'subscription', 'changed'],
106
+ },
107
+ payload: SubscriptionChangedPayload,
108
+ });