@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.
- package/.turbo/turbo-build$colon$bundle.log +113 -0
- package/.turbo/turbo-build.log +114 -0
- package/CHANGELOG.md +246 -0
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/billing/billing.entity.d.ts +61 -0
- package/dist/billing/billing.entity.d.ts.map +1 -0
- package/dist/billing/billing.entity.js +122 -0
- package/dist/billing/billing.entity.js.map +1 -0
- package/dist/billing/billing.enum.d.ts +16 -0
- package/dist/billing/billing.enum.d.ts.map +1 -0
- package/dist/billing/billing.enum.js +27 -0
- package/dist/billing/billing.enum.js.map +1 -0
- package/dist/billing/billing.event.d.ts +86 -0
- package/dist/billing/billing.event.d.ts.map +1 -0
- package/dist/billing/billing.event.js +153 -0
- package/dist/billing/billing.event.js.map +1 -0
- package/dist/billing/billing.handler.d.ts +82 -0
- package/dist/billing/billing.handler.d.ts.map +1 -0
- package/dist/billing/billing.handler.js +58 -0
- package/dist/billing/billing.handler.js.map +1 -0
- package/dist/billing/billing.operations.d.ts +166 -0
- package/dist/billing/billing.operations.d.ts.map +1 -0
- package/dist/billing/billing.operations.js +181 -0
- package/dist/billing/billing.operations.js.map +1 -0
- package/dist/billing/billing.presentation.d.ts +15 -0
- package/dist/billing/billing.presentation.d.ts.map +1 -0
- package/dist/billing/billing.presentation.js +59 -0
- package/dist/billing/billing.presentation.js.map +1 -0
- package/dist/billing/billing.schema.d.ts +201 -0
- package/dist/billing/billing.schema.d.ts.map +1 -0
- package/dist/billing/billing.schema.js +214 -0
- package/dist/billing/billing.schema.js.map +1 -0
- package/dist/billing/index.d.ts +8 -0
- package/dist/billing/index.js +9 -0
- package/dist/dashboard/dashboard.presentation.d.ts +15 -0
- package/dist/dashboard/dashboard.presentation.d.ts.map +1 -0
- package/dist/dashboard/dashboard.presentation.js +55 -0
- package/dist/dashboard/dashboard.presentation.js.map +1 -0
- package/dist/dashboard/index.d.ts +2 -0
- package/dist/dashboard/index.js +3 -0
- package/dist/docs/index.d.ts +1 -0
- package/dist/docs/index.js +1 -0
- package/dist/docs/saas-boilerplate.docblock.d.ts +1 -0
- package/dist/docs/saas-boilerplate.docblock.js +100 -0
- package/dist/docs/saas-boilerplate.docblock.js.map +1 -0
- package/dist/example.d.ts +37 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/example.js +46 -0
- package/dist/example.js.map +1 -0
- package/dist/handlers/index.d.ts +3 -0
- package/dist/handlers/index.js +4 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/presentations/index.d.ts +17 -0
- package/dist/presentations/index.d.ts.map +1 -0
- package/dist/presentations/index.js +17 -0
- package/dist/presentations/index.js.map +1 -0
- package/dist/project/index.d.ts +8 -0
- package/dist/project/index.js +9 -0
- package/dist/project/project.entity.d.ts +40 -0
- package/dist/project/project.entity.d.ts.map +1 -0
- package/dist/project/project.entity.js +85 -0
- package/dist/project/project.entity.js.map +1 -0
- package/dist/project/project.enum.d.ts +16 -0
- package/dist/project/project.enum.d.ts.map +1 -0
- package/dist/project/project.enum.js +26 -0
- package/dist/project/project.enum.js.map +1 -0
- package/dist/project/project.event.d.ts +92 -0
- package/dist/project/project.event.d.ts.map +1 -0
- package/dist/project/project.event.js +165 -0
- package/dist/project/project.event.js.map +1 -0
- package/dist/project/project.handler.d.ts +72 -0
- package/dist/project/project.handler.d.ts.map +1 -0
- package/dist/project/project.handler.js +82 -0
- package/dist/project/project.handler.js.map +1 -0
- package/dist/project/project.operations.d.ts +419 -0
- package/dist/project/project.operations.d.ts.map +1 -0
- package/dist/project/project.operations.js +260 -0
- package/dist/project/project.operations.js.map +1 -0
- package/dist/project/project.presentation.d.ts +15 -0
- package/dist/project/project.presentation.d.ts.map +1 -0
- package/dist/project/project.presentation.js +65 -0
- package/dist/project/project.presentation.js.map +1 -0
- package/dist/project/project.schema.d.ts +235 -0
- package/dist/project/project.schema.d.ts.map +1 -0
- package/dist/project/project.schema.js +215 -0
- package/dist/project/project.schema.js.map +1 -0
- package/dist/saas-boilerplate.feature.d.ts +12 -0
- package/dist/saas-boilerplate.feature.d.ts.map +1 -0
- package/dist/saas-boilerplate.feature.js +201 -0
- package/dist/saas-boilerplate.feature.js.map +1 -0
- package/dist/settings/index.d.ts +3 -0
- package/dist/settings/index.js +4 -0
- package/dist/settings/settings.entity.d.ts +37 -0
- package/dist/settings/settings.entity.d.ts.map +1 -0
- package/dist/settings/settings.entity.js +78 -0
- package/dist/settings/settings.entity.js.map +1 -0
- package/dist/settings/settings.enum.d.ts +10 -0
- package/dist/settings/settings.enum.d.ts.map +1 -0
- package/dist/settings/settings.enum.js +21 -0
- package/dist/settings/settings.enum.js.map +1 -0
- package/dist/shared/mock-data.d.ts +86 -0
- package/dist/shared/mock-data.d.ts.map +1 -0
- package/dist/shared/mock-data.js +138 -0
- package/dist/shared/mock-data.js.map +1 -0
- package/example.ts +1 -0
- package/package.json +113 -0
- package/src/billing/billing.entity.ts +158 -0
- package/src/billing/billing.enum.ts +23 -0
- package/src/billing/billing.event.ts +108 -0
- package/src/billing/billing.handler.ts +137 -0
- package/src/billing/billing.operations.ts +187 -0
- package/src/billing/billing.presentation.ts +57 -0
- package/src/billing/billing.schema.ts +133 -0
- package/src/billing/index.ts +64 -0
- package/src/dashboard/dashboard.presentation.ts +57 -0
- package/src/dashboard/index.ts +8 -0
- package/src/docs/index.ts +1 -0
- package/src/docs/saas-boilerplate.docblock.ts +98 -0
- package/src/example.ts +31 -0
- package/src/handlers/index.ts +20 -0
- package/src/index.ts +71 -0
- package/src/presentations/index.ts +36 -0
- package/src/project/index.ts +66 -0
- package/src/project/project.entity.ts +93 -0
- package/src/project/project.enum.ts +22 -0
- package/src/project/project.event.ts +128 -0
- package/src/project/project.handler.ts +168 -0
- package/src/project/project.operations.ts +272 -0
- package/src/project/project.presentation.ts +59 -0
- package/src/project/project.schema.ts +147 -0
- package/src/saas-boilerplate.feature.ts +109 -0
- package/src/settings/index.ts +9 -0
- package/src/settings/settings.entity.ts +89 -0
- package/src/settings/settings.enum.ts +11 -0
- package/src/shared/mock-data.ts +110 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsdown.config.js +7 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaaS Boilerplate Feature Module Specification
|
|
3
|
+
*
|
|
4
|
+
* Defines the feature module for the SaaS application foundation.
|
|
5
|
+
*/
|
|
6
|
+
import type { FeatureModuleSpec } from '@contractspec/lib.contracts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* SaaS Boilerplate feature module that bundles project management,
|
|
10
|
+
* billing, and settings operations into an installable feature.
|
|
11
|
+
*/
|
|
12
|
+
export const SaasBoilerplateFeature: FeatureModuleSpec = {
|
|
13
|
+
meta: {
|
|
14
|
+
key: 'saas-boilerplate',
|
|
15
|
+
title: 'SaaS Boilerplate',
|
|
16
|
+
description:
|
|
17
|
+
'SaaS application foundation with projects, billing, and settings',
|
|
18
|
+
domain: 'saas',
|
|
19
|
+
owners: ['@saas-team'],
|
|
20
|
+
tags: ['saas', 'projects', 'billing'],
|
|
21
|
+
stability: 'experimental',
|
|
22
|
+
version: 1,
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// All contract operations included in this feature
|
|
26
|
+
operations: [
|
|
27
|
+
// Project operations
|
|
28
|
+
{ key: 'saas.project.create', version: 1 },
|
|
29
|
+
{ key: 'saas.project.get', version: 1 },
|
|
30
|
+
{ key: 'saas.project.update', version: 1 },
|
|
31
|
+
{ key: 'saas.project.delete', version: 1 },
|
|
32
|
+
{ key: 'saas.project.list', version: 1 },
|
|
33
|
+
|
|
34
|
+
// Billing operations
|
|
35
|
+
{ key: 'saas.billing.subscription.get', version: 1 },
|
|
36
|
+
{ key: 'saas.billing.usage.record', version: 1 },
|
|
37
|
+
{ key: 'saas.billing.usage.summary', version: 1 },
|
|
38
|
+
{ key: 'saas.billing.feature.check', version: 1 },
|
|
39
|
+
],
|
|
40
|
+
|
|
41
|
+
// Events emitted by this feature
|
|
42
|
+
events: [
|
|
43
|
+
// Project events
|
|
44
|
+
{ key: 'project.created', version: 1 },
|
|
45
|
+
{ key: 'project.updated', version: 1 },
|
|
46
|
+
{ key: 'project.deleted', version: 1 },
|
|
47
|
+
{ key: 'project.archived', version: 1 },
|
|
48
|
+
|
|
49
|
+
// Billing events
|
|
50
|
+
{ key: 'billing.usage.recorded', version: 1 },
|
|
51
|
+
{ key: 'billing.subscription.changed', version: 1 },
|
|
52
|
+
{ key: 'billing.limit.reached', version: 1 },
|
|
53
|
+
],
|
|
54
|
+
|
|
55
|
+
// Presentations associated with this feature
|
|
56
|
+
presentations: [
|
|
57
|
+
{ key: 'saas.dashboard', version: 1 },
|
|
58
|
+
{ key: 'saas.project.list', version: 1 },
|
|
59
|
+
{ key: 'saas.project.detail', version: 1 },
|
|
60
|
+
{ key: 'saas.billing.subscription', version: 1 },
|
|
61
|
+
{ key: 'saas.billing.usage', version: 1 },
|
|
62
|
+
{ key: 'saas.settings', version: 1 },
|
|
63
|
+
],
|
|
64
|
+
|
|
65
|
+
// Link operations to their primary presentations
|
|
66
|
+
opToPresentation: [
|
|
67
|
+
{
|
|
68
|
+
op: { key: 'saas.project.list', version: 1 },
|
|
69
|
+
pres: { key: 'saas.project.list', version: 1 },
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
op: { key: 'saas.project.get', version: 1 },
|
|
73
|
+
pres: { key: 'saas.project.detail', version: 1 },
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
op: { key: 'saas.billing.subscription.get', version: 1 },
|
|
77
|
+
pres: { key: 'saas.billing.subscription', version: 1 },
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
op: { key: 'saas.billing.usage.summary', version: 1 },
|
|
81
|
+
pres: { key: 'saas.billing.usage', version: 1 },
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
|
|
85
|
+
// Target requirements for multi-surface rendering
|
|
86
|
+
presentationsTargets: [
|
|
87
|
+
{ key: 'saas.dashboard', version: 1, targets: ['react', 'markdown'] },
|
|
88
|
+
{
|
|
89
|
+
key: 'saas.project.list',
|
|
90
|
+
version: 1,
|
|
91
|
+
targets: ['react', 'markdown', 'application/json'],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
key: 'saas.billing.subscription',
|
|
95
|
+
version: 1,
|
|
96
|
+
targets: ['react', 'markdown'],
|
|
97
|
+
},
|
|
98
|
+
{ key: 'saas.billing.usage', version: 1, targets: ['react', 'markdown'] },
|
|
99
|
+
],
|
|
100
|
+
|
|
101
|
+
// Capability requirements
|
|
102
|
+
capabilities: {
|
|
103
|
+
requires: [
|
|
104
|
+
{ key: 'identity', version: 1 },
|
|
105
|
+
{ key: 'audit-trail', version: 1 },
|
|
106
|
+
{ key: 'notifications', version: 1 },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { defineEntity, field, index } from '@contractspec/lib.schema';
|
|
2
|
+
import { SettingsScopeEnum } from './settings.enum';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Settings entity - key-value configuration store.
|
|
6
|
+
*/
|
|
7
|
+
export const SettingsEntity = defineEntity({
|
|
8
|
+
name: 'Settings',
|
|
9
|
+
description: 'Application, organization, or user settings.',
|
|
10
|
+
schema: 'saas_app',
|
|
11
|
+
map: 'settings',
|
|
12
|
+
fields: {
|
|
13
|
+
id: field.id(),
|
|
14
|
+
|
|
15
|
+
// Key identification
|
|
16
|
+
key: field.string({
|
|
17
|
+
description: 'Setting key (e.g., "theme", "notifications.email")',
|
|
18
|
+
}),
|
|
19
|
+
|
|
20
|
+
// Scope
|
|
21
|
+
scope: field.enum('SettingsScope'),
|
|
22
|
+
scopeId: field.string({
|
|
23
|
+
isOptional: true,
|
|
24
|
+
description: 'ID of scoped entity (org, user, project)',
|
|
25
|
+
}),
|
|
26
|
+
|
|
27
|
+
// Value
|
|
28
|
+
value: field.json({ description: 'Setting value' }),
|
|
29
|
+
valueType: field.string({
|
|
30
|
+
default: '"string"',
|
|
31
|
+
description: 'Type hint for value',
|
|
32
|
+
}),
|
|
33
|
+
|
|
34
|
+
// Schema
|
|
35
|
+
schema: field.json({
|
|
36
|
+
isOptional: true,
|
|
37
|
+
description: 'JSON schema for validation',
|
|
38
|
+
}),
|
|
39
|
+
|
|
40
|
+
// Metadata
|
|
41
|
+
description: field.string({ isOptional: true }),
|
|
42
|
+
isSecret: field.boolean({
|
|
43
|
+
default: false,
|
|
44
|
+
description: 'Whether value should be encrypted',
|
|
45
|
+
}),
|
|
46
|
+
|
|
47
|
+
// Timestamps
|
|
48
|
+
createdAt: field.createdAt(),
|
|
49
|
+
updatedAt: field.updatedAt(),
|
|
50
|
+
},
|
|
51
|
+
indexes: [
|
|
52
|
+
index.unique(['scope', 'scopeId', 'key']),
|
|
53
|
+
index.on(['scope', 'key']),
|
|
54
|
+
],
|
|
55
|
+
enums: [SettingsScopeEnum],
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* FeatureFlag entity - feature toggles.
|
|
60
|
+
*/
|
|
61
|
+
export const FeatureFlagEntity = defineEntity({
|
|
62
|
+
name: 'FeatureFlag',
|
|
63
|
+
description: 'Feature flags for progressive rollout.',
|
|
64
|
+
schema: 'saas_app',
|
|
65
|
+
map: 'feature_flag',
|
|
66
|
+
fields: {
|
|
67
|
+
id: field.id(),
|
|
68
|
+
key: field.string({ isUnique: true, description: 'Feature flag key' }),
|
|
69
|
+
name: field.string({ description: 'Human-readable name' }),
|
|
70
|
+
description: field.string({ isOptional: true }),
|
|
71
|
+
|
|
72
|
+
// Status
|
|
73
|
+
enabled: field.boolean({ default: false }),
|
|
74
|
+
|
|
75
|
+
// Targeting
|
|
76
|
+
defaultValue: field.boolean({ default: false }),
|
|
77
|
+
rules: field.json({ isOptional: true, description: 'Targeting rules' }),
|
|
78
|
+
|
|
79
|
+
// Rollout
|
|
80
|
+
rolloutPercentage: field.int({
|
|
81
|
+
default: 0,
|
|
82
|
+
description: 'Percentage rollout (0-100)',
|
|
83
|
+
}),
|
|
84
|
+
|
|
85
|
+
// Timestamps
|
|
86
|
+
createdAt: field.createdAt(),
|
|
87
|
+
updatedAt: field.updatedAt(),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineEntityEnum } from '@contractspec/lib.schema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Settings scope enum.
|
|
5
|
+
*/
|
|
6
|
+
export const SettingsScopeEnum = defineEntityEnum({
|
|
7
|
+
name: 'SettingsScope',
|
|
8
|
+
values: ['APP', 'ORG', 'USER', 'PROJECT'] as const,
|
|
9
|
+
schema: 'saas_app',
|
|
10
|
+
description: 'Scope of a setting.',
|
|
11
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared mock data for saas-boilerplate handlers.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// ============ Project Mock Data ============
|
|
6
|
+
|
|
7
|
+
export const MOCK_PROJECTS = [
|
|
8
|
+
{
|
|
9
|
+
id: 'proj-1',
|
|
10
|
+
name: 'Marketing Website',
|
|
11
|
+
description: 'Main company website redesign project',
|
|
12
|
+
slug: 'marketing-website',
|
|
13
|
+
organizationId: 'demo-org',
|
|
14
|
+
createdBy: 'user-1',
|
|
15
|
+
status: 'ACTIVE' as const,
|
|
16
|
+
isPublic: false,
|
|
17
|
+
tags: ['marketing', 'website', 'redesign'],
|
|
18
|
+
createdAt: new Date('2024-01-15T10:00:00Z'),
|
|
19
|
+
updatedAt: new Date('2024-03-20T14:30:00Z'),
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'proj-2',
|
|
23
|
+
name: 'Mobile App v2',
|
|
24
|
+
description: 'Next generation mobile application',
|
|
25
|
+
slug: 'mobile-app-v2',
|
|
26
|
+
organizationId: 'demo-org',
|
|
27
|
+
createdBy: 'user-2',
|
|
28
|
+
status: 'ACTIVE' as const,
|
|
29
|
+
isPublic: false,
|
|
30
|
+
tags: ['mobile', 'app', 'v2'],
|
|
31
|
+
createdAt: new Date('2024-02-01T09:00:00Z'),
|
|
32
|
+
updatedAt: new Date('2024-04-05T11:15:00Z'),
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'proj-3',
|
|
36
|
+
name: 'API Integration',
|
|
37
|
+
description: 'Third-party API integration project',
|
|
38
|
+
slug: 'api-integration',
|
|
39
|
+
organizationId: 'demo-org',
|
|
40
|
+
createdBy: 'user-1',
|
|
41
|
+
status: 'DRAFT' as const,
|
|
42
|
+
isPublic: false,
|
|
43
|
+
tags: ['api', 'integration'],
|
|
44
|
+
createdAt: new Date('2024-03-10T08:00:00Z'),
|
|
45
|
+
updatedAt: new Date('2024-03-10T08:00:00Z'),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'proj-4',
|
|
49
|
+
name: 'Analytics Dashboard',
|
|
50
|
+
description: 'Internal analytics and reporting dashboard',
|
|
51
|
+
slug: 'analytics-dashboard',
|
|
52
|
+
organizationId: 'demo-org',
|
|
53
|
+
createdBy: 'user-3',
|
|
54
|
+
status: 'ARCHIVED' as const,
|
|
55
|
+
isPublic: true,
|
|
56
|
+
tags: ['analytics', 'dashboard', 'reporting'],
|
|
57
|
+
createdAt: new Date('2023-10-01T12:00:00Z'),
|
|
58
|
+
updatedAt: new Date('2024-02-28T16:45:00Z'),
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
// ============ Subscription Mock Data ============
|
|
63
|
+
|
|
64
|
+
export const MOCK_SUBSCRIPTION = {
|
|
65
|
+
id: 'sub-1',
|
|
66
|
+
organizationId: 'demo-org',
|
|
67
|
+
planId: 'pro',
|
|
68
|
+
planName: 'Professional',
|
|
69
|
+
status: 'ACTIVE' as const,
|
|
70
|
+
currentPeriodStart: new Date('2024-04-01T00:00:00Z'),
|
|
71
|
+
currentPeriodEnd: new Date('2024-05-01T00:00:00Z'),
|
|
72
|
+
limits: {
|
|
73
|
+
projects: 25,
|
|
74
|
+
users: 10,
|
|
75
|
+
storage: 50, // GB
|
|
76
|
+
apiCalls: 100000,
|
|
77
|
+
},
|
|
78
|
+
usage: {
|
|
79
|
+
projects: 4,
|
|
80
|
+
users: 5,
|
|
81
|
+
storage: 12.5,
|
|
82
|
+
apiCalls: 45230,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// ============ Usage Summary Mock Data ============
|
|
87
|
+
|
|
88
|
+
export const MOCK_USAGE_SUMMARY = {
|
|
89
|
+
organizationId: 'demo-org',
|
|
90
|
+
period: 'current_month',
|
|
91
|
+
apiCalls: {
|
|
92
|
+
total: 45230,
|
|
93
|
+
limit: 100000,
|
|
94
|
+
percentUsed: 45.23,
|
|
95
|
+
},
|
|
96
|
+
storage: {
|
|
97
|
+
totalGb: 12.5,
|
|
98
|
+
limitGb: 50,
|
|
99
|
+
percentUsed: 25,
|
|
100
|
+
},
|
|
101
|
+
activeProjects: 4,
|
|
102
|
+
activeUsers: 5,
|
|
103
|
+
breakdown: [
|
|
104
|
+
{ date: '2024-04-01', apiCalls: 3200, storageGb: 12.1 },
|
|
105
|
+
{ date: '2024-04-02', apiCalls: 2800, storageGb: 12.2 },
|
|
106
|
+
{ date: '2024-04-03', apiCalls: 4100, storageGb: 12.3 },
|
|
107
|
+
{ date: '2024-04-04', apiCalls: 3600, storageGb: 12.4 },
|
|
108
|
+
{ date: '2024-04-05', apiCalls: 3800, storageGb: 12.5 },
|
|
109
|
+
],
|
|
110
|
+
};
|