@contractspec/example.saas-boilerplate 3.7.5 → 3.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/AGENTS.md +50 -27
  3. package/CHANGELOG.md +16 -0
  4. package/README.md +64 -144
  5. package/dist/billing/billing.event.js +1 -1
  6. package/dist/billing/index.d.ts +6 -6
  7. package/dist/billing/index.js +1 -1
  8. package/dist/browser/billing/billing.event.js +1 -1
  9. package/dist/browser/billing/index.js +1 -1
  10. package/dist/browser/index.js +931 -932
  11. package/dist/browser/project/index.js +209 -209
  12. package/dist/browser/project/project.event.js +1 -1
  13. package/dist/browser/ui/SaasDashboard.js +45 -45
  14. package/dist/browser/ui/SaasProjectList.js +7 -7
  15. package/dist/browser/ui/SaasSettingsPanel.js +12 -12
  16. package/dist/browser/ui/hooks/index.js +2 -2
  17. package/dist/browser/ui/hooks/useProjectList.js +1 -1
  18. package/dist/browser/ui/hooks/useProjectMutations.js +1 -1
  19. package/dist/browser/ui/index.js +483 -484
  20. package/dist/browser/ui/modals/CreateProjectModal.js +10 -10
  21. package/dist/browser/ui/modals/ProjectActionsModal.js +13 -13
  22. package/dist/browser/ui/modals/index.js +23 -23
  23. package/dist/browser/ui/renderers/index.js +112 -112
  24. package/dist/browser/ui/renderers/project-list.renderer.js +7 -7
  25. package/dist/handlers/index.d.ts +2 -2
  26. package/dist/index.d.ts +4 -4
  27. package/dist/index.js +931 -932
  28. package/dist/node/billing/billing.event.js +1 -1
  29. package/dist/node/billing/index.js +1 -1
  30. package/dist/node/index.js +931 -932
  31. package/dist/node/project/index.js +209 -209
  32. package/dist/node/project/project.event.js +1 -1
  33. package/dist/node/ui/SaasDashboard.js +45 -45
  34. package/dist/node/ui/SaasProjectList.js +7 -7
  35. package/dist/node/ui/SaasSettingsPanel.js +12 -12
  36. package/dist/node/ui/hooks/index.js +2 -2
  37. package/dist/node/ui/hooks/useProjectList.js +1 -1
  38. package/dist/node/ui/hooks/useProjectMutations.js +1 -1
  39. package/dist/node/ui/index.js +483 -484
  40. package/dist/node/ui/modals/CreateProjectModal.js +10 -10
  41. package/dist/node/ui/modals/ProjectActionsModal.js +13 -13
  42. package/dist/node/ui/modals/index.js +23 -23
  43. package/dist/node/ui/renderers/index.js +112 -112
  44. package/dist/node/ui/renderers/project-list.renderer.js +7 -7
  45. package/dist/presentations/index.d.ts +1 -1
  46. package/dist/project/index.d.ts +7 -7
  47. package/dist/project/index.js +209 -209
  48. package/dist/project/project.event.js +1 -1
  49. package/dist/settings/index.d.ts +1 -1
  50. package/dist/ui/SaasDashboard.js +45 -45
  51. package/dist/ui/SaasProjectList.js +7 -7
  52. package/dist/ui/SaasSettingsPanel.js +12 -12
  53. package/dist/ui/hooks/index.d.ts +2 -2
  54. package/dist/ui/hooks/index.js +2 -2
  55. package/dist/ui/hooks/useProjectList.d.ts +5 -0
  56. package/dist/ui/hooks/useProjectList.js +1 -1
  57. package/dist/ui/hooks/useProjectMutations.d.ts +8 -0
  58. package/dist/ui/hooks/useProjectMutations.js +1 -1
  59. package/dist/ui/index.d.ts +4 -4
  60. package/dist/ui/index.js +483 -484
  61. package/dist/ui/modals/CreateProjectModal.js +10 -10
  62. package/dist/ui/modals/ProjectActionsModal.js +13 -13
  63. package/dist/ui/modals/index.js +23 -23
  64. package/dist/ui/renderers/index.d.ts +1 -1
  65. package/dist/ui/renderers/index.js +112 -112
  66. package/dist/ui/renderers/project-list.renderer.d.ts +1 -1
  67. package/dist/ui/renderers/project-list.renderer.js +7 -7
  68. package/package.json +14 -14
  69. package/src/billing/billing.entity.ts +132 -132
  70. package/src/billing/billing.enum.ts +9 -9
  71. package/src/billing/billing.event.ts +71 -71
  72. package/src/billing/billing.handler.ts +87 -87
  73. package/src/billing/billing.operations.ts +158 -158
  74. package/src/billing/billing.presentation.ts +45 -45
  75. package/src/billing/billing.schema.ts +76 -76
  76. package/src/billing/index.ts +43 -48
  77. package/src/dashboard/dashboard.presentation.ts +45 -45
  78. package/src/dashboard/index.ts +2 -2
  79. package/src/docs/saas-boilerplate.docblock.ts +43 -43
  80. package/src/example.ts +32 -32
  81. package/src/handlers/index.ts +9 -9
  82. package/src/handlers/saas.handlers.ts +250 -249
  83. package/src/index.ts +40 -41
  84. package/src/presentations/index.ts +18 -20
  85. package/src/project/index.ts +45 -50
  86. package/src/project/project.entity.ts +68 -68
  87. package/src/project/project.enum.ts +8 -8
  88. package/src/project/project.event.ts +79 -79
  89. package/src/project/project.handler.ts +103 -103
  90. package/src/project/project.operations.ts +236 -236
  91. package/src/project/project.presentation.ts +46 -46
  92. package/src/project/project.schema.ts +90 -90
  93. package/src/saas-boilerplate.feature.ts +100 -100
  94. package/src/seeders/index.ts +20 -20
  95. package/src/settings/index.ts +2 -3
  96. package/src/settings/settings.entity.ts +65 -65
  97. package/src/settings/settings.enum.ts +4 -4
  98. package/src/shared/mock-data.ts +92 -92
  99. package/src/shared/overlay-types.ts +23 -23
  100. package/src/tests/operations.test-spec.ts +96 -96
  101. package/src/ui/SaasDashboard.tsx +270 -270
  102. package/src/ui/SaasProjectList.tsx +90 -90
  103. package/src/ui/SaasSettingsPanel.tsx +84 -84
  104. package/src/ui/hooks/index.ts +3 -3
  105. package/src/ui/hooks/useProjectList.ts +69 -68
  106. package/src/ui/hooks/useProjectMutations.ts +144 -143
  107. package/src/ui/index.ts +8 -12
  108. package/src/ui/modals/CreateProjectModal.tsx +154 -154
  109. package/src/ui/modals/ProjectActionsModal.tsx +321 -321
  110. package/src/ui/overlays/demo-overlays.ts +49 -49
  111. package/src/ui/renderers/index.ts +5 -4
  112. package/src/ui/renderers/project-list.markdown.ts +204 -204
  113. package/src/ui/renderers/project-list.renderer.tsx +14 -13
  114. package/tsconfig.json +7 -8
  115. package/tsdown.config.js +7 -3
@@ -170,6 +170,79 @@ async function mockDeleteProjectHandler(input) {
170
170
  return { success: true };
171
171
  }
172
172
 
173
+ // src/project/project.entity.ts
174
+ import {
175
+ defineEntity,
176
+ defineEntityEnum,
177
+ field,
178
+ index
179
+ } from "@contractspec/lib.schema";
180
+ var ProjectStatusEnum = defineEntityEnum({
181
+ name: "ProjectStatus",
182
+ values: ["DRAFT", "ACTIVE", "ARCHIVED", "DELETED"],
183
+ schema: "saas_app",
184
+ description: "Status of a project."
185
+ });
186
+ var ProjectEntity = defineEntity({
187
+ name: "Project",
188
+ description: "A project belonging to an organization.",
189
+ schema: "saas_app",
190
+ map: "project",
191
+ fields: {
192
+ id: field.id({ description: "Unique project ID" }),
193
+ name: field.string({ description: "Project name" }),
194
+ description: field.string({
195
+ isOptional: true,
196
+ description: "Project description"
197
+ }),
198
+ slug: field.string({
199
+ isOptional: true,
200
+ description: "URL-friendly identifier"
201
+ }),
202
+ organizationId: field.foreignKey({ description: "Owning organization" }),
203
+ createdBy: field.foreignKey({
204
+ description: "User who created the project"
205
+ }),
206
+ status: field.enum("ProjectStatus", { default: "DRAFT" }),
207
+ isPublic: field.boolean({
208
+ default: false,
209
+ description: "Whether project is publicly visible"
210
+ }),
211
+ settings: field.json({
212
+ isOptional: true,
213
+ description: "Project-specific settings"
214
+ }),
215
+ tags: field.string({ isArray: true, description: "Project tags" }),
216
+ metadata: field.json({ isOptional: true }),
217
+ createdAt: field.createdAt(),
218
+ updatedAt: field.updatedAt(),
219
+ archivedAt: field.dateTime({ isOptional: true })
220
+ },
221
+ indexes: [
222
+ index.on(["organizationId", "status"]),
223
+ index.on(["organizationId", "createdAt"]),
224
+ index.unique(["organizationId", "slug"])
225
+ ],
226
+ enums: [ProjectStatusEnum]
227
+ });
228
+ var ProjectMemberEntity = defineEntity({
229
+ name: "ProjectMember",
230
+ description: "User access to a specific project.",
231
+ schema: "saas_app",
232
+ map: "project_member",
233
+ fields: {
234
+ id: field.id(),
235
+ projectId: field.foreignKey(),
236
+ userId: field.foreignKey(),
237
+ role: field.string({
238
+ description: "Role in project (owner, editor, viewer)"
239
+ }),
240
+ addedBy: field.string({ isOptional: true }),
241
+ createdAt: field.createdAt()
242
+ },
243
+ indexes: [index.unique(["projectId", "userId"])]
244
+ });
245
+
173
246
  // src/project/project.enum.ts
174
247
  import { defineEnum } from "@contractspec/lib.schema";
175
248
  var ProjectStatusSchemaEnum = defineEnum("ProjectStatus", [
@@ -185,112 +258,210 @@ var ProjectStatusFilterEnum = defineEnum("ProjectStatusFilter", [
185
258
  "all"
186
259
  ]);
187
260
 
188
- // src/project/project.schema.ts
261
+ // src/project/project.event.ts
262
+ import { defineEvent } from "@contractspec/lib.contracts-spec";
189
263
  import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
190
- var ProjectModel = defineSchemaModel({
191
- name: "Project",
192
- description: "A project within an organization",
264
+ var ProjectCreatedPayload = defineSchemaModel({
265
+ name: "ProjectCreatedPayload",
266
+ description: "Payload when a project is created",
193
267
  fields: {
194
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
268
+ projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
195
269
  name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
196
- description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
197
- slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
198
270
  organizationId: {
199
271
  type: ScalarTypeEnum.String_unsecure(),
200
272
  isOptional: false
201
273
  },
202
274
  createdBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
203
- status: { type: ProjectStatusSchemaEnum, isOptional: false },
204
- isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: false },
205
- tags: {
275
+ createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
276
+ }
277
+ });
278
+ var ProjectUpdatedPayload = defineSchemaModel({
279
+ name: "ProjectUpdatedPayload",
280
+ description: "Payload when a project is updated",
281
+ fields: {
282
+ projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
283
+ updatedFields: {
206
284
  type: ScalarTypeEnum.String_unsecure(),
207
285
  isArray: true,
208
286
  isOptional: false
209
287
  },
210
- createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },
288
+ updatedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
211
289
  updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
212
290
  }
213
291
  });
214
- var CreateProjectInputModel = defineSchemaModel({
292
+ var ProjectDeletedPayload = defineSchemaModel({
293
+ name: "ProjectDeletedPayload",
294
+ description: "Payload when a project is deleted",
295
+ fields: {
296
+ projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
297
+ organizationId: {
298
+ type: ScalarTypeEnum.String_unsecure(),
299
+ isOptional: false
300
+ },
301
+ deletedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
302
+ deletedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
303
+ }
304
+ });
305
+ var ProjectArchivedPayload = defineSchemaModel({
306
+ name: "ProjectArchivedPayload",
307
+ description: "Payload when a project is archived",
308
+ fields: {
309
+ projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
310
+ archivedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
311
+ archivedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
312
+ }
313
+ });
314
+ var ProjectCreatedEvent = defineEvent({
315
+ meta: {
316
+ key: "project.created",
317
+ version: "1.0.0",
318
+ description: "A new project has been created.",
319
+ stability: "stable",
320
+ owners: ["@saas-team"],
321
+ tags: ["project", "created"]
322
+ },
323
+ payload: ProjectCreatedPayload
324
+ });
325
+ var ProjectUpdatedEvent = defineEvent({
326
+ meta: {
327
+ key: "project.updated",
328
+ version: "1.0.0",
329
+ description: "A project has been updated.",
330
+ stability: "stable",
331
+ owners: ["@saas-team"],
332
+ tags: ["project", "updated"]
333
+ },
334
+ payload: ProjectUpdatedPayload
335
+ });
336
+ var ProjectDeletedEvent = defineEvent({
337
+ meta: {
338
+ key: "project.deleted",
339
+ version: "1.0.0",
340
+ description: "A project has been deleted.",
341
+ stability: "stable",
342
+ owners: ["@saas-team"],
343
+ tags: ["project", "deleted"]
344
+ },
345
+ payload: ProjectDeletedPayload
346
+ });
347
+ var ProjectArchivedEvent = defineEvent({
348
+ meta: {
349
+ key: "project.archived",
350
+ version: "1.0.0",
351
+ description: "A project has been archived.",
352
+ stability: "stable",
353
+ owners: ["@saas-team"],
354
+ tags: ["project", "archived"]
355
+ },
356
+ payload: ProjectArchivedPayload
357
+ });
358
+
359
+ // src/project/project.schema.ts
360
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
361
+ var ProjectModel = defineSchemaModel2({
362
+ name: "Project",
363
+ description: "A project within an organization",
364
+ fields: {
365
+ id: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
366
+ name: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
367
+ description: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
368
+ slug: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
369
+ organizationId: {
370
+ type: ScalarTypeEnum2.String_unsecure(),
371
+ isOptional: false
372
+ },
373
+ createdBy: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
374
+ status: { type: ProjectStatusSchemaEnum, isOptional: false },
375
+ isPublic: { type: ScalarTypeEnum2.Boolean(), isOptional: false },
376
+ tags: {
377
+ type: ScalarTypeEnum2.String_unsecure(),
378
+ isArray: true,
379
+ isOptional: false
380
+ },
381
+ createdAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false },
382
+ updatedAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
383
+ }
384
+ });
385
+ var CreateProjectInputModel = defineSchemaModel2({
215
386
  name: "CreateProjectInput",
216
387
  description: "Input for creating a project",
217
388
  fields: {
218
- name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
219
- description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
220
- slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
221
- isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: true },
389
+ name: { type: ScalarTypeEnum2.NonEmptyString(), isOptional: false },
390
+ description: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
391
+ slug: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
392
+ isPublic: { type: ScalarTypeEnum2.Boolean(), isOptional: true },
222
393
  tags: {
223
- type: ScalarTypeEnum.String_unsecure(),
394
+ type: ScalarTypeEnum2.String_unsecure(),
224
395
  isArray: true,
225
396
  isOptional: true
226
397
  }
227
398
  }
228
399
  });
229
- var UpdateProjectInputModel = defineSchemaModel({
400
+ var UpdateProjectInputModel = defineSchemaModel2({
230
401
  name: "UpdateProjectInput",
231
402
  description: "Input for updating a project",
232
403
  fields: {
233
- projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
234
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
235
- description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
236
- slug: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
237
- isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: true },
404
+ projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
405
+ name: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
406
+ description: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
407
+ slug: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
408
+ isPublic: { type: ScalarTypeEnum2.Boolean(), isOptional: true },
238
409
  tags: {
239
- type: ScalarTypeEnum.String_unsecure(),
410
+ type: ScalarTypeEnum2.String_unsecure(),
240
411
  isArray: true,
241
412
  isOptional: true
242
413
  },
243
414
  status: { type: ProjectStatusSchemaEnum, isOptional: true }
244
415
  }
245
416
  });
246
- var GetProjectInputModel = defineSchemaModel({
417
+ var GetProjectInputModel = defineSchemaModel2({
247
418
  name: "GetProjectInput",
248
419
  fields: {
249
- projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
420
+ projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
250
421
  }
251
422
  });
252
- var DeleteProjectInputModel = defineSchemaModel({
423
+ var DeleteProjectInputModel = defineSchemaModel2({
253
424
  name: "DeleteProjectInput",
254
425
  fields: {
255
- projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
426
+ projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
256
427
  }
257
428
  });
258
- var DeleteProjectOutputModel = defineSchemaModel({
429
+ var DeleteProjectOutputModel = defineSchemaModel2({
259
430
  name: "DeleteProjectOutput",
260
431
  fields: {
261
- success: { type: ScalarTypeEnum.Boolean(), isOptional: false }
432
+ success: { type: ScalarTypeEnum2.Boolean(), isOptional: false }
262
433
  }
263
434
  });
264
- var ProjectDeletedPayloadModel = defineSchemaModel({
435
+ var ProjectDeletedPayloadModel = defineSchemaModel2({
265
436
  name: "ProjectDeletedPayload",
266
437
  fields: {
267
- projectId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
438
+ projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
268
439
  }
269
440
  });
270
- var ListProjectsInputModel = defineSchemaModel({
441
+ var ListProjectsInputModel = defineSchemaModel2({
271
442
  name: "ListProjectsInput",
272
443
  description: "Input for listing projects",
273
444
  fields: {
274
445
  status: { type: ProjectStatusFilterEnum, isOptional: true },
275
- search: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
446
+ search: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
276
447
  limit: {
277
- type: ScalarTypeEnum.Int_unsecure(),
448
+ type: ScalarTypeEnum2.Int_unsecure(),
278
449
  isOptional: true,
279
450
  defaultValue: 20
280
451
  },
281
452
  offset: {
282
- type: ScalarTypeEnum.Int_unsecure(),
453
+ type: ScalarTypeEnum2.Int_unsecure(),
283
454
  isOptional: true,
284
455
  defaultValue: 0
285
456
  }
286
457
  }
287
458
  });
288
- var ListProjectsOutputModel = defineSchemaModel({
459
+ var ListProjectsOutputModel = defineSchemaModel2({
289
460
  name: "ListProjectsOutput",
290
461
  description: "Output for listing projects",
291
462
  fields: {
292
463
  projects: { type: ProjectModel, isArray: true, isOptional: false },
293
- total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false }
464
+ total: { type: ScalarTypeEnum2.Int_unsecure(), isOptional: false }
294
465
  }
295
466
  });
296
467
 
@@ -536,177 +707,6 @@ var ListProjectsContract = defineQuery({
536
707
  }
537
708
  });
538
709
 
539
- // src/project/project.event.ts
540
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
541
- import { defineEvent } from "@contractspec/lib.contracts-spec";
542
- var ProjectCreatedPayload = defineSchemaModel2({
543
- name: "ProjectCreatedPayload",
544
- description: "Payload when a project is created",
545
- fields: {
546
- projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
547
- name: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
548
- organizationId: {
549
- type: ScalarTypeEnum2.String_unsecure(),
550
- isOptional: false
551
- },
552
- createdBy: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
553
- createdAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
554
- }
555
- });
556
- var ProjectUpdatedPayload = defineSchemaModel2({
557
- name: "ProjectUpdatedPayload",
558
- description: "Payload when a project is updated",
559
- fields: {
560
- projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
561
- updatedFields: {
562
- type: ScalarTypeEnum2.String_unsecure(),
563
- isArray: true,
564
- isOptional: false
565
- },
566
- updatedBy: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
567
- updatedAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
568
- }
569
- });
570
- var ProjectDeletedPayload = defineSchemaModel2({
571
- name: "ProjectDeletedPayload",
572
- description: "Payload when a project is deleted",
573
- fields: {
574
- projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
575
- organizationId: {
576
- type: ScalarTypeEnum2.String_unsecure(),
577
- isOptional: false
578
- },
579
- deletedBy: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
580
- deletedAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
581
- }
582
- });
583
- var ProjectArchivedPayload = defineSchemaModel2({
584
- name: "ProjectArchivedPayload",
585
- description: "Payload when a project is archived",
586
- fields: {
587
- projectId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
588
- archivedBy: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
589
- archivedAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
590
- }
591
- });
592
- var ProjectCreatedEvent = defineEvent({
593
- meta: {
594
- key: "project.created",
595
- version: "1.0.0",
596
- description: "A new project has been created.",
597
- stability: "stable",
598
- owners: ["@saas-team"],
599
- tags: ["project", "created"]
600
- },
601
- payload: ProjectCreatedPayload
602
- });
603
- var ProjectUpdatedEvent = defineEvent({
604
- meta: {
605
- key: "project.updated",
606
- version: "1.0.0",
607
- description: "A project has been updated.",
608
- stability: "stable",
609
- owners: ["@saas-team"],
610
- tags: ["project", "updated"]
611
- },
612
- payload: ProjectUpdatedPayload
613
- });
614
- var ProjectDeletedEvent = defineEvent({
615
- meta: {
616
- key: "project.deleted",
617
- version: "1.0.0",
618
- description: "A project has been deleted.",
619
- stability: "stable",
620
- owners: ["@saas-team"],
621
- tags: ["project", "deleted"]
622
- },
623
- payload: ProjectDeletedPayload
624
- });
625
- var ProjectArchivedEvent = defineEvent({
626
- meta: {
627
- key: "project.archived",
628
- version: "1.0.0",
629
- description: "A project has been archived.",
630
- stability: "stable",
631
- owners: ["@saas-team"],
632
- tags: ["project", "archived"]
633
- },
634
- payload: ProjectArchivedPayload
635
- });
636
-
637
- // src/project/project.entity.ts
638
- import {
639
- defineEntity,
640
- defineEntityEnum,
641
- field,
642
- index
643
- } from "@contractspec/lib.schema";
644
- var ProjectStatusEnum = defineEntityEnum({
645
- name: "ProjectStatus",
646
- values: ["DRAFT", "ACTIVE", "ARCHIVED", "DELETED"],
647
- schema: "saas_app",
648
- description: "Status of a project."
649
- });
650
- var ProjectEntity = defineEntity({
651
- name: "Project",
652
- description: "A project belonging to an organization.",
653
- schema: "saas_app",
654
- map: "project",
655
- fields: {
656
- id: field.id({ description: "Unique project ID" }),
657
- name: field.string({ description: "Project name" }),
658
- description: field.string({
659
- isOptional: true,
660
- description: "Project description"
661
- }),
662
- slug: field.string({
663
- isOptional: true,
664
- description: "URL-friendly identifier"
665
- }),
666
- organizationId: field.foreignKey({ description: "Owning organization" }),
667
- createdBy: field.foreignKey({
668
- description: "User who created the project"
669
- }),
670
- status: field.enum("ProjectStatus", { default: "DRAFT" }),
671
- isPublic: field.boolean({
672
- default: false,
673
- description: "Whether project is publicly visible"
674
- }),
675
- settings: field.json({
676
- isOptional: true,
677
- description: "Project-specific settings"
678
- }),
679
- tags: field.string({ isArray: true, description: "Project tags" }),
680
- metadata: field.json({ isOptional: true }),
681
- createdAt: field.createdAt(),
682
- updatedAt: field.updatedAt(),
683
- archivedAt: field.dateTime({ isOptional: true })
684
- },
685
- indexes: [
686
- index.on(["organizationId", "status"]),
687
- index.on(["organizationId", "createdAt"]),
688
- index.unique(["organizationId", "slug"])
689
- ],
690
- enums: [ProjectStatusEnum]
691
- });
692
- var ProjectMemberEntity = defineEntity({
693
- name: "ProjectMember",
694
- description: "User access to a specific project.",
695
- schema: "saas_app",
696
- map: "project_member",
697
- fields: {
698
- id: field.id(),
699
- projectId: field.foreignKey(),
700
- userId: field.foreignKey(),
701
- role: field.string({
702
- description: "Role in project (owner, editor, viewer)"
703
- }),
704
- addedBy: field.string({ isOptional: true }),
705
- createdAt: field.createdAt()
706
- },
707
- indexes: [index.unique(["projectId", "userId"])]
708
- });
709
-
710
710
  // src/project/project.presentation.ts
711
711
  import {
712
712
  definePresentation,
@@ -1,6 +1,6 @@
1
1
  // src/project/project.event.ts
2
- import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
3
2
  import { defineEvent } from "@contractspec/lib.contracts-spec";
3
+ import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
4
4
  var ProjectCreatedPayload = defineSchemaModel({
5
5
  name: "ProjectCreatedPayload",
6
6
  description: "Payload when a project is created",