@contractspec/example.saas-boilerplate 1.44.0 → 1.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +22 -22
  2. package/.turbo/turbo-build.log +28 -28
  3. package/CHANGELOG.md +45 -0
  4. package/dist/billing/billing.event.d.ts +21 -21
  5. package/dist/billing/billing.event.js +3 -3
  6. package/dist/billing/billing.event.js.map +1 -1
  7. package/dist/billing/billing.operations.d.ts +43 -43
  8. package/dist/billing/billing.operations.js +5 -5
  9. package/dist/billing/billing.operations.js.map +1 -1
  10. package/dist/billing/billing.presentation.js +2 -2
  11. package/dist/billing/billing.presentation.js.map +1 -1
  12. package/dist/dashboard/dashboard.presentation.js +2 -2
  13. package/dist/dashboard/dashboard.presentation.js.map +1 -1
  14. package/dist/example.d.ts +3 -33
  15. package/dist/example.d.ts.map +1 -1
  16. package/dist/example.js +16 -11
  17. package/dist/example.js.map +1 -1
  18. package/dist/project/project.event.js +4 -4
  19. package/dist/project/project.event.js.map +1 -1
  20. package/dist/project/project.operations.d.ts +3 -3
  21. package/dist/project/project.operations.js +8 -8
  22. package/dist/project/project.operations.js.map +1 -1
  23. package/dist/project/project.presentation.js +2 -2
  24. package/dist/project/project.presentation.js.map +1 -1
  25. package/dist/saas-boilerplate.feature.js +38 -38
  26. package/dist/saas-boilerplate.feature.js.map +1 -1
  27. package/package.json +10 -10
  28. package/src/billing/billing.event.ts +3 -3
  29. package/src/billing/billing.operations.ts +5 -5
  30. package/src/billing/billing.presentation.ts +2 -2
  31. package/src/dashboard/dashboard.presentation.ts +2 -2
  32. package/src/example.ts +16 -9
  33. package/src/project/project.event.ts +4 -4
  34. package/src/project/project.operations.ts +8 -8
  35. package/src/project/project.presentation.ts +2 -2
  36. package/src/saas-boilerplate.feature.ts +42 -38
  37. package/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"project.operations.js","names":[],"sources":["../../src/project/project.operations.ts"],"sourcesContent":["import {\n defineCommand,\n defineQuery,\n} from '@contractspec/lib.contracts/operations';\nimport {\n CreateProjectInputModel,\n DeleteProjectInputModel,\n DeleteProjectOutputModel,\n GetProjectInputModel,\n ListProjectsInputModel,\n ListProjectsOutputModel,\n ProjectDeletedPayloadModel,\n ProjectModel,\n UpdateProjectInputModel,\n} from './project.schema';\n\nconst OWNERS = ['example.saas-boilerplate'] as const;\n\n/**\n * Create a new project.\n */\nexport const CreateProjectContract = defineCommand({\n meta: {\n key: 'saas.project.create',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'create'],\n description: 'Create a new project in the organization.',\n goal: 'Allow users to create projects for organizing work.',\n context: 'Called from project creation UI or API.',\n },\n io: {\n input: CreateProjectInputModel,\n output: ProjectModel,\n errors: {\n SLUG_EXISTS: {\n description: 'A project with this slug already exists',\n http: 409,\n gqlCode: 'SLUG_EXISTS',\n when: 'Slug is already taken in the organization',\n },\n LIMIT_REACHED: {\n description: 'Project limit reached for this plan',\n http: 403,\n gqlCode: 'LIMIT_REACHED',\n when: 'Organization has reached project limit',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'project.created',\n version: 1,\n when: 'Project is created',\n payload: ProjectModel,\n },\n ],\n audit: ['project.created'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'create-project-happy-path',\n given: ['User is authenticated'],\n when: ['User creates project'],\n then: ['Project is created', 'ProjectCreated event is emitted'],\n },\n ],\n examples: [\n {\n key: 'create-basic',\n input: { name: 'Website Redesign', slug: 'website-redesign' },\n output: { id: 'proj-123', name: 'Website Redesign', isArchived: false },\n },\n ],\n },\n});\n\n/**\n * Get project by ID.\n */\nexport const GetProjectContract = defineQuery({\n meta: {\n key: 'saas.project.get',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'get'],\n description: 'Get a project by ID.',\n goal: 'Retrieve project details.',\n context: 'Project detail page, API calls.',\n },\n io: {\n input: GetProjectInputModel,\n output: ProjectModel,\n errors: {\n NOT_FOUND: {\n description: 'Project not found',\n http: 404,\n gqlCode: 'NOT_FOUND',\n when: 'Project ID is invalid or user lacks access',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n acceptance: {\n scenarios: [\n {\n key: 'get-project-happy-path',\n given: ['Project exists'],\n when: ['User requests project'],\n then: ['Project details are returned'],\n },\n ],\n examples: [\n {\n key: 'get-existing',\n input: { projectId: 'proj-123' },\n output: { id: 'proj-123', name: 'Website Redesign' },\n },\n ],\n },\n});\n\n/**\n * Update a project.\n */\nexport const UpdateProjectContract = defineCommand({\n meta: {\n key: 'saas.project.update',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'update'],\n description: 'Update project details.',\n goal: 'Allow project owners/editors to modify project.',\n context: 'Project settings page.',\n },\n io: {\n input: UpdateProjectInputModel,\n output: ProjectModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'project.updated',\n version: 1,\n when: 'Project is updated',\n payload: ProjectModel,\n },\n ],\n audit: ['project.updated'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'update-project-happy-path',\n given: ['Project exists'],\n when: ['User updates description'],\n then: ['Project is updated', 'ProjectUpdated event is emitted'],\n },\n ],\n examples: [\n {\n key: 'update-desc',\n input: { projectId: 'proj-123', description: 'New description' },\n output: { id: 'proj-123', description: 'New description' },\n },\n ],\n },\n});\n\n/**\n * Delete a project.\n */\nexport const DeleteProjectContract = defineCommand({\n meta: {\n key: 'saas.project.delete',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'delete'],\n description: 'Delete a project (soft delete).',\n goal: 'Allow project owners to remove projects.',\n context: 'Project settings page.',\n },\n io: {\n input: DeleteProjectInputModel,\n output: DeleteProjectOutputModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'project.deleted',\n version: 1,\n when: 'Project is deleted',\n payload: ProjectDeletedPayloadModel,\n },\n ],\n audit: ['project.deleted'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'delete-project-happy-path',\n given: ['Project exists'],\n when: ['User deletes project'],\n then: ['Project is deleted', 'ProjectDeleted event is emitted'],\n },\n ],\n examples: [\n {\n key: 'delete-existing',\n input: { projectId: 'proj-123' },\n output: { success: true },\n },\n ],\n },\n});\n\n/**\n * List organization projects.\n */\nexport const ListProjectsContract = defineQuery({\n meta: {\n key: 'saas.project.list',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'list'],\n description: 'List projects in the organization.',\n goal: 'Show all projects user has access to.',\n context: 'Project list page, dashboard.',\n },\n io: {\n input: ListProjectsInputModel,\n output: ListProjectsOutputModel,\n },\n policy: {\n auth: 'user',\n },\n acceptance: {\n scenarios: [\n {\n key: 'list-projects-happy-path',\n given: ['Projects exist'],\n when: ['User lists projects'],\n then: ['List of projects is returned'],\n },\n ],\n examples: [\n {\n key: 'list-all',\n input: { limit: 10 },\n output: { items: [], total: 5 },\n },\n ],\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"project.operations.js","names":[],"sources":["../../src/project/project.operations.ts"],"sourcesContent":["import {\n defineCommand,\n defineQuery,\n} from '@contractspec/lib.contracts/operations';\nimport {\n CreateProjectInputModel,\n DeleteProjectInputModel,\n DeleteProjectOutputModel,\n GetProjectInputModel,\n ListProjectsInputModel,\n ListProjectsOutputModel,\n ProjectDeletedPayloadModel,\n ProjectModel,\n UpdateProjectInputModel,\n} from './project.schema';\n\nconst OWNERS = ['example.saas-boilerplate'] as const;\n\n/**\n * Create a new project.\n */\nexport const CreateProjectContract = defineCommand({\n meta: {\n key: 'saas.project.create',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'create'],\n description: 'Create a new project in the organization.',\n goal: 'Allow users to create projects for organizing work.',\n context: 'Called from project creation UI or API.',\n },\n io: {\n input: CreateProjectInputModel,\n output: ProjectModel,\n errors: {\n SLUG_EXISTS: {\n description: 'A project with this slug already exists',\n http: 409,\n gqlCode: 'SLUG_EXISTS',\n when: 'Slug is already taken in the organization',\n },\n LIMIT_REACHED: {\n description: 'Project limit reached for this plan',\n http: 403,\n gqlCode: 'LIMIT_REACHED',\n when: 'Organization has reached project limit',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'project.created',\n version: '1.0.0',\n when: 'Project is created',\n payload: ProjectModel,\n },\n ],\n audit: ['project.created'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'create-project-happy-path',\n given: ['User is authenticated'],\n when: ['User creates project'],\n then: ['Project is created', 'ProjectCreated event is emitted'],\n },\n ],\n examples: [\n {\n key: 'create-basic',\n input: { name: 'Website Redesign', slug: 'website-redesign' },\n output: { id: 'proj-123', name: 'Website Redesign', isArchived: false },\n },\n ],\n },\n});\n\n/**\n * Get project by ID.\n */\nexport const GetProjectContract = defineQuery({\n meta: {\n key: 'saas.project.get',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'get'],\n description: 'Get a project by ID.',\n goal: 'Retrieve project details.',\n context: 'Project detail page, API calls.',\n },\n io: {\n input: GetProjectInputModel,\n output: ProjectModel,\n errors: {\n NOT_FOUND: {\n description: 'Project not found',\n http: 404,\n gqlCode: 'NOT_FOUND',\n when: 'Project ID is invalid or user lacks access',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n acceptance: {\n scenarios: [\n {\n key: 'get-project-happy-path',\n given: ['Project exists'],\n when: ['User requests project'],\n then: ['Project details are returned'],\n },\n ],\n examples: [\n {\n key: 'get-existing',\n input: { projectId: 'proj-123' },\n output: { id: 'proj-123', name: 'Website Redesign' },\n },\n ],\n },\n});\n\n/**\n * Update a project.\n */\nexport const UpdateProjectContract = defineCommand({\n meta: {\n key: 'saas.project.update',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'update'],\n description: 'Update project details.',\n goal: 'Allow project owners/editors to modify project.',\n context: 'Project settings page.',\n },\n io: {\n input: UpdateProjectInputModel,\n output: ProjectModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'project.updated',\n version: '1.0.0',\n when: 'Project is updated',\n payload: ProjectModel,\n },\n ],\n audit: ['project.updated'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'update-project-happy-path',\n given: ['Project exists'],\n when: ['User updates description'],\n then: ['Project is updated', 'ProjectUpdated event is emitted'],\n },\n ],\n examples: [\n {\n key: 'update-desc',\n input: { projectId: 'proj-123', description: 'New description' },\n output: { id: 'proj-123', description: 'New description' },\n },\n ],\n },\n});\n\n/**\n * Delete a project.\n */\nexport const DeleteProjectContract = defineCommand({\n meta: {\n key: 'saas.project.delete',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'delete'],\n description: 'Delete a project (soft delete).',\n goal: 'Allow project owners to remove projects.',\n context: 'Project settings page.',\n },\n io: {\n input: DeleteProjectInputModel,\n output: DeleteProjectOutputModel,\n },\n policy: {\n auth: 'user',\n },\n sideEffects: {\n emits: [\n {\n key: 'project.deleted',\n version: '1.0.0',\n when: 'Project is deleted',\n payload: ProjectDeletedPayloadModel,\n },\n ],\n audit: ['project.deleted'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'delete-project-happy-path',\n given: ['Project exists'],\n when: ['User deletes project'],\n then: ['Project is deleted', 'ProjectDeleted event is emitted'],\n },\n ],\n examples: [\n {\n key: 'delete-existing',\n input: { projectId: 'proj-123' },\n output: { success: true },\n },\n ],\n },\n});\n\n/**\n * List organization projects.\n */\nexport const ListProjectsContract = defineQuery({\n meta: {\n key: 'saas.project.list',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['saas', 'project', 'list'],\n description: 'List projects in the organization.',\n goal: 'Show all projects user has access to.',\n context: 'Project list page, dashboard.',\n },\n io: {\n input: ListProjectsInputModel,\n output: ListProjectsOutputModel,\n },\n policy: {\n auth: 'user',\n },\n acceptance: {\n scenarios: [\n {\n key: 'list-projects-happy-path',\n given: ['Projects exist'],\n when: ['User lists projects'],\n then: ['List of projects is returned'],\n },\n ],\n examples: [\n {\n key: 'list-all',\n input: { limit: 10 },\n output: { items: [], total: 5 },\n },\n ],\n },\n});\n"],"mappings":";;;;AAgBA,MAAM,SAAS,CAAC,2BAA2B;;;;AAK3C,MAAa,wBAAwB,cAAc;CACjD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAQ;GAAW;GAAS;EACnC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ;GACN,aAAa;IACX,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACD,eAAe;IACb,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACD,aAAa;EACX,OAAO,CACL;GACE,KAAK;GACL,SAAS;GACT,MAAM;GACN,SAAS;GACV,CACF;EACD,OAAO,CAAC,kBAAkB;EAC3B;CACD,YAAY;EACV,WAAW,CACT;GACE,KAAK;GACL,OAAO,CAAC,wBAAwB;GAChC,MAAM,CAAC,uBAAuB;GAC9B,MAAM,CAAC,sBAAsB,kCAAkC;GAChE,CACF;EACD,UAAU,CACR;GACE,KAAK;GACL,OAAO;IAAE,MAAM;IAAoB,MAAM;IAAoB;GAC7D,QAAQ;IAAE,IAAI;IAAY,MAAM;IAAoB,YAAY;IAAO;GACxE,CACF;EACF;CACF,CAAC;;;;AAKF,MAAa,qBAAqB,YAAY;CAC5C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAQ;GAAW;GAAM;EAChC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,WAAW;GACT,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACD,YAAY;EACV,WAAW,CACT;GACE,KAAK;GACL,OAAO,CAAC,iBAAiB;GACzB,MAAM,CAAC,wBAAwB;GAC/B,MAAM,CAAC,+BAA+B;GACvC,CACF;EACD,UAAU,CACR;GACE,KAAK;GACL,OAAO,EAAE,WAAW,YAAY;GAChC,QAAQ;IAAE,IAAI;IAAY,MAAM;IAAoB;GACrD,CACF;EACF;CACF,CAAC;;;;AAKF,MAAa,wBAAwB,cAAc;CACjD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAQ;GAAW;GAAS;EACnC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACT;CACD,QAAQ,EACN,MAAM,QACP;CACD,aAAa;EACX,OAAO,CACL;GACE,KAAK;GACL,SAAS;GACT,MAAM;GACN,SAAS;GACV,CACF;EACD,OAAO,CAAC,kBAAkB;EAC3B;CACD,YAAY;EACV,WAAW,CACT;GACE,KAAK;GACL,OAAO,CAAC,iBAAiB;GACzB,MAAM,CAAC,2BAA2B;GAClC,MAAM,CAAC,sBAAsB,kCAAkC;GAChE,CACF;EACD,UAAU,CACR;GACE,KAAK;GACL,OAAO;IAAE,WAAW;IAAY,aAAa;IAAmB;GAChE,QAAQ;IAAE,IAAI;IAAY,aAAa;IAAmB;GAC3D,CACF;EACF;CACF,CAAC;;;;AAKF,MAAa,wBAAwB,cAAc;CACjD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAQ;GAAW;GAAS;EACnC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACT;CACD,QAAQ,EACN,MAAM,QACP;CACD,aAAa;EACX,OAAO,CACL;GACE,KAAK;GACL,SAAS;GACT,MAAM;GACN,SAAS;GACV,CACF;EACD,OAAO,CAAC,kBAAkB;EAC3B;CACD,YAAY;EACV,WAAW,CACT;GACE,KAAK;GACL,OAAO,CAAC,iBAAiB;GACzB,MAAM,CAAC,uBAAuB;GAC9B,MAAM,CAAC,sBAAsB,kCAAkC;GAChE,CACF;EACD,UAAU,CACR;GACE,KAAK;GACL,OAAO,EAAE,WAAW,YAAY;GAChC,QAAQ,EAAE,SAAS,MAAM;GAC1B,CACF;EACF;CACF,CAAC;;;;AAKF,MAAa,uBAAuB,YAAY;CAC9C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAQ;GAAW;GAAO;EACjC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACT;CACD,QAAQ,EACN,MAAM,QACP;CACD,YAAY;EACV,WAAW,CACT;GACE,KAAK;GACL,OAAO,CAAC,iBAAiB;GACzB,MAAM,CAAC,sBAAsB;GAC7B,MAAM,CAAC,+BAA+B;GACvC,CACF;EACD,UAAU,CACR;GACE,KAAK;GACL,OAAO,EAAE,OAAO,IAAI;GACpB,QAAQ;IAAE,OAAO,EAAE;IAAE,OAAO;IAAG;GAChC,CACF;EACF;CACF,CAAC"}
@@ -8,7 +8,7 @@ import { StabilityEnum } from "@contractspec/lib.contracts";
8
8
  const ProjectListPresentation = {
9
9
  meta: {
10
10
  key: "saas.project.list",
11
- version: 1,
11
+ version: "1.0.0",
12
12
  title: "Project List",
13
13
  description: "List view of projects with status, tags, and last updated info",
14
14
  domain: "saas-boilerplate",
@@ -41,7 +41,7 @@ const ProjectListPresentation = {
41
41
  const ProjectDetailPresentation = {
42
42
  meta: {
43
43
  key: "saas.project.detail",
44
- version: 1,
44
+ version: "1.0.0",
45
45
  title: "Project Details",
46
46
  description: "Detailed view of a project with settings and activity",
47
47
  domain: "saas-boilerplate",
@@ -1 +1 @@
1
- {"version":3,"file":"project.presentation.js","names":["ProjectListPresentation: PresentationSpec","ProjectDetailPresentation: PresentationSpec"],"sources":["../../src/project/project.presentation.ts"],"sourcesContent":["import type { PresentationSpec } from '@contractspec/lib.contracts';\nimport { StabilityEnum } from '@contractspec/lib.contracts';\nimport { ProjectModel } from './project.schema';\n\n/**\n * Presentation for displaying a list of projects.\n */\nexport const ProjectListPresentation: PresentationSpec = {\n meta: {\n key: 'saas.project.list',\n version: 1,\n title: 'Project List',\n description:\n 'List view of projects with status, tags, and last updated info',\n domain: 'saas-boilerplate',\n owners: ['@saas-team'],\n tags: ['project', 'list', 'dashboard'],\n stability: StabilityEnum.Beta,\n goal: 'Browse and manage projects',\n context: 'Project list page',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'ProjectListView',\n props: ProjectModel,\n },\n targets: ['react', 'markdown', 'application/json'],\n policy: {\n flags: ['saas.projects.enabled'],\n },\n};\n\n/**\n * Presentation for project detail view.\n */\nexport const ProjectDetailPresentation: PresentationSpec = {\n meta: {\n key: 'saas.project.detail',\n version: 1,\n title: 'Project Details',\n description: 'Detailed view of a project with settings and activity',\n domain: 'saas-boilerplate',\n owners: ['@saas-team'],\n tags: ['project', 'detail'],\n stability: StabilityEnum.Beta,\n goal: 'View and edit project details',\n context: 'Project detail page',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'ProjectDetailView',\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['saas.projects.enabled'],\n },\n};\n"],"mappings":";;;;;;;AAOA,MAAaA,0BAA4C;CACvD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,aAAa;EACtB,MAAM;GAAC;GAAW;GAAQ;GAAY;EACtC,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACd,OAAO;EACR;CACD,SAAS;EAAC;EAAS;EAAY;EAAmB;CAClD,QAAQ,EACN,OAAO,CAAC,wBAAwB,EACjC;CACF;;;;AAKD,MAAaC,4BAA8C;CACzD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aAAa;EACb,QAAQ;EACR,QAAQ,CAAC,aAAa;EACtB,MAAM,CAAC,WAAW,SAAS;EAC3B,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACf;CACD,SAAS,CAAC,SAAS,WAAW;CAC9B,QAAQ,EACN,OAAO,CAAC,wBAAwB,EACjC;CACF"}
1
+ {"version":3,"file":"project.presentation.js","names":["ProjectListPresentation: PresentationSpec","ProjectDetailPresentation: PresentationSpec"],"sources":["../../src/project/project.presentation.ts"],"sourcesContent":["import type { PresentationSpec } from '@contractspec/lib.contracts';\nimport { StabilityEnum } from '@contractspec/lib.contracts';\nimport { ProjectModel } from './project.schema';\n\n/**\n * Presentation for displaying a list of projects.\n */\nexport const ProjectListPresentation: PresentationSpec = {\n meta: {\n key: 'saas.project.list',\n version: '1.0.0',\n title: 'Project List',\n description:\n 'List view of projects with status, tags, and last updated info',\n domain: 'saas-boilerplate',\n owners: ['@saas-team'],\n tags: ['project', 'list', 'dashboard'],\n stability: StabilityEnum.Beta,\n goal: 'Browse and manage projects',\n context: 'Project list page',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'ProjectListView',\n props: ProjectModel,\n },\n targets: ['react', 'markdown', 'application/json'],\n policy: {\n flags: ['saas.projects.enabled'],\n },\n};\n\n/**\n * Presentation for project detail view.\n */\nexport const ProjectDetailPresentation: PresentationSpec = {\n meta: {\n key: 'saas.project.detail',\n version: '1.0.0',\n title: 'Project Details',\n description: 'Detailed view of a project with settings and activity',\n domain: 'saas-boilerplate',\n owners: ['@saas-team'],\n tags: ['project', 'detail'],\n stability: StabilityEnum.Beta,\n goal: 'View and edit project details',\n context: 'Project detail page',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'ProjectDetailView',\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['saas.projects.enabled'],\n },\n};\n"],"mappings":";;;;;;;AAOA,MAAaA,0BAA4C;CACvD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,aAAa;EACtB,MAAM;GAAC;GAAW;GAAQ;GAAY;EACtC,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACd,OAAO;EACR;CACD,SAAS;EAAC;EAAS;EAAY;EAAmB;CAClD,QAAQ,EACN,OAAO,CAAC,wBAAwB,EACjC;CACF;;;;AAKD,MAAaC,4BAA8C;CACzD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aAAa;EACb,QAAQ;EACR,QAAQ,CAAC,aAAa;EACtB,MAAM,CAAC,WAAW,SAAS;EAC3B,WAAW,cAAc;EACzB,MAAM;EACN,SAAS;EACV;CACD,QAAQ;EACN,MAAM;EACN,WAAW;EACX,cAAc;EACf;CACD,SAAS,CAAC,SAAS,WAAW;CAC9B,QAAQ,EACN,OAAO,CAAC,wBAAwB,EACjC;CACF"}
@@ -16,153 +16,153 @@ const SaasBoilerplateFeature = {
16
16
  "billing"
17
17
  ],
18
18
  stability: "experimental",
19
- version: 1
19
+ version: "1.0.0"
20
20
  },
21
21
  operations: [
22
22
  {
23
23
  key: "saas.project.create",
24
- version: 1
24
+ version: "1.0.0"
25
25
  },
26
26
  {
27
27
  key: "saas.project.get",
28
- version: 1
28
+ version: "1.0.0"
29
29
  },
30
30
  {
31
31
  key: "saas.project.update",
32
- version: 1
32
+ version: "1.0.0"
33
33
  },
34
34
  {
35
35
  key: "saas.project.delete",
36
- version: 1
36
+ version: "1.0.0"
37
37
  },
38
38
  {
39
39
  key: "saas.project.list",
40
- version: 1
40
+ version: "1.0.0"
41
41
  },
42
42
  {
43
43
  key: "saas.billing.subscription.get",
44
- version: 1
44
+ version: "1.0.0"
45
45
  },
46
46
  {
47
47
  key: "saas.billing.usage.record",
48
- version: 1
48
+ version: "1.0.0"
49
49
  },
50
50
  {
51
51
  key: "saas.billing.usage.summary",
52
- version: 1
52
+ version: "1.0.0"
53
53
  },
54
54
  {
55
55
  key: "saas.billing.feature.check",
56
- version: 1
56
+ version: "1.0.0"
57
57
  }
58
58
  ],
59
59
  events: [
60
60
  {
61
61
  key: "project.created",
62
- version: 1
62
+ version: "1.0.0"
63
63
  },
64
64
  {
65
65
  key: "project.updated",
66
- version: 1
66
+ version: "1.0.0"
67
67
  },
68
68
  {
69
69
  key: "project.deleted",
70
- version: 1
70
+ version: "1.0.0"
71
71
  },
72
72
  {
73
73
  key: "project.archived",
74
- version: 1
74
+ version: "1.0.0"
75
75
  },
76
76
  {
77
77
  key: "billing.usage.recorded",
78
- version: 1
78
+ version: "1.0.0"
79
79
  },
80
80
  {
81
81
  key: "billing.subscription.changed",
82
- version: 1
82
+ version: "1.0.0"
83
83
  },
84
84
  {
85
85
  key: "billing.limit.reached",
86
- version: 1
86
+ version: "1.0.0"
87
87
  }
88
88
  ],
89
89
  presentations: [
90
90
  {
91
91
  key: "saas.dashboard",
92
- version: 1
92
+ version: "1.0.0"
93
93
  },
94
94
  {
95
95
  key: "saas.project.list",
96
- version: 1
96
+ version: "1.0.0"
97
97
  },
98
98
  {
99
99
  key: "saas.project.detail",
100
- version: 1
100
+ version: "1.0.0"
101
101
  },
102
102
  {
103
103
  key: "saas.billing.subscription",
104
- version: 1
104
+ version: "1.0.0"
105
105
  },
106
106
  {
107
107
  key: "saas.billing.usage",
108
- version: 1
108
+ version: "1.0.0"
109
109
  },
110
110
  {
111
111
  key: "saas.settings",
112
- version: 1
112
+ version: "1.0.0"
113
113
  }
114
114
  ],
115
115
  opToPresentation: [
116
116
  {
117
117
  op: {
118
118
  key: "saas.project.list",
119
- version: 1
119
+ version: "1.0.0"
120
120
  },
121
121
  pres: {
122
122
  key: "saas.project.list",
123
- version: 1
123
+ version: "1.0.0"
124
124
  }
125
125
  },
126
126
  {
127
127
  op: {
128
128
  key: "saas.project.get",
129
- version: 1
129
+ version: "1.0.0"
130
130
  },
131
131
  pres: {
132
132
  key: "saas.project.detail",
133
- version: 1
133
+ version: "1.0.0"
134
134
  }
135
135
  },
136
136
  {
137
137
  op: {
138
138
  key: "saas.billing.subscription.get",
139
- version: 1
139
+ version: "1.0.0"
140
140
  },
141
141
  pres: {
142
142
  key: "saas.billing.subscription",
143
- version: 1
143
+ version: "1.0.0"
144
144
  }
145
145
  },
146
146
  {
147
147
  op: {
148
148
  key: "saas.billing.usage.summary",
149
- version: 1
149
+ version: "1.0.0"
150
150
  },
151
151
  pres: {
152
152
  key: "saas.billing.usage",
153
- version: 1
153
+ version: "1.0.0"
154
154
  }
155
155
  }
156
156
  ],
157
157
  presentationsTargets: [
158
158
  {
159
159
  key: "saas.dashboard",
160
- version: 1,
160
+ version: "1.0.0",
161
161
  targets: ["react", "markdown"]
162
162
  },
163
163
  {
164
164
  key: "saas.project.list",
165
- version: 1,
165
+ version: "1.0.0",
166
166
  targets: [
167
167
  "react",
168
168
  "markdown",
@@ -171,27 +171,27 @@ const SaasBoilerplateFeature = {
171
171
  },
172
172
  {
173
173
  key: "saas.billing.subscription",
174
- version: 1,
174
+ version: "1.0.0",
175
175
  targets: ["react", "markdown"]
176
176
  },
177
177
  {
178
178
  key: "saas.billing.usage",
179
- version: 1,
179
+ version: "1.0.0",
180
180
  targets: ["react", "markdown"]
181
181
  }
182
182
  ],
183
183
  capabilities: { requires: [
184
184
  {
185
185
  key: "identity",
186
- version: 1
186
+ version: "1.0.0"
187
187
  },
188
188
  {
189
189
  key: "audit-trail",
190
- version: 1
190
+ version: "1.0.0"
191
191
  },
192
192
  {
193
193
  key: "notifications",
194
- version: 1
194
+ version: "1.0.0"
195
195
  }
196
196
  ] }
197
197
  };
@@ -1 +1 @@
1
- {"version":3,"file":"saas-boilerplate.feature.js","names":["SaasBoilerplateFeature: FeatureModuleSpec"],"sources":["../src/saas-boilerplate.feature.ts"],"sourcesContent":["/**\n * SaaS Boilerplate Feature Module Specification\n *\n * Defines the feature module for the SaaS application foundation.\n */\nimport type { FeatureModuleSpec } from '@contractspec/lib.contracts';\n\n/**\n * SaaS Boilerplate feature module that bundles project management,\n * billing, and settings operations into an installable feature.\n */\nexport const SaasBoilerplateFeature: FeatureModuleSpec = {\n meta: {\n key: 'saas-boilerplate',\n title: 'SaaS Boilerplate',\n description:\n 'SaaS application foundation with projects, billing, and settings',\n domain: 'saas',\n owners: ['@saas-team'],\n tags: ['saas', 'projects', 'billing'],\n stability: 'experimental',\n version: 1,\n },\n\n // All contract operations included in this feature\n operations: [\n // Project operations\n { key: 'saas.project.create', version: 1 },\n { key: 'saas.project.get', version: 1 },\n { key: 'saas.project.update', version: 1 },\n { key: 'saas.project.delete', version: 1 },\n { key: 'saas.project.list', version: 1 },\n\n // Billing operations\n { key: 'saas.billing.subscription.get', version: 1 },\n { key: 'saas.billing.usage.record', version: 1 },\n { key: 'saas.billing.usage.summary', version: 1 },\n { key: 'saas.billing.feature.check', version: 1 },\n ],\n\n // Events emitted by this feature\n events: [\n // Project events\n { key: 'project.created', version: 1 },\n { key: 'project.updated', version: 1 },\n { key: 'project.deleted', version: 1 },\n { key: 'project.archived', version: 1 },\n\n // Billing events\n { key: 'billing.usage.recorded', version: 1 },\n { key: 'billing.subscription.changed', version: 1 },\n { key: 'billing.limit.reached', version: 1 },\n ],\n\n // Presentations associated with this feature\n presentations: [\n { key: 'saas.dashboard', version: 1 },\n { key: 'saas.project.list', version: 1 },\n { key: 'saas.project.detail', version: 1 },\n { key: 'saas.billing.subscription', version: 1 },\n { key: 'saas.billing.usage', version: 1 },\n { key: 'saas.settings', version: 1 },\n ],\n\n // Link operations to their primary presentations\n opToPresentation: [\n {\n op: { key: 'saas.project.list', version: 1 },\n pres: { key: 'saas.project.list', version: 1 },\n },\n {\n op: { key: 'saas.project.get', version: 1 },\n pres: { key: 'saas.project.detail', version: 1 },\n },\n {\n op: { key: 'saas.billing.subscription.get', version: 1 },\n pres: { key: 'saas.billing.subscription', version: 1 },\n },\n {\n op: { key: 'saas.billing.usage.summary', version: 1 },\n pres: { key: 'saas.billing.usage', version: 1 },\n },\n ],\n\n // Target requirements for multi-surface rendering\n presentationsTargets: [\n { key: 'saas.dashboard', version: 1, targets: ['react', 'markdown'] },\n {\n key: 'saas.project.list',\n version: 1,\n targets: ['react', 'markdown', 'application/json'],\n },\n {\n key: 'saas.billing.subscription',\n version: 1,\n targets: ['react', 'markdown'],\n },\n { key: 'saas.billing.usage', version: 1, targets: ['react', 'markdown'] },\n ],\n\n // Capability requirements\n capabilities: {\n requires: [\n { key: 'identity', version: 1 },\n { key: 'audit-trail', version: 1 },\n { key: 'notifications', version: 1 },\n ],\n },\n};\n"],"mappings":";;;;;AAWA,MAAaA,yBAA4C;CACvD,MAAM;EACJ,KAAK;EACL,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,aAAa;EACtB,MAAM;GAAC;GAAQ;GAAY;GAAU;EACrC,WAAW;EACX,SAAS;EACV;CAGD,YAAY;EAEV;GAAE,KAAK;GAAuB,SAAS;GAAG;EAC1C;GAAE,KAAK;GAAoB,SAAS;GAAG;EACvC;GAAE,KAAK;GAAuB,SAAS;GAAG;EAC1C;GAAE,KAAK;GAAuB,SAAS;GAAG;EAC1C;GAAE,KAAK;GAAqB,SAAS;GAAG;EAGxC;GAAE,KAAK;GAAiC,SAAS;GAAG;EACpD;GAAE,KAAK;GAA6B,SAAS;GAAG;EAChD;GAAE,KAAK;GAA8B,SAAS;GAAG;EACjD;GAAE,KAAK;GAA8B,SAAS;GAAG;EAClD;CAGD,QAAQ;EAEN;GAAE,KAAK;GAAmB,SAAS;GAAG;EACtC;GAAE,KAAK;GAAmB,SAAS;GAAG;EACtC;GAAE,KAAK;GAAmB,SAAS;GAAG;EACtC;GAAE,KAAK;GAAoB,SAAS;GAAG;EAGvC;GAAE,KAAK;GAA0B,SAAS;GAAG;EAC7C;GAAE,KAAK;GAAgC,SAAS;GAAG;EACnD;GAAE,KAAK;GAAyB,SAAS;GAAG;EAC7C;CAGD,eAAe;EACb;GAAE,KAAK;GAAkB,SAAS;GAAG;EACrC;GAAE,KAAK;GAAqB,SAAS;GAAG;EACxC;GAAE,KAAK;GAAuB,SAAS;GAAG;EAC1C;GAAE,KAAK;GAA6B,SAAS;GAAG;EAChD;GAAE,KAAK;GAAsB,SAAS;GAAG;EACzC;GAAE,KAAK;GAAiB,SAAS;GAAG;EACrC;CAGD,kBAAkB;EAChB;GACE,IAAI;IAAE,KAAK;IAAqB,SAAS;IAAG;GAC5C,MAAM;IAAE,KAAK;IAAqB,SAAS;IAAG;GAC/C;EACD;GACE,IAAI;IAAE,KAAK;IAAoB,SAAS;IAAG;GAC3C,MAAM;IAAE,KAAK;IAAuB,SAAS;IAAG;GACjD;EACD;GACE,IAAI;IAAE,KAAK;IAAiC,SAAS;IAAG;GACxD,MAAM;IAAE,KAAK;IAA6B,SAAS;IAAG;GACvD;EACD;GACE,IAAI;IAAE,KAAK;IAA8B,SAAS;IAAG;GACrD,MAAM;IAAE,KAAK;IAAsB,SAAS;IAAG;GAChD;EACF;CAGD,sBAAsB;EACpB;GAAE,KAAK;GAAkB,SAAS;GAAG,SAAS,CAAC,SAAS,WAAW;GAAE;EACrE;GACE,KAAK;GACL,SAAS;GACT,SAAS;IAAC;IAAS;IAAY;IAAmB;GACnD;EACD;GACE,KAAK;GACL,SAAS;GACT,SAAS,CAAC,SAAS,WAAW;GAC/B;EACD;GAAE,KAAK;GAAsB,SAAS;GAAG,SAAS,CAAC,SAAS,WAAW;GAAE;EAC1E;CAGD,cAAc,EACZ,UAAU;EACR;GAAE,KAAK;GAAY,SAAS;GAAG;EAC/B;GAAE,KAAK;GAAe,SAAS;GAAG;EAClC;GAAE,KAAK;GAAiB,SAAS;GAAG;EACrC,EACF;CACF"}
1
+ {"version":3,"file":"saas-boilerplate.feature.js","names":["SaasBoilerplateFeature: FeatureModuleSpec"],"sources":["../src/saas-boilerplate.feature.ts"],"sourcesContent":["/**\n * SaaS Boilerplate Feature Module Specification\n *\n * Defines the feature module for the SaaS application foundation.\n */\nimport type { FeatureModuleSpec } from '@contractspec/lib.contracts';\n\n/**\n * SaaS Boilerplate feature module that bundles project management,\n * billing, and settings operations into an installable feature.\n */\nexport const SaasBoilerplateFeature: FeatureModuleSpec = {\n meta: {\n key: 'saas-boilerplate',\n title: 'SaaS Boilerplate',\n description:\n 'SaaS application foundation with projects, billing, and settings',\n domain: 'saas',\n owners: ['@saas-team'],\n tags: ['saas', 'projects', 'billing'],\n stability: 'experimental',\n version: '1.0.0',\n },\n\n // All contract operations included in this feature\n operations: [\n // Project operations\n { key: 'saas.project.create', version: '1.0.0' },\n { key: 'saas.project.get', version: '1.0.0' },\n { key: 'saas.project.update', version: '1.0.0' },\n { key: 'saas.project.delete', version: '1.0.0' },\n { key: 'saas.project.list', version: '1.0.0' },\n\n // Billing operations\n { key: 'saas.billing.subscription.get', version: '1.0.0' },\n { key: 'saas.billing.usage.record', version: '1.0.0' },\n { key: 'saas.billing.usage.summary', version: '1.0.0' },\n { key: 'saas.billing.feature.check', version: '1.0.0' },\n ],\n\n // Events emitted by this feature\n events: [\n // Project events\n { key: 'project.created', version: '1.0.0' },\n { key: 'project.updated', version: '1.0.0' },\n { key: 'project.deleted', version: '1.0.0' },\n { key: 'project.archived', version: '1.0.0' },\n\n // Billing events\n { key: 'billing.usage.recorded', version: '1.0.0' },\n { key: 'billing.subscription.changed', version: '1.0.0' },\n { key: 'billing.limit.reached', version: '1.0.0' },\n ],\n\n // Presentations associated with this feature\n presentations: [\n { key: 'saas.dashboard', version: '1.0.0' },\n { key: 'saas.project.list', version: '1.0.0' },\n { key: 'saas.project.detail', version: '1.0.0' },\n { key: 'saas.billing.subscription', version: '1.0.0' },\n { key: 'saas.billing.usage', version: '1.0.0' },\n { key: 'saas.settings', version: '1.0.0' },\n ],\n\n // Link operations to their primary presentations\n opToPresentation: [\n {\n op: { key: 'saas.project.list', version: '1.0.0' },\n pres: { key: 'saas.project.list', version: '1.0.0' },\n },\n {\n op: { key: 'saas.project.get', version: '1.0.0' },\n pres: { key: 'saas.project.detail', version: '1.0.0' },\n },\n {\n op: { key: 'saas.billing.subscription.get', version: '1.0.0' },\n pres: { key: 'saas.billing.subscription', version: '1.0.0' },\n },\n {\n op: { key: 'saas.billing.usage.summary', version: '1.0.0' },\n pres: { key: 'saas.billing.usage', version: '1.0.0' },\n },\n ],\n\n // Target requirements for multi-surface rendering\n presentationsTargets: [\n { key: 'saas.dashboard', version: '1.0.0', targets: ['react', 'markdown'] },\n {\n key: 'saas.project.list',\n version: '1.0.0',\n targets: ['react', 'markdown', 'application/json'],\n },\n {\n key: 'saas.billing.subscription',\n version: '1.0.0',\n targets: ['react', 'markdown'],\n },\n {\n key: 'saas.billing.usage',\n version: '1.0.0',\n targets: ['react', 'markdown'],\n },\n ],\n\n // Capability requirements\n capabilities: {\n requires: [\n { key: 'identity', version: '1.0.0' },\n { key: 'audit-trail', version: '1.0.0' },\n { key: 'notifications', version: '1.0.0' },\n ],\n },\n};\n"],"mappings":";;;;;AAWA,MAAaA,yBAA4C;CACvD,MAAM;EACJ,KAAK;EACL,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,aAAa;EACtB,MAAM;GAAC;GAAQ;GAAY;GAAU;EACrC,WAAW;EACX,SAAS;EACV;CAGD,YAAY;EAEV;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAoB,SAAS;GAAS;EAC7C;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAqB,SAAS;GAAS;EAG9C;GAAE,KAAK;GAAiC,SAAS;GAAS;EAC1D;GAAE,KAAK;GAA6B,SAAS;GAAS;EACtD;GAAE,KAAK;GAA8B,SAAS;GAAS;EACvD;GAAE,KAAK;GAA8B,SAAS;GAAS;EACxD;CAGD,QAAQ;EAEN;GAAE,KAAK;GAAmB,SAAS;GAAS;EAC5C;GAAE,KAAK;GAAmB,SAAS;GAAS;EAC5C;GAAE,KAAK;GAAmB,SAAS;GAAS;EAC5C;GAAE,KAAK;GAAoB,SAAS;GAAS;EAG7C;GAAE,KAAK;GAA0B,SAAS;GAAS;EACnD;GAAE,KAAK;GAAgC,SAAS;GAAS;EACzD;GAAE,KAAK;GAAyB,SAAS;GAAS;EACnD;CAGD,eAAe;EACb;GAAE,KAAK;GAAkB,SAAS;GAAS;EAC3C;GAAE,KAAK;GAAqB,SAAS;GAAS;EAC9C;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAA6B,SAAS;GAAS;EACtD;GAAE,KAAK;GAAsB,SAAS;GAAS;EAC/C;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC3C;CAGD,kBAAkB;EAChB;GACE,IAAI;IAAE,KAAK;IAAqB,SAAS;IAAS;GAClD,MAAM;IAAE,KAAK;IAAqB,SAAS;IAAS;GACrD;EACD;GACE,IAAI;IAAE,KAAK;IAAoB,SAAS;IAAS;GACjD,MAAM;IAAE,KAAK;IAAuB,SAAS;IAAS;GACvD;EACD;GACE,IAAI;IAAE,KAAK;IAAiC,SAAS;IAAS;GAC9D,MAAM;IAAE,KAAK;IAA6B,SAAS;IAAS;GAC7D;EACD;GACE,IAAI;IAAE,KAAK;IAA8B,SAAS;IAAS;GAC3D,MAAM;IAAE,KAAK;IAAsB,SAAS;IAAS;GACtD;EACF;CAGD,sBAAsB;EACpB;GAAE,KAAK;GAAkB,SAAS;GAAS,SAAS,CAAC,SAAS,WAAW;GAAE;EAC3E;GACE,KAAK;GACL,SAAS;GACT,SAAS;IAAC;IAAS;IAAY;IAAmB;GACnD;EACD;GACE,KAAK;GACL,SAAS;GACT,SAAS,CAAC,SAAS,WAAW;GAC/B;EACD;GACE,KAAK;GACL,SAAS;GACT,SAAS,CAAC,SAAS,WAAW;GAC/B;EACF;CAGD,cAAc,EACZ,UAAU;EACR;GAAE,KAAK;GAAY,SAAS;GAAS;EACrC;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC3C,EACF;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/example.saas-boilerplate",
3
- "version": "1.44.0",
3
+ "version": "1.45.0",
4
4
  "description": "SaaS Boilerplate - Users, Orgs, Projects, Billing, Settings",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -51,18 +51,18 @@
51
51
  "test": "bun run"
52
52
  },
53
53
  "dependencies": {
54
- "@contractspec/lib.schema": "1.44.0",
55
- "@contractspec/lib.contracts": "1.44.0",
56
- "@contractspec/lib.bus": "1.44.0",
57
- "@contractspec/lib.identity-rbac": "1.44.0",
58
- "@contractspec/lib.jobs": "1.44.0",
59
- "@contractspec/module.audit-trail": "1.44.0",
60
- "@contractspec/module.notifications": "1.44.0",
54
+ "@contractspec/lib.schema": "1.45.0",
55
+ "@contractspec/lib.contracts": "1.45.0",
56
+ "@contractspec/lib.bus": "1.45.0",
57
+ "@contractspec/lib.identity-rbac": "1.45.0",
58
+ "@contractspec/lib.jobs": "1.45.0",
59
+ "@contractspec/module.audit-trail": "1.45.0",
60
+ "@contractspec/module.notifications": "1.45.0",
61
61
  "zod": "^4.1.13"
62
62
  },
63
63
  "devDependencies": {
64
- "@contractspec/tool.tsdown": "1.44.0",
65
- "@contractspec/tool.typescript": "1.44.0",
64
+ "@contractspec/tool.tsdown": "1.45.0",
65
+ "@contractspec/tool.typescript": "1.45.0",
66
66
  "tsdown": "^0.18.3",
67
67
  "typescript": "^5.9.3"
68
68
  },
@@ -68,7 +68,7 @@ const SubscriptionChangedPayload = defineSchemaModel({
68
68
  export const UsageRecordedEvent = defineEvent({
69
69
  meta: {
70
70
  key: 'billing.usage.recorded',
71
- version: 1,
71
+ version: '1.0.0',
72
72
  description: 'Feature usage has been recorded.',
73
73
  stability: 'stable',
74
74
  owners: ['@saas-team'],
@@ -83,7 +83,7 @@ export const UsageRecordedEvent = defineEvent({
83
83
  export const UsageLimitReachedEvent = defineEvent({
84
84
  meta: {
85
85
  key: 'billing.limit.reached',
86
- version: 1,
86
+ version: '1.0.0',
87
87
  description: 'Usage limit has been reached for a feature.',
88
88
  stability: 'stable',
89
89
  owners: ['@saas-team'],
@@ -98,7 +98,7 @@ export const UsageLimitReachedEvent = defineEvent({
98
98
  export const SubscriptionChangedEvent = defineEvent({
99
99
  meta: {
100
100
  key: 'billing.subscription.changed',
101
- version: 1,
101
+ version: '1.0.0',
102
102
  description: 'Subscription status has changed.',
103
103
  stability: 'stable',
104
104
  owners: ['@saas-team'],
@@ -18,7 +18,7 @@ const OWNERS = ['@example.saas-boilerplate'] as const;
18
18
  export const GetSubscriptionContract = defineQuery({
19
19
  meta: {
20
20
  key: 'saas.billing.subscription.get',
21
- version: 1,
21
+ version: '1.0.0',
22
22
  stability: 'stable',
23
23
  owners: [...OWNERS],
24
24
  tags: ['saas', 'billing', 'subscription'],
@@ -62,7 +62,7 @@ export const GetSubscriptionContract = defineQuery({
62
62
  export const RecordUsageContract = defineCommand({
63
63
  meta: {
64
64
  key: 'saas.billing.usage.record',
65
- version: 1,
65
+ version: '1.0.0',
66
66
  stability: 'stable',
67
67
  owners: [...OWNERS],
68
68
  tags: ['saas', 'billing', 'usage'],
@@ -81,7 +81,7 @@ export const RecordUsageContract = defineCommand({
81
81
  emits: [
82
82
  {
83
83
  key: 'billing.usage.recorded',
84
- version: 1,
84
+ version: '1.0.0',
85
85
  when: 'Usage is recorded',
86
86
  payload: UsageRecordedPayloadModel,
87
87
  },
@@ -112,7 +112,7 @@ export const RecordUsageContract = defineCommand({
112
112
  export const GetUsageSummaryContract = defineQuery({
113
113
  meta: {
114
114
  key: 'saas.billing.usage.summary',
115
- version: 1,
115
+ version: '1.0.0',
116
116
  stability: 'stable',
117
117
  owners: [...OWNERS],
118
118
  tags: ['saas', 'billing', 'usage'],
@@ -152,7 +152,7 @@ export const GetUsageSummaryContract = defineQuery({
152
152
  export const CheckFeatureAccessContract = defineQuery({
153
153
  meta: {
154
154
  key: 'saas.billing.feature.check',
155
- version: 1,
155
+ version: '1.0.0',
156
156
  stability: 'stable',
157
157
  owners: [...OWNERS],
158
158
  tags: ['saas', 'billing', 'feature'],
@@ -7,7 +7,7 @@ import { StabilityEnum } from '@contractspec/lib.contracts';
7
7
  export const SubscriptionPresentation: PresentationSpec = {
8
8
  meta: {
9
9
  key: 'saas.billing.subscription',
10
- version: 1,
10
+ version: '1.0.0',
11
11
  title: 'Subscription Status',
12
12
  description:
13
13
  'Subscription status with plan info, limits, and current usage',
@@ -35,7 +35,7 @@ export const SubscriptionPresentation: PresentationSpec = {
35
35
  export const UsageDashboardPresentation: PresentationSpec = {
36
36
  meta: {
37
37
  key: 'saas.billing.usage',
38
- version: 1,
38
+ version: '1.0.0',
39
39
  title: 'Usage Dashboard',
40
40
  description: 'Usage metrics and breakdown by resource type',
41
41
  domain: 'saas-boilerplate',
@@ -7,7 +7,7 @@ import { StabilityEnum } from '@contractspec/lib.contracts';
7
7
  export const SaasDashboardPresentation: PresentationSpec = {
8
8
  meta: {
9
9
  key: 'saas.dashboard',
10
- version: 1,
10
+ version: '1.0.0',
11
11
  title: 'SaaS Dashboard',
12
12
  description:
13
13
  'Main SaaS dashboard with project overview, usage stats, and quick actions',
@@ -35,7 +35,7 @@ export const SaasDashboardPresentation: PresentationSpec = {
35
35
  export const SettingsPanelPresentation: PresentationSpec = {
36
36
  meta: {
37
37
  key: 'saas.settings',
38
- version: 1,
38
+ version: '1.0.0',
39
39
  title: 'Settings Panel',
40
40
  description: 'Organization and user settings panel',
41
41
  domain: 'saas-boilerplate',
package/src/example.ts CHANGED
@@ -1,11 +1,18 @@
1
- const example = {
2
- id: 'saas-boilerplate',
3
- title: 'SaaS Boilerplate',
4
- summary:
5
- 'Multi-tenant SaaS foundation with orgs, projects, settings, billing usage, and RBAC.',
6
- tags: ['saas', 'multi-tenant', 'billing', 'rbac'],
7
- kind: 'template',
8
- visibility: 'public',
1
+ import type { ExampleSpec } from '@contractspec/lib.contracts';
2
+
3
+ const example: ExampleSpec = {
4
+ meta: {
5
+ key: 'saas-boilerplate',
6
+ version: '1.0.0',
7
+ title: 'SaaS Boilerplate',
8
+ description:
9
+ 'Multi-tenant SaaS foundation with orgs, projects, settings, billing usage, and RBAC.',
10
+ kind: 'template',
11
+ visibility: 'public',
12
+ stability: 'experimental',
13
+ owners: ['@platform.core'],
14
+ tags: ['saas', 'multi-tenant', 'billing', 'rbac'],
15
+ },
9
16
  docs: {
10
17
  rootDocId: 'docs.examples.saas-boilerplate',
11
18
  },
@@ -26,6 +33,6 @@ const example = {
26
33
  studio: { enabled: true, installable: true },
27
34
  mcp: { enabled: true },
28
35
  },
29
- } as const;
36
+ };
30
37
 
31
38
  export default example;
@@ -73,7 +73,7 @@ const ProjectArchivedPayload = defineSchemaModel({
73
73
  export const ProjectCreatedEvent = defineEvent({
74
74
  meta: {
75
75
  key: 'project.created',
76
- version: 1,
76
+ version: '1.0.0',
77
77
  description: 'A new project has been created.',
78
78
  stability: 'stable',
79
79
  owners: ['@saas-team'],
@@ -88,7 +88,7 @@ export const ProjectCreatedEvent = defineEvent({
88
88
  export const ProjectUpdatedEvent = defineEvent({
89
89
  meta: {
90
90
  key: 'project.updated',
91
- version: 1,
91
+ version: '1.0.0',
92
92
  description: 'A project has been updated.',
93
93
  stability: 'stable',
94
94
  owners: ['@saas-team'],
@@ -103,7 +103,7 @@ export const ProjectUpdatedEvent = defineEvent({
103
103
  export const ProjectDeletedEvent = defineEvent({
104
104
  meta: {
105
105
  key: 'project.deleted',
106
- version: 1,
106
+ version: '1.0.0',
107
107
  description: 'A project has been deleted.',
108
108
  stability: 'stable',
109
109
  owners: ['@saas-team'],
@@ -118,7 +118,7 @@ export const ProjectDeletedEvent = defineEvent({
118
118
  export const ProjectArchivedEvent = defineEvent({
119
119
  meta: {
120
120
  key: 'project.archived',
121
- version: 1,
121
+ version: '1.0.0',
122
122
  description: 'A project has been archived.',
123
123
  stability: 'stable',
124
124
  owners: ['@saas-team'],
@@ -22,7 +22,7 @@ const OWNERS = ['example.saas-boilerplate'] as const;
22
22
  export const CreateProjectContract = defineCommand({
23
23
  meta: {
24
24
  key: 'saas.project.create',
25
- version: 1,
25
+ version: '1.0.0',
26
26
  stability: 'stable',
27
27
  owners: [...OWNERS],
28
28
  tags: ['saas', 'project', 'create'],
@@ -55,7 +55,7 @@ export const CreateProjectContract = defineCommand({
55
55
  emits: [
56
56
  {
57
57
  key: 'project.created',
58
- version: 1,
58
+ version: '1.0.0',
59
59
  when: 'Project is created',
60
60
  payload: ProjectModel,
61
61
  },
@@ -87,7 +87,7 @@ export const CreateProjectContract = defineCommand({
87
87
  export const GetProjectContract = defineQuery({
88
88
  meta: {
89
89
  key: 'saas.project.get',
90
- version: 1,
90
+ version: '1.0.0',
91
91
  stability: 'stable',
92
92
  owners: [...OWNERS],
93
93
  tags: ['saas', 'project', 'get'],
@@ -135,7 +135,7 @@ export const GetProjectContract = defineQuery({
135
135
  export const UpdateProjectContract = defineCommand({
136
136
  meta: {
137
137
  key: 'saas.project.update',
138
- version: 1,
138
+ version: '1.0.0',
139
139
  stability: 'stable',
140
140
  owners: [...OWNERS],
141
141
  tags: ['saas', 'project', 'update'],
@@ -154,7 +154,7 @@ export const UpdateProjectContract = defineCommand({
154
154
  emits: [
155
155
  {
156
156
  key: 'project.updated',
157
- version: 1,
157
+ version: '1.0.0',
158
158
  when: 'Project is updated',
159
159
  payload: ProjectModel,
160
160
  },
@@ -186,7 +186,7 @@ export const UpdateProjectContract = defineCommand({
186
186
  export const DeleteProjectContract = defineCommand({
187
187
  meta: {
188
188
  key: 'saas.project.delete',
189
- version: 1,
189
+ version: '1.0.0',
190
190
  stability: 'stable',
191
191
  owners: [...OWNERS],
192
192
  tags: ['saas', 'project', 'delete'],
@@ -205,7 +205,7 @@ export const DeleteProjectContract = defineCommand({
205
205
  emits: [
206
206
  {
207
207
  key: 'project.deleted',
208
- version: 1,
208
+ version: '1.0.0',
209
209
  when: 'Project is deleted',
210
210
  payload: ProjectDeletedPayloadModel,
211
211
  },
@@ -237,7 +237,7 @@ export const DeleteProjectContract = defineCommand({
237
237
  export const ListProjectsContract = defineQuery({
238
238
  meta: {
239
239
  key: 'saas.project.list',
240
- version: 1,
240
+ version: '1.0.0',
241
241
  stability: 'stable',
242
242
  owners: [...OWNERS],
243
243
  tags: ['saas', 'project', 'list'],
@@ -8,7 +8,7 @@ import { ProjectModel } from './project.schema';
8
8
  export const ProjectListPresentation: PresentationSpec = {
9
9
  meta: {
10
10
  key: 'saas.project.list',
11
- version: 1,
11
+ version: '1.0.0',
12
12
  title: 'Project List',
13
13
  description:
14
14
  'List view of projects with status, tags, and last updated info',
@@ -37,7 +37,7 @@ export const ProjectListPresentation: PresentationSpec = {
37
37
  export const ProjectDetailPresentation: PresentationSpec = {
38
38
  meta: {
39
39
  key: 'saas.project.detail',
40
- version: 1,
40
+ version: '1.0.0',
41
41
  title: 'Project Details',
42
42
  description: 'Detailed view of a project with settings and activity',
43
43
  domain: 'saas-boilerplate',