@lssm/example.saas-boilerplate 0.0.0-canary-20251215234153 → 0.0.0-canary-20251216023757
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.
- package/.turbo/turbo-build.log +32 -24
- package/CHANGELOG.md +8 -8
- package/dist/billing/billing.contracts.js +1 -0
- package/dist/billing/billing.enum.js +1 -0
- package/dist/billing/billing.event.js +1 -0
- package/dist/billing/billing.handler.js +1 -0
- package/dist/billing/billing.schema.js +1 -0
- package/dist/billing/index.js +1 -0
- package/dist/dashboard/index.js +1 -0
- package/dist/handlers/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/presentations/index.js +1 -1
- package/dist/project/index.js +1 -0
- package/dist/project/project.contracts.js +1 -0
- package/dist/project/project.enum.js +1 -0
- package/dist/project/project.event.js +1 -0
- package/dist/project/project.handler.js +1 -0
- package/dist/project/project.presentation.js +1 -0
- package/dist/project/project.schema.js +1 -0
- package/dist/settings/index.js +1 -0
- package/dist/settings/settings.entity.js +1 -0
- package/dist/settings/settings.enum.js +1 -0
- package/package.json +45 -29
- package/src/billing/billing.contracts.ts +116 -0
- package/src/{entities/billing.ts → billing/billing.entity.ts} +2 -1
- package/src/billing/billing.enum.ts +24 -0
- package/src/billing/billing.event.ts +94 -0
- package/src/{handlers/billing.handlers.ts → billing/billing.handler.ts} +7 -8
- package/src/{presentations/billing.ts → billing/billing.presentation.ts} +1 -3
- package/src/{contracts/billing.ts → billing/billing.schema.ts} +29 -131
- package/src/billing/index.ts +65 -0
- package/src/{presentations/dashboard.ts → dashboard/dashboard.presentation.ts} +1 -3
- package/src/dashboard/index.ts +9 -0
- package/src/handlers/index.ts +12 -26
- package/src/index.ts +43 -6
- package/src/presentations/index.ts +24 -30
- package/src/project/index.ts +67 -0
- package/src/project/project.contracts.ts +185 -0
- package/src/{entities/project.ts → project/project.entity.ts} +2 -1
- package/src/project/project.enum.ts +23 -0
- package/src/project/project.event.ts +109 -0
- package/src/{handlers/project.handlers.ts → project/project.handler.ts} +8 -9
- package/src/{presentations/project-list.ts → project/project.presentation.ts} +2 -4
- package/src/project/project.schema.ts +145 -0
- package/src/settings/index.ts +10 -0
- package/src/{entities/settings.ts → settings/settings.entity.ts} +3 -11
- package/src/settings/settings.enum.ts +12 -0
- package/src/{handlers → shared}/mock-data.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/contracts/billing.js +0 -1
- package/dist/contracts/index.js +0 -1
- package/dist/contracts/project.js +0 -1
- package/dist/entities/index.js +0 -1
- package/dist/entities/settings.js +0 -1
- package/dist/events.js +0 -1
- package/dist/handlers/billing.handlers.js +0 -1
- package/dist/handlers/project.handlers.js +0 -1
- package/dist/presentations/project-list.js +0 -1
- package/src/contracts/index.ts +0 -36
- package/src/contracts/project.ts +0 -314
- package/src/entities/index.ts +0 -62
- package/src/events.ts +0 -177
- /package/dist/{entities/billing.js → billing/billing.entity.js} +0 -0
- /package/dist/{presentations/billing.js → billing/billing.presentation.js} +0 -0
- /package/dist/{presentations/dashboard.js → dashboard/dashboard.presentation.js} +0 -0
- /package/dist/{entities/project.js → project/project.entity.js} +0 -0
- /package/dist/{handlers → shared}/mock-data.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Mock handlers for Billing contracts
|
|
2
|
+
* Mock handlers for Billing contracts.
|
|
3
3
|
*/
|
|
4
|
-
import { MOCK_SUBSCRIPTION, MOCK_USAGE_SUMMARY } from '
|
|
4
|
+
import { MOCK_SUBSCRIPTION, MOCK_USAGE_SUMMARY } from '../shared/mock-data';
|
|
5
5
|
|
|
6
6
|
// Types inferred from contract schemas
|
|
7
7
|
export interface Subscription {
|
|
@@ -71,14 +71,14 @@ export interface CheckFeatureAccessOutput {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* Mock handler for GetSubscriptionContract
|
|
74
|
+
* Mock handler for GetSubscriptionContract.
|
|
75
75
|
*/
|
|
76
76
|
export async function mockGetSubscriptionHandler(): Promise<Subscription> {
|
|
77
77
|
return MOCK_SUBSCRIPTION;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* Mock handler for GetUsageSummaryContract
|
|
81
|
+
* Mock handler for GetUsageSummaryContract.
|
|
82
82
|
*/
|
|
83
83
|
export async function mockGetUsageSummaryHandler(input: {
|
|
84
84
|
period?: string;
|
|
@@ -90,12 +90,11 @@ export async function mockGetUsageSummaryHandler(input: {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
|
-
* Mock handler for RecordUsageContract
|
|
93
|
+
* Mock handler for RecordUsageContract.
|
|
94
94
|
*/
|
|
95
95
|
export async function mockRecordUsageHandler(
|
|
96
96
|
input: RecordUsageInput
|
|
97
97
|
): Promise<{ recorded: boolean; newTotal: number }> {
|
|
98
|
-
// Simulate recording usage
|
|
99
98
|
const currentUsage = MOCK_USAGE_SUMMARY.apiCalls.total;
|
|
100
99
|
const newTotal = currentUsage + input.quantity;
|
|
101
100
|
|
|
@@ -106,14 +105,13 @@ export async function mockRecordUsageHandler(
|
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
/**
|
|
109
|
-
* Mock handler for CheckFeatureAccessContract
|
|
108
|
+
* Mock handler for CheckFeatureAccessContract.
|
|
110
109
|
*/
|
|
111
110
|
export async function mockCheckFeatureAccessHandler(
|
|
112
111
|
input: CheckFeatureAccessInput
|
|
113
112
|
): Promise<CheckFeatureAccessOutput> {
|
|
114
113
|
const { feature } = input;
|
|
115
114
|
|
|
116
|
-
// Simulate feature access checks
|
|
117
115
|
const featureMap: Record<string, CheckFeatureAccessOutput> = {
|
|
118
116
|
custom_domains: {
|
|
119
117
|
allowed: true,
|
|
@@ -137,3 +135,4 @@ export async function mockCheckFeatureAccessHandler(
|
|
|
137
135
|
|
|
138
136
|
return featureMap[feature] ?? { allowed: true };
|
|
139
137
|
}
|
|
138
|
+
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Billing Presentation Descriptors
|
|
3
|
-
*/
|
|
4
1
|
import type { PresentationDescriptorV2 } from '@lssm/lib.contracts';
|
|
5
2
|
|
|
6
3
|
/**
|
|
@@ -49,3 +46,4 @@ export const UsageDashboardPresentation: PresentationDescriptorV2 = {
|
|
|
49
46
|
flags: ['saas.billing.enabled'],
|
|
50
47
|
},
|
|
51
48
|
};
|
|
49
|
+
|
|
@@ -1,32 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
defineQuery,
|
|
4
|
-
defineSchemaModel,
|
|
5
|
-
} from '@lssm/lib.contracts';
|
|
6
|
-
import { ScalarTypeEnum, defineEnum } from '@lssm/lib.schema';
|
|
7
|
-
|
|
8
|
-
const OWNERS = ['example.saas-boilerplate'] as const;
|
|
9
|
-
|
|
10
|
-
// ============ Enums (for contract schemas) ============
|
|
11
|
-
// Note: Entity enums for Prisma are defined separately in ../entities
|
|
12
|
-
|
|
13
|
-
const SubscriptionStatusSchemaEnum = defineEnum('SubscriptionStatus', [
|
|
14
|
-
'TRIALING',
|
|
15
|
-
'ACTIVE',
|
|
16
|
-
'PAST_DUE',
|
|
17
|
-
'CANCELED',
|
|
18
|
-
'PAUSED',
|
|
19
|
-
]);
|
|
20
|
-
|
|
21
|
-
export const FeatureAccessReasonEnum = defineEnum('FeatureAccessReason', [
|
|
22
|
-
'included',
|
|
23
|
-
'limit_available',
|
|
24
|
-
'limit_reached',
|
|
25
|
-
'not_in_plan',
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
// ============ Schemas ============
|
|
1
|
+
import { defineSchemaModel, ScalarTypeEnum } from '@lssm/lib.schema';
|
|
2
|
+
import { SubscriptionStatusSchemaEnum, FeatureAccessReasonEnum } from './billing.enum';
|
|
29
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Organization subscription details schema.
|
|
6
|
+
*/
|
|
30
7
|
export const SubscriptionModel = defineSchemaModel({
|
|
31
8
|
name: 'Subscription',
|
|
32
9
|
description: 'Organization subscription details',
|
|
@@ -46,6 +23,9 @@ export const SubscriptionModel = defineSchemaModel({
|
|
|
46
23
|
},
|
|
47
24
|
});
|
|
48
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Usage summary for a feature schema.
|
|
28
|
+
*/
|
|
49
29
|
export const UsageSummaryModel = defineSchemaModel({
|
|
50
30
|
name: 'UsageSummary',
|
|
51
31
|
description: 'Usage summary for a feature',
|
|
@@ -58,6 +38,9 @@ export const UsageSummaryModel = defineSchemaModel({
|
|
|
58
38
|
},
|
|
59
39
|
});
|
|
60
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Input for recording feature usage.
|
|
43
|
+
*/
|
|
61
44
|
export const RecordUsageInputModel = defineSchemaModel({
|
|
62
45
|
name: 'RecordUsageInput',
|
|
63
46
|
description: 'Input for recording feature usage',
|
|
@@ -70,6 +53,9 @@ export const RecordUsageInputModel = defineSchemaModel({
|
|
|
70
53
|
},
|
|
71
54
|
});
|
|
72
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Output for recording feature usage.
|
|
58
|
+
*/
|
|
73
59
|
export const RecordUsageOutputModel = defineSchemaModel({
|
|
74
60
|
name: 'RecordUsageOutput',
|
|
75
61
|
description: 'Output for recording feature usage',
|
|
@@ -81,6 +67,9 @@ export const RecordUsageOutputModel = defineSchemaModel({
|
|
|
81
67
|
},
|
|
82
68
|
});
|
|
83
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Payload for usage.recorded event.
|
|
72
|
+
*/
|
|
84
73
|
export const UsageRecordedPayloadModel = defineSchemaModel({
|
|
85
74
|
name: 'UsageRecordedPayload',
|
|
86
75
|
description: 'Payload for usage.recorded event',
|
|
@@ -90,6 +79,9 @@ export const UsageRecordedPayloadModel = defineSchemaModel({
|
|
|
90
79
|
},
|
|
91
80
|
});
|
|
92
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Input for getting usage summary.
|
|
84
|
+
*/
|
|
93
85
|
export const GetUsageSummaryInputModel = defineSchemaModel({
|
|
94
86
|
name: 'GetUsageSummaryInput',
|
|
95
87
|
description: 'Input for getting usage summary',
|
|
@@ -98,6 +90,9 @@ export const GetUsageSummaryInputModel = defineSchemaModel({
|
|
|
98
90
|
},
|
|
99
91
|
});
|
|
100
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Output for usage summary.
|
|
95
|
+
*/
|
|
101
96
|
export const GetUsageSummaryOutputModel = defineSchemaModel({
|
|
102
97
|
name: 'GetUsageSummaryOutput',
|
|
103
98
|
description: 'Output for usage summary',
|
|
@@ -110,6 +105,9 @@ export const GetUsageSummaryOutputModel = defineSchemaModel({
|
|
|
110
105
|
},
|
|
111
106
|
});
|
|
112
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Input for checking feature access.
|
|
110
|
+
*/
|
|
113
111
|
export const CheckFeatureAccessInputModel = defineSchemaModel({
|
|
114
112
|
name: 'CheckFeatureAccessInput',
|
|
115
113
|
description: 'Input for checking feature access',
|
|
@@ -118,6 +116,9 @@ export const CheckFeatureAccessInputModel = defineSchemaModel({
|
|
|
118
116
|
},
|
|
119
117
|
});
|
|
120
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Output for feature access check.
|
|
121
|
+
*/
|
|
121
122
|
export const CheckFeatureAccessOutputModel = defineSchemaModel({
|
|
122
123
|
name: 'CheckFeatureAccessOutput',
|
|
123
124
|
description: 'Output for feature access check',
|
|
@@ -128,106 +129,3 @@ export const CheckFeatureAccessOutputModel = defineSchemaModel({
|
|
|
128
129
|
},
|
|
129
130
|
});
|
|
130
131
|
|
|
131
|
-
// ============ Contracts ============
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Get subscription status.
|
|
135
|
-
*/
|
|
136
|
-
export const GetSubscriptionContract = defineQuery({
|
|
137
|
-
meta: {
|
|
138
|
-
name: 'saas.billing.subscription.get',
|
|
139
|
-
version: 1,
|
|
140
|
-
stability: 'stable',
|
|
141
|
-
owners: [...OWNERS],
|
|
142
|
-
tags: ['saas', 'billing', 'subscription'],
|
|
143
|
-
description: 'Get organization subscription status.',
|
|
144
|
-
goal: 'Show current plan and billing status.',
|
|
145
|
-
context: 'Billing page, plan upgrade prompts.',
|
|
146
|
-
},
|
|
147
|
-
io: {
|
|
148
|
-
input: null,
|
|
149
|
-
output: SubscriptionModel,
|
|
150
|
-
},
|
|
151
|
-
policy: {
|
|
152
|
-
auth: 'user',
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Record feature usage.
|
|
158
|
-
*/
|
|
159
|
-
export const RecordUsageContract = defineCommand({
|
|
160
|
-
meta: {
|
|
161
|
-
name: 'saas.billing.usage.record',
|
|
162
|
-
version: 1,
|
|
163
|
-
stability: 'stable',
|
|
164
|
-
owners: [...OWNERS],
|
|
165
|
-
tags: ['saas', 'billing', 'usage'],
|
|
166
|
-
description: 'Record usage of a metered feature.',
|
|
167
|
-
goal: 'Track feature usage for billing.',
|
|
168
|
-
context: 'Called by services when metered features are used.',
|
|
169
|
-
},
|
|
170
|
-
io: {
|
|
171
|
-
input: RecordUsageInputModel,
|
|
172
|
-
output: RecordUsageOutputModel,
|
|
173
|
-
},
|
|
174
|
-
policy: {
|
|
175
|
-
auth: 'user',
|
|
176
|
-
},
|
|
177
|
-
sideEffects: {
|
|
178
|
-
emits: [
|
|
179
|
-
{
|
|
180
|
-
name: 'billing.usage.recorded',
|
|
181
|
-
version: 1,
|
|
182
|
-
when: 'Usage is recorded',
|
|
183
|
-
payload: UsageRecordedPayloadModel,
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
},
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Get usage summary.
|
|
191
|
-
*/
|
|
192
|
-
export const GetUsageSummaryContract = defineQuery({
|
|
193
|
-
meta: {
|
|
194
|
-
name: 'saas.billing.usage.summary',
|
|
195
|
-
version: 1,
|
|
196
|
-
stability: 'stable',
|
|
197
|
-
owners: [...OWNERS],
|
|
198
|
-
tags: ['saas', 'billing', 'usage'],
|
|
199
|
-
description: 'Get usage summary for the current billing period.',
|
|
200
|
-
goal: 'Show usage vs limits.',
|
|
201
|
-
context: 'Billing page, usage dashboards.',
|
|
202
|
-
},
|
|
203
|
-
io: {
|
|
204
|
-
input: GetUsageSummaryInputModel,
|
|
205
|
-
output: GetUsageSummaryOutputModel,
|
|
206
|
-
},
|
|
207
|
-
policy: {
|
|
208
|
-
auth: 'user',
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Check feature access.
|
|
214
|
-
*/
|
|
215
|
-
export const CheckFeatureAccessContract = defineQuery({
|
|
216
|
-
meta: {
|
|
217
|
-
name: 'saas.billing.feature.check',
|
|
218
|
-
version: 1,
|
|
219
|
-
stability: 'stable',
|
|
220
|
-
owners: [...OWNERS],
|
|
221
|
-
tags: ['saas', 'billing', 'feature'],
|
|
222
|
-
description: 'Check if organization has access to a feature.',
|
|
223
|
-
goal: 'Gate features based on plan/usage.',
|
|
224
|
-
context: 'Feature access checks, upgrade prompts.',
|
|
225
|
-
},
|
|
226
|
-
io: {
|
|
227
|
-
input: CheckFeatureAccessInputModel,
|
|
228
|
-
output: CheckFeatureAccessOutputModel,
|
|
229
|
-
},
|
|
230
|
-
policy: {
|
|
231
|
-
auth: 'user',
|
|
232
|
-
},
|
|
233
|
-
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Billing domain - subscription, usage tracking, and feature access.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Enums
|
|
6
|
+
export {
|
|
7
|
+
SubscriptionStatusSchemaEnum,
|
|
8
|
+
FeatureAccessReasonEnum,
|
|
9
|
+
} from './billing.enum';
|
|
10
|
+
|
|
11
|
+
// Schema models
|
|
12
|
+
export {
|
|
13
|
+
SubscriptionModel,
|
|
14
|
+
UsageSummaryModel,
|
|
15
|
+
RecordUsageInputModel,
|
|
16
|
+
RecordUsageOutputModel,
|
|
17
|
+
UsageRecordedPayloadModel,
|
|
18
|
+
GetUsageSummaryInputModel,
|
|
19
|
+
GetUsageSummaryOutputModel,
|
|
20
|
+
CheckFeatureAccessInputModel,
|
|
21
|
+
CheckFeatureAccessOutputModel,
|
|
22
|
+
} from './billing.schema';
|
|
23
|
+
|
|
24
|
+
// Contracts
|
|
25
|
+
export {
|
|
26
|
+
GetSubscriptionContract,
|
|
27
|
+
RecordUsageContract,
|
|
28
|
+
GetUsageSummaryContract,
|
|
29
|
+
CheckFeatureAccessContract,
|
|
30
|
+
} from './billing.contracts';
|
|
31
|
+
|
|
32
|
+
// Events
|
|
33
|
+
export {
|
|
34
|
+
UsageRecordedEvent,
|
|
35
|
+
UsageLimitReachedEvent,
|
|
36
|
+
SubscriptionChangedEvent,
|
|
37
|
+
} from './billing.event';
|
|
38
|
+
|
|
39
|
+
// Entities
|
|
40
|
+
export {
|
|
41
|
+
SubscriptionStatusEnum,
|
|
42
|
+
SubscriptionEntity,
|
|
43
|
+
BillingUsageEntity,
|
|
44
|
+
UsageLimitEntity,
|
|
45
|
+
} from './billing.entity';
|
|
46
|
+
|
|
47
|
+
// Presentations
|
|
48
|
+
export {
|
|
49
|
+
SubscriptionPresentation,
|
|
50
|
+
UsageDashboardPresentation,
|
|
51
|
+
} from './billing.presentation';
|
|
52
|
+
|
|
53
|
+
// Handlers
|
|
54
|
+
export {
|
|
55
|
+
mockGetSubscriptionHandler,
|
|
56
|
+
mockGetUsageSummaryHandler,
|
|
57
|
+
mockRecordUsageHandler,
|
|
58
|
+
mockCheckFeatureAccessHandler,
|
|
59
|
+
type Subscription,
|
|
60
|
+
type UsageSummary,
|
|
61
|
+
type RecordUsageInput,
|
|
62
|
+
type CheckFeatureAccessInput,
|
|
63
|
+
type CheckFeatureAccessOutput,
|
|
64
|
+
} from './billing.handler';
|
|
65
|
+
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SaaS Dashboard Presentation Descriptor
|
|
3
|
-
*/
|
|
4
1
|
import type { PresentationDescriptorV2 } from '@lssm/lib.contracts';
|
|
5
2
|
|
|
6
3
|
/**
|
|
@@ -49,3 +46,4 @@ export const SettingsPanelPresentation: PresentationDescriptorV2 = {
|
|
|
49
46
|
flags: ['saas.enabled'],
|
|
50
47
|
},
|
|
51
48
|
};
|
|
49
|
+
|
package/src/handlers/index.ts
CHANGED
|
@@ -1,36 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* These handlers provide mock implementations of all contracts
|
|
5
|
-
* for use in demos, tests, and the sandbox environment.
|
|
2
|
+
* SaaS Boilerplate Handlers - re-exports from domain modules for backward compatibility.
|
|
6
3
|
*/
|
|
7
4
|
|
|
8
|
-
//
|
|
9
|
-
export
|
|
5
|
+
// Billing handlers
|
|
6
|
+
export {
|
|
7
|
+
mockGetSubscriptionHandler,
|
|
8
|
+
mockRecordUsageHandler,
|
|
9
|
+
mockGetUsageSummaryHandler,
|
|
10
|
+
mockCheckFeatureAccessHandler,
|
|
11
|
+
} from '../billing/billing.handler';
|
|
10
12
|
|
|
11
13
|
// Project handlers
|
|
12
14
|
export {
|
|
13
|
-
mockListProjectsHandler,
|
|
14
|
-
mockGetProjectHandler,
|
|
15
15
|
mockCreateProjectHandler,
|
|
16
|
+
mockGetProjectHandler,
|
|
17
|
+
mockListProjectsHandler,
|
|
16
18
|
mockUpdateProjectHandler,
|
|
17
19
|
mockDeleteProjectHandler,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
type UpdateProjectInput,
|
|
21
|
-
type ListProjectsInput,
|
|
22
|
-
type ListProjectsOutput,
|
|
23
|
-
} from './project.handlers';
|
|
20
|
+
} from '../project/project.handler';
|
|
21
|
+
|
|
24
22
|
|
|
25
|
-
// Billing handlers
|
|
26
|
-
export {
|
|
27
|
-
mockGetSubscriptionHandler,
|
|
28
|
-
mockGetUsageSummaryHandler,
|
|
29
|
-
mockRecordUsageHandler,
|
|
30
|
-
mockCheckFeatureAccessHandler,
|
|
31
|
-
type Subscription,
|
|
32
|
-
type UsageSummary,
|
|
33
|
-
type RecordUsageInput,
|
|
34
|
-
type CheckFeatureAccessInput,
|
|
35
|
-
type CheckFeatureAccessOutput,
|
|
36
|
-
} from './billing.handlers';
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
// SaaS Boilerplate Example
|
|
2
2
|
// Demonstrates ContractSpec principles for a complete SaaS application
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
4
|
+
// Export all domain modules
|
|
5
|
+
export * from './billing';
|
|
6
|
+
export * from './project';
|
|
7
|
+
export * from './settings';
|
|
8
|
+
export * from './dashboard';
|
|
9
|
+
|
|
10
|
+
// Export feature and example metadata
|
|
9
11
|
export * from './feature';
|
|
10
12
|
export { default as example } from './example';
|
|
13
|
+
|
|
14
|
+
// Import docs for registration
|
|
11
15
|
import './docs';
|
|
12
16
|
|
|
13
17
|
// Schema composition configuration
|
|
@@ -15,7 +19,40 @@ import { identityRbacSchemaContribution } from '@lssm/lib.identity-rbac';
|
|
|
15
19
|
import { jobsSchemaContribution } from '@lssm/lib.jobs';
|
|
16
20
|
import { auditTrailSchemaContribution } from '@lssm/module.audit-trail';
|
|
17
21
|
import { notificationsSchemaContribution } from '@lssm/module.notifications';
|
|
18
|
-
import {
|
|
22
|
+
import type { ModuleSchemaContribution } from '@lssm/lib.schema';
|
|
23
|
+
import {
|
|
24
|
+
ProjectEntity,
|
|
25
|
+
ProjectMemberEntity,
|
|
26
|
+
ProjectStatusEnum,
|
|
27
|
+
} from './project/project.entity';
|
|
28
|
+
import {
|
|
29
|
+
SettingsEntity,
|
|
30
|
+
FeatureFlagEntity,
|
|
31
|
+
SettingsScopeEnum,
|
|
32
|
+
} from './settings';
|
|
33
|
+
import {
|
|
34
|
+
SubscriptionEntity,
|
|
35
|
+
BillingUsageEntity,
|
|
36
|
+
UsageLimitEntity,
|
|
37
|
+
SubscriptionStatusEnum,
|
|
38
|
+
} from './billing/billing.entity';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* SaaS boilerplate schema contribution.
|
|
42
|
+
*/
|
|
43
|
+
export const saasBoilerplateSchemaContribution: ModuleSchemaContribution = {
|
|
44
|
+
moduleId: '@lssm/example.saas-boilerplate',
|
|
45
|
+
entities: [
|
|
46
|
+
ProjectEntity,
|
|
47
|
+
ProjectMemberEntity,
|
|
48
|
+
SettingsEntity,
|
|
49
|
+
FeatureFlagEntity,
|
|
50
|
+
SubscriptionEntity,
|
|
51
|
+
BillingUsageEntity,
|
|
52
|
+
UsageLimitEntity,
|
|
53
|
+
],
|
|
54
|
+
enums: [ProjectStatusEnum, SettingsScopeEnum, SubscriptionStatusEnum],
|
|
55
|
+
};
|
|
19
56
|
|
|
20
57
|
/**
|
|
21
58
|
* Complete schema composition for SaaS Boilerplate.
|
|
@@ -1,44 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* SaaS Boilerplate Presentations - re-exports from domain modules for backward compatibility.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
// Project presentations
|
|
6
|
-
export {
|
|
7
|
-
ProjectListPresentation,
|
|
8
|
-
ProjectDetailPresentation,
|
|
9
|
-
} from './project-list';
|
|
10
|
-
|
|
11
5
|
// Billing presentations
|
|
12
6
|
export {
|
|
13
7
|
SubscriptionPresentation,
|
|
14
8
|
UsageDashboardPresentation,
|
|
15
|
-
} from '
|
|
9
|
+
} from '../billing/billing.presentation';
|
|
16
10
|
|
|
17
|
-
//
|
|
11
|
+
// Project presentations
|
|
18
12
|
export {
|
|
19
|
-
SaasDashboardPresentation,
|
|
20
|
-
SettingsPanelPresentation,
|
|
21
|
-
} from './dashboard';
|
|
22
|
-
|
|
23
|
-
// Re-export all presentations as an array
|
|
24
|
-
import {
|
|
25
13
|
ProjectListPresentation,
|
|
26
14
|
ProjectDetailPresentation,
|
|
27
|
-
} from '
|
|
28
|
-
import {
|
|
29
|
-
SubscriptionPresentation,
|
|
30
|
-
UsageDashboardPresentation,
|
|
31
|
-
} from './billing';
|
|
32
|
-
import {
|
|
33
|
-
SaasDashboardPresentation,
|
|
34
|
-
SettingsPanelPresentation,
|
|
35
|
-
} from './dashboard';
|
|
15
|
+
} from '../project/project.presentation';
|
|
36
16
|
|
|
37
|
-
|
|
17
|
+
// Dashboard presentations
|
|
18
|
+
export {
|
|
38
19
|
SaasDashboardPresentation,
|
|
39
|
-
ProjectListPresentation,
|
|
40
|
-
ProjectDetailPresentation,
|
|
41
|
-
SubscriptionPresentation,
|
|
42
|
-
UsageDashboardPresentation,
|
|
43
20
|
SettingsPanelPresentation,
|
|
44
|
-
|
|
21
|
+
} from '../dashboard/dashboard.presentation';
|
|
22
|
+
|
|
23
|
+
// All presentations collection
|
|
24
|
+
export const SaasBoilerplatePresentations = {
|
|
25
|
+
// Billing
|
|
26
|
+
SubscriptionPresentation: undefined,
|
|
27
|
+
UsageDashboardPresentation: undefined,
|
|
28
|
+
|
|
29
|
+
// Project
|
|
30
|
+
ProjectListPresentation: undefined,
|
|
31
|
+
ProjectDetailPresentation: undefined,
|
|
32
|
+
|
|
33
|
+
// Dashboard
|
|
34
|
+
SaasDashboardPresentation: undefined,
|
|
35
|
+
SettingsPanelPresentation: undefined,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project domain - project management within organizations.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Enums
|
|
6
|
+
export {
|
|
7
|
+
ProjectStatusSchemaEnum,
|
|
8
|
+
ProjectStatusFilterEnum,
|
|
9
|
+
} from './project.enum';
|
|
10
|
+
|
|
11
|
+
// Schema models
|
|
12
|
+
export {
|
|
13
|
+
ProjectModel,
|
|
14
|
+
CreateProjectInputModel,
|
|
15
|
+
UpdateProjectInputModel,
|
|
16
|
+
GetProjectInputModel,
|
|
17
|
+
DeleteProjectInputModel,
|
|
18
|
+
DeleteProjectOutputModel,
|
|
19
|
+
ProjectDeletedPayloadModel,
|
|
20
|
+
ListProjectsInputModel,
|
|
21
|
+
ListProjectsOutputModel,
|
|
22
|
+
} from './project.schema';
|
|
23
|
+
|
|
24
|
+
// Contracts
|
|
25
|
+
export {
|
|
26
|
+
CreateProjectContract,
|
|
27
|
+
GetProjectContract,
|
|
28
|
+
UpdateProjectContract,
|
|
29
|
+
DeleteProjectContract,
|
|
30
|
+
ListProjectsContract,
|
|
31
|
+
} from './project.contracts';
|
|
32
|
+
|
|
33
|
+
// Events
|
|
34
|
+
export {
|
|
35
|
+
ProjectCreatedEvent,
|
|
36
|
+
ProjectUpdatedEvent,
|
|
37
|
+
ProjectDeletedEvent,
|
|
38
|
+
ProjectArchivedEvent,
|
|
39
|
+
} from './project.event';
|
|
40
|
+
|
|
41
|
+
// Entities
|
|
42
|
+
export {
|
|
43
|
+
ProjectStatusEnum,
|
|
44
|
+
ProjectEntity,
|
|
45
|
+
ProjectMemberEntity,
|
|
46
|
+
} from './project.entity';
|
|
47
|
+
|
|
48
|
+
// Presentations
|
|
49
|
+
export {
|
|
50
|
+
ProjectListPresentation,
|
|
51
|
+
ProjectDetailPresentation,
|
|
52
|
+
} from './project.presentation';
|
|
53
|
+
|
|
54
|
+
// Handlers
|
|
55
|
+
export {
|
|
56
|
+
mockListProjectsHandler,
|
|
57
|
+
mockGetProjectHandler,
|
|
58
|
+
mockCreateProjectHandler,
|
|
59
|
+
mockUpdateProjectHandler,
|
|
60
|
+
mockDeleteProjectHandler,
|
|
61
|
+
type Project,
|
|
62
|
+
type CreateProjectInput,
|
|
63
|
+
type UpdateProjectInput,
|
|
64
|
+
type ListProjectsInput,
|
|
65
|
+
type ListProjectsOutput,
|
|
66
|
+
} from './project.handler';
|
|
67
|
+
|