@contractspec/example.saas-boilerplate 3.8.9 → 3.8.11
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 +155 -155
- package/CHANGELOG.md +34 -0
- package/dist/billing/billing.entity.js +1 -113
- package/dist/billing/billing.enum.js +1 -19
- package/dist/billing/billing.event.js +1 -90
- package/dist/billing/billing.handler.js +1 -148
- package/dist/billing/billing.operations.js +1 -278
- package/dist/billing/billing.presentation.js +1 -55
- package/dist/billing/billing.schema.js +1 -121
- package/dist/billing/index.js +1 -691
- package/dist/browser/billing/billing.entity.js +1 -113
- package/dist/browser/billing/billing.enum.js +1 -19
- package/dist/browser/billing/billing.event.js +1 -90
- package/dist/browser/billing/billing.handler.js +1 -148
- package/dist/browser/billing/billing.operations.js +1 -278
- package/dist/browser/billing/billing.presentation.js +1 -55
- package/dist/browser/billing/billing.schema.js +1 -121
- package/dist/browser/billing/index.js +1 -691
- package/dist/browser/dashboard/dashboard.presentation.js +1 -55
- package/dist/browser/dashboard/index.js +1 -55
- package/dist/browser/docs/index.js +5 -49
- package/dist/browser/docs/saas-boilerplate.docblock.js +5 -49
- package/dist/browser/example.js +1 -39
- package/dist/browser/handlers/index.js +2 -358
- package/dist/browser/handlers/saas.handlers.js +2 -134
- package/dist/browser/index.js +9 -3591
- package/dist/browser/presentations/index.js +1 -299
- package/dist/browser/project/index.js +1 -793
- package/dist/browser/project/project.entity.js +1 -77
- package/dist/browser/project/project.enum.js +1 -18
- package/dist/browser/project/project.event.js +1 -103
- package/dist/browser/project/project.handler.js +1 -178
- package/dist/browser/project/project.operations.js +1 -372
- package/dist/browser/project/project.presentation.js +1 -180
- package/dist/browser/project/project.schema.js +1 -134
- package/dist/browser/saas-boilerplate.feature.js +1 -304
- package/dist/browser/seeders/index.js +2 -20
- package/dist/browser/settings/index.js +1 -75
- package/dist/browser/settings/settings.entity.js +1 -74
- package/dist/browser/settings/settings.enum.js +1 -11
- package/dist/browser/shared/mock-data.js +1 -104
- package/dist/browser/tests/operations.test-spec.js +1 -112
- package/dist/browser/ui/SaasDashboard.js +1 -1239
- package/dist/browser/ui/SaasDashboard.visualizations.js +1 -249
- package/dist/browser/ui/SaasProjectList.js +1 -162
- package/dist/browser/ui/SaasSettingsPanel.js +1 -145
- package/dist/browser/ui/hooks/index.js +1 -159
- package/dist/browser/ui/hooks/useProjectList.js +1 -66
- package/dist/browser/ui/hooks/useProjectMutations.js +1 -91
- package/dist/browser/ui/index.js +5 -2077
- package/dist/browser/ui/modals/CreateProjectModal.js +1 -153
- package/dist/browser/ui/modals/ProjectActionsModal.js +1 -335
- package/dist/browser/ui/modals/index.js +1 -487
- package/dist/browser/ui/overlays/demo-overlays.js +1 -61
- package/dist/browser/ui/overlays/index.js +1 -61
- package/dist/browser/ui/renderers/index.js +5 -901
- package/dist/browser/ui/renderers/project-list.markdown.js +5 -725
- package/dist/browser/ui/renderers/project-list.renderer.js +1 -177
- package/dist/browser/visualizations/catalog.js +1 -155
- package/dist/browser/visualizations/index.js +1 -217
- package/dist/browser/visualizations/selectors.js +1 -210
- package/dist/dashboard/dashboard.presentation.js +1 -55
- package/dist/dashboard/index.js +1 -55
- package/dist/docs/index.js +5 -49
- package/dist/docs/saas-boilerplate.docblock.js +5 -49
- package/dist/example.js +1 -39
- package/dist/handlers/index.js +2 -358
- package/dist/handlers/saas.handlers.js +2 -134
- package/dist/index.js +9 -3591
- package/dist/node/billing/billing.entity.js +1 -113
- package/dist/node/billing/billing.enum.js +1 -19
- package/dist/node/billing/billing.event.js +1 -90
- package/dist/node/billing/billing.handler.js +1 -148
- package/dist/node/billing/billing.operations.js +1 -278
- package/dist/node/billing/billing.presentation.js +1 -55
- package/dist/node/billing/billing.schema.js +1 -121
- package/dist/node/billing/index.js +1 -691
- package/dist/node/dashboard/dashboard.presentation.js +1 -55
- package/dist/node/dashboard/index.js +1 -55
- package/dist/node/docs/index.js +5 -49
- package/dist/node/docs/saas-boilerplate.docblock.js +5 -49
- package/dist/node/example.js +1 -39
- package/dist/node/handlers/index.js +2 -358
- package/dist/node/handlers/saas.handlers.js +2 -134
- package/dist/node/index.js +9 -3591
- package/dist/node/presentations/index.js +1 -299
- package/dist/node/project/index.js +1 -793
- package/dist/node/project/project.entity.js +1 -77
- package/dist/node/project/project.enum.js +1 -18
- package/dist/node/project/project.event.js +1 -103
- package/dist/node/project/project.handler.js +1 -178
- package/dist/node/project/project.operations.js +1 -372
- package/dist/node/project/project.presentation.js +1 -180
- package/dist/node/project/project.schema.js +1 -134
- package/dist/node/saas-boilerplate.feature.js +1 -304
- package/dist/node/seeders/index.js +2 -20
- package/dist/node/settings/index.js +1 -75
- package/dist/node/settings/settings.entity.js +1 -74
- package/dist/node/settings/settings.enum.js +1 -11
- package/dist/node/shared/mock-data.js +1 -104
- package/dist/node/tests/operations.test-spec.js +1 -112
- package/dist/node/ui/SaasDashboard.js +1 -1239
- package/dist/node/ui/SaasDashboard.visualizations.js +1 -249
- package/dist/node/ui/SaasProjectList.js +1 -162
- package/dist/node/ui/SaasSettingsPanel.js +1 -145
- package/dist/node/ui/hooks/index.js +1 -159
- package/dist/node/ui/hooks/useProjectList.js +1 -66
- package/dist/node/ui/hooks/useProjectMutations.js +1 -91
- package/dist/node/ui/index.js +5 -2077
- package/dist/node/ui/modals/CreateProjectModal.js +1 -153
- package/dist/node/ui/modals/ProjectActionsModal.js +1 -335
- package/dist/node/ui/modals/index.js +1 -487
- package/dist/node/ui/overlays/demo-overlays.js +1 -61
- package/dist/node/ui/overlays/index.js +1 -61
- package/dist/node/ui/renderers/index.js +5 -901
- package/dist/node/ui/renderers/project-list.markdown.js +5 -725
- package/dist/node/ui/renderers/project-list.renderer.js +1 -177
- package/dist/node/visualizations/catalog.js +1 -155
- package/dist/node/visualizations/index.js +1 -217
- package/dist/node/visualizations/selectors.js +1 -210
- package/dist/presentations/index.js +1 -299
- package/dist/project/index.js +1 -793
- package/dist/project/project.entity.js +1 -77
- package/dist/project/project.enum.js +1 -18
- package/dist/project/project.event.js +1 -103
- package/dist/project/project.handler.js +1 -178
- package/dist/project/project.operations.js +1 -372
- package/dist/project/project.presentation.js +1 -180
- package/dist/project/project.schema.js +1 -134
- package/dist/saas-boilerplate.feature.js +1 -304
- package/dist/seeders/index.js +2 -20
- package/dist/settings/index.js +1 -75
- package/dist/settings/settings.entity.js +1 -74
- package/dist/settings/settings.enum.js +1 -11
- package/dist/shared/mock-data.js +1 -104
- package/dist/tests/operations.test-spec.js +1 -112
- package/dist/ui/SaasDashboard.js +1 -1239
- package/dist/ui/SaasDashboard.visualizations.js +1 -249
- package/dist/ui/SaasProjectList.js +1 -162
- package/dist/ui/SaasSettingsPanel.js +1 -145
- package/dist/ui/hooks/index.js +1 -159
- package/dist/ui/hooks/useProjectList.js +1 -66
- package/dist/ui/hooks/useProjectMutations.js +1 -91
- package/dist/ui/index.js +5 -2077
- package/dist/ui/modals/CreateProjectModal.js +1 -153
- package/dist/ui/modals/ProjectActionsModal.js +1 -335
- package/dist/ui/modals/index.js +1 -487
- package/dist/ui/overlays/demo-overlays.js +1 -61
- package/dist/ui/overlays/index.js +1 -61
- package/dist/ui/renderers/index.js +5 -901
- package/dist/ui/renderers/project-list.markdown.js +5 -725
- package/dist/ui/renderers/project-list.renderer.js +1 -177
- package/dist/visualizations/catalog.js +1 -155
- package/dist/visualizations/index.js +1 -217
- package/dist/visualizations/selectors.js +1 -210
- package/package.json +12 -12
|
@@ -1,134 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defineEnum } from "@contractspec/lib.schema";
|
|
3
|
-
var ProjectStatusSchemaEnum = defineEnum("ProjectStatus", [
|
|
4
|
-
"DRAFT",
|
|
5
|
-
"ACTIVE",
|
|
6
|
-
"ARCHIVED",
|
|
7
|
-
"DELETED"
|
|
8
|
-
]);
|
|
9
|
-
var ProjectStatusFilterEnum = defineEnum("ProjectStatusFilter", [
|
|
10
|
-
"DRAFT",
|
|
11
|
-
"ACTIVE",
|
|
12
|
-
"ARCHIVED",
|
|
13
|
-
"all"
|
|
14
|
-
]);
|
|
15
|
-
|
|
16
|
-
// src/project/project.schema.ts
|
|
17
|
-
import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
18
|
-
var ProjectModel = defineSchemaModel({
|
|
19
|
-
name: "Project",
|
|
20
|
-
description: "A project within an organization",
|
|
21
|
-
fields: {
|
|
22
|
-
id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
23
|
-
name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
24
|
-
description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
25
|
-
slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
26
|
-
organizationId: {
|
|
27
|
-
type: ScalarTypeEnum.String_unsecure(),
|
|
28
|
-
isOptional: false
|
|
29
|
-
},
|
|
30
|
-
createdBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
31
|
-
status: { type: ProjectStatusSchemaEnum, isOptional: false },
|
|
32
|
-
isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: false },
|
|
33
|
-
tags: {
|
|
34
|
-
type: ScalarTypeEnum.String_unsecure(),
|
|
35
|
-
isArray: true,
|
|
36
|
-
isOptional: false
|
|
37
|
-
},
|
|
38
|
-
createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
|
|
39
|
-
updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
var CreateProjectInputModel = defineSchemaModel({
|
|
43
|
-
name: "CreateProjectInput",
|
|
44
|
-
description: "Input for creating a project",
|
|
45
|
-
fields: {
|
|
46
|
-
name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
|
|
47
|
-
description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
48
|
-
slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
49
|
-
isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: true },
|
|
50
|
-
tags: {
|
|
51
|
-
type: ScalarTypeEnum.String_unsecure(),
|
|
52
|
-
isArray: true,
|
|
53
|
-
isOptional: true
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
var UpdateProjectInputModel = defineSchemaModel({
|
|
58
|
-
name: "UpdateProjectInput",
|
|
59
|
-
description: "Input for updating a project",
|
|
60
|
-
fields: {
|
|
61
|
-
projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
62
|
-
name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
63
|
-
description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
64
|
-
slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
65
|
-
isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: true },
|
|
66
|
-
tags: {
|
|
67
|
-
type: ScalarTypeEnum.String_unsecure(),
|
|
68
|
-
isArray: true,
|
|
69
|
-
isOptional: true
|
|
70
|
-
},
|
|
71
|
-
status: { type: ProjectStatusSchemaEnum, isOptional: true }
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
var GetProjectInputModel = defineSchemaModel({
|
|
75
|
-
name: "GetProjectInput",
|
|
76
|
-
fields: {
|
|
77
|
-
projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
var DeleteProjectInputModel = defineSchemaModel({
|
|
81
|
-
name: "DeleteProjectInput",
|
|
82
|
-
fields: {
|
|
83
|
-
projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
var DeleteProjectOutputModel = defineSchemaModel({
|
|
87
|
-
name: "DeleteProjectOutput",
|
|
88
|
-
fields: {
|
|
89
|
-
success: { type: ScalarTypeEnum.Boolean(), isOptional: false }
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
var ProjectDeletedPayloadModel = defineSchemaModel({
|
|
93
|
-
name: "ProjectDeletedPayload",
|
|
94
|
-
fields: {
|
|
95
|
-
projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
var ListProjectsInputModel = defineSchemaModel({
|
|
99
|
-
name: "ListProjectsInput",
|
|
100
|
-
description: "Input for listing projects",
|
|
101
|
-
fields: {
|
|
102
|
-
status: { type: ProjectStatusFilterEnum, isOptional: true },
|
|
103
|
-
search: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
104
|
-
limit: {
|
|
105
|
-
type: ScalarTypeEnum.Int_unsecure(),
|
|
106
|
-
isOptional: true,
|
|
107
|
-
defaultValue: 20
|
|
108
|
-
},
|
|
109
|
-
offset: {
|
|
110
|
-
type: ScalarTypeEnum.Int_unsecure(),
|
|
111
|
-
isOptional: true,
|
|
112
|
-
defaultValue: 0
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
var ListProjectsOutputModel = defineSchemaModel({
|
|
117
|
-
name: "ListProjectsOutput",
|
|
118
|
-
description: "Output for listing projects",
|
|
119
|
-
fields: {
|
|
120
|
-
projects: { type: ProjectModel, isArray: true, isOptional: false },
|
|
121
|
-
total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false }
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
export {
|
|
125
|
-
UpdateProjectInputModel,
|
|
126
|
-
ProjectModel,
|
|
127
|
-
ProjectDeletedPayloadModel,
|
|
128
|
-
ListProjectsOutputModel,
|
|
129
|
-
ListProjectsInputModel,
|
|
130
|
-
GetProjectInputModel,
|
|
131
|
-
DeleteProjectOutputModel,
|
|
132
|
-
DeleteProjectInputModel,
|
|
133
|
-
CreateProjectInputModel
|
|
134
|
-
};
|
|
1
|
+
import{defineEnum as w}from"@contractspec/lib.schema";var v=w("ProjectStatus",["DRAFT","ACTIVE","ARCHIVED","DELETED"]),x=w("ProjectStatusFilter",["DRAFT","ACTIVE","ARCHIVED","all"]);import{defineSchemaModel as q,ScalarTypeEnum as k}from"@contractspec/lib.schema";var z=q({name:"Project",description:"A project within an organization",fields:{id:{type:k.String_unsecure(),isOptional:!1},name:{type:k.String_unsecure(),isOptional:!1},description:{type:k.String_unsecure(),isOptional:!0},slug:{type:k.String_unsecure(),isOptional:!0},organizationId:{type:k.String_unsecure(),isOptional:!1},createdBy:{type:k.String_unsecure(),isOptional:!1},status:{type:v,isOptional:!1},isPublic:{type:k.Boolean(),isOptional:!1},tags:{type:k.String_unsecure(),isArray:!0,isOptional:!1},createdAt:{type:k.DateTime(),isOptional:!1},updatedAt:{type:k.DateTime(),isOptional:!1}}}),G=q({name:"CreateProjectInput",description:"Input for creating a project",fields:{name:{type:k.NonEmptyString(),isOptional:!1},description:{type:k.String_unsecure(),isOptional:!0},slug:{type:k.String_unsecure(),isOptional:!0},isPublic:{type:k.Boolean(),isOptional:!0},tags:{type:k.String_unsecure(),isArray:!0,isOptional:!0}}}),H=q({name:"UpdateProjectInput",description:"Input for updating a project",fields:{projectId:{type:k.String_unsecure(),isOptional:!1},name:{type:k.String_unsecure(),isOptional:!0},description:{type:k.String_unsecure(),isOptional:!0},slug:{type:k.String_unsecure(),isOptional:!0},isPublic:{type:k.Boolean(),isOptional:!0},tags:{type:k.String_unsecure(),isArray:!0,isOptional:!0},status:{type:v,isOptional:!0}}}),I=q({name:"GetProjectInput",fields:{projectId:{type:k.String_unsecure(),isOptional:!1}}}),J=q({name:"DeleteProjectInput",fields:{projectId:{type:k.String_unsecure(),isOptional:!1}}}),K=q({name:"DeleteProjectOutput",fields:{success:{type:k.Boolean(),isOptional:!1}}}),L=q({name:"ProjectDeletedPayload",fields:{projectId:{type:k.String_unsecure(),isOptional:!1}}}),N=q({name:"ListProjectsInput",description:"Input for listing projects",fields:{status:{type:x,isOptional:!0},search:{type:k.String_unsecure(),isOptional:!0},limit:{type:k.Int_unsecure(),isOptional:!0,defaultValue:20},offset:{type:k.Int_unsecure(),isOptional:!0,defaultValue:0}}}),Q=q({name:"ListProjectsOutput",description:"Output for listing projects",fields:{projects:{type:z,isArray:!0,isOptional:!1},total:{type:k.Int_unsecure(),isOptional:!1}}});export{H as UpdateProjectInputModel,z as ProjectModel,L as ProjectDeletedPayloadModel,Q as ListProjectsOutputModel,N as ListProjectsInputModel,I as GetProjectInputModel,K as DeleteProjectOutputModel,J as DeleteProjectInputModel,G as CreateProjectInputModel};
|
|
@@ -1,304 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
defineVisualization,
|
|
4
|
-
VisualizationRegistry
|
|
5
|
-
} from "@contractspec/lib.contracts-spec/visualizations";
|
|
6
|
-
var PROJECT_LIST_REF = {
|
|
7
|
-
key: "saas.project.list",
|
|
8
|
-
version: "1.0.0"
|
|
9
|
-
};
|
|
10
|
-
var META = {
|
|
11
|
-
version: "1.0.0",
|
|
12
|
-
domain: "saas",
|
|
13
|
-
stability: "experimental",
|
|
14
|
-
owners: ["@example.saas-boilerplate"],
|
|
15
|
-
tags: ["saas", "visualization", "projects"]
|
|
16
|
-
};
|
|
17
|
-
var SaasProjectUsageVisualization = defineVisualization({
|
|
18
|
-
meta: {
|
|
19
|
-
...META,
|
|
20
|
-
key: "saas-boilerplate.visualization.project-usage",
|
|
21
|
-
title: "Project Capacity",
|
|
22
|
-
description: "Current project count against the current plan limit.",
|
|
23
|
-
goal: "Show usage against the active plan allowance.",
|
|
24
|
-
context: "SaaS account overview."
|
|
25
|
-
},
|
|
26
|
-
source: { primary: PROJECT_LIST_REF, resultPath: "data" },
|
|
27
|
-
visualization: {
|
|
28
|
-
kind: "metric",
|
|
29
|
-
measure: "totalProjects",
|
|
30
|
-
comparisonMeasure: "projectLimit",
|
|
31
|
-
measures: [
|
|
32
|
-
{
|
|
33
|
-
key: "totalProjects",
|
|
34
|
-
label: "Projects",
|
|
35
|
-
dataPath: "totalProjects",
|
|
36
|
-
format: "number"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
key: "projectLimit",
|
|
40
|
-
label: "Plan Limit",
|
|
41
|
-
dataPath: "projectLimit",
|
|
42
|
-
format: "number"
|
|
43
|
-
}
|
|
44
|
-
],
|
|
45
|
-
table: { caption: "Current project count and plan limit." }
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
var SaasProjectStatusVisualization = defineVisualization({
|
|
49
|
-
meta: {
|
|
50
|
-
...META,
|
|
51
|
-
key: "saas-boilerplate.visualization.project-status",
|
|
52
|
-
title: "Project Status",
|
|
53
|
-
description: "Distribution of project states.",
|
|
54
|
-
goal: "Show the mix of active, draft, and archived projects.",
|
|
55
|
-
context: "Project portfolio overview."
|
|
56
|
-
},
|
|
57
|
-
source: { primary: PROJECT_LIST_REF, resultPath: "data" },
|
|
58
|
-
visualization: {
|
|
59
|
-
kind: "pie",
|
|
60
|
-
nameDimension: "status",
|
|
61
|
-
valueMeasure: "projects",
|
|
62
|
-
dimensions: [
|
|
63
|
-
{ key: "status", label: "Status", dataPath: "status", type: "category" }
|
|
64
|
-
],
|
|
65
|
-
measures: [
|
|
66
|
-
{
|
|
67
|
-
key: "projects",
|
|
68
|
-
label: "Projects",
|
|
69
|
-
dataPath: "projects",
|
|
70
|
-
format: "number"
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
table: { caption: "Project counts by status." }
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
var SaasProjectTierVisualization = defineVisualization({
|
|
77
|
-
meta: {
|
|
78
|
-
...META,
|
|
79
|
-
key: "saas-boilerplate.visualization.project-tiers",
|
|
80
|
-
title: "Tier Comparison",
|
|
81
|
-
description: "Distribution of projects across tiers.",
|
|
82
|
-
goal: "Compare how the current portfolio is distributed by tier.",
|
|
83
|
-
context: "Plan and packaging overview."
|
|
84
|
-
},
|
|
85
|
-
source: { primary: PROJECT_LIST_REF, resultPath: "data" },
|
|
86
|
-
visualization: {
|
|
87
|
-
kind: "cartesian",
|
|
88
|
-
variant: "bar",
|
|
89
|
-
xDimension: "tier",
|
|
90
|
-
yMeasures: ["projects"],
|
|
91
|
-
dimensions: [
|
|
92
|
-
{ key: "tier", label: "Tier", dataPath: "tier", type: "category" }
|
|
93
|
-
],
|
|
94
|
-
measures: [
|
|
95
|
-
{
|
|
96
|
-
key: "projects",
|
|
97
|
-
label: "Projects",
|
|
98
|
-
dataPath: "projects",
|
|
99
|
-
format: "number",
|
|
100
|
-
color: "#1d4ed8"
|
|
101
|
-
}
|
|
102
|
-
],
|
|
103
|
-
table: { caption: "Project counts by tier." }
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
var SaasProjectActivityVisualization = defineVisualization({
|
|
107
|
-
meta: {
|
|
108
|
-
...META,
|
|
109
|
-
key: "saas-boilerplate.visualization.project-activity",
|
|
110
|
-
title: "Recent Project Activity",
|
|
111
|
-
description: "Daily project creation activity.",
|
|
112
|
-
goal: "Show recent project activity over time.",
|
|
113
|
-
context: "Project portfolio trend view."
|
|
114
|
-
},
|
|
115
|
-
source: { primary: PROJECT_LIST_REF, resultPath: "data" },
|
|
116
|
-
visualization: {
|
|
117
|
-
kind: "cartesian",
|
|
118
|
-
variant: "line",
|
|
119
|
-
xDimension: "day",
|
|
120
|
-
yMeasures: ["projects"],
|
|
121
|
-
dimensions: [{ key: "day", label: "Day", dataPath: "day", type: "time" }],
|
|
122
|
-
measures: [
|
|
123
|
-
{
|
|
124
|
-
key: "projects",
|
|
125
|
-
label: "Projects",
|
|
126
|
-
dataPath: "projects",
|
|
127
|
-
format: "number",
|
|
128
|
-
color: "#0f766e"
|
|
129
|
-
}
|
|
130
|
-
],
|
|
131
|
-
table: { caption: "Daily project creation counts." }
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
var SaasVisualizationSpecs = [
|
|
135
|
-
SaasProjectUsageVisualization,
|
|
136
|
-
SaasProjectStatusVisualization,
|
|
137
|
-
SaasProjectTierVisualization,
|
|
138
|
-
SaasProjectActivityVisualization
|
|
139
|
-
];
|
|
140
|
-
var SaasVisualizationRegistry = new VisualizationRegistry([
|
|
141
|
-
...SaasVisualizationSpecs
|
|
142
|
-
]);
|
|
143
|
-
var SaasVisualizationRefs = SaasVisualizationSpecs.map((spec) => ({
|
|
144
|
-
key: spec.meta.key,
|
|
145
|
-
version: spec.meta.version
|
|
146
|
-
}));
|
|
147
|
-
|
|
148
|
-
// src/visualizations/selectors.ts
|
|
149
|
-
function toDayKey(value) {
|
|
150
|
-
const date = value instanceof Date ? value : new Date(value);
|
|
151
|
-
return date.toISOString().slice(0, 10);
|
|
152
|
-
}
|
|
153
|
-
function createSaasVisualizationItems(projects, projectLimit = 10) {
|
|
154
|
-
const statusCounts = new Map;
|
|
155
|
-
const tierCounts = new Map;
|
|
156
|
-
const activityCounts = new Map;
|
|
157
|
-
for (const project of projects) {
|
|
158
|
-
statusCounts.set(project.status, (statusCounts.get(project.status) ?? 0) + 1);
|
|
159
|
-
tierCounts.set(project.tier, (tierCounts.get(project.tier) ?? 0) + 1);
|
|
160
|
-
const day = toDayKey(project.createdAt);
|
|
161
|
-
activityCounts.set(day, (activityCounts.get(day) ?? 0) + 1);
|
|
162
|
-
}
|
|
163
|
-
return [
|
|
164
|
-
{
|
|
165
|
-
key: "saas-capacity",
|
|
166
|
-
spec: SaasProjectUsageVisualization,
|
|
167
|
-
data: { data: [{ totalProjects: projects.length, projectLimit }] },
|
|
168
|
-
title: "Project Capacity",
|
|
169
|
-
description: "Current project count compared to the active limit.",
|
|
170
|
-
height: 220
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
key: "saas-status",
|
|
174
|
-
spec: SaasProjectStatusVisualization,
|
|
175
|
-
data: {
|
|
176
|
-
data: Array.from(statusCounts.entries()).map(([status, count]) => ({
|
|
177
|
-
status,
|
|
178
|
-
projects: count
|
|
179
|
-
}))
|
|
180
|
-
},
|
|
181
|
-
title: "Project Status",
|
|
182
|
-
description: "Status mix across the current project portfolio.",
|
|
183
|
-
height: 260
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
key: "saas-tier",
|
|
187
|
-
spec: SaasProjectTierVisualization,
|
|
188
|
-
data: {
|
|
189
|
-
data: Array.from(tierCounts.entries()).map(([tier, count]) => ({
|
|
190
|
-
tier,
|
|
191
|
-
projects: count
|
|
192
|
-
}))
|
|
193
|
-
},
|
|
194
|
-
title: "Tier Comparison",
|
|
195
|
-
description: "How projects are distributed across tiers."
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
key: "saas-activity",
|
|
199
|
-
spec: SaasProjectActivityVisualization,
|
|
200
|
-
data: {
|
|
201
|
-
data: Array.from(activityCounts.entries()).sort(([left], [right]) => left.localeCompare(right)).map(([day, count]) => ({ day, projects: count }))
|
|
202
|
-
},
|
|
203
|
-
title: "Recent Project Activity",
|
|
204
|
-
description: "Daily project creation activity."
|
|
205
|
-
}
|
|
206
|
-
];
|
|
207
|
-
}
|
|
208
|
-
// src/saas-boilerplate.feature.ts
|
|
209
|
-
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
210
|
-
var SaasBoilerplateFeature = defineFeature({
|
|
211
|
-
meta: {
|
|
212
|
-
key: "saas-boilerplate",
|
|
213
|
-
title: "SaaS Boilerplate",
|
|
214
|
-
description: "SaaS application foundation with projects, billing, and settings",
|
|
215
|
-
domain: "saas",
|
|
216
|
-
owners: ["@saas-team"],
|
|
217
|
-
tags: ["saas", "projects", "billing"],
|
|
218
|
-
stability: "experimental",
|
|
219
|
-
version: "1.0.0"
|
|
220
|
-
},
|
|
221
|
-
operations: [
|
|
222
|
-
{ key: "saas.project.create", version: "1.0.0" },
|
|
223
|
-
{ key: "saas.project.get", version: "1.0.0" },
|
|
224
|
-
{ key: "saas.project.update", version: "1.0.0" },
|
|
225
|
-
{ key: "saas.project.delete", version: "1.0.0" },
|
|
226
|
-
{ key: "saas.project.list", version: "1.0.0" },
|
|
227
|
-
{ key: "saas.billing.subscription.get", version: "1.0.0" },
|
|
228
|
-
{ key: "saas.billing.usage.record", version: "1.0.0" },
|
|
229
|
-
{ key: "saas.billing.usage.summary", version: "1.0.0" },
|
|
230
|
-
{ key: "saas.billing.feature.check", version: "1.0.0" }
|
|
231
|
-
],
|
|
232
|
-
events: [
|
|
233
|
-
{ key: "project.created", version: "1.0.0" },
|
|
234
|
-
{ key: "project.updated", version: "1.0.0" },
|
|
235
|
-
{ key: "project.deleted", version: "1.0.0" },
|
|
236
|
-
{ key: "project.archived", version: "1.0.0" },
|
|
237
|
-
{ key: "billing.usage.recorded", version: "1.0.0" },
|
|
238
|
-
{ key: "billing.subscription.changed", version: "1.0.0" },
|
|
239
|
-
{ key: "billing.limit.reached", version: "1.0.0" }
|
|
240
|
-
],
|
|
241
|
-
presentations: [
|
|
242
|
-
{ key: "saas.dashboard", version: "1.0.0" },
|
|
243
|
-
{ key: "saas.project.list", version: "1.0.0" },
|
|
244
|
-
{ key: "saas.project.detail", version: "1.0.0" },
|
|
245
|
-
{ key: "saas.billing.subscription", version: "1.0.0" },
|
|
246
|
-
{ key: "saas.billing.usage", version: "1.0.0" },
|
|
247
|
-
{ key: "saas.settings", version: "1.0.0" }
|
|
248
|
-
],
|
|
249
|
-
opToPresentation: [
|
|
250
|
-
{
|
|
251
|
-
op: { key: "saas.project.list", version: "1.0.0" },
|
|
252
|
-
pres: { key: "saas.project.list", version: "1.0.0" }
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
op: { key: "saas.project.get", version: "1.0.0" },
|
|
256
|
-
pres: { key: "saas.project.detail", version: "1.0.0" }
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
op: { key: "saas.billing.subscription.get", version: "1.0.0" },
|
|
260
|
-
pres: { key: "saas.billing.subscription", version: "1.0.0" }
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
op: { key: "saas.billing.usage.summary", version: "1.0.0" },
|
|
264
|
-
pres: { key: "saas.billing.usage", version: "1.0.0" }
|
|
265
|
-
}
|
|
266
|
-
],
|
|
267
|
-
presentationsTargets: [
|
|
268
|
-
{ key: "saas.dashboard", version: "1.0.0", targets: ["react", "markdown"] },
|
|
269
|
-
{
|
|
270
|
-
key: "saas.project.list",
|
|
271
|
-
version: "1.0.0",
|
|
272
|
-
targets: ["react", "markdown", "application/json"]
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
key: "saas.billing.subscription",
|
|
276
|
-
version: "1.0.0",
|
|
277
|
-
targets: ["react", "markdown"]
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
key: "saas.billing.usage",
|
|
281
|
-
version: "1.0.0",
|
|
282
|
-
targets: ["react", "markdown"]
|
|
283
|
-
}
|
|
284
|
-
],
|
|
285
|
-
visualizations: SaasVisualizationRefs,
|
|
286
|
-
capabilities: {
|
|
287
|
-
requires: [
|
|
288
|
-
{ key: "identity", version: "1.0.0" },
|
|
289
|
-
{ key: "audit-trail", version: "1.0.0" },
|
|
290
|
-
{ key: "notifications", version: "1.0.0" }
|
|
291
|
-
]
|
|
292
|
-
},
|
|
293
|
-
telemetry: [{ key: "saas-boilerplate.telemetry", version: "1.0.0" }],
|
|
294
|
-
jobs: [{ key: "saas-boilerplate.job.usage-recording", version: "1.0.0" }],
|
|
295
|
-
docs: [
|
|
296
|
-
"docs.examples.saas-boilerplate.goal",
|
|
297
|
-
"docs.examples.saas-boilerplate.usage",
|
|
298
|
-
"docs.examples.saas-boilerplate.reference",
|
|
299
|
-
"docs.examples.saas-boilerplate.constraints"
|
|
300
|
-
]
|
|
301
|
-
});
|
|
302
|
-
export {
|
|
303
|
-
SaasBoilerplateFeature
|
|
304
|
-
};
|
|
1
|
+
import{defineVisualization as q,VisualizationRegistry as D}from"@contractspec/lib.contracts-spec/visualizations";var w={key:"saas.project.list",version:"1.0.0"},B={version:"1.0.0",domain:"saas",stability:"experimental",owners:["@example.saas-boilerplate"],tags:["saas","visualization","projects"]},Q=q({meta:{...B,key:"saas-boilerplate.visualization.project-usage",title:"Project Capacity",description:"Current project count against the current plan limit.",goal:"Show usage against the active plan allowance.",context:"SaaS account overview."},source:{primary:w,resultPath:"data"},visualization:{kind:"metric",measure:"totalProjects",comparisonMeasure:"projectLimit",measures:[{key:"totalProjects",label:"Projects",dataPath:"totalProjects",format:"number"},{key:"projectLimit",label:"Plan Limit",dataPath:"projectLimit",format:"number"}],table:{caption:"Current project count and plan limit."}}}),W=q({meta:{...B,key:"saas-boilerplate.visualization.project-status",title:"Project Status",description:"Distribution of project states.",goal:"Show the mix of active, draft, and archived projects.",context:"Project portfolio overview."},source:{primary:w,resultPath:"data"},visualization:{kind:"pie",nameDimension:"status",valueMeasure:"projects",dimensions:[{key:"status",label:"Status",dataPath:"status",type:"category"}],measures:[{key:"projects",label:"Projects",dataPath:"projects",format:"number"}],table:{caption:"Project counts by status."}}}),X=q({meta:{...B,key:"saas-boilerplate.visualization.project-tiers",title:"Tier Comparison",description:"Distribution of projects across tiers.",goal:"Compare how the current portfolio is distributed by tier.",context:"Plan and packaging overview."},source:{primary:w,resultPath:"data"},visualization:{kind:"cartesian",variant:"bar",xDimension:"tier",yMeasures:["projects"],dimensions:[{key:"tier",label:"Tier",dataPath:"tier",type:"category"}],measures:[{key:"projects",label:"Projects",dataPath:"projects",format:"number",color:"#1d4ed8"}],table:{caption:"Project counts by tier."}}}),Y=q({meta:{...B,key:"saas-boilerplate.visualization.project-activity",title:"Recent Project Activity",description:"Daily project creation activity.",goal:"Show recent project activity over time.",context:"Project portfolio trend view."},source:{primary:w,resultPath:"data"},visualization:{kind:"cartesian",variant:"line",xDimension:"day",yMeasures:["projects"],dimensions:[{key:"day",label:"Day",dataPath:"day",type:"time"}],measures:[{key:"projects",label:"Projects",dataPath:"projects",format:"number",color:"#0f766e"}],table:{caption:"Daily project creation counts."}}}),$=[Q,W,X,Y],I=new D([...$]),b=$.map((m)=>({key:m.meta.key,version:m.meta.version}));function K(m){return(m instanceof Date?m:new Date(m)).toISOString().slice(0,10)}function O(m,Z=10){let G=new Map,H=new Map,N=new Map;for(let x of m){G.set(x.status,(G.get(x.status)??0)+1),H.set(x.tier,(H.get(x.tier)??0)+1);let k=K(x.createdAt);N.set(k,(N.get(k)??0)+1)}return[{key:"saas-capacity",spec:Q,data:{data:[{totalProjects:m.length,projectLimit:Z}]},title:"Project Capacity",description:"Current project count compared to the active limit.",height:220},{key:"saas-status",spec:W,data:{data:Array.from(G.entries()).map(([x,k])=>({status:x,projects:k}))},title:"Project Status",description:"Status mix across the current project portfolio.",height:260},{key:"saas-tier",spec:X,data:{data:Array.from(H.entries()).map(([x,k])=>({tier:x,projects:k}))},title:"Tier Comparison",description:"How projects are distributed across tiers."},{key:"saas-activity",spec:Y,data:{data:Array.from(N.entries()).sort(([x],[k])=>x.localeCompare(k)).map(([x,k])=>({day:x,projects:k}))},title:"Recent Project Activity",description:"Daily project creation activity."}]}import{defineFeature as h}from"@contractspec/lib.contracts-spec";var d=h({meta:{key:"saas-boilerplate",title:"SaaS Boilerplate",description:"SaaS application foundation with projects, billing, and settings",domain:"saas",owners:["@saas-team"],tags:["saas","projects","billing"],stability:"experimental",version:"1.0.0"},operations:[{key:"saas.project.create",version:"1.0.0"},{key:"saas.project.get",version:"1.0.0"},{key:"saas.project.update",version:"1.0.0"},{key:"saas.project.delete",version:"1.0.0"},{key:"saas.project.list",version:"1.0.0"},{key:"saas.billing.subscription.get",version:"1.0.0"},{key:"saas.billing.usage.record",version:"1.0.0"},{key:"saas.billing.usage.summary",version:"1.0.0"},{key:"saas.billing.feature.check",version:"1.0.0"}],events:[{key:"project.created",version:"1.0.0"},{key:"project.updated",version:"1.0.0"},{key:"project.deleted",version:"1.0.0"},{key:"project.archived",version:"1.0.0"},{key:"billing.usage.recorded",version:"1.0.0"},{key:"billing.subscription.changed",version:"1.0.0"},{key:"billing.limit.reached",version:"1.0.0"}],presentations:[{key:"saas.dashboard",version:"1.0.0"},{key:"saas.project.list",version:"1.0.0"},{key:"saas.project.detail",version:"1.0.0"},{key:"saas.billing.subscription",version:"1.0.0"},{key:"saas.billing.usage",version:"1.0.0"},{key:"saas.settings",version:"1.0.0"}],opToPresentation:[{op:{key:"saas.project.list",version:"1.0.0"},pres:{key:"saas.project.list",version:"1.0.0"}},{op:{key:"saas.project.get",version:"1.0.0"},pres:{key:"saas.project.detail",version:"1.0.0"}},{op:{key:"saas.billing.subscription.get",version:"1.0.0"},pres:{key:"saas.billing.subscription",version:"1.0.0"}},{op:{key:"saas.billing.usage.summary",version:"1.0.0"},pres:{key:"saas.billing.usage",version:"1.0.0"}}],presentationsTargets:[{key:"saas.dashboard",version:"1.0.0",targets:["react","markdown"]},{key:"saas.project.list",version:"1.0.0",targets:["react","markdown","application/json"]},{key:"saas.billing.subscription",version:"1.0.0",targets:["react","markdown"]},{key:"saas.billing.usage",version:"1.0.0",targets:["react","markdown"]}],visualizations:b,capabilities:{requires:[{key:"identity",version:"1.0.0"},{key:"audit-trail",version:"1.0.0"},{key:"notifications",version:"1.0.0"}]},telemetry:[{key:"saas-boilerplate.telemetry",version:"1.0.0"}],jobs:[{key:"saas-boilerplate.job.usage-recording",version:"1.0.0"}],docs:["docs.examples.saas-boilerplate.goal","docs.examples.saas-boilerplate.usage","docs.examples.saas-boilerplate.reference","docs.examples.saas-boilerplate.constraints"]});export{d as SaasBoilerplateFeature};
|
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { projectId, db } = params;
|
|
4
|
-
const existing = await db.query(`SELECT COUNT(*) as count FROM saas_project WHERE "projectId" = $1`, [projectId]);
|
|
5
|
-
if (existing.rows[0]?.count > 0)
|
|
6
|
-
return;
|
|
7
|
-
await db.execute(`INSERT INTO saas_project (id, "projectId", "organizationId", name, description, status, tier)
|
|
8
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7)`, [
|
|
9
|
-
"saas_proj_1",
|
|
10
|
-
projectId,
|
|
11
|
-
"org_demo",
|
|
12
|
-
"Demo Project",
|
|
13
|
-
"A demo SaaS project",
|
|
14
|
-
"ACTIVE",
|
|
15
|
-
"PRO"
|
|
16
|
-
]);
|
|
17
|
-
}
|
|
18
|
-
export {
|
|
19
|
-
seedSaasBoilerplate
|
|
20
|
-
};
|
|
1
|
+
async function r(a){let{projectId:t,db:e}=a;if((await e.query('SELECT COUNT(*) as count FROM saas_project WHERE "projectId" = $1',[t])).rows[0]?.count>0)return;await e.execute(`INSERT INTO saas_project (id, "projectId", "organizationId", name, description, status, tier)
|
|
2
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)`,["saas_proj_1",t,"org_demo","Demo Project","A demo SaaS project","ACTIVE","PRO"])}export{r as seedSaasBoilerplate};
|
|
@@ -1,75 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defineEntityEnum } from "@contractspec/lib.schema";
|
|
3
|
-
var SettingsScopeEnum = defineEntityEnum({
|
|
4
|
-
name: "SettingsScope",
|
|
5
|
-
values: ["APP", "ORG", "USER", "PROJECT"],
|
|
6
|
-
schema: "saas_app",
|
|
7
|
-
description: "Scope of a setting."
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
// src/settings/settings.entity.ts
|
|
11
|
-
import { defineEntity, field, index } from "@contractspec/lib.schema";
|
|
12
|
-
var SettingsEntity = defineEntity({
|
|
13
|
-
name: "Settings",
|
|
14
|
-
description: "Application, organization, or user settings.",
|
|
15
|
-
schema: "saas_app",
|
|
16
|
-
map: "settings",
|
|
17
|
-
fields: {
|
|
18
|
-
id: field.id(),
|
|
19
|
-
key: field.string({
|
|
20
|
-
description: 'Setting key (e.g., "theme", "notifications.email")'
|
|
21
|
-
}),
|
|
22
|
-
scope: field.enum("SettingsScope"),
|
|
23
|
-
scopeId: field.string({
|
|
24
|
-
isOptional: true,
|
|
25
|
-
description: "ID of scoped entity (org, user, project)"
|
|
26
|
-
}),
|
|
27
|
-
value: field.json({ description: "Setting value" }),
|
|
28
|
-
valueType: field.string({
|
|
29
|
-
default: '"string"',
|
|
30
|
-
description: "Type hint for value"
|
|
31
|
-
}),
|
|
32
|
-
schema: field.json({
|
|
33
|
-
isOptional: true,
|
|
34
|
-
description: "JSON schema for validation"
|
|
35
|
-
}),
|
|
36
|
-
description: field.string({ isOptional: true }),
|
|
37
|
-
isSecret: field.boolean({
|
|
38
|
-
default: false,
|
|
39
|
-
description: "Whether value should be encrypted"
|
|
40
|
-
}),
|
|
41
|
-
createdAt: field.createdAt(),
|
|
42
|
-
updatedAt: field.updatedAt()
|
|
43
|
-
},
|
|
44
|
-
indexes: [
|
|
45
|
-
index.unique(["scope", "scopeId", "key"]),
|
|
46
|
-
index.on(["scope", "key"])
|
|
47
|
-
],
|
|
48
|
-
enums: [SettingsScopeEnum]
|
|
49
|
-
});
|
|
50
|
-
var FeatureFlagEntity = defineEntity({
|
|
51
|
-
name: "FeatureFlag",
|
|
52
|
-
description: "Feature flags for progressive rollout.",
|
|
53
|
-
schema: "saas_app",
|
|
54
|
-
map: "feature_flag",
|
|
55
|
-
fields: {
|
|
56
|
-
id: field.id(),
|
|
57
|
-
key: field.string({ isUnique: true, description: "Feature flag key" }),
|
|
58
|
-
name: field.string({ description: "Human-readable name" }),
|
|
59
|
-
description: field.string({ isOptional: true }),
|
|
60
|
-
enabled: field.boolean({ default: false }),
|
|
61
|
-
defaultValue: field.boolean({ default: false }),
|
|
62
|
-
rules: field.json({ isOptional: true, description: "Targeting rules" }),
|
|
63
|
-
rolloutPercentage: field.int({
|
|
64
|
-
default: 0,
|
|
65
|
-
description: "Percentage rollout (0-100)"
|
|
66
|
-
}),
|
|
67
|
-
createdAt: field.createdAt(),
|
|
68
|
-
updatedAt: field.updatedAt()
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
export {
|
|
72
|
-
SettingsScopeEnum,
|
|
73
|
-
SettingsEntity,
|
|
74
|
-
FeatureFlagEntity
|
|
75
|
-
};
|
|
1
|
+
import{defineEntityEnum as s}from"@contractspec/lib.schema";var t=s({name:"SettingsScope",values:["APP","ORG","USER","PROJECT"],schema:"saas_app",description:"Scope of a setting."});import{defineEntity as p,field as o,index as n}from"@contractspec/lib.schema";var a=p({name:"Settings",description:"Application, organization, or user settings.",schema:"saas_app",map:"settings",fields:{id:o.id(),key:o.string({description:'Setting key (e.g., "theme", "notifications.email")'}),scope:o.enum("SettingsScope"),scopeId:o.string({isOptional:!0,description:"ID of scoped entity (org, user, project)"}),value:o.json({description:"Setting value"}),valueType:o.string({default:'"string"',description:"Type hint for value"}),schema:o.json({isOptional:!0,description:"JSON schema for validation"}),description:o.string({isOptional:!0}),isSecret:o.boolean({default:!1,description:"Whether value should be encrypted"}),createdAt:o.createdAt(),updatedAt:o.updatedAt()},indexes:[n.unique(["scope","scopeId","key"]),n.on(["scope","key"])],enums:[t]}),r=p({name:"FeatureFlag",description:"Feature flags for progressive rollout.",schema:"saas_app",map:"feature_flag",fields:{id:o.id(),key:o.string({isUnique:!0,description:"Feature flag key"}),name:o.string({description:"Human-readable name"}),description:o.string({isOptional:!0}),enabled:o.boolean({default:!1}),defaultValue:o.boolean({default:!1}),rules:o.json({isOptional:!0,description:"Targeting rules"}),rolloutPercentage:o.int({default:0,description:"Percentage rollout (0-100)"}),createdAt:o.createdAt(),updatedAt:o.updatedAt()}});export{t as SettingsScopeEnum,a as SettingsEntity,r as FeatureFlagEntity};
|
|
@@ -1,74 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defineEntityEnum } from "@contractspec/lib.schema";
|
|
3
|
-
var SettingsScopeEnum = defineEntityEnum({
|
|
4
|
-
name: "SettingsScope",
|
|
5
|
-
values: ["APP", "ORG", "USER", "PROJECT"],
|
|
6
|
-
schema: "saas_app",
|
|
7
|
-
description: "Scope of a setting."
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
// src/settings/settings.entity.ts
|
|
11
|
-
import { defineEntity, field, index } from "@contractspec/lib.schema";
|
|
12
|
-
var SettingsEntity = defineEntity({
|
|
13
|
-
name: "Settings",
|
|
14
|
-
description: "Application, organization, or user settings.",
|
|
15
|
-
schema: "saas_app",
|
|
16
|
-
map: "settings",
|
|
17
|
-
fields: {
|
|
18
|
-
id: field.id(),
|
|
19
|
-
key: field.string({
|
|
20
|
-
description: 'Setting key (e.g., "theme", "notifications.email")'
|
|
21
|
-
}),
|
|
22
|
-
scope: field.enum("SettingsScope"),
|
|
23
|
-
scopeId: field.string({
|
|
24
|
-
isOptional: true,
|
|
25
|
-
description: "ID of scoped entity (org, user, project)"
|
|
26
|
-
}),
|
|
27
|
-
value: field.json({ description: "Setting value" }),
|
|
28
|
-
valueType: field.string({
|
|
29
|
-
default: '"string"',
|
|
30
|
-
description: "Type hint for value"
|
|
31
|
-
}),
|
|
32
|
-
schema: field.json({
|
|
33
|
-
isOptional: true,
|
|
34
|
-
description: "JSON schema for validation"
|
|
35
|
-
}),
|
|
36
|
-
description: field.string({ isOptional: true }),
|
|
37
|
-
isSecret: field.boolean({
|
|
38
|
-
default: false,
|
|
39
|
-
description: "Whether value should be encrypted"
|
|
40
|
-
}),
|
|
41
|
-
createdAt: field.createdAt(),
|
|
42
|
-
updatedAt: field.updatedAt()
|
|
43
|
-
},
|
|
44
|
-
indexes: [
|
|
45
|
-
index.unique(["scope", "scopeId", "key"]),
|
|
46
|
-
index.on(["scope", "key"])
|
|
47
|
-
],
|
|
48
|
-
enums: [SettingsScopeEnum]
|
|
49
|
-
});
|
|
50
|
-
var FeatureFlagEntity = defineEntity({
|
|
51
|
-
name: "FeatureFlag",
|
|
52
|
-
description: "Feature flags for progressive rollout.",
|
|
53
|
-
schema: "saas_app",
|
|
54
|
-
map: "feature_flag",
|
|
55
|
-
fields: {
|
|
56
|
-
id: field.id(),
|
|
57
|
-
key: field.string({ isUnique: true, description: "Feature flag key" }),
|
|
58
|
-
name: field.string({ description: "Human-readable name" }),
|
|
59
|
-
description: field.string({ isOptional: true }),
|
|
60
|
-
enabled: field.boolean({ default: false }),
|
|
61
|
-
defaultValue: field.boolean({ default: false }),
|
|
62
|
-
rules: field.json({ isOptional: true, description: "Targeting rules" }),
|
|
63
|
-
rolloutPercentage: field.int({
|
|
64
|
-
default: 0,
|
|
65
|
-
description: "Percentage rollout (0-100)"
|
|
66
|
-
}),
|
|
67
|
-
createdAt: field.createdAt(),
|
|
68
|
-
updatedAt: field.updatedAt()
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
export {
|
|
72
|
-
SettingsEntity,
|
|
73
|
-
FeatureFlagEntity
|
|
74
|
-
};
|
|
1
|
+
import{defineEntityEnum as c}from"@contractspec/lib.schema";var p=c({name:"SettingsScope",values:["APP","ORG","USER","PROJECT"],schema:"saas_app",description:"Scope of a setting."});import{defineEntity as S,field as o,index as P}from"@contractspec/lib.schema";var m=S({name:"Settings",description:"Application, organization, or user settings.",schema:"saas_app",map:"settings",fields:{id:o.id(),key:o.string({description:'Setting key (e.g., "theme", "notifications.email")'}),scope:o.enum("SettingsScope"),scopeId:o.string({isOptional:!0,description:"ID of scoped entity (org, user, project)"}),value:o.json({description:"Setting value"}),valueType:o.string({default:'"string"',description:"Type hint for value"}),schema:o.json({isOptional:!0,description:"JSON schema for validation"}),description:o.string({isOptional:!0}),isSecret:o.boolean({default:!1,description:"Whether value should be encrypted"}),createdAt:o.createdAt(),updatedAt:o.updatedAt()},indexes:[P.unique(["scope","scopeId","key"]),P.on(["scope","key"])],enums:[p]}),v=S({name:"FeatureFlag",description:"Feature flags for progressive rollout.",schema:"saas_app",map:"feature_flag",fields:{id:o.id(),key:o.string({isUnique:!0,description:"Feature flag key"}),name:o.string({description:"Human-readable name"}),description:o.string({isOptional:!0}),enabled:o.boolean({default:!1}),defaultValue:o.boolean({default:!1}),rules:o.json({isOptional:!0,description:"Targeting rules"}),rolloutPercentage:o.int({default:0,description:"Percentage rollout (0-100)"}),createdAt:o.createdAt(),updatedAt:o.updatedAt()}});export{m as SettingsEntity,v as FeatureFlagEntity};
|
|
@@ -1,11 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { defineEntityEnum } from "@contractspec/lib.schema";
|
|
3
|
-
var SettingsScopeEnum = defineEntityEnum({
|
|
4
|
-
name: "SettingsScope",
|
|
5
|
-
values: ["APP", "ORG", "USER", "PROJECT"],
|
|
6
|
-
schema: "saas_app",
|
|
7
|
-
description: "Scope of a setting."
|
|
8
|
-
});
|
|
9
|
-
export {
|
|
10
|
-
SettingsScopeEnum
|
|
11
|
-
};
|
|
1
|
+
import{defineEntityEnum as e}from"@contractspec/lib.schema";var n=e({name:"SettingsScope",values:["APP","ORG","USER","PROJECT"],schema:"saas_app",description:"Scope of a setting."});export{n as SettingsScopeEnum};
|