@contractspec/example.service-business-os 3.7.6 → 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.
@@ -67,117 +67,74 @@ var CreateClientContract = defineCommand({
67
67
  ]
68
68
  }
69
69
  });
70
- // src/quote/quote.schema.ts
70
+ // src/invoice/invoice.schema.ts
71
71
  import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
72
- var QuoteModel = defineSchemaModel2({
73
- name: "Quote",
74
- description: "Quote/proposal",
72
+ var InvoiceModel = defineSchemaModel2({
73
+ name: "Invoice",
74
+ description: "Invoice issued for a job",
75
75
  fields: {
76
76
  id: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
77
- clientId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
78
- title: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
79
- description: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
77
+ jobId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
78
+ invoiceNumber: {
79
+ type: ScalarTypeEnum2.String_unsecure(),
80
+ isOptional: false
81
+ },
80
82
  amount: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false },
81
83
  currency: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
82
84
  status: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
83
- validUntil: { type: ScalarTypeEnum2.DateTime(), isOptional: true },
84
- createdAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
85
+ dueDate: { type: ScalarTypeEnum2.DateTime(), isOptional: true },
86
+ issuedAt: { type: ScalarTypeEnum2.DateTime(), isOptional: true },
87
+ paidAt: { type: ScalarTypeEnum2.DateTime(), isOptional: true }
85
88
  }
86
89
  });
87
- var CreateQuoteInputModel = defineSchemaModel2({
88
- name: "CreateQuoteInput",
89
- description: "Input for creating a quote",
90
- fields: {
91
- clientId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
92
- title: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
93
- description: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
94
- amount: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false },
95
- currency: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
96
- validUntil: { type: ScalarTypeEnum2.DateTime(), isOptional: true },
97
- orgId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
98
- ownerId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
99
- }
100
- });
101
- var AcceptQuoteInputModel = defineSchemaModel2({
102
- name: "AcceptQuoteInput",
103
- description: "Input for accepting a quote",
90
+ var IssueInvoiceInputModel = defineSchemaModel2({
91
+ name: "IssueInvoiceInput",
92
+ description: "Input for issuing an invoice",
104
93
  fields: {
105
- quoteId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
106
- acceptedBy: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
107
- notes: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true }
94
+ jobId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
95
+ dueDate: { type: ScalarTypeEnum2.DateTime(), isOptional: true },
96
+ notes: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
97
+ lineItems: { type: ScalarTypeEnum2.JSON(), isOptional: true }
108
98
  }
109
99
  });
110
100
 
111
- // src/quote/quote.operations.ts
101
+ // src/invoice/invoice.operations.ts
112
102
  import { defineCommand as defineCommand2 } from "@contractspec/lib.contracts-spec";
113
103
  var OWNERS2 = ["@examples.service-business-os"];
114
- var CreateQuoteContract = defineCommand2({
104
+ var IssueInvoiceContract = defineCommand2({
115
105
  meta: {
116
- key: "service.quote.create",
106
+ key: "service.invoice.issue",
117
107
  version: "1.0.0",
118
108
  stability: "stable",
119
109
  owners: [...OWNERS2],
120
- tags: ["service-business-os", "quote", "create"],
121
- description: "Create a quote/proposal.",
122
- goal: "Quote clients.",
123
- context: "Quote creation."
110
+ tags: ["service-business-os", "invoice", "issue"],
111
+ description: "Issue an invoice for a job.",
112
+ goal: "Bill clients.",
113
+ context: "Billing."
124
114
  },
125
115
  io: {
126
- input: CreateQuoteInputModel,
127
- output: QuoteModel
116
+ input: IssueInvoiceInputModel,
117
+ output: InvoiceModel
128
118
  },
129
119
  policy: { auth: "user" },
130
120
  acceptance: {
131
121
  scenarios: [
132
122
  {
133
- key: "create-quote-happy-path",
134
- given: ["Client exists"],
135
- when: ["User creates quote"],
136
- then: ["Quote is created"]
123
+ key: "issue-invoice-happy-path",
124
+ given: ["Job is complete"],
125
+ when: ["User issues invoice"],
126
+ then: ["Invoice is created and sent"]
137
127
  }
138
128
  ],
139
129
  examples: [
140
130
  {
141
- key: "create-proposal",
131
+ key: "issue-standard",
142
132
  input: {
143
- clientId: "client-123",
144
- items: [{ description: "Project A", price: 5000 }]
133
+ jobId: "job-123",
134
+ dueDate: "2025-02-01",
135
+ items: [{ description: "Service", amount: 100 }]
145
136
  },
146
- output: { id: "quote-123", status: "draft", total: 5000 }
147
- }
148
- ]
149
- }
150
- });
151
- var AcceptQuoteContract = defineCommand2({
152
- meta: {
153
- key: "service.quote.accept",
154
- version: "1.0.0",
155
- stability: "stable",
156
- owners: [...OWNERS2],
157
- tags: ["service-business-os", "quote", "accept"],
158
- description: "Accept a quote.",
159
- goal: "Confirm quote.",
160
- context: "Quote acceptance."
161
- },
162
- io: {
163
- input: AcceptQuoteInputModel,
164
- output: QuoteModel
165
- },
166
- policy: { auth: "user" },
167
- acceptance: {
168
- scenarios: [
169
- {
170
- key: "accept-quote-happy-path",
171
- given: ["Quote is open"],
172
- when: ["Client accepts quote"],
173
- then: ["Quote status becomes ACCEPTED"]
174
- }
175
- ],
176
- examples: [
177
- {
178
- key: "client-accepts",
179
- input: { quoteId: "quote-123", signature: "John Doe" },
180
- output: { id: "quote-123", status: "accepted" }
137
+ output: { id: "inv-456", status: "issued", total: 100 }
181
138
  }
182
139
  ]
183
140
  }
@@ -347,138 +304,181 @@ var CompleteJobContract = defineCommand3({
347
304
  ]
348
305
  }
349
306
  });
350
- // src/invoice/invoice.schema.ts
307
+ // src/payment/payment.schema.ts
351
308
  import { defineSchemaModel as defineSchemaModel5, ScalarTypeEnum as ScalarTypeEnum5 } from "@contractspec/lib.schema";
352
- var InvoiceModel = defineSchemaModel5({
353
- name: "Invoice",
354
- description: "Invoice issued for a job",
309
+ var PaymentModel = defineSchemaModel5({
310
+ name: "Payment",
311
+ description: "Payment applied to invoice",
355
312
  fields: {
356
313
  id: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
357
- jobId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
358
- invoiceNumber: {
359
- type: ScalarTypeEnum5.String_unsecure(),
360
- isOptional: false
361
- },
314
+ invoiceId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
362
315
  amount: { type: ScalarTypeEnum5.Float_unsecure(), isOptional: false },
363
316
  currency: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
364
- status: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
365
- dueDate: { type: ScalarTypeEnum5.DateTime(), isOptional: true },
366
- issuedAt: { type: ScalarTypeEnum5.DateTime(), isOptional: true },
367
- paidAt: { type: ScalarTypeEnum5.DateTime(), isOptional: true }
317
+ method: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
318
+ reference: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
319
+ receivedAt: { type: ScalarTypeEnum5.DateTime(), isOptional: false }
368
320
  }
369
321
  });
370
- var IssueInvoiceInputModel = defineSchemaModel5({
371
- name: "IssueInvoiceInput",
372
- description: "Input for issuing an invoice",
322
+ var RecordPaymentInputModel = defineSchemaModel5({
323
+ name: "RecordPaymentInput",
324
+ description: "Input for recording a payment",
373
325
  fields: {
374
- jobId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
375
- dueDate: { type: ScalarTypeEnum5.DateTime(), isOptional: true },
376
- notes: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
377
- lineItems: { type: ScalarTypeEnum5.JSON(), isOptional: true }
326
+ invoiceId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
327
+ amount: { type: ScalarTypeEnum5.Float_unsecure(), isOptional: false },
328
+ method: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
329
+ reference: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
330
+ receivedAt: { type: ScalarTypeEnum5.DateTime(), isOptional: true }
378
331
  }
379
332
  });
380
333
 
381
- // src/invoice/invoice.operations.ts
334
+ // src/payment/payment.operations.ts
382
335
  import { defineCommand as defineCommand4 } from "@contractspec/lib.contracts-spec";
383
336
  var OWNERS4 = ["@examples.service-business-os"];
384
- var IssueInvoiceContract = defineCommand4({
337
+ var RecordPaymentContract = defineCommand4({
385
338
  meta: {
386
- key: "service.invoice.issue",
339
+ key: "service.payment.record",
387
340
  version: "1.0.0",
388
341
  stability: "stable",
389
342
  owners: [...OWNERS4],
390
- tags: ["service-business-os", "invoice", "issue"],
391
- description: "Issue an invoice for a job.",
392
- goal: "Bill clients.",
343
+ tags: ["service-business-os", "payment", "record"],
344
+ description: "Record a payment.",
345
+ goal: "Track payments.",
393
346
  context: "Billing."
394
347
  },
395
348
  io: {
396
- input: IssueInvoiceInputModel,
397
- output: InvoiceModel
349
+ input: RecordPaymentInputModel,
350
+ output: PaymentModel
398
351
  },
399
352
  policy: { auth: "user" },
400
353
  acceptance: {
401
354
  scenarios: [
402
355
  {
403
- key: "issue-invoice-happy-path",
404
- given: ["Job is complete"],
405
- when: ["User issues invoice"],
406
- then: ["Invoice is created and sent"]
356
+ key: "record-payment-happy-path",
357
+ given: ["Invoice exists"],
358
+ when: ["User records payment"],
359
+ then: ["Payment is recorded"]
407
360
  }
408
361
  ],
409
362
  examples: [
410
363
  {
411
- key: "issue-standard",
412
- input: {
413
- jobId: "job-123",
414
- dueDate: "2025-02-01",
415
- items: [{ description: "Service", amount: 100 }]
416
- },
417
- output: { id: "inv-456", status: "issued", total: 100 }
364
+ key: "record-check",
365
+ input: { invoiceId: "inv-456", amount: 100, method: "check" },
366
+ output: { id: "pay-123", status: "completed" }
418
367
  }
419
368
  ]
420
369
  }
421
370
  });
422
- // src/payment/payment.schema.ts
371
+ // src/quote/quote.schema.ts
423
372
  import { defineSchemaModel as defineSchemaModel6, ScalarTypeEnum as ScalarTypeEnum6 } from "@contractspec/lib.schema";
424
- var PaymentModel = defineSchemaModel6({
425
- name: "Payment",
426
- description: "Payment applied to invoice",
373
+ var QuoteModel = defineSchemaModel6({
374
+ name: "Quote",
375
+ description: "Quote/proposal",
427
376
  fields: {
428
377
  id: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
429
- invoiceId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
378
+ clientId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
379
+ title: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
380
+ description: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
430
381
  amount: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
431
382
  currency: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
432
- method: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
433
- reference: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
434
- receivedAt: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
383
+ status: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
384
+ validUntil: { type: ScalarTypeEnum6.DateTime(), isOptional: true },
385
+ createdAt: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
435
386
  }
436
387
  });
437
- var RecordPaymentInputModel = defineSchemaModel6({
438
- name: "RecordPaymentInput",
439
- description: "Input for recording a payment",
388
+ var CreateQuoteInputModel = defineSchemaModel6({
389
+ name: "CreateQuoteInput",
390
+ description: "Input for creating a quote",
440
391
  fields: {
441
- invoiceId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
392
+ clientId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
393
+ title: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
394
+ description: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
442
395
  amount: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
443
- method: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
444
- reference: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
445
- receivedAt: { type: ScalarTypeEnum6.DateTime(), isOptional: true }
396
+ currency: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
397
+ validUntil: { type: ScalarTypeEnum6.DateTime(), isOptional: true },
398
+ orgId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
399
+ ownerId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false }
400
+ }
401
+ });
402
+ var AcceptQuoteInputModel = defineSchemaModel6({
403
+ name: "AcceptQuoteInput",
404
+ description: "Input for accepting a quote",
405
+ fields: {
406
+ quoteId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
407
+ acceptedBy: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
408
+ notes: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true }
446
409
  }
447
410
  });
448
411
 
449
- // src/payment/payment.operations.ts
412
+ // src/quote/quote.operations.ts
450
413
  import { defineCommand as defineCommand5 } from "@contractspec/lib.contracts-spec";
451
414
  var OWNERS5 = ["@examples.service-business-os"];
452
- var RecordPaymentContract = defineCommand5({
415
+ var CreateQuoteContract = defineCommand5({
453
416
  meta: {
454
- key: "service.payment.record",
417
+ key: "service.quote.create",
455
418
  version: "1.0.0",
456
419
  stability: "stable",
457
420
  owners: [...OWNERS5],
458
- tags: ["service-business-os", "payment", "record"],
459
- description: "Record a payment.",
460
- goal: "Track payments.",
461
- context: "Billing."
421
+ tags: ["service-business-os", "quote", "create"],
422
+ description: "Create a quote/proposal.",
423
+ goal: "Quote clients.",
424
+ context: "Quote creation."
462
425
  },
463
426
  io: {
464
- input: RecordPaymentInputModel,
465
- output: PaymentModel
427
+ input: CreateQuoteInputModel,
428
+ output: QuoteModel
466
429
  },
467
430
  policy: { auth: "user" },
468
431
  acceptance: {
469
432
  scenarios: [
470
433
  {
471
- key: "record-payment-happy-path",
472
- given: ["Invoice exists"],
473
- when: ["User records payment"],
474
- then: ["Payment is recorded"]
434
+ key: "create-quote-happy-path",
435
+ given: ["Client exists"],
436
+ when: ["User creates quote"],
437
+ then: ["Quote is created"]
475
438
  }
476
439
  ],
477
440
  examples: [
478
441
  {
479
- key: "record-check",
480
- input: { invoiceId: "inv-456", amount: 100, method: "check" },
481
- output: { id: "pay-123", status: "completed" }
442
+ key: "create-proposal",
443
+ input: {
444
+ clientId: "client-123",
445
+ items: [{ description: "Project A", price: 5000 }]
446
+ },
447
+ output: { id: "quote-123", status: "draft", total: 5000 }
448
+ }
449
+ ]
450
+ }
451
+ });
452
+ var AcceptQuoteContract = defineCommand5({
453
+ meta: {
454
+ key: "service.quote.accept",
455
+ version: "1.0.0",
456
+ stability: "stable",
457
+ owners: [...OWNERS5],
458
+ tags: ["service-business-os", "quote", "accept"],
459
+ description: "Accept a quote.",
460
+ goal: "Confirm quote.",
461
+ context: "Quote acceptance."
462
+ },
463
+ io: {
464
+ input: AcceptQuoteInputModel,
465
+ output: QuoteModel
466
+ },
467
+ policy: { auth: "user" },
468
+ acceptance: {
469
+ scenarios: [
470
+ {
471
+ key: "accept-quote-happy-path",
472
+ given: ["Quote is open"],
473
+ when: ["Client accepts quote"],
474
+ then: ["Quote status becomes ACCEPTED"]
475
+ }
476
+ ],
477
+ examples: [
478
+ {
479
+ key: "client-accepts",
480
+ input: { quoteId: "quote-123", signature: "John Doe" },
481
+ output: { id: "quote-123", status: "accepted" }
482
482
  }
483
483
  ]
484
484
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Client domain - Client management.
3
3
  */
4
- export { ClientModel, CreateClientInputModel } from './client.schema';
5
4
  export { CreateClientContract } from './client.operations';
5
+ export { ClientModel, CreateClientInputModel } from './client.schema';
package/dist/events.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // src/events.ts
3
- import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
4
3
  import { defineEvent } from "@contractspec/lib.contracts-spec";
4
+ import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
5
5
  var QuoteEventPayload = defineSchemaModel({
6
6
  name: "QuoteEventPayload",
7
7
  description: "Event payload for quote lifecycle",
@@ -3,9 +3,9 @@
3
3
  * Implementations would persist to DB and integrate with Files, Notifications, and Jobs.
4
4
  */
5
5
  import type { CreateClientContract } from '../client';
6
- import type { CreateQuoteContract, AcceptQuoteContract } from '../quote';
7
- import type { ScheduleJobContract, CompleteJobContract } from '../job';
8
6
  import type { IssueInvoiceContract } from '../invoice';
7
+ import type { CompleteJobContract, ScheduleJobContract } from '../job';
9
8
  import type { RecordPaymentContract } from '../payment';
9
+ import type { AcceptQuoteContract, CreateQuoteContract } from '../quote';
10
10
  export declare function registerServiceBusinessHandlers(): void;
11
11
  export type ServiceBusinessHandlers = typeof AcceptQuoteContract | typeof CreateClientContract | typeof CreateQuoteContract | typeof ScheduleJobContract | typeof CompleteJobContract | typeof IssueInvoiceContract | typeof RecordPaymentContract;
package/dist/index.d.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  * Demonstrates a complete service business workflow with clients, quotes, jobs, invoices, and payments.
5
5
  */
6
6
  export * from './client';
7
- export * from './quote';
8
- export * from './job';
9
7
  export * from './invoice';
8
+ export * from './job';
10
9
  export * from './payment';
11
10
  export * from './presentations';
11
+ export * from './quote';
12
12
  export * from './service.feature';