@contractspec/example.service-business-os 3.7.17 → 3.7.18

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 (82) hide show
  1. package/dist/browser/client/client.operations.js +1 -72
  2. package/dist/browser/client/client.schema.js +1 -31
  3. package/dist/browser/client/index.js +1 -74
  4. package/dist/browser/docs/index.js +5 -49
  5. package/dist/browser/docs/service-business-os.docblock.js +5 -49
  6. package/dist/browser/entities/index.js +1 -246
  7. package/dist/browser/events.js +1 -135
  8. package/dist/browser/example.js +1 -39
  9. package/dist/browser/handlers/index.js +1 -5
  10. package/dist/browser/index.js +1 -766
  11. package/dist/browser/invoice/index.js +1 -77
  12. package/dist/browser/invoice/invoice.operations.js +1 -75
  13. package/dist/browser/invoice/invoice.schema.js +1 -34
  14. package/dist/browser/job/index.js +1 -175
  15. package/dist/browser/job/job.operations.js +1 -172
  16. package/dist/browser/job/job.schema.js +1 -41
  17. package/dist/browser/operations/index.js +1 -506
  18. package/dist/browser/payment/index.js +1 -69
  19. package/dist/browser/payment/payment.operations.js +1 -67
  20. package/dist/browser/payment/payment.schema.js +1 -30
  21. package/dist/browser/presentations/index.js +1 -13
  22. package/dist/browser/presentations.js +1 -175
  23. package/dist/browser/quote/index.js +1 -122
  24. package/dist/browser/quote/quote.operations.js +1 -119
  25. package/dist/browser/quote/quote.schema.js +1 -45
  26. package/dist/browser/service-business-os.capability.js +1 -31
  27. package/dist/browser/service.feature.js +1 -85
  28. package/dist/client/client.operations.js +1 -72
  29. package/dist/client/client.schema.js +1 -31
  30. package/dist/client/index.js +1 -74
  31. package/dist/docs/index.js +5 -49
  32. package/dist/docs/service-business-os.docblock.js +5 -49
  33. package/dist/entities/index.js +1 -246
  34. package/dist/events.js +1 -135
  35. package/dist/example.js +1 -39
  36. package/dist/handlers/index.js +1 -5
  37. package/dist/index.js +1 -766
  38. package/dist/invoice/index.js +1 -77
  39. package/dist/invoice/invoice.operations.js +1 -75
  40. package/dist/invoice/invoice.schema.js +1 -34
  41. package/dist/job/index.js +1 -175
  42. package/dist/job/job.operations.js +1 -172
  43. package/dist/job/job.schema.js +1 -41
  44. package/dist/node/client/client.operations.js +1 -72
  45. package/dist/node/client/client.schema.js +1 -31
  46. package/dist/node/client/index.js +1 -74
  47. package/dist/node/docs/index.js +5 -49
  48. package/dist/node/docs/service-business-os.docblock.js +5 -49
  49. package/dist/node/entities/index.js +1 -246
  50. package/dist/node/events.js +1 -135
  51. package/dist/node/example.js +1 -39
  52. package/dist/node/handlers/index.js +1 -5
  53. package/dist/node/index.js +1 -766
  54. package/dist/node/invoice/index.js +1 -77
  55. package/dist/node/invoice/invoice.operations.js +1 -75
  56. package/dist/node/invoice/invoice.schema.js +1 -34
  57. package/dist/node/job/index.js +1 -175
  58. package/dist/node/job/job.operations.js +1 -172
  59. package/dist/node/job/job.schema.js +1 -41
  60. package/dist/node/operations/index.js +1 -506
  61. package/dist/node/payment/index.js +1 -69
  62. package/dist/node/payment/payment.operations.js +1 -67
  63. package/dist/node/payment/payment.schema.js +1 -30
  64. package/dist/node/presentations/index.js +1 -13
  65. package/dist/node/presentations.js +1 -175
  66. package/dist/node/quote/index.js +1 -122
  67. package/dist/node/quote/quote.operations.js +1 -119
  68. package/dist/node/quote/quote.schema.js +1 -45
  69. package/dist/node/service-business-os.capability.js +1 -31
  70. package/dist/node/service.feature.js +1 -85
  71. package/dist/operations/index.js +1 -506
  72. package/dist/payment/index.js +1 -69
  73. package/dist/payment/payment.operations.js +1 -67
  74. package/dist/payment/payment.schema.js +1 -30
  75. package/dist/presentations/index.js +1 -13
  76. package/dist/presentations.js +1 -175
  77. package/dist/quote/index.js +1 -122
  78. package/dist/quote/quote.operations.js +1 -119
  79. package/dist/quote/quote.schema.js +1 -45
  80. package/dist/service-business-os.capability.js +1 -31
  81. package/dist/service.feature.js +1 -85
  82. package/package.json +5 -5
@@ -1,73 +1,2 @@
1
1
  // @bun
2
- // src/client/client.schema.ts
3
- import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
4
- var ClientModel = defineSchemaModel({
5
- name: "Client",
6
- description: "Client profile",
7
- fields: {
8
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
9
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
10
- contactEmail: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
11
- phone: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
12
- orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
13
- ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
14
- createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
15
- }
16
- });
17
- var CreateClientInputModel = defineSchemaModel({
18
- name: "CreateClientInput",
19
- description: "Input for creating a client",
20
- fields: {
21
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
22
- contactEmail: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
23
- phone: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
24
- orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
25
- ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
26
- metadata: { type: ScalarTypeEnum.JSON(), isOptional: true }
27
- }
28
- });
29
-
30
- // src/client/client.operations.ts
31
- import { defineCommand } from "@contractspec/lib.contracts-spec";
32
- var OWNERS = ["@examples.service-business-os"];
33
- var CreateClientContract = defineCommand({
34
- meta: {
35
- key: "service.client.create",
36
- version: "1.0.0",
37
- stability: "stable",
38
- owners: [...OWNERS],
39
- tags: ["service-business-os", "client", "create"],
40
- description: "Create a new client.",
41
- goal: "Onboard clients.",
42
- context: "CRM."
43
- },
44
- io: {
45
- input: CreateClientInputModel,
46
- output: ClientModel
47
- },
48
- policy: { auth: "user" },
49
- acceptance: {
50
- scenarios: [
51
- {
52
- key: "create-client-happy-path",
53
- given: ["User is authenticated"],
54
- when: ["User creates a new client"],
55
- then: ["Client is created"]
56
- }
57
- ],
58
- examples: [
59
- {
60
- key: "create-basic",
61
- input: {
62
- name: "Acme Corp",
63
- email: "contact@acme.com",
64
- phone: "555-0123"
65
- },
66
- output: { id: "client-123", name: "Acme Corp" }
67
- }
68
- ]
69
- }
70
- });
71
- export {
72
- CreateClientContract
73
- };
2
+ import{defineSchemaModel as k,ScalarTypeEnum as j}from"@contractspec/lib.schema";var q=k({name:"Client",description:"Client profile",fields:{id:{type:j.String_unsecure(),isOptional:!1},name:{type:j.String_unsecure(),isOptional:!1},contactEmail:{type:j.String_unsecure(),isOptional:!0},phone:{type:j.String_unsecure(),isOptional:!0},orgId:{type:j.String_unsecure(),isOptional:!1},ownerId:{type:j.String_unsecure(),isOptional:!1},createdAt:{type:j.DateTime(),isOptional:!1}}}),v=k({name:"CreateClientInput",description:"Input for creating a client",fields:{name:{type:j.String_unsecure(),isOptional:!1},contactEmail:{type:j.String_unsecure(),isOptional:!0},phone:{type:j.String_unsecure(),isOptional:!0},orgId:{type:j.String_unsecure(),isOptional:!1},ownerId:{type:j.String_unsecure(),isOptional:!1},metadata:{type:j.JSON(),isOptional:!0}}});import{defineCommand as w}from"@contractspec/lib.contracts-spec";var x=["@examples.service-business-os"],F=w({meta:{key:"service.client.create",version:"1.0.0",stability:"stable",owners:[...x],tags:["service-business-os","client","create"],description:"Create a new client.",goal:"Onboard clients.",context:"CRM."},io:{input:v,output:q},policy:{auth:"user"},acceptance:{scenarios:[{key:"create-client-happy-path",given:["User is authenticated"],when:["User creates a new client"],then:["Client is created"]}],examples:[{key:"create-basic",input:{name:"Acme Corp",email:"contact@acme.com",phone:"555-0123"},output:{id:"client-123",name:"Acme Corp"}}]}});export{F as CreateClientContract};
@@ -1,32 +1,2 @@
1
1
  // @bun
2
- // src/client/client.schema.ts
3
- import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
4
- var ClientModel = defineSchemaModel({
5
- name: "Client",
6
- description: "Client profile",
7
- fields: {
8
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
9
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
10
- contactEmail: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
11
- phone: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
12
- orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
13
- ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
14
- createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
15
- }
16
- });
17
- var CreateClientInputModel = defineSchemaModel({
18
- name: "CreateClientInput",
19
- description: "Input for creating a client",
20
- fields: {
21
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
22
- contactEmail: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
23
- phone: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
24
- orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
25
- ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
26
- metadata: { type: ScalarTypeEnum.JSON(), isOptional: true }
27
- }
28
- });
29
- export {
30
- CreateClientInputModel,
31
- ClientModel
32
- };
2
+ import{defineSchemaModel as k,ScalarTypeEnum as j}from"@contractspec/lib.schema";var v=k({name:"Client",description:"Client profile",fields:{id:{type:j.String_unsecure(),isOptional:!1},name:{type:j.String_unsecure(),isOptional:!1},contactEmail:{type:j.String_unsecure(),isOptional:!0},phone:{type:j.String_unsecure(),isOptional:!0},orgId:{type:j.String_unsecure(),isOptional:!1},ownerId:{type:j.String_unsecure(),isOptional:!1},createdAt:{type:j.DateTime(),isOptional:!1}}}),w=k({name:"CreateClientInput",description:"Input for creating a client",fields:{name:{type:j.String_unsecure(),isOptional:!1},contactEmail:{type:j.String_unsecure(),isOptional:!0},phone:{type:j.String_unsecure(),isOptional:!0},orgId:{type:j.String_unsecure(),isOptional:!1},ownerId:{type:j.String_unsecure(),isOptional:!1},metadata:{type:j.JSON(),isOptional:!0}}});export{w as CreateClientInputModel,v as ClientModel};
@@ -1,75 +1,2 @@
1
1
  // @bun
2
- // src/client/client.schema.ts
3
- import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
4
- var ClientModel = defineSchemaModel({
5
- name: "Client",
6
- description: "Client profile",
7
- fields: {
8
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
9
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
10
- contactEmail: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
11
- phone: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
12
- orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
13
- ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
14
- createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
15
- }
16
- });
17
- var CreateClientInputModel = defineSchemaModel({
18
- name: "CreateClientInput",
19
- description: "Input for creating a client",
20
- fields: {
21
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
22
- contactEmail: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
23
- phone: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
24
- orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
25
- ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
26
- metadata: { type: ScalarTypeEnum.JSON(), isOptional: true }
27
- }
28
- });
29
-
30
- // src/client/client.operations.ts
31
- import { defineCommand } from "@contractspec/lib.contracts-spec";
32
- var OWNERS = ["@examples.service-business-os"];
33
- var CreateClientContract = defineCommand({
34
- meta: {
35
- key: "service.client.create",
36
- version: "1.0.0",
37
- stability: "stable",
38
- owners: [...OWNERS],
39
- tags: ["service-business-os", "client", "create"],
40
- description: "Create a new client.",
41
- goal: "Onboard clients.",
42
- context: "CRM."
43
- },
44
- io: {
45
- input: CreateClientInputModel,
46
- output: ClientModel
47
- },
48
- policy: { auth: "user" },
49
- acceptance: {
50
- scenarios: [
51
- {
52
- key: "create-client-happy-path",
53
- given: ["User is authenticated"],
54
- when: ["User creates a new client"],
55
- then: ["Client is created"]
56
- }
57
- ],
58
- examples: [
59
- {
60
- key: "create-basic",
61
- input: {
62
- name: "Acme Corp",
63
- email: "contact@acme.com",
64
- phone: "555-0123"
65
- },
66
- output: { id: "client-123", name: "Acme Corp" }
67
- }
68
- ]
69
- }
70
- });
71
- export {
72
- CreateClientInputModel,
73
- CreateClientContract,
74
- ClientModel
75
- };
2
+ import{defineSchemaModel as j,ScalarTypeEnum as C}from"@contractspec/lib.schema";var x=j({name:"Client",description:"Client profile",fields:{id:{type:C.String_unsecure(),isOptional:!1},name:{type:C.String_unsecure(),isOptional:!1},contactEmail:{type:C.String_unsecure(),isOptional:!0},phone:{type:C.String_unsecure(),isOptional:!0},orgId:{type:C.String_unsecure(),isOptional:!1},ownerId:{type:C.String_unsecure(),isOptional:!1},createdAt:{type:C.DateTime(),isOptional:!1}}}),g=j({name:"CreateClientInput",description:"Input for creating a client",fields:{name:{type:C.String_unsecure(),isOptional:!1},contactEmail:{type:C.String_unsecure(),isOptional:!0},phone:{type:C.String_unsecure(),isOptional:!0},orgId:{type:C.String_unsecure(),isOptional:!1},ownerId:{type:C.String_unsecure(),isOptional:!1},metadata:{type:C.JSON(),isOptional:!0}}});import{defineCommand as k}from"@contractspec/lib.contracts-spec";var q=["@examples.service-business-os"],v=k({meta:{key:"service.client.create",version:"1.0.0",stability:"stable",owners:[...q],tags:["service-business-os","client","create"],description:"Create a new client.",goal:"Onboard clients.",context:"CRM."},io:{input:g,output:x},policy:{auth:"user"},acceptance:{scenarios:[{key:"create-client-happy-path",given:["User is authenticated"],when:["User creates a new client"],then:["Client is created"]}],examples:[{key:"create-basic",input:{name:"Acme Corp",email:"contact@acme.com",phone:"555-0123"},output:{id:"client-123",name:"Acme Corp"}}]}});export{g as CreateClientInputModel,v as CreateClientContract,x as ClientModel};
@@ -1,16 +1,5 @@
1
1
  // @bun
2
- // src/docs/service-business-os.docblock.ts
3
- import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
4
- var serviceBusinessDocBlocks = [
5
- {
6
- id: "docs.examples.service-business-os",
7
- title: "Service Business OS",
8
- summary: "Field/service business flow from client intake to quote, job scheduling, invoicing, and payments with notifications and audit trail.",
9
- kind: "reference",
10
- visibility: "public",
11
- route: "/docs/examples/service-business-os",
12
- tags: ["services", "quotes", "jobs", "invoices", "payments"],
13
- body: `## Flows
2
+ import{registerDocBlocks as m}from"@contractspec/lib.contracts-spec/docs";var f=[{id:"docs.examples.service-business-os",title:"Service Business OS",summary:"Field/service business flow from client intake to quote, job scheduling, invoicing, and payments with notifications and audit trail.",kind:"reference",visibility:"public",route:"/docs/examples/service-business-os",tags:["services","quotes","jobs","invoices","payments"],body:`## Flows
14
3
 
15
4
  1) **Client intake** \u2192 create client, capture contact + owner.
16
5
  2) **Quote** \u2192 draft, send, accept/reject (events + notifications).
@@ -27,17 +16,7 @@ var serviceBusinessDocBlocks = [
27
16
 
28
17
  ## Presentations
29
18
  - Dashboard, client list, quote list/detail, job board, invoice list, payment list (React + Markdown targets).
30
- `
31
- },
32
- {
33
- id: "docs.examples.service-business-os.goal",
34
- title: "Service Business OS \u2014 Goal",
35
- summary: "Why this field-service OS exists and outcomes it targets.",
36
- kind: "goal",
37
- visibility: "public",
38
- route: "/docs/examples/service-business-os/goal",
39
- tags: ["services", "goal"],
40
- body: `## Why it matters
19
+ `},{id:"docs.examples.service-business-os.goal",title:"Service Business OS \u2014 Goal",summary:"Why this field-service OS exists and outcomes it targets.",kind:"goal",visibility:"public",route:"/docs/examples/service-business-os/goal",tags:["services","goal"],body:`## Why it matters
41
20
  - Provides a regenerable, end-to-end service lifecycle (client \u2192 quote \u2192 job \u2192 invoice \u2192 payment).
42
21
  - Keeps pricing, scheduling, invoicing, and payments consistent across surfaces.
43
22
 
@@ -47,17 +26,7 @@ var serviceBusinessDocBlocks = [
47
26
 
48
27
  ## Success criteria
49
28
  - Spec changes regenerate UI/API/events cleanly across lifecycle steps.
50
- - Audit/Notifications/Jobs remain wired for every mutation.`
51
- },
52
- {
53
- id: "docs.examples.service-business-os.usage",
54
- title: "Service Business OS \u2014 Usage",
55
- summary: "How to operate, extend, and regenerate the service OS safely.",
56
- kind: "usage",
57
- visibility: "public",
58
- route: "/docs/examples/service-business-os/usage",
59
- tags: ["services", "usage"],
60
- body: `## Setup
29
+ - Audit/Notifications/Jobs remain wired for every mutation.`},{id:"docs.examples.service-business-os.usage",title:"Service Business OS \u2014 Usage",summary:"How to operate, extend, and regenerate the service OS safely.",kind:"usage",visibility:"public",route:"/docs/examples/service-business-os/usage",tags:["services","usage"],body:`## Setup
61
30
  1) Seed (if provided) or create client \u2192 quote \u2192 job \u2192 invoice \u2192 payment via UI.
62
31
  2) Configure Files for attachments and Notifications for quote/job/invoice events.
63
32
 
@@ -69,17 +38,7 @@ var serviceBusinessDocBlocks = [
69
38
  ## Guardrails
70
39
  - Emit events for quote accepted/rejected, job scheduled/completed, invoice overdue, payment recorded.
71
40
  - Keep pricing/tax rules explicit in spec; avoid implicit handler math.
72
- - Use Audit Trail for lifecycle mutations; schedule reminders via Jobs.`
73
- },
74
- {
75
- id: "docs.examples.service-business-os.constraints",
76
- title: "Service Business OS \u2014 Constraints & Safety",
77
- summary: "Internal guardrails for quotes/jobs/invoices/payments and regeneration safety.",
78
- kind: "reference",
79
- visibility: "internal",
80
- route: "/docs/examples/service-business-os/constraints",
81
- tags: ["services", "constraints", "internal"],
82
- body: `## Constraints
41
+ - Use Audit Trail for lifecycle mutations; schedule reminders via Jobs.`},{id:"docs.examples.service-business-os.constraints",title:"Service Business OS \u2014 Constraints & Safety",summary:"Internal guardrails for quotes/jobs/invoices/payments and regeneration safety.",kind:"reference",visibility:"internal",route:"/docs/examples/service-business-os/constraints",tags:["services","constraints","internal"],body:`## Constraints
83
42
  - Commission/tax/payment rules must be explicit in spec; no hidden handler math.
84
43
  - Events to emit: quote.sent/accepted/rejected, job.scheduled/completed, invoice.issued/overdue, payment.recorded.
85
44
  - Regeneration must not alter payment semantics without reviewed spec changes.
@@ -91,7 +50,4 @@ var serviceBusinessDocBlocks = [
91
50
  ## Verification
92
51
  - Add fixtures for quote/job/invoice state transitions.
93
52
  - Ensure Notifications/Audit/Jobs wiring persists after regeneration.
94
- - Use Feature Flags to trial new payment rules/reminder cadences; default safe/off.`
95
- }
96
- ];
97
- registerDocBlocks(serviceBusinessDocBlocks);
53
+ - Use Feature Flags to trial new payment rules/reminder cadences; default safe/off.`}];m(f);
@@ -1,16 +1,5 @@
1
1
  // @bun
2
- // src/docs/service-business-os.docblock.ts
3
- import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
4
- var serviceBusinessDocBlocks = [
5
- {
6
- id: "docs.examples.service-business-os",
7
- title: "Service Business OS",
8
- summary: "Field/service business flow from client intake to quote, job scheduling, invoicing, and payments with notifications and audit trail.",
9
- kind: "reference",
10
- visibility: "public",
11
- route: "/docs/examples/service-business-os",
12
- tags: ["services", "quotes", "jobs", "invoices", "payments"],
13
- body: `## Flows
2
+ import{registerDocBlocks as f}from"@contractspec/lib.contracts-spec/docs";var h=[{id:"docs.examples.service-business-os",title:"Service Business OS",summary:"Field/service business flow from client intake to quote, job scheduling, invoicing, and payments with notifications and audit trail.",kind:"reference",visibility:"public",route:"/docs/examples/service-business-os",tags:["services","quotes","jobs","invoices","payments"],body:`## Flows
14
3
 
15
4
  1) **Client intake** \u2192 create client, capture contact + owner.
16
5
  2) **Quote** \u2192 draft, send, accept/reject (events + notifications).
@@ -27,17 +16,7 @@ var serviceBusinessDocBlocks = [
27
16
 
28
17
  ## Presentations
29
18
  - Dashboard, client list, quote list/detail, job board, invoice list, payment list (React + Markdown targets).
30
- `
31
- },
32
- {
33
- id: "docs.examples.service-business-os.goal",
34
- title: "Service Business OS \u2014 Goal",
35
- summary: "Why this field-service OS exists and outcomes it targets.",
36
- kind: "goal",
37
- visibility: "public",
38
- route: "/docs/examples/service-business-os/goal",
39
- tags: ["services", "goal"],
40
- body: `## Why it matters
19
+ `},{id:"docs.examples.service-business-os.goal",title:"Service Business OS \u2014 Goal",summary:"Why this field-service OS exists and outcomes it targets.",kind:"goal",visibility:"public",route:"/docs/examples/service-business-os/goal",tags:["services","goal"],body:`## Why it matters
41
20
  - Provides a regenerable, end-to-end service lifecycle (client \u2192 quote \u2192 job \u2192 invoice \u2192 payment).
42
21
  - Keeps pricing, scheduling, invoicing, and payments consistent across surfaces.
43
22
 
@@ -47,17 +26,7 @@ var serviceBusinessDocBlocks = [
47
26
 
48
27
  ## Success criteria
49
28
  - Spec changes regenerate UI/API/events cleanly across lifecycle steps.
50
- - Audit/Notifications/Jobs remain wired for every mutation.`
51
- },
52
- {
53
- id: "docs.examples.service-business-os.usage",
54
- title: "Service Business OS \u2014 Usage",
55
- summary: "How to operate, extend, and regenerate the service OS safely.",
56
- kind: "usage",
57
- visibility: "public",
58
- route: "/docs/examples/service-business-os/usage",
59
- tags: ["services", "usage"],
60
- body: `## Setup
29
+ - Audit/Notifications/Jobs remain wired for every mutation.`},{id:"docs.examples.service-business-os.usage",title:"Service Business OS \u2014 Usage",summary:"How to operate, extend, and regenerate the service OS safely.",kind:"usage",visibility:"public",route:"/docs/examples/service-business-os/usage",tags:["services","usage"],body:`## Setup
61
30
  1) Seed (if provided) or create client \u2192 quote \u2192 job \u2192 invoice \u2192 payment via UI.
62
31
  2) Configure Files for attachments and Notifications for quote/job/invoice events.
63
32
 
@@ -69,17 +38,7 @@ var serviceBusinessDocBlocks = [
69
38
  ## Guardrails
70
39
  - Emit events for quote accepted/rejected, job scheduled/completed, invoice overdue, payment recorded.
71
40
  - Keep pricing/tax rules explicit in spec; avoid implicit handler math.
72
- - Use Audit Trail for lifecycle mutations; schedule reminders via Jobs.`
73
- },
74
- {
75
- id: "docs.examples.service-business-os.constraints",
76
- title: "Service Business OS \u2014 Constraints & Safety",
77
- summary: "Internal guardrails for quotes/jobs/invoices/payments and regeneration safety.",
78
- kind: "reference",
79
- visibility: "internal",
80
- route: "/docs/examples/service-business-os/constraints",
81
- tags: ["services", "constraints", "internal"],
82
- body: `## Constraints
41
+ - Use Audit Trail for lifecycle mutations; schedule reminders via Jobs.`},{id:"docs.examples.service-business-os.constraints",title:"Service Business OS \u2014 Constraints & Safety",summary:"Internal guardrails for quotes/jobs/invoices/payments and regeneration safety.",kind:"reference",visibility:"internal",route:"/docs/examples/service-business-os/constraints",tags:["services","constraints","internal"],body:`## Constraints
83
42
  - Commission/tax/payment rules must be explicit in spec; no hidden handler math.
84
43
  - Events to emit: quote.sent/accepted/rejected, job.scheduled/completed, invoice.issued/overdue, payment.recorded.
85
44
  - Regeneration must not alter payment semantics without reviewed spec changes.
@@ -91,7 +50,4 @@ var serviceBusinessDocBlocks = [
91
50
  ## Verification
92
51
  - Add fixtures for quote/job/invoice state transitions.
93
52
  - Ensure Notifications/Audit/Jobs wiring persists after regeneration.
94
- - Use Feature Flags to trial new payment rules/reminder cadences; default safe/off.`
95
- }
96
- ];
97
- registerDocBlocks(serviceBusinessDocBlocks);
53
+ - Use Feature Flags to trial new payment rules/reminder cadences; default safe/off.`}];f(h);
@@ -1,247 +1,2 @@
1
1
  // @bun
2
- // src/entities/index.ts
3
- import {
4
- defineEntity,
5
- defineEntityEnum,
6
- field,
7
- index
8
- } from "@contractspec/lib.schema";
9
- var schema = "lssm_service_os";
10
- var QuoteStatusEnum = defineEntityEnum({
11
- name: "QuoteStatus",
12
- schema,
13
- values: ["DRAFT", "SENT", "ACCEPTED", "REJECTED", "EXPIRED"],
14
- description: "Lifecycle for quotes/proposals."
15
- });
16
- var JobStatusEnum = defineEntityEnum({
17
- name: "JobStatus",
18
- schema,
19
- values: ["SCHEDULED", "IN_PROGRESS", "COMPLETED", "CANCELLED"],
20
- description: "Lifecycle for service jobs/interventions."
21
- });
22
- var InvoiceStatusEnum = defineEntityEnum({
23
- name: "InvoiceStatus",
24
- schema,
25
- values: ["DRAFT", "SENT", "PAID", "OVERDUE", "CANCELLED"],
26
- description: "Lifecycle for invoices."
27
- });
28
- var PaymentMethodEnum = defineEntityEnum({
29
- name: "PaymentMethod",
30
- schema,
31
- values: ["CARD", "BANK_TRANSFER", "CASH", "CHECK"],
32
- description: "Payment method used."
33
- });
34
- var ClientEntity = defineEntity({
35
- name: "Client",
36
- description: "Customer organization or individual.",
37
- schema,
38
- map: "client",
39
- fields: {
40
- id: field.id({ description: "Unique client identifier" }),
41
- name: field.string({ description: "Client display name" }),
42
- contactEmail: field.string({
43
- description: "Primary contact email",
44
- isOptional: true
45
- }),
46
- phone: field.string({ description: "Primary phone", isOptional: true }),
47
- address: field.json({ description: "Mailing address", isOptional: true }),
48
- industry: field.string({
49
- description: "Industry/vertical",
50
- isOptional: true
51
- }),
52
- orgId: field.string({ description: "Owning organization" }),
53
- ownerId: field.string({ description: "Account owner" }),
54
- metadata: field.json({
55
- description: "Additional metadata",
56
- isOptional: true
57
- }),
58
- createdAt: field.createdAt(),
59
- updatedAt: field.updatedAt(),
60
- quotes: field.hasMany("Quote"),
61
- jobs: field.hasMany("Job")
62
- },
63
- indexes: [index.on(["orgId"]), index.on(["ownerId"]), index.on(["name"])]
64
- });
65
- var QuoteEntity = defineEntity({
66
- name: "Quote",
67
- description: "Proposal/quote for a job.",
68
- schema,
69
- map: "quote",
70
- fields: {
71
- id: field.id({ description: "Unique quote identifier" }),
72
- clientId: field.foreignKey({ description: "Client receiving quote" }),
73
- title: field.string({ description: "Quote title" }),
74
- description: field.string({
75
- description: "Work summary",
76
- isOptional: true
77
- }),
78
- amount: field.float({ description: "Total quoted amount" }),
79
- currency: field.string({ description: "Currency code", default: '"USD"' }),
80
- status: field.enum("QuoteStatus", {
81
- description: "Quote status",
82
- default: "DRAFT"
83
- }),
84
- validUntil: field.dateTime({
85
- description: "Expiration date",
86
- isOptional: true
87
- }),
88
- terms: field.string({
89
- description: "Payment/engagement terms",
90
- isOptional: true
91
- }),
92
- orgId: field.string({ description: "Owning organization" }),
93
- ownerId: field.string({ description: "Account owner" }),
94
- createdAt: field.createdAt(),
95
- updatedAt: field.updatedAt(),
96
- client: field.belongsTo("Client", ["clientId"], ["id"], {
97
- onDelete: "Cascade"
98
- }),
99
- jobs: field.hasMany("Job")
100
- },
101
- enums: [QuoteStatusEnum],
102
- indexes: [
103
- index.on(["orgId", "status"]),
104
- index.on(["clientId"]),
105
- index.on(["validUntil"])
106
- ]
107
- });
108
- var JobEntity = defineEntity({
109
- name: "Job",
110
- description: "Service job/intervention derived from an accepted quote.",
111
- schema,
112
- map: "job",
113
- fields: {
114
- id: field.id({ description: "Unique job identifier" }),
115
- quoteId: field.foreignKey({ description: "Source quote" }),
116
- clientId: field.foreignKey({ description: "Client receiving service" }),
117
- title: field.string({ description: "Job title" }),
118
- status: field.enum("JobStatus", {
119
- description: "Job status",
120
- default: "SCHEDULED"
121
- }),
122
- scheduledAt: field.dateTime({
123
- description: "Scheduled start date/time",
124
- isOptional: true
125
- }),
126
- completedAt: field.dateTime({
127
- description: "Completion timestamp",
128
- isOptional: true
129
- }),
130
- assignedTo: field.string({
131
- description: "Assignee/technician user ID",
132
- isOptional: true
133
- }),
134
- location: field.json({ description: "Location details", isOptional: true }),
135
- notes: field.string({ description: "Internal notes", isOptional: true }),
136
- orgId: field.string({ description: "Owning organization" }),
137
- createdAt: field.createdAt(),
138
- updatedAt: field.updatedAt(),
139
- quote: field.belongsTo("Quote", ["quoteId"], ["id"], {
140
- onDelete: "SetNull"
141
- }),
142
- client: field.belongsTo("Client", ["clientId"], ["id"], {
143
- onDelete: "Cascade"
144
- }),
145
- invoices: field.hasMany("Invoice")
146
- },
147
- enums: [JobStatusEnum],
148
- indexes: [
149
- index.on(["orgId", "status"]),
150
- index.on(["clientId"]),
151
- index.on(["assignedTo", "status"]),
152
- index.on(["scheduledAt"])
153
- ]
154
- });
155
- var InvoiceEntity = defineEntity({
156
- name: "Invoice",
157
- description: "Invoice issued for a completed job.",
158
- schema,
159
- map: "invoice",
160
- fields: {
161
- id: field.id({ description: "Unique invoice identifier" }),
162
- jobId: field.foreignKey({ description: "Related job" }),
163
- invoiceNumber: field.string({
164
- description: "Invoice number",
165
- isUnique: true
166
- }),
167
- amount: field.decimal({ description: "Invoice amount" }),
168
- currency: field.string({ description: "Currency code", default: '"USD"' }),
169
- status: field.enum("InvoiceStatus", {
170
- description: "Invoice status",
171
- default: "DRAFT"
172
- }),
173
- dueDate: field.dateTime({ description: "Due date", isOptional: true }),
174
- issuedAt: field.dateTime({
175
- description: "Issued timestamp",
176
- isOptional: true
177
- }),
178
- paidAt: field.dateTime({ description: "Paid timestamp", isOptional: true }),
179
- orgId: field.string({ description: "Owning organization" }),
180
- notes: field.string({ description: "Invoice notes", isOptional: true }),
181
- metadata: field.json({ description: "Metadata", isOptional: true }),
182
- createdAt: field.createdAt(),
183
- updatedAt: field.updatedAt(),
184
- job: field.belongsTo("Job", ["jobId"], ["id"], { onDelete: "Cascade" }),
185
- payments: field.hasMany("Payment")
186
- },
187
- enums: [InvoiceStatusEnum],
188
- indexes: [
189
- index.on(["invoiceNumber"]),
190
- index.on(["orgId", "status"]),
191
- index.on(["dueDate"])
192
- ]
193
- });
194
- var PaymentEntity = defineEntity({
195
- name: "Payment",
196
- description: "Payment received for an invoice.",
197
- schema,
198
- map: "payment",
199
- fields: {
200
- id: field.id({ description: "Unique payment identifier" }),
201
- invoiceId: field.foreignKey({ description: "Invoice being paid" }),
202
- amount: field.decimal({ description: "Payment amount" }),
203
- currency: field.string({ description: "Currency code", default: '"USD"' }),
204
- method: field.enum("PaymentMethod", { description: "Payment method" }),
205
- reference: field.string({
206
- description: "Payment reference/transaction ID",
207
- isOptional: true
208
- }),
209
- receivedAt: field.dateTime({ description: "When payment was received" }),
210
- orgId: field.string({ description: "Owning organization" }),
211
- createdAt: field.createdAt(),
212
- invoice: field.belongsTo("Invoice", ["invoiceId"], ["id"], {
213
- onDelete: "Cascade"
214
- })
215
- },
216
- enums: [PaymentMethodEnum],
217
- indexes: [
218
- index.on(["invoiceId"]),
219
- index.on(["orgId"]),
220
- index.on(["receivedAt"])
221
- ]
222
- });
223
- var serviceBusinessEntities = [
224
- ClientEntity,
225
- QuoteEntity,
226
- JobEntity,
227
- InvoiceEntity,
228
- PaymentEntity
229
- ];
230
- var serviceBusinessSchemaContribution = {
231
- moduleId: "@contractspec/example.service-business-os",
232
- entities: serviceBusinessEntities,
233
- enums: [QuoteStatusEnum, JobStatusEnum, InvoiceStatusEnum, PaymentMethodEnum]
234
- };
235
- export {
236
- serviceBusinessSchemaContribution,
237
- serviceBusinessEntities,
238
- QuoteStatusEnum,
239
- QuoteEntity,
240
- PaymentMethodEnum,
241
- PaymentEntity,
242
- JobStatusEnum,
243
- JobEntity,
244
- InvoiceStatusEnum,
245
- InvoiceEntity,
246
- ClientEntity
247
- };
2
+ import{defineEntity as n,defineEntityEnum as o,field as e,index as t}from"@contractspec/lib.schema";var i="lssm_service_os",s=o({name:"QuoteStatus",schema:i,values:["DRAFT","SENT","ACCEPTED","REJECTED","EXPIRED"],description:"Lifecycle for quotes/proposals."}),r=o({name:"JobStatus",schema:i,values:["SCHEDULED","IN_PROGRESS","COMPLETED","CANCELLED"],description:"Lifecycle for service jobs/interventions."}),d=o({name:"InvoiceStatus",schema:i,values:["DRAFT","SENT","PAID","OVERDUE","CANCELLED"],description:"Lifecycle for invoices."}),a=o({name:"PaymentMethod",schema:i,values:["CARD","BANK_TRANSFER","CASH","CHECK"],description:"Payment method used."}),c=n({name:"Client",description:"Customer organization or individual.",schema:i,map:"client",fields:{id:e.id({description:"Unique client identifier"}),name:e.string({description:"Client display name"}),contactEmail:e.string({description:"Primary contact email",isOptional:!0}),phone:e.string({description:"Primary phone",isOptional:!0}),address:e.json({description:"Mailing address",isOptional:!0}),industry:e.string({description:"Industry/vertical",isOptional:!0}),orgId:e.string({description:"Owning organization"}),ownerId:e.string({description:"Account owner"}),metadata:e.json({description:"Additional metadata",isOptional:!0}),createdAt:e.createdAt(),updatedAt:e.updatedAt(),quotes:e.hasMany("Quote"),jobs:e.hasMany("Job")},indexes:[t.on(["orgId"]),t.on(["ownerId"]),t.on(["name"])]}),u=n({name:"Quote",description:"Proposal/quote for a job.",schema:i,map:"quote",fields:{id:e.id({description:"Unique quote identifier"}),clientId:e.foreignKey({description:"Client receiving quote"}),title:e.string({description:"Quote title"}),description:e.string({description:"Work summary",isOptional:!0}),amount:e.float({description:"Total quoted amount"}),currency:e.string({description:"Currency code",default:'"USD"'}),status:e.enum("QuoteStatus",{description:"Quote status",default:"DRAFT"}),validUntil:e.dateTime({description:"Expiration date",isOptional:!0}),terms:e.string({description:"Payment/engagement terms",isOptional:!0}),orgId:e.string({description:"Owning organization"}),ownerId:e.string({description:"Account owner"}),createdAt:e.createdAt(),updatedAt:e.updatedAt(),client:e.belongsTo("Client",["clientId"],["id"],{onDelete:"Cascade"}),jobs:e.hasMany("Job")},enums:[s],indexes:[t.on(["orgId","status"]),t.on(["clientId"]),t.on(["validUntil"])]}),p=n({name:"Job",description:"Service job/intervention derived from an accepted quote.",schema:i,map:"job",fields:{id:e.id({description:"Unique job identifier"}),quoteId:e.foreignKey({description:"Source quote"}),clientId:e.foreignKey({description:"Client receiving service"}),title:e.string({description:"Job title"}),status:e.enum("JobStatus",{description:"Job status",default:"SCHEDULED"}),scheduledAt:e.dateTime({description:"Scheduled start date/time",isOptional:!0}),completedAt:e.dateTime({description:"Completion timestamp",isOptional:!0}),assignedTo:e.string({description:"Assignee/technician user ID",isOptional:!0}),location:e.json({description:"Location details",isOptional:!0}),notes:e.string({description:"Internal notes",isOptional:!0}),orgId:e.string({description:"Owning organization"}),createdAt:e.createdAt(),updatedAt:e.updatedAt(),quote:e.belongsTo("Quote",["quoteId"],["id"],{onDelete:"SetNull"}),client:e.belongsTo("Client",["clientId"],["id"],{onDelete:"Cascade"}),invoices:e.hasMany("Invoice")},enums:[r],indexes:[t.on(["orgId","status"]),t.on(["clientId"]),t.on(["assignedTo","status"]),t.on(["scheduledAt"])]}),l=n({name:"Invoice",description:"Invoice issued for a completed job.",schema:i,map:"invoice",fields:{id:e.id({description:"Unique invoice identifier"}),jobId:e.foreignKey({description:"Related job"}),invoiceNumber:e.string({description:"Invoice number",isUnique:!0}),amount:e.decimal({description:"Invoice amount"}),currency:e.string({description:"Currency code",default:'"USD"'}),status:e.enum("InvoiceStatus",{description:"Invoice status",default:"DRAFT"}),dueDate:e.dateTime({description:"Due date",isOptional:!0}),issuedAt:e.dateTime({description:"Issued timestamp",isOptional:!0}),paidAt:e.dateTime({description:"Paid timestamp",isOptional:!0}),orgId:e.string({description:"Owning organization"}),notes:e.string({description:"Invoice notes",isOptional:!0}),metadata:e.json({description:"Metadata",isOptional:!0}),createdAt:e.createdAt(),updatedAt:e.updatedAt(),job:e.belongsTo("Job",["jobId"],["id"],{onDelete:"Cascade"}),payments:e.hasMany("Payment")},enums:[d],indexes:[t.on(["invoiceNumber"]),t.on(["orgId","status"]),t.on(["dueDate"])]}),m=n({name:"Payment",description:"Payment received for an invoice.",schema:i,map:"payment",fields:{id:e.id({description:"Unique payment identifier"}),invoiceId:e.foreignKey({description:"Invoice being paid"}),amount:e.decimal({description:"Payment amount"}),currency:e.string({description:"Currency code",default:'"USD"'}),method:e.enum("PaymentMethod",{description:"Payment method"}),reference:e.string({description:"Payment reference/transaction ID",isOptional:!0}),receivedAt:e.dateTime({description:"When payment was received"}),orgId:e.string({description:"Owning organization"}),createdAt:e.createdAt(),invoice:e.belongsTo("Invoice",["invoiceId"],["id"],{onDelete:"Cascade"})},enums:[a],indexes:[t.on(["invoiceId"]),t.on(["orgId"]),t.on(["receivedAt"])]}),g=[c,u,p,l,m],v={moduleId:"@contractspec/example.service-business-os",entities:g,enums:[s,r,d,a]};export{v as serviceBusinessSchemaContribution,g as serviceBusinessEntities,s as QuoteStatusEnum,u as QuoteEntity,a as PaymentMethodEnum,m as PaymentEntity,r as JobStatusEnum,p as JobEntity,d as InvoiceStatusEnum,l as InvoiceEntity,c as ClientEntity};