@contractspec/example.saas-boilerplate 3.7.5 → 3.7.7

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 (115) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/AGENTS.md +50 -27
  3. package/CHANGELOG.md +16 -0
  4. package/README.md +64 -144
  5. package/dist/billing/billing.event.js +1 -1
  6. package/dist/billing/index.d.ts +6 -6
  7. package/dist/billing/index.js +1 -1
  8. package/dist/browser/billing/billing.event.js +1 -1
  9. package/dist/browser/billing/index.js +1 -1
  10. package/dist/browser/index.js +931 -932
  11. package/dist/browser/project/index.js +209 -209
  12. package/dist/browser/project/project.event.js +1 -1
  13. package/dist/browser/ui/SaasDashboard.js +45 -45
  14. package/dist/browser/ui/SaasProjectList.js +7 -7
  15. package/dist/browser/ui/SaasSettingsPanel.js +12 -12
  16. package/dist/browser/ui/hooks/index.js +2 -2
  17. package/dist/browser/ui/hooks/useProjectList.js +1 -1
  18. package/dist/browser/ui/hooks/useProjectMutations.js +1 -1
  19. package/dist/browser/ui/index.js +483 -484
  20. package/dist/browser/ui/modals/CreateProjectModal.js +10 -10
  21. package/dist/browser/ui/modals/ProjectActionsModal.js +13 -13
  22. package/dist/browser/ui/modals/index.js +23 -23
  23. package/dist/browser/ui/renderers/index.js +112 -112
  24. package/dist/browser/ui/renderers/project-list.renderer.js +7 -7
  25. package/dist/handlers/index.d.ts +2 -2
  26. package/dist/index.d.ts +4 -4
  27. package/dist/index.js +931 -932
  28. package/dist/node/billing/billing.event.js +1 -1
  29. package/dist/node/billing/index.js +1 -1
  30. package/dist/node/index.js +931 -932
  31. package/dist/node/project/index.js +209 -209
  32. package/dist/node/project/project.event.js +1 -1
  33. package/dist/node/ui/SaasDashboard.js +45 -45
  34. package/dist/node/ui/SaasProjectList.js +7 -7
  35. package/dist/node/ui/SaasSettingsPanel.js +12 -12
  36. package/dist/node/ui/hooks/index.js +2 -2
  37. package/dist/node/ui/hooks/useProjectList.js +1 -1
  38. package/dist/node/ui/hooks/useProjectMutations.js +1 -1
  39. package/dist/node/ui/index.js +483 -484
  40. package/dist/node/ui/modals/CreateProjectModal.js +10 -10
  41. package/dist/node/ui/modals/ProjectActionsModal.js +13 -13
  42. package/dist/node/ui/modals/index.js +23 -23
  43. package/dist/node/ui/renderers/index.js +112 -112
  44. package/dist/node/ui/renderers/project-list.renderer.js +7 -7
  45. package/dist/presentations/index.d.ts +1 -1
  46. package/dist/project/index.d.ts +7 -7
  47. package/dist/project/index.js +209 -209
  48. package/dist/project/project.event.js +1 -1
  49. package/dist/settings/index.d.ts +1 -1
  50. package/dist/ui/SaasDashboard.js +45 -45
  51. package/dist/ui/SaasProjectList.js +7 -7
  52. package/dist/ui/SaasSettingsPanel.js +12 -12
  53. package/dist/ui/hooks/index.d.ts +2 -2
  54. package/dist/ui/hooks/index.js +2 -2
  55. package/dist/ui/hooks/useProjectList.d.ts +5 -0
  56. package/dist/ui/hooks/useProjectList.js +1 -1
  57. package/dist/ui/hooks/useProjectMutations.d.ts +8 -0
  58. package/dist/ui/hooks/useProjectMutations.js +1 -1
  59. package/dist/ui/index.d.ts +4 -4
  60. package/dist/ui/index.js +483 -484
  61. package/dist/ui/modals/CreateProjectModal.js +10 -10
  62. package/dist/ui/modals/ProjectActionsModal.js +13 -13
  63. package/dist/ui/modals/index.js +23 -23
  64. package/dist/ui/renderers/index.d.ts +1 -1
  65. package/dist/ui/renderers/index.js +112 -112
  66. package/dist/ui/renderers/project-list.renderer.d.ts +1 -1
  67. package/dist/ui/renderers/project-list.renderer.js +7 -7
  68. package/package.json +14 -14
  69. package/src/billing/billing.entity.ts +132 -132
  70. package/src/billing/billing.enum.ts +9 -9
  71. package/src/billing/billing.event.ts +71 -71
  72. package/src/billing/billing.handler.ts +87 -87
  73. package/src/billing/billing.operations.ts +158 -158
  74. package/src/billing/billing.presentation.ts +45 -45
  75. package/src/billing/billing.schema.ts +76 -76
  76. package/src/billing/index.ts +43 -48
  77. package/src/dashboard/dashboard.presentation.ts +45 -45
  78. package/src/dashboard/index.ts +2 -2
  79. package/src/docs/saas-boilerplate.docblock.ts +43 -43
  80. package/src/example.ts +32 -32
  81. package/src/handlers/index.ts +9 -9
  82. package/src/handlers/saas.handlers.ts +250 -249
  83. package/src/index.ts +40 -41
  84. package/src/presentations/index.ts +18 -20
  85. package/src/project/index.ts +45 -50
  86. package/src/project/project.entity.ts +68 -68
  87. package/src/project/project.enum.ts +8 -8
  88. package/src/project/project.event.ts +79 -79
  89. package/src/project/project.handler.ts +103 -103
  90. package/src/project/project.operations.ts +236 -236
  91. package/src/project/project.presentation.ts +46 -46
  92. package/src/project/project.schema.ts +90 -90
  93. package/src/saas-boilerplate.feature.ts +100 -100
  94. package/src/seeders/index.ts +20 -20
  95. package/src/settings/index.ts +2 -3
  96. package/src/settings/settings.entity.ts +65 -65
  97. package/src/settings/settings.enum.ts +4 -4
  98. package/src/shared/mock-data.ts +92 -92
  99. package/src/shared/overlay-types.ts +23 -23
  100. package/src/tests/operations.test-spec.ts +96 -96
  101. package/src/ui/SaasDashboard.tsx +270 -270
  102. package/src/ui/SaasProjectList.tsx +90 -90
  103. package/src/ui/SaasSettingsPanel.tsx +84 -84
  104. package/src/ui/hooks/index.ts +3 -3
  105. package/src/ui/hooks/useProjectList.ts +69 -68
  106. package/src/ui/hooks/useProjectMutations.ts +144 -143
  107. package/src/ui/index.ts +8 -12
  108. package/src/ui/modals/CreateProjectModal.tsx +154 -154
  109. package/src/ui/modals/ProjectActionsModal.tsx +321 -321
  110. package/src/ui/overlays/demo-overlays.ts +49 -49
  111. package/src/ui/renderers/index.ts +5 -4
  112. package/src/ui/renderers/project-list.markdown.ts +204 -204
  113. package/src/ui/renderers/project-list.renderer.tsx +14 -13
  114. package/tsconfig.json +7 -8
  115. package/tsdown.config.js +7 -3
@@ -5,85 +5,85 @@ import { SettingsScopeEnum } from './settings.enum';
5
5
  * Settings entity - key-value configuration store.
6
6
  */
7
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(),
8
+ name: 'Settings',
9
+ description: 'Application, organization, or user settings.',
10
+ schema: 'saas_app',
11
+ map: 'settings',
12
+ fields: {
13
+ id: field.id(),
14
14
 
15
- // Key identification
16
- key: field.string({
17
- description: 'Setting key (e.g., "theme", "notifications.email")',
18
- }),
15
+ // Key identification
16
+ key: field.string({
17
+ description: 'Setting key (e.g., "theme", "notifications.email")',
18
+ }),
19
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
- }),
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
26
 
27
- // Value
28
- value: field.json({ description: 'Setting value' }),
29
- valueType: field.string({
30
- default: '"string"',
31
- description: 'Type hint for value',
32
- }),
27
+ // Value
28
+ value: field.json({ description: 'Setting value' }),
29
+ valueType: field.string({
30
+ default: '"string"',
31
+ description: 'Type hint for value',
32
+ }),
33
33
 
34
- // Schema
35
- schema: field.json({
36
- isOptional: true,
37
- description: 'JSON schema for validation',
38
- }),
34
+ // Schema
35
+ schema: field.json({
36
+ isOptional: true,
37
+ description: 'JSON schema for validation',
38
+ }),
39
39
 
40
- // Metadata
41
- description: field.string({ isOptional: true }),
42
- isSecret: field.boolean({
43
- default: false,
44
- description: 'Whether value should be encrypted',
45
- }),
40
+ // Metadata
41
+ description: field.string({ isOptional: true }),
42
+ isSecret: field.boolean({
43
+ default: false,
44
+ description: 'Whether value should be encrypted',
45
+ }),
46
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],
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
56
  });
57
57
 
58
58
  /**
59
59
  * FeatureFlag entity - feature toggles.
60
60
  */
61
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 }),
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
71
 
72
- // Status
73
- enabled: field.boolean({ default: false }),
72
+ // Status
73
+ enabled: field.boolean({ default: false }),
74
74
 
75
- // Targeting
76
- defaultValue: field.boolean({ default: false }),
77
- rules: field.json({ isOptional: true, description: 'Targeting rules' }),
75
+ // Targeting
76
+ defaultValue: field.boolean({ default: false }),
77
+ rules: field.json({ isOptional: true, description: 'Targeting rules' }),
78
78
 
79
- // Rollout
80
- rolloutPercentage: field.int({
81
- default: 0,
82
- description: 'Percentage rollout (0-100)',
83
- }),
79
+ // Rollout
80
+ rolloutPercentage: field.int({
81
+ default: 0,
82
+ description: 'Percentage rollout (0-100)',
83
+ }),
84
84
 
85
- // Timestamps
86
- createdAt: field.createdAt(),
87
- updatedAt: field.updatedAt(),
88
- },
85
+ // Timestamps
86
+ createdAt: field.createdAt(),
87
+ updatedAt: field.updatedAt(),
88
+ },
89
89
  });
@@ -4,8 +4,8 @@ import { defineEntityEnum } from '@contractspec/lib.schema';
4
4
  * Settings scope enum.
5
5
  */
6
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.',
7
+ name: 'SettingsScope',
8
+ values: ['APP', 'ORG', 'USER', 'PROJECT'] as const,
9
+ schema: 'saas_app',
10
+ description: 'Scope of a setting.',
11
11
  });
@@ -5,106 +5,106 @@
5
5
  // ============ Project Mock Data ============
6
6
 
7
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
- },
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
60
  ];
61
61
 
62
62
  // ============ Subscription Mock Data ============
63
63
 
64
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
- },
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
84
  };
85
85
 
86
86
  // ============ Usage Summary Mock Data ============
87
87
 
88
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
- ],
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
110
  };
@@ -1,39 +1,39 @@
1
1
  export interface OverlayDefinition {
2
- overlayId: string;
3
- version: string;
4
- description: string;
5
- appliesTo: Record<string, string>;
6
- modifications: OverlayModification[];
2
+ overlayId: string;
3
+ version: string;
4
+ description: string;
5
+ appliesTo: Record<string, string>;
6
+ modifications: OverlayModification[];
7
7
  }
8
8
 
9
9
  export type OverlayModification =
10
- | HideFieldModification
11
- | RenameLabelModification
12
- | AddBadgeModification
13
- | SetLimitModification;
10
+ | HideFieldModification
11
+ | RenameLabelModification
12
+ | AddBadgeModification
13
+ | SetLimitModification;
14
14
 
15
15
  export interface HideFieldModification {
16
- type: 'hideField';
17
- field: string;
18
- reason?: string;
16
+ type: 'hideField';
17
+ field: string;
18
+ reason?: string;
19
19
  }
20
20
 
21
21
  export interface RenameLabelModification {
22
- type: 'renameLabel';
23
- field: string;
24
- newLabel: string;
22
+ type: 'renameLabel';
23
+ field: string;
24
+ newLabel: string;
25
25
  }
26
26
 
27
27
  export interface AddBadgeModification {
28
- type: 'addBadge';
29
- position: 'header' | 'footer';
30
- label: string;
31
- variant: 'warning' | 'info' | 'error' | 'success' | 'default';
28
+ type: 'addBadge';
29
+ position: 'header' | 'footer';
30
+ label: string;
31
+ variant: 'warning' | 'info' | 'error' | 'success' | 'default';
32
32
  }
33
33
 
34
34
  export interface SetLimitModification {
35
- type: 'setLimit';
36
- field: string;
37
- max: number;
38
- message: string;
35
+ type: 'setLimit';
36
+ field: string;
37
+ max: number;
38
+ message: string;
39
39
  }
@@ -1,109 +1,109 @@
1
1
  import { defineTestSpec } from '@contractspec/lib.contracts-spec/tests';
2
2
 
3
3
  export const ProjectListTest = defineTestSpec({
4
- meta: {
5
- key: 'saas.project.list.test',
6
- version: '1.0.0',
7
- stability: 'experimental',
8
- owners: ['@example.saas-boilerplate'],
9
- description: 'Test for listing projects',
10
- tags: ['test'],
11
- },
12
- target: {
13
- type: 'operation',
14
- operation: { key: 'saas.project.list', version: '1.0.0' },
15
- },
16
- scenarios: [
17
- {
18
- key: 'success',
19
- when: { operation: { key: 'saas.project.list' } },
20
- then: [{ type: 'expectOutput', match: {} }],
21
- },
22
- {
23
- key: 'error',
24
- when: { operation: { key: 'saas.project.list' } },
25
- then: [{ type: 'expectError' }],
26
- },
27
- ],
4
+ meta: {
5
+ key: 'saas.project.list.test',
6
+ version: '1.0.0',
7
+ stability: 'experimental',
8
+ owners: ['@example.saas-boilerplate'],
9
+ description: 'Test for listing projects',
10
+ tags: ['test'],
11
+ },
12
+ target: {
13
+ type: 'operation',
14
+ operation: { key: 'saas.project.list', version: '1.0.0' },
15
+ },
16
+ scenarios: [
17
+ {
18
+ key: 'success',
19
+ when: { operation: { key: 'saas.project.list' } },
20
+ then: [{ type: 'expectOutput', match: {} }],
21
+ },
22
+ {
23
+ key: 'error',
24
+ when: { operation: { key: 'saas.project.list' } },
25
+ then: [{ type: 'expectError' }],
26
+ },
27
+ ],
28
28
  });
29
29
 
30
30
  export const ProjectGetTest = defineTestSpec({
31
- meta: {
32
- key: 'saas.project.get.test',
33
- version: '1.0.0',
34
- stability: 'experimental',
35
- owners: ['@example.saas-boilerplate'],
36
- description: 'Test for getting project',
37
- tags: ['test'],
38
- },
39
- target: {
40
- type: 'operation',
41
- operation: { key: 'saas.project.get', version: '1.0.0' },
42
- },
43
- scenarios: [
44
- {
45
- key: 'success',
46
- when: { operation: { key: 'saas.project.get' } },
47
- then: [{ type: 'expectOutput', match: {} }],
48
- },
49
- {
50
- key: 'error',
51
- when: { operation: { key: 'saas.project.get' } },
52
- then: [{ type: 'expectError' }],
53
- },
54
- ],
31
+ meta: {
32
+ key: 'saas.project.get.test',
33
+ version: '1.0.0',
34
+ stability: 'experimental',
35
+ owners: ['@example.saas-boilerplate'],
36
+ description: 'Test for getting project',
37
+ tags: ['test'],
38
+ },
39
+ target: {
40
+ type: 'operation',
41
+ operation: { key: 'saas.project.get', version: '1.0.0' },
42
+ },
43
+ scenarios: [
44
+ {
45
+ key: 'success',
46
+ when: { operation: { key: 'saas.project.get' } },
47
+ then: [{ type: 'expectOutput', match: {} }],
48
+ },
49
+ {
50
+ key: 'error',
51
+ when: { operation: { key: 'saas.project.get' } },
52
+ then: [{ type: 'expectError' }],
53
+ },
54
+ ],
55
55
  });
56
56
 
57
57
  export const BillingSubscriptionGetTest = defineTestSpec({
58
- meta: {
59
- key: 'saas.billing.subscription.get.test',
60
- version: '1.0.0',
61
- stability: 'experimental',
62
- owners: ['@example.saas-boilerplate'],
63
- description: 'Test for getting subscription',
64
- tags: ['test'],
65
- },
66
- target: {
67
- type: 'operation',
68
- operation: { key: 'saas.billing.subscription.get', version: '1.0.0' },
69
- },
70
- scenarios: [
71
- {
72
- key: 'success',
73
- when: { operation: { key: 'saas.billing.subscription.get' } },
74
- then: [{ type: 'expectOutput', match: {} }],
75
- },
76
- {
77
- key: 'error',
78
- when: { operation: { key: 'saas.billing.subscription.get' } },
79
- then: [{ type: 'expectError' }],
80
- },
81
- ],
58
+ meta: {
59
+ key: 'saas.billing.subscription.get.test',
60
+ version: '1.0.0',
61
+ stability: 'experimental',
62
+ owners: ['@example.saas-boilerplate'],
63
+ description: 'Test for getting subscription',
64
+ tags: ['test'],
65
+ },
66
+ target: {
67
+ type: 'operation',
68
+ operation: { key: 'saas.billing.subscription.get', version: '1.0.0' },
69
+ },
70
+ scenarios: [
71
+ {
72
+ key: 'success',
73
+ when: { operation: { key: 'saas.billing.subscription.get' } },
74
+ then: [{ type: 'expectOutput', match: {} }],
75
+ },
76
+ {
77
+ key: 'error',
78
+ when: { operation: { key: 'saas.billing.subscription.get' } },
79
+ then: [{ type: 'expectError' }],
80
+ },
81
+ ],
82
82
  });
83
83
 
84
84
  export const BillingUsageSummaryTest = defineTestSpec({
85
- meta: {
86
- key: 'saas.billing.usage.summary.test',
87
- version: '1.0.0',
88
- stability: 'experimental',
89
- owners: ['@example.saas-boilerplate'],
90
- description: 'Test for getting usage summary',
91
- tags: ['test'],
92
- },
93
- target: {
94
- type: 'operation',
95
- operation: { key: 'saas.billing.usage.summary', version: '1.0.0' },
96
- },
97
- scenarios: [
98
- {
99
- key: 'success',
100
- when: { operation: { key: 'saas.billing.usage.summary' } },
101
- then: [{ type: 'expectOutput', match: {} }],
102
- },
103
- {
104
- key: 'error',
105
- when: { operation: { key: 'saas.billing.usage.summary' } },
106
- then: [{ type: 'expectError' }],
107
- },
108
- ],
85
+ meta: {
86
+ key: 'saas.billing.usage.summary.test',
87
+ version: '1.0.0',
88
+ stability: 'experimental',
89
+ owners: ['@example.saas-boilerplate'],
90
+ description: 'Test for getting usage summary',
91
+ tags: ['test'],
92
+ },
93
+ target: {
94
+ type: 'operation',
95
+ operation: { key: 'saas.billing.usage.summary', version: '1.0.0' },
96
+ },
97
+ scenarios: [
98
+ {
99
+ key: 'success',
100
+ when: { operation: { key: 'saas.billing.usage.summary' } },
101
+ then: [{ type: 'expectOutput', match: {} }],
102
+ },
103
+ {
104
+ key: 'error',
105
+ when: { operation: { key: 'saas.billing.usage.summary' } },
106
+ then: [{ type: 'expectError' }],
107
+ },
108
+ ],
109
109
  });