@rubytech/create-sitedesk-code 0.1.348 → 0.1.349

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 (91) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-style/dist/index.d.ts +1 -1
  3. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/graph-style/dist/index.js +20 -12
  5. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  6. package/payload/platform/lib/graph-style/src/__tests__/parity.test.ts +9 -9
  7. package/payload/platform/lib/graph-style/src/index.ts +20 -12
  8. package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
  9. package/payload/platform/lib/graph-write/dist/index.js +3 -2
  10. package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
  11. package/payload/platform/lib/graph-write/src/index.ts +3 -2
  12. package/payload/platform/neo4j/schema.cypher +110 -31
  13. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  14. package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +1 -0
  15. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +36 -3
  16. package/payload/platform/plugins/docs/references/calendar-booking.md +1 -1
  17. package/payload/platform/plugins/docs/references/joblogic.md +28 -0
  18. package/payload/platform/plugins/docs/references/memory-guide.md +1 -1
  19. package/payload/platform/plugins/joblogic/.claude-plugin/plugin.json +21 -0
  20. package/payload/platform/plugins/joblogic/PLUGIN.md +182 -0
  21. package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/index.js +193 -0
  22. package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/package.json +3 -0
  23. package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts +2 -0
  24. package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts.map +1 -0
  25. package/payload/platform/plugins/joblogic/mcp/dist/index.js +229 -0
  26. package/payload/platform/plugins/joblogic/mcp/dist/index.js.map +1 -0
  27. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts +31 -0
  28. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts.map +1 -0
  29. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js +78 -0
  30. package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js.map +1 -0
  31. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts +35 -0
  32. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts.map +1 -0
  33. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js +106 -0
  34. package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js.map +1 -0
  35. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts +8 -0
  36. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts.map +1 -0
  37. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js +41 -0
  38. package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js.map +1 -0
  39. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts +21 -0
  40. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts.map +1 -0
  41. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js +47 -0
  42. package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js.map +1 -0
  43. package/payload/platform/plugins/joblogic/mcp/package.json +10 -0
  44. package/payload/platform/plugins/joblogic/skills/joblogic/SKILL.md +32 -0
  45. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relationship-patterns.test.js +28 -22
  46. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relationship-patterns.test.js.map +1 -1
  47. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js +8 -4
  48. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js.map +1 -1
  49. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.js +39 -10
  50. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.js.map +1 -1
  51. package/payload/platform/plugins/memory/mcp/dist/lib/relationship-patterns.d.ts +1 -1
  52. package/payload/platform/plugins/memory/mcp/dist/lib/relationship-patterns.js +1 -1
  53. package/payload/platform/plugins/memory/references/schema-construction.md +152 -57
  54. package/payload/platform/plugins/memory/references/schema-trades.md +22 -24
  55. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  56. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +46 -0
  57. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  58. package/payload/premium-plugins/sitedesk/plugins/sitedesk-job/skills/timesheet/SKILL.md +2 -2
  59. package/payload/premium-plugins/sitedesk/plugins/sitedesk-job/skills/timesheet/references/checkin-contract.md +19 -14
  60. package/payload/premium-plugins/sitedesk/plugins/sitedesk-job/skills/timesheet/references/documents.md +1 -1
  61. package/payload/premium-plugins/sitedesk/plugins/sitedesk-job/skills/timesheet/references/roll-up.md +1 -1
  62. package/payload/premium-plugins/sitedesk/plugins/sitedesk-job/skills/valuation/SKILL.md +8 -8
  63. package/payload/premium-plugins/sitedesk/plugins/sitedesk-job/skills/valuation/references/contract-template.md +2 -2
  64. package/payload/premium-plugins/sitedesk/plugins/sitedesk-job/skills/valuation/references/issue-flow.md +3 -3
  65. package/payload/server/public/assets/{AdminLoginScreens-B_5wYcR-.js → AdminLoginScreens-BEzoTk56.js} +1 -1
  66. package/payload/server/public/assets/{AdminShell-CMV3XY-s.js → AdminShell-BG7YD4UO.js} +1 -1
  67. package/payload/server/public/assets/{Checkbox-LplFUKpb.js → Checkbox-CvTFOczj.js} +1 -1
  68. package/payload/server/public/assets/{OperatorConversations-C4Cx814-.css → OperatorConversations-CnP9Y6g2.css} +1 -1
  69. package/payload/server/public/assets/{admin-3QQtd7j2.js → admin-Bhxa1HOy.js} +1 -1
  70. package/payload/server/public/assets/{browser-D5q26eZL.js → browser-BAQFuyma.js} +1 -1
  71. package/payload/server/public/assets/calendar-sSr6zUjW.js +1 -0
  72. package/payload/server/public/assets/chat-ZH4Fsyu0.js +1 -0
  73. package/payload/server/public/assets/{data-HwT5wPmj.js → data-CH6GNBO3.js} +1 -1
  74. package/payload/server/public/assets/{graph-DFQbqmi9.js → graph-DbGjFYPS.js} +1 -1
  75. package/payload/server/public/assets/graph-labels-IGIEr-uc.js +1 -0
  76. package/payload/server/public/assets/{operator-BlCyq4q1.js → operator-Ba5afDyM.js} +1 -1
  77. package/payload/server/public/assets/{page-drg1V-yA.js → page-D7uwMUOy.js} +1 -1
  78. package/payload/server/public/assets/{public-BVjeYfsD.js → public-DikYWzOd.js} +1 -1
  79. package/payload/server/public/browser.html +4 -4
  80. package/payload/server/public/calendar.html +4 -4
  81. package/payload/server/public/chat.html +5 -5
  82. package/payload/server/public/data.html +4 -4
  83. package/payload/server/public/graph.html +6 -6
  84. package/payload/server/public/index.html +6 -6
  85. package/payload/server/public/operator.html +7 -7
  86. package/payload/server/public/public.html +5 -5
  87. package/payload/server/server.js +32 -15
  88. package/payload/server/public/assets/calendar-Csbdj7rp.js +0 -1
  89. package/payload/server/public/assets/chat-Ct86qtMI.js +0 -1
  90. package/payload/server/public/assets/graph-labels-kCti2CaC.js +0 -1
  91. /package/payload/server/public/assets/{OperatorConversations-Bp-g80PM.js → OperatorConversations-DU8CqO-z.js} +0 -0
@@ -1,39 +1,86 @@
1
- # Schema Reference — Construction
1
+ # Schema Reference — Construction / Field Service
2
2
 
3
- Vertical schema for `businessType: "construction"` — small building firms and independent building contractors (the SiteDesk brand).
3
+ Vertical schema for `businessType: "construction"` — building firms, contractors, and
4
+ field-service operators (the SiteDesk brand). This is the **canonical, opinionated** SiteDesk
5
+ service-delivery ontology, authored from JobLogic's proven field-service domain so that an
6
+ operator's job maps onto shipped labels without inventing the model. JobLogic's term is the
7
+ canonical label name for each concept.
4
8
 
5
- This reference extends the base schema. All base node types (Person, Organization, Invoice, PostalAddress, Event, etc.) remain valid. Load `schema-base.md` first.
9
+ This reference extends the base schema. All base node types (Person, Organization, Invoice,
10
+ PostalAddress, Event, etc.) remain valid. Load `schema-base.md` first.
6
11
 
7
12
  When loading this reference, confirm: "Using schema-base + schema-construction".
8
13
 
9
- ---
10
-
11
- ## Additional Node Types
12
-
13
- | Entity | Neo4j Label | Schema.org Type | Required Properties |
14
- |--------|-------------|-----------------|---------------------|
15
- | Job | `Job` | `schema:Project` | `accountId`, `jobId`, `client`, `address`, `status` (quoting/active/complete), `contractValue` |
16
- | LineItem | `LineItem` | `cdm:LineItem` | `accountId`, `jobId`, `trade`, `description`, `contractValue` |
17
- | Valuation | `Valuation` | `schema:MonetaryAmount` | `accountId`, `jobId`, `valuationNumber`, `date`, `totalValue` |
18
- | Milestone | `Milestone` | `schema:Event` (subtype) | `accountId`, `jobId`, `name`, `completedDate` |
19
- | QuoteDocument | `QuoteDocument` | `schema:DigitalDocument` | `accountId`, `jobId`, `ref`, `totalPaymentDue`, `date`, `status` (draft/sent/accepted) |
20
- | VariationNote | `VariationNote` | `schema:DigitalDocument` | `accountId`, `jobId`, `variationNumber`, `description`, `totalPaymentDue`, `status` |
21
- | InboundInvoice | `InboundInvoice` | `schema:Invoice` | `accountId`, `supplier`, `confirmationNumber`, `totalPaymentDue`, `status` (pending/approved/processed) |
22
- | Worker | `Worker` (label on `Person`) | `schema:Person` (config) | `accountId`, `personId`, `name`, `engagement` (employee/cis), `dayRatePence`, `showCisDeduction`, `invoiceEmail` |
23
- | CheckIn | `CheckIn` | `schema:Action` | `accountId`, `personId`, `source`, `date`, `site`, `description`, `dayHundredths` |
24
- | WhatsAppGroup | `WhatsAppGroup` | `cdm:Channel` | `accountId`, `groupId`, `jobId`, `clientName` |
25
-
26
- `awardedDate` on `Job` is expected once `status` is `active` or `complete` — a job still `quoting` has no award date. Never write a sentinel value (`"pending"`, `""`) to stand in for an unknown date; omit the property until the real date is known.
27
-
28
- These entities model a general builder job folder: a `Job` has a generated client `QuoteDocument` that carries many `LineItem` rows organised by trade stage, supplier and sub-contractor invoices, and per-trade structure. A residential building job's line items typically span stages such as groundworks, sub-structure, superstructure, roof, structural alterations & envelope, first fix, drylining & plastering, floor screed, second fixing, knock-throughs, windows & doors, completion items and preliminaries, plus sub-contractor trades (scaffolding, roofing, electrical, plumbing, plastering, tiling, decorations). The schema carries no client, job, or pricing data of its own — those are per-account runtime values.
29
-
30
- ### Distinctions from schema-trades
31
-
32
- `QuoteDocument` is the generated client quote artefact (the `Q-XXXX` document), distinct from schema-trades' `Quote` (a pre-acceptance Order estimate). `InboundInvoice` is a received/payable invoice with job + trade assignment, distinct from the base `Invoice`. A subcontractor company's received invoices use the same `InboundInvoice` model as any other supplier.
14
+ Property fidelity: properties marked **(JobLogic-exact)** are taken from JobLogic's API field
15
+ model; properties marked **(authored)** are modelled from JobLogic's vocabulary plus the
16
+ field-service domain where the captured reference does not document the entity at field level.
33
17
 
34
- ### Field-worker time and pay
18
+ ---
35
19
 
36
- A field worker's time and pay is the `:Worker`/`:CheckIn` model. `:Worker` is an operator-config label on the worker's `:Person` (engagement, day rate, whether the CIS deduction shows, the office invoice address); `:CheckIn` is one record per working day, linked to the worker by `(:Worker)-[:LOGGED]->(:CheckIn)` and unified for roll-up by the shared `personId`. The timesheet skill rolls the check-ins for a period into a per-worker timesheet, and for a CIS worker an invoice that is rendered and emailed, not stored as a node.
20
+ ## Top-level node types (operator-entry, natural key)
21
+
22
+ | Entity | Neo4j Label | Schema.org Type | Required Properties | Fidelity |
23
+ |--------|-------------|-----------------|---------------------|----------|
24
+ | Job | `Job` | `schema:Project` | `accountId`, `jobId`, `status` | JobLogic-exact |
25
+ | Customer | `Customer` | `schema:Organization` | `accountId`, `customerId`, `name`, `customerType` | JobLogic-exact |
26
+ | Site | `Site` | `schema:Place` | `accountId`, `siteId`, `name`, `region` | JobLogic-exact |
27
+ | Asset | `Asset` | `schema:Product` | `accountId`, `assetId`, `name`, `assetType`, `assetClass`, `condition` | authored |
28
+ | Visit | `Visit` | `schema:Event` (subtype) | `accountId`, `visitId`, `status`, `startDate`, `purpose` | authored |
29
+ | Quote | `Quote` | `schema:Order` (estimate) | `accountId`, `ref`, `status`, `totalPaymentDue`, `date` | authored |
30
+ | Supplier invoice | `InboundInvoice` | `schema:Invoice` | `accountId`, `supplier`, `confirmationNumber`, `totalPaymentDue` | JobLogic-exact |
31
+ | Part | `Part` | `schema:Product` | `accountId`, `partId`, `name`, `sku`, `partCategory` | authored |
32
+ | Purchase Order | `PurchaseOrder` | `schema:Order` | `accountId`, `poNumber`, `status`, `completionStatus`, `dateRaised` | JobLogic-exact |
33
+ | PPM Contract | `PpmContract` | `schema:Service` (contract) | `accountId`, `contractId`, `name`, `startDate`, `endDate` | authored |
34
+ | WhatsApp Group | `WhatsAppGroup` | `cdm:Channel` | `accountId`, `groupId`, `jobId`, `clientName` | n/a (transport) |
35
+
36
+ `Job.status` is one of JobLogic's job statuses: `New Job`, `Allocated`, `Attended`,
37
+ `Parts To Fit`, `Awaiting Parts`, `Completed`, `Costed`, `Reqs. Invoice`, `Invoiced`, `Paid`,
38
+ `Cancelled`, `Recall`. `Job.jobType` is the highest categorisation (Call out, Installation,
39
+ Maintenance, Out of Hours, Reactive, Non-Productive); `Job.jobCategory` is the finer trade
40
+ detail. `Site.region` is one of `East`, `North`, `South`, `West`. `PurchaseOrder.status` is one
41
+ of `InProgress`, `Sent`, `Cancelled`, `NeedsApproval`; `PurchaseOrder.completionStatus` one of
42
+ `NotApplicable`, `NotCompleted`, `PartiallyCompleted`, `FullyCompleted`. Never write a sentinel
43
+ value for an unknown date — omit the property until the real value is known.
44
+
45
+ Two distinct invoice documents. The received supplier invoice is `InboundInvoice` (keyed
46
+ `(accountId, supplier, confirmationNumber)`), now linked to the `PurchaseOrder` it pays — a
47
+ subcontractor company's received invoice uses the same model as any other supplier. The
48
+ customer-facing outbound bill is the base `Invoice` (`schema-base.md`), whose billing chain is
49
+ the child `InvoiceLine`, `InvoicePayment`, and `Credit`. The two labels carry different required
50
+ fields (supplier vs customer), so they stay distinct rather than one label with a direction flag.
51
+
52
+ ## Child node types (write-time MERGE; reached via parent neighbourhood)
53
+
54
+ | Entity | Neo4j Label | Required Properties | Fidelity |
55
+ |--------|-------------|---------------------|----------|
56
+ | Quote line | `QuoteLine` | `accountId`, `jobId`, `trade`, `description`, `contractValue` | authored |
57
+ | Valuation | `Valuation` | `accountId`, `jobId`, `valuationNumber`, `date`, `totalValue` | authored |
58
+ | Milestone | `Milestone` | `accountId`, `jobId`, `name`, `completedDate` | authored |
59
+ | Variation | `VariationNote` | `accountId`, `jobId`, `variationNumber`, `description`, `totalPaymentDue`, `status` | authored |
60
+ | Job cost | `JobCost` | `accountId`, `costType` | JobLogic-exact |
61
+ | Contact | `Contact` | `accountId`, `contactId`, `name` | JobLogic-exact |
62
+ | PO line | `PurchaseOrderLine` | `accountId`, `poNumber`, `lineId`, `description`, `quantity`, `pricePerUnit` | JobLogic-exact |
63
+ | Invoice line | `InvoiceLine` | `accountId`, `invoiceId`, `lineId`, `description`, `quantity`, `amount` | authored |
64
+ | Invoice payment | `InvoicePayment` | `accountId`, `invoiceId`, `paymentId`, `amount`, `date`, `paymentType` | JobLogic-exact |
65
+ | Credit | `Credit` | `accountId`, `creditId`, `amount`, `date` | authored |
66
+
67
+ `JobCost.costType` is one of `labour`, `material`, `travel`, `mileage`, `expense`,
68
+ `subcontractor`, `scheduleOfRates` — the JobLogic cost-line taxonomy. A logged labour day (the
69
+ old check-in) is a `JobCost` with `costType:'labour'`. `JobCost.priceCalculationType` is `0`
70
+ (Non-Chargeable), `1` (Calculated Price), or `2` (Fixed Price), JobLogic's enum.
71
+
72
+ `QuoteLine` is one priced row of the `Quote` contract schedule — the line a `Valuation` measures
73
+ percent-complete against. It is **not** a `JobCost`: the quote line is the priced contract value,
74
+ the job cost is the incurred cost. Per-line percent-complete a valuation records is carried
75
+ valuation state, not a property of the line or the edge.
76
+
77
+ ## Additional labels on a base node
78
+
79
+ `Engineer` is an additional label on the field engineer's `:Person` (`accountId`, `engineerId`,
80
+ `name`, `engagement` (employee/cis), `dayRatePence`, `showCisDeduction`, `invoiceEmail`); there
81
+ is no standalone `:Engineer`. `Supplier` is an additional label on a supplier's `:Organization`
82
+ (`accountId`, `supplierId`, `accountNumber`); there is no standalone `:Supplier`. Both are set
83
+ via `memory-update`, mirroring how the field worker was modelled before the JobLogic adoption.
37
84
 
38
85
  ---
39
86
 
@@ -42,55 +89,103 @@ A field worker's time and pay is the `:Worker`/`:CheckIn` model. `:Worker` is an
42
89
  MERGE keys per label:
43
90
 
44
91
  - `:Job` — `(accountId, jobId)`
92
+ - `:Customer` — `(accountId, customerId)`
93
+ - `:Site` — `(accountId, siteId)`
94
+ - `:Asset` — `(accountId, assetId)`
95
+ - `:Visit` — `(accountId, visitId)`
96
+ - `:Quote` — `(accountId, ref)`
97
+ - `:InboundInvoice` — `(accountId, supplier, confirmationNumber)` — the received supplier invoice
98
+ - `:Invoice` — `(accountId, confirmationNumber)` — the base outbound customer invoice (schema-base.md)
99
+ - `:Part` — `(accountId, partId)`
100
+ - `:PurchaseOrder` — `(accountId, poNumber)`
101
+ - `:PpmContract` — `(accountId, contractId)`
102
+ - `:WhatsAppGroup` — `(accountId, groupId)`
103
+ - `:QuoteLine` — `(accountId, jobId, trade, description)` — child of `:Quote`, write-time MERGE
45
104
  - `:Valuation` — `(accountId, jobId, valuationNumber)`
46
- - `:QuoteDocument` — `(accountId, ref)`
105
+ - `:Milestone` — `(accountId, jobId, name)` — child of `:Job`, write-time MERGE
47
106
  - `:VariationNote` — `(accountId, jobId, variationNumber)`
48
- - `:InboundInvoice` — `(accountId, supplier, confirmationNumber)`
49
- - `:WhatsAppGroup` — `(accountId, groupId)`
50
- - `:LineItem` — `(accountId, jobId, trade, description)` — child of the `:QuoteDocument`, write-time MERGE only
51
- - `:Milestone` — `(accountId, jobId, name)` — child of `:Job`, write-time MERGE only
52
- - `:Worker` — `(accountId, personId)` — an additional label on the worker's `:Person`, set via `memory-update`
53
- - `:CheckIn` — `(accountId, personId, date)` — child of the worker's `:Person`, write-time MERGE only
107
+ - `:JobCost` — `(accountId, costId)` — write-time MERGE; `jobId` is set when the cost is job-scoped, omitted for a worker-day labour roll-up
108
+ - `:Contact` — `(accountId, contactId)` — write-time MERGE
109
+ - `:PurchaseOrderLine` — `(accountId, poNumber, lineId)` — child of `:PurchaseOrder`
110
+ - `:InvoiceLine` — `(accountId, invoiceId, lineId)` — child of `:Invoice`
111
+ - `:InvoicePayment` — `(accountId, invoiceId, paymentId)` — child of `:Invoice`
112
+ - `:Credit` — `(accountId, creditId)` — child of `:Invoice`
113
+ - `:Engineer` — `(accountId, personId)` — additional label on `:Person`, set via `memory-update`
114
+ - `:Supplier` — `(accountId, organizationId)` — additional label on `:Organization`
54
115
 
55
116
  ---
56
117
 
57
118
  ## Relationship Patterns
58
119
 
59
120
  ```
121
+ (:Job)-[:FOR_CUSTOMER]->(:Customer)
122
+ (:Customer)-[:HAS_SITE]->(:Site)
123
+ (:Job)-[:AT_SITE]->(:Site)
124
+ (:Site)-[:HAS_ASSET]->(:Asset)
125
+ (:Job)-[:HAS_VISIT]->(:Visit)
126
+ (:Visit)-[:ATTENDED_BY]->(:Engineer)
127
+ (:Job)-[:HAS_QUOTE]->(:Quote)
128
+ (:Quote)-[:HAS_LINE]->(:QuoteLine)
60
129
  (:Job)-[:HAS_VALUATION]->(:Valuation)
61
- (:Job)-[:HAS_MILESTONE]->(:Milestone)
62
- (:Job)-[:HAS_QUOTE]->(:QuoteDocument)
63
- (:QuoteDocument)-[:HAS_LINE_ITEM]->(:LineItem)
64
- (:Valuation)-[:VALUES]->(:LineItem)
130
+ (:Valuation)-[:VALUES]->(:QuoteLine)
65
131
  (:Job)-[:HAS_VARIATION]->(:VariationNote)
66
- (:Job)-[:FOR_CLIENT]->(:Person)
67
- (:Job)-[:AT_ADDRESS]->(:PostalAddress)
68
- (:InboundInvoice)-[:ASSIGNED_TO]->(:Job)
69
- (:InboundInvoice)-[:FROM_SUPPLIER]->(:Organization)
70
- (:Worker)-[:LOGGED]->(:CheckIn)
132
+ (:Job)-[:HAS_MILESTONE]->(:Milestone)
133
+ (:Job)-[:HAS_COST]->(:JobCost)
134
+ (:JobCost)-[:INCURRED_BY]->(:Engineer)
135
+ (:PurchaseOrder)-[:HAS_PO_LINE]->(:PurchaseOrderLine)
136
+ (:PurchaseOrderLine)-[:FOR_PART]->(:Part)
137
+ (:PurchaseOrder)-[:FROM_SUPPLIER]->(:Supplier)
138
+ (:InboundInvoice)-[:ON_PURCHASE_ORDER]->(:PurchaseOrder)
139
+ (:Invoice)-[:HAS_INVOICE_LINE]->(:InvoiceLine)
140
+ (:Invoice)-[:HAS_PAYMENT]->(:InvoicePayment)
141
+ (:Invoice)-[:HAS_CREDIT]->(:Credit)
142
+ (:PpmContract)-[:FOR_CUSTOMER]->(:Customer)
143
+ (:PpmContract)-[:COVERS_SITE]->(:Site)
144
+ (:Contact)-[:CONTACT_FOR]->(:Customer)
71
145
  (:WhatsAppGroup)-[:MAPPED_TO]->(:Job)
72
146
  ```
73
147
 
74
- Every `:Job` is the parent node for its valuations, milestones, quotes, and variations, satisfying the ≥1-adjacency write-gate doctrine. Line items are **not** a direct child of the `:Job`: a `:LineItem` is one row of the priced contract schedule, owned by the `:QuoteDocument` that priced it, and reached from the job through the quote — `(:Job)-[:HAS_QUOTE]->(:QuoteDocument)-[:HAS_LINE_ITEM]->(:LineItem)`. Each valuation links the lines it measures with `(:Valuation)-[:VALUES]->(:LineItem)`; the per-line percent-complete a valuation records is carried valuation state, not a property of the edge or the line. A `:Job` links to its client (`:Person`) and site (`:PostalAddress`); inbound supplier invoices link to the `:Job` they are assigned to and the `:Organization` that issued them.
148
+ Every `:Job` is the hub for its visits, quotes, valuations, variations, milestones, and costs,
149
+ satisfying the ≥1-adjacency write-gate doctrine. Quote lines are reached from the job through
150
+ the quote — `(:Job)-[:HAS_QUOTE]->(:Quote)-[:HAS_LINE]->(:QuoteLine)` — and each valuation links
151
+ the lines it measures with `(:Valuation)-[:VALUES]->(:QuoteLine)`. A job links to its customer
152
+ and site; an asset hangs off the site it lives at. Costs link to the engineer who incurred them.
153
+ Procurement is a `:PurchaseOrder` of `:PurchaseOrderLine`s for `:Part`s from a `:Supplier`; the
154
+ received supplier invoice is an `:InboundInvoice` on that PO. A `:PpmContract` is a
155
+ planned-maintenance agreement for a customer/site, distinct from a reactive `:Job`.
75
156
 
76
157
  ---
77
158
 
78
159
  ## Filesystem ↔ graph (base template)
79
160
 
80
- The graph is a disciplined projection of the operator's job folder: every node corresponds to a filesystem artefact, and the edges follow the folder containment. This mapping is the **base template** — the default a standard building-contractor job folder projects into. It is shipped-generic; the folder names, sheet names and trade list below are the common default, not any operator's data.
161
+ The graph is the canonical ontology; the operator's job folder is a conforming projection of it.
162
+ Every node corresponds to a filesystem artefact, and the edges follow the folder containment.
163
+ This mapping is the **base template** — the default a standard field-service job folder projects
164
+ into. It is shipped-generic; the folder names below are the common default, not any operator's
165
+ data. On any divergence, the graph is canonical.
81
166
 
82
167
  A standard job folder, `{jobId} - {name}, {address} ({client})/`, projects as:
83
168
 
84
169
  | Folder / artefact | Node | Edge from the job |
85
170
  |---|---|---|
86
- | the job folder itself | `:Job` | — (the hub); `(:Job)-[:FOR_CLIENT]->(:Person)`, `(:Job)-[:AT_ADDRESS]->(:PostalAddress)` |
87
- | `Quotations/` — the client quote (`Q {jobId}`) and its priced schedule | `:QuoteDocument`; its priced rows → `:LineItem` | `(:Job)-[:HAS_QUOTE]->(:QuoteDocument)-[:HAS_LINE_ITEM]->(:LineItem)` |
88
- | `Finances/Valuations/` — one interim valuation per cycle | `:Valuation`; each measures the priced lines | `(:Job)-[:HAS_VALUATION]->(:Valuation)-[:VALUES]->(:LineItem)` |
171
+ | the job folder itself | `:Job` | — (the hub); `(:Job)-[:FOR_CUSTOMER]->(:Customer)`, `(:Job)-[:AT_SITE]->(:Site)` |
172
+ | `Quotations/` — the client quote and its priced schedule | `:Quote`; its priced rows → `:QuoteLine` | `(:Job)-[:HAS_QUOTE]->(:Quote)-[:HAS_LINE]->(:QuoteLine)` |
173
+ | `Finances/Valuations/` — one interim valuation per cycle | `:Valuation`; each measures the priced lines | `(:Job)-[:HAS_VALUATION]->(:Valuation)-[:VALUES]->(:QuoteLine)` |
89
174
  | the variations register | `:VariationNote` | `(:Job)-[:HAS_VARIATION]->(:VariationNote)` |
90
- | `Contractors/<Trade>/{Enquiries,Quotes,Invoices,Superseded}` | `:Organization`; invoices `:InboundInvoice` | `(:InboundInvoice)-[:ASSIGNED_TO]->(:Job)`, `(:InboundInvoice)-[:FROM_SUPPLIER]->(:Organization)` |
91
- | `Suppliers/<Supplier>/{Enquiries,Quotes,Invoices,Superseded}` | `:Organization`; invoices `:InboundInvoice` | `(:InboundInvoice)-[:ASSIGNED_TO]->(:Job)`, `(:InboundInvoice)-[:FROM_SUPPLIER]->(:Organization)` |
92
- | `Drawings/`, `Health & Safety/`, `Emails/`, `Snagging/`, `Meetings/`, `Programs/`, `Materials/`, `Admin/` | ingested documents (`:KnowledgeDocument` + `:Section`) | linked to the `:Job` |
93
-
94
- A contractor who keeps the whole job in one master workbook holds the same model in sheets rather than folders: a cover/calculation sheet is the priced schedule (`:QuoteDocument` + `:LineItem`s), one sheet per valuation cycle is a `:Valuation` measuring those lines, a variations sheet is the `:VariationNote` register, and per-trade sheets are the sub-contractor packages. Folder and workbook are two views of one job; both project into this same graph.
95
-
96
- Operators vary this template — they rename folders, add trades, restructure their workbook. This template is the shipped-generic default the agent projects against; the graph follows this one canonical ontology, not a per-operator schema. Where a real folder does not fit the default, the agent maps it to the nearest canonical node rather than inventing a node or edge type absent from this reference.
175
+ | `Costs/` — labour days, materials, travel, mileage, expenses, subcontractor | `:JobCost` (by `costType`) | `(:Job)-[:HAS_COST]->(:JobCost)-[:INCURRED_BY]->(:Engineer)` |
176
+ | `Visits/` attendance records | `:Visit` | `(:Job)-[:HAS_VISIT]->(:Visit)-[:ATTENDED_BY]->(:Engineer)` |
177
+ | `Suppliers/<Supplier>/{Quotes,POs,Invoices}` | `:Organization:Supplier`; POs `:PurchaseOrder`+`:PurchaseOrderLine`; received invoices `:InboundInvoice` | `(:PurchaseOrder)-[:FROM_SUPPLIER]->(:Supplier)`, `(:InboundInvoice)-[:ON_PURCHASE_ORDER]->(:PurchaseOrder)` |
178
+ | `Assets/` — serviced plant on the site | `:Asset` | `(:Site)-[:HAS_ASSET]->(:Asset)` |
179
+ | `Drawings/`, `Health & Safety/`, `Emails/`, `Snagging/`, `Admin/` | ingested documents (`:KnowledgeDocument` + `:Section`) | linked to the `:Job` |
180
+
181
+ A contractor who keeps the whole job in one master workbook holds the same model in sheets
182
+ rather than folders: a cover/calculation sheet is the priced schedule (`:Quote` + `:QuoteLine`s),
183
+ one sheet per valuation cycle is a `:Valuation`, a variations sheet is the `:VariationNote`
184
+ register, a costs sheet is the `:JobCost` lines, and per-supplier sheets are the procurement
185
+ packages. Folder and workbook are two views of one job; both project into this same graph.
186
+
187
+ Operators vary this template — they rename folders, add trades, restructure their workbook. This
188
+ template is the shipped-generic default the agent projects against; the graph follows this one
189
+ canonical ontology, not a per-operator schema. Where a real folder does not fit the default, the
190
+ agent maps it to the nearest canonical node rather than inventing a node or edge type absent from
191
+ this reference.
@@ -1,36 +1,34 @@
1
1
  # Schema Reference — Trades
2
2
 
3
- Vertical schema for `businessType: "trades"` — home services, construction, and tradespeople (plumber, electrician, builder, decorator).
3
+ Vertical schema for `businessType: "trades"` — home services and tradespeople (plumber,
4
+ electrician, builder, decorator). Trades and construction share the **one canonical SiteDesk
5
+ service-delivery ontology** authored from JobLogic (see `schema-construction.md` for the full
6
+ label set, properties, idempotency keys, relationships, and the filesystem↔graph template).
7
+ There are no trades-specific labels that diverge from the canonical model.
4
8
 
5
- This reference extends the base schema. All base node types (Person, Organization, Order, Event, Invoice, Service, etc.) remain valid. Load `schema-base.md` first.
9
+ This reference extends the base schema. All base node types (Person, Organization, Order, Event,
10
+ Invoice, Service, etc.) remain valid. Load `schema-base.md` first.
6
11
 
7
12
  When loading this reference, confirm: "Using schema-base + schema-trades".
8
13
 
9
14
  ---
10
15
 
11
- ## Additional Node Types
16
+ ## Canonical labels for the trades case
12
17
 
13
- | Entity | Neo4j Label | Schema.org Type | Required Properties |
14
- |--------|-------------|-----------------|---------------------|
15
- | Quote | `Quote` | `schema:Order` + `cdm:Opportunity` | `accountId`, `quoteNumber`, `customer` (id), `lineItems`, `validUntil`, `totalPrice` |
16
- | SiteVisit | `SiteVisit` | `schema:Event` (subtype) | `accountId`, `address` (id), `engineer` (id), `startDate`, `purpose` |
17
- | Inspection | `Inspection` | `cdm:Case` (subtype) | `accountId`, `address` (id), `findings`, `recommendations`, `photos` |
18
- | Certification | `Certification` | `schema:DigitalDocument` | `accountId`, `type` (gas safe, NICEIC, etc.), `issuedDate`, `expiryDate` |
19
- | Material | `Material` | `schema:Product` | `accountId`, `name`, `sku`, `unitCost`, `supplier` (id) |
18
+ A tradesperson's work maps onto the same canonical labels as a contractor's:
20
19
 
21
- ### Quote vs base Order
20
+ | Trades concept | Canonical label | Notes |
21
+ |----------------|-----------------|-------|
22
+ | The job / call-out | Job | `jobType` distinguishes Call out / Installation / Maintenance / Reactive |
23
+ | Customer and the work address | Customer, Site | site is the work location, distinct from the customer |
24
+ | An attendance / site visit | Visit | the lifecycle attendance record on a job (was the homegrown SiteVisit) |
25
+ | The estimate / quote | Quote, QuoteLine | priced estimate and its lines |
26
+ | Parts and materials used | Part, JobCost (costType material) | catalogue part vs the incurred material cost on a job |
27
+ | Serviced equipment on site | Asset | boiler, AC unit, alarm panel, etc. |
28
+ | A planned-maintenance agreement | PpmContract | recurring service contract, distinct from a reactive Job |
22
29
 
23
- `Quote` is the trades-specific label for estimates and quotes before acceptance. Use `Quote` (not `Order`) when the work is proposed but not yet confirmed. Once a quote is accepted, create a base `Order` node linked to it, or update the Quote's `orderStatus` to reflect acceptance.
30
+ Trade certifications (Gas Safe, NICEIC, Part P) a person holds are recorded as a credential on
31
+ that person's `:Person` node via the base credential model, not as a separate construction label.
32
+ Inspection findings are recorded as notes/documents on the `:Visit` or `:Asset` they concern.
24
33
 
25
- ---
26
-
27
- ## Relationship Patterns
28
-
29
- ```
30
- (:Order)-[:REQUIRES_VISIT]->(:SiteVisit)
31
- (:Order)-[:USES_MATERIAL]->(:Material)
32
- (:SiteVisit)-[:AT_ADDRESS]->(:PostalAddress)
33
- (:Certification)-[:HELD_BY]->(:Person)
34
- ```
35
-
36
- The `(:Certification)-[:HELD_BY]->(:Person)` relationship tracks which staff member holds a trade certification (e.g., Gas Safe, NICEIC, Part P).
34
+ See `schema-construction.md` for the authoritative definition of every label above.
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAkB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAqMtD,CAAA"}
1
+ {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAmB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAkPtD,CAAA"}
@@ -14,6 +14,7 @@ export const MAXY_MCP_PLUGINS = [
14
14
  "email",
15
15
  "graph",
16
16
  "graph-viewer",
17
+ "joblogic",
17
18
  "memory",
18
19
  "outlook",
19
20
  "quickbooks",
@@ -109,6 +110,51 @@ export const CANONICAL_MAXY_TOOL_NAMES = [
109
110
  "mcp__plugin_graph_graph__maxy-graph-get_neo4j_schema",
110
111
  "mcp__plugin_graph_graph__maxy-graph-read_neo4j_cypher",
111
112
  "mcp__plugin_graph_graph__maxy-graph-write_neo4j_cypher",
113
+ "mcp__plugin_joblogic_joblogic__joblogic-asset-create",
114
+ "mcp__plugin_joblogic_joblogic__joblogic-asset-get",
115
+ "mcp__plugin_joblogic_joblogic__joblogic-asset-list",
116
+ "mcp__plugin_joblogic_joblogic__joblogic-asset-update",
117
+ "mcp__plugin_joblogic_joblogic__joblogic-attachment-url-generate",
118
+ "mcp__plugin_joblogic_joblogic__joblogic-connection-status",
119
+ "mcp__plugin_joblogic_joblogic__joblogic-credentials-set",
120
+ "mcp__plugin_joblogic_joblogic__joblogic-customer-create",
121
+ "mcp__plugin_joblogic_joblogic__joblogic-customer-get",
122
+ "mcp__plugin_joblogic_joblogic__joblogic-customer-list",
123
+ "mcp__plugin_joblogic_joblogic__joblogic-customer-update",
124
+ "mcp__plugin_joblogic_joblogic__joblogic-engineer-get",
125
+ "mcp__plugin_joblogic_joblogic__joblogic-engineer-list",
126
+ "mcp__plugin_joblogic_joblogic__joblogic-engineer-map-list",
127
+ "mcp__plugin_joblogic_joblogic__joblogic-engineer-map-set",
128
+ "mcp__plugin_joblogic_joblogic__joblogic-invoice-create",
129
+ "mcp__plugin_joblogic_joblogic__joblogic-invoice-get",
130
+ "mcp__plugin_joblogic_joblogic__joblogic-invoice-list",
131
+ "mcp__plugin_joblogic_joblogic__joblogic-invoice-payment-create",
132
+ "mcp__plugin_joblogic_joblogic__joblogic-job-approve",
133
+ "mcp__plugin_joblogic_joblogic__joblogic-job-create",
134
+ "mcp__plugin_joblogic_joblogic__joblogic-job-get",
135
+ "mcp__plugin_joblogic_joblogic__joblogic-job-list",
136
+ "mcp__plugin_joblogic_joblogic__joblogic-job-set-status",
137
+ "mcp__plugin_joblogic_joblogic__joblogic-job-update",
138
+ "mcp__plugin_joblogic_joblogic__joblogic-jobcost-create",
139
+ "mcp__plugin_joblogic_joblogic__joblogic-jobcost-update",
140
+ "mcp__plugin_joblogic_joblogic__joblogic-note-create",
141
+ "mcp__plugin_joblogic_joblogic__joblogic-quote-approve",
142
+ "mcp__plugin_joblogic_joblogic__joblogic-quote-create",
143
+ "mcp__plugin_joblogic_joblogic__joblogic-quote-get",
144
+ "mcp__plugin_joblogic_joblogic__joblogic-quote-list",
145
+ "mcp__plugin_joblogic_joblogic__joblogic-site-create",
146
+ "mcp__plugin_joblogic_joblogic__joblogic-site-get",
147
+ "mcp__plugin_joblogic_joblogic__joblogic-site-list",
148
+ "mcp__plugin_joblogic_joblogic__joblogic-site-update",
149
+ "mcp__plugin_joblogic_joblogic__joblogic-timesheet-create",
150
+ "mcp__plugin_joblogic_joblogic__joblogic-timesheet-list",
151
+ "mcp__plugin_joblogic_joblogic__joblogic-timesheet-update",
152
+ "mcp__plugin_joblogic_joblogic__joblogic-visit-cancel",
153
+ "mcp__plugin_joblogic_joblogic__joblogic-visit-create",
154
+ "mcp__plugin_joblogic_joblogic__joblogic-visit-deploy",
155
+ "mcp__plugin_joblogic_joblogic__joblogic-visit-get",
156
+ "mcp__plugin_joblogic_joblogic__joblogic-visit-search-planner",
157
+ "mcp__plugin_joblogic_joblogic__joblogic-visit-update",
112
158
  "mcp__plugin_memory_memory__conversation-archive-derive-insights",
113
159
  "mcp__plugin_memory_memory__conversation-archive-enrich-rejection",
114
160
  "mcp__plugin_memory_memory__conversation-archive-list-chunks",
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
@@ -21,13 +21,13 @@ maths ([references/roll-up.md](references/roll-up.md)), and the two documents
21
21
  ## Two surfaces
22
22
 
23
23
  - **Worker setup (per worker, once).** Capture the worker's engagement, day rate, UTR (CIS only),
24
- whether the 20% deduction shows, and the office invoice address. Store it as the `:Worker` config
24
+ whether the 20% deduction shows, and the office invoice address. Store it as the `:Engineer` config
25
25
  on his `:Person`. The worker logs his days through the receive-only `worker-checkin` agent; the
26
26
  platform's multi-channel transport delivers those messages into one session.
27
27
 
28
28
  - **Roll-up (operator-run, per period).** For a worker (or all workers) and a period:
29
29
  1. Read his check-ins for the period by `personId` — structure the worker's delivered messages
30
- into `:CheckIn` records (one per working day) at this point.
30
+ into `:JobCost` records (one per working day) at this point.
31
31
  2. Run `rollup.mjs compute <worker.json> <checkins.json>` — never compute by hand.
32
32
  3. Render the timesheet (and, for CIS, the invoice) from the computed figures.
33
33
  4. Run `rollup.mjs reconcile <computed.json> <netPence> <dayHundredths>` — both gates must pass.
@@ -2,30 +2,35 @@
2
2
 
3
3
  This skill ships these shapes, never a worker's data.
4
4
 
5
- ## `:Worker` (operator config, one per worker)
5
+ ## `:Engineer` (operator config, one per worker)
6
6
 
7
- `(:Worker { personId, accountId, name, engagement: "employee"|"cis", dayRatePence,
7
+ `(:Engineer { personId, accountId, name, engagement: "employee"|"cis", dayRatePence,
8
8
  utr?, showCisDeduction: bool, invoiceEmail, createdAt })`
9
9
 
10
10
  `personId` ties the worker to his `:Person`. `dayRatePence` is integer pence. `utr` is present
11
11
  only for `engagement: "cis"`. `invoiceEmail` is the office invoice address. Captured by the
12
12
  operator at runtime (see [setup.md](setup.md)), never written into this tree.
13
13
 
14
- ## `:CheckIn` (one per working day, keyed to the worker, not the transport)
14
+ ## `:JobCost` (one labour cost per working day, `costType: "labour"`)
15
15
 
16
- `(:CheckIn { personId, accountId, source, receivedAt,
16
+ `(:JobCost { costId, costType: "labour", personId, accountId, source, receivedAt,
17
17
  date, site, description, dayHundredths, createdAt })`
18
18
 
19
- `personId` is the unifying key the roll-up reads every `:CheckIn` for the worker regardless of
20
- which channel produced it. `source` records the channel the message arrived on (`web`, `whatsapp`,
21
- …). `dayHundredths` is 100 for a full day; a smaller value only when the operator enabled part-day
22
- handling. One `:CheckIn` per working day.
23
-
24
- Each `:CheckIn` is linked to its worker's `:Person` with the canonical edge
25
- `(:Worker)-[:LOGGED]->(:CheckIn)` the edge type is fixed by `schema-construction.md`; write no
26
- edge type absent from it. The edge satisfies the write-doctrine adjacency requirement (a node is
27
- written with at least one relationship); `personId` carries the same identity for roll-up reads.
19
+ A logged labour day is an incurred labour cost. `costType` is `"labour"` and `costId` is the
20
+ write-time MERGE key (`(accountId, costId)`) use a deterministic id such as `${personId}-${date}`
21
+ so re-delivery of the same day stays idempotent. `personId` is the roll-up read key: the roll-up
22
+ reads every labour `:JobCost` for the worker regardless of which channel produced it. `source`
23
+ records the channel the message arrived on (`web`, `whatsapp`, …). `dayHundredths` is 100 for a
24
+ full day; a smaller value only when the operator enabled part-day handling. One labour `:JobCost`
25
+ per working day.
26
+
27
+ Each `:JobCost` is linked to the engineer who incurred it with the canonical edge
28
+ `(:JobCost)-[:INCURRED_BY]->(:Engineer)` (an additional label on that worker's `:Person`), and to
29
+ its job with `(:Job)-[:HAS_COST]->(:JobCost)` — the edge types are fixed by
30
+ `schema-construction.md`; write no edge type absent from it. The edge satisfies the write-doctrine
31
+ adjacency requirement (a node is written with at least one relationship); `personId` carries the
32
+ same identity for roll-up reads.
28
33
 
29
34
  These records come from the worker's delivered messages. The platform's multi-channel transport
30
- delivers those messages into one session; the step that turns them into `:CheckIn` records is this
35
+ delivers those messages into one session; the step that turns them into `:JobCost` records is this
31
36
  skill's roll-up (structure at roll-up — see [roll-up.md](roll-up.md)).
@@ -7,7 +7,7 @@ operator's data; every figure comes from the roll-up engine, displayed never rec
7
7
  ## Timesheet — data regions (all required)
8
8
 
9
9
  - **Header** — worker name, period, office.
10
- - **Day schedule** — one row per `:CheckIn`: date, site, description, day count (full/part).
10
+ - **Day schedule** — one row per `:JobCost`: date, site, description, day count (full/part).
11
11
  - **Day total** — the sum of the day counts. This is the figure the `reconcile` day gate checks.
12
12
 
13
13
  ## Invoice — data regions (all required)
@@ -7,7 +7,7 @@ are computed by `rollup.mjs`, never by hand. The engine carries no operator cont
7
7
 
8
8
  A worker's daily messages arrive over whatever channel and the platform delivers them into one session.
9
9
  At roll-up time, read the worker's messages for the period and structure each working day into one
10
- `:CheckIn` (see [checkin-contract.md](checkin-contract.md)): `date`, `site`, `description`,
10
+ `:JobCost` (see [checkin-contract.md](checkin-contract.md)): `date`, `site`, `description`,
11
11
  `dayHundredths`. One message-day = one check-in. Structuring happens here, in the operator-run step,
12
12
  not in the unattended receive path — so the operator can review before anything is sent.
13
13
 
@@ -33,8 +33,8 @@ valuation reconciles and is filed.
33
33
 
34
34
  ## Two surfaces
35
35
 
36
- - **Job setup (once).** Create or update the `:Job` and the `:QuoteDocument` the job is priced
37
- from; seed the contract-works schedule as `:LineItem`s **on that `:QuoteDocument`** (not on the
36
+ - **Job setup (once).** Create or update the `:Job` and the `:Quote` the job is priced
37
+ from; seed the contract-works schedule as `:QuoteLine`s **on that `:Quote`** (not on the
38
38
  `:Job`) from the generic contract-stage template
39
39
  ([references/contract-template.md](references/contract-template.md)), then take the operator's
40
40
  adjustments to descriptions, contract values and provisional sums; record the contract sum, VAT
@@ -81,18 +81,18 @@ fixed document is the defect.
81
81
 
82
82
  The job uses the existing construction-schema nodes **and relationships** as defined in
83
83
  `schema-construction.md`, the authority for both the node labels and the edge types; this skill
84
- invents neither. `:Job` is the hub: it links to its client `:Person` (`FOR_CLIENT`), site
85
- `:PostalAddress` (`AT_ADDRESS`), `:QuoteDocument` (`HAS_QUOTE`), `:Valuation`s (`HAS_VALUATION`)
84
+ invents neither. `:Job` is the hub: it links to its `:Customer` (`FOR_CUSTOMER`), its `:Site`
85
+ (`AT_SITE`), `:Quote` (`HAS_QUOTE`), `:Valuation`s (`HAS_VALUATION`)
86
86
  and `:VariationNote`s (`HAS_VARIATION`).
87
87
 
88
- Line items are owned by the quote, not the job: a `:LineItem` is one row of the priced contract
89
- schedule, held under the `:QuoteDocument` (`(:QuoteDocument)-[:HAS_LINE_ITEM]->(:LineItem)`) and
88
+ Line items are owned by the quote, not the job: a `:QuoteLine` is one row of the priced contract
89
+ schedule, held under the `:Quote` (`(:Quote)-[:HAS_LINE]->(:QuoteLine)`) and
90
90
  reached from the job through the quote. Each issued valuation links the lines it measures with
91
- `(:Valuation)-[:VALUES]->(:LineItem)`.
91
+ `(:Valuation)-[:VALUES]->(:QuoteLine)`.
92
92
 
93
93
  The nodes are idempotent on their natural keys — `:Valuation` on
94
94
  `(accountId, jobId, valuationNumber)`, `:VariationNote` on `(accountId, jobId, variationNumber)`,
95
- `:LineItem` on `(accountId, jobId, trade, description)`. Per-line `% complete`, per-line comment
95
+ `:QuoteLine` on `(accountId, jobId, trade, description)`. Per-line `% complete`, per-line comment
96
96
  and per-variation `% complete` are **carried cycle state**, not fixed node properties — they live
97
97
  in `engine-state.json` and the `:Valuation` snapshot body, never as new labels or properties; the
98
98
  `VALUES` edge only identifies which lines a valuation measures, it does not carry the percentage.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Job setup seeds the contract-works schedule from a generic new-build stage list. This template
4
4
  is **stage names only**: it carries no values, no rates, no quantities, and no client data. Its
5
- sole purpose is to give the operator a familiar starting skeleton of `:LineItem` rows to adjust.
5
+ sole purpose is to give the operator a familiar starting skeleton of `:QuoteLine` rows to adjust.
6
6
 
7
7
  A standard new-build sequence:
8
8
 
@@ -22,7 +22,7 @@ A standard new-build sequence:
22
22
 
23
23
  ## How it seeds a job
24
24
 
25
- At setup, each stage name becomes one `:LineItem` with an empty contract value. The operator
25
+ At setup, each stage name becomes one `:QuoteLine` with an empty contract value. The operator
26
26
  then adjusts: renames or removes stages that do not apply, adds stages the job has, and sets
27
27
  each line's contract value and any provisional sums — all from the operator's own contract, none
28
28
  of it carried here. A job whose schedule looks nothing like a new-build (a refurbishment, a
@@ -80,9 +80,9 @@ an unrelated purge, so nothing keys off it. Carry the per-line and per-variation
80
80
 
81
81
  Connect the `:Valuation` to its job with the canonical edge `(:Job)-[:HAS_VALUATION]->(:Valuation)`
82
82
  — never an invented type such as `VALUATION_FOR`. Link the lines this valuation measures with
83
- `(:Valuation)-[:VALUES]->(:LineItem)`, reading those lines through the quote
84
- (`(:Job)-[:HAS_QUOTE]->(:QuoteDocument)-[:HAS_LINE_ITEM]->(:LineItem)`) — line items belong to the
85
- `:QuoteDocument`, never written directly onto the `:Job`. The edge types are fixed by
83
+ `(:Valuation)-[:VALUES]->(:QuoteLine)`, reading those lines through the quote
84
+ (`(:Job)-[:HAS_QUOTE]->(:Quote)-[:HAS_LINE]->(:QuoteLine)`) — line items belong to the
85
+ `:Quote`, never written directly onto the `:Job`. The edge types are fixed by
86
86
  `schema-construction.md`; write no edge type absent from it. Account scope is the `accountId`
87
87
  property, never an ownership edge.
88
88