Commercial services: exploratory module cleanup
Status: implemented on 9 September 2026. Felix removed the four exploratory modules and Original Baseline lookup in CRM; live metadata confirms their absence. The retained records and fresh MSP report are verified after deletion.
The commercial service design retains Commercial Services, native Invoices and the existing MSP Invoice Lines module. Labour, cost and recurrence extensions for the Tech Project pilot remain separate work.
Implemented changes
| Location | Implemented result |
|---|---|
| Invoices | Optional Commercial_Service lookup with Commercial Invoices related list; 135 confirmed header links |
| MSP Invoice Lines | Optional Commercial_Service lookup with Service Lines related list; all 166 existing lines linked |
| MSP Invoice Lines Standard layout | Plan is optional; Product remains required |
| Existing records | All Plan links, Products, quantities, prices, dates, invoice IDs and native items are preserved |
| Live reporting | Retained CRM records plus Xero actuals and immutable historical ownership; no reads of the four selected modules |
| Exploratory migration writers | Module creation and record writes to the four selected modules are rejected |
The other 161 native Invoices remain unassigned: 160 have insufficient service evidence, and INV-0299 has a pre-existing mismatch between its Xero customer and its CRM Plan/service customer. The cleanup-added header on INV-0299 was removed with a conditional write and readback; its original Plan and financial values are preserved. The report keeps its revenue visible as unreviewed ownership.
The lookup backfill updates only Commercial Service, disables workflows, compares modification timestamps and business before-images, and reads the saved records back. Already-correct relationships are unchanged on repeat; differing relationships or business changes are preserved for review. The invoice header represents one service; mixed-service documents use item attribution. Adding a line without Plan does not enrol it in MSP generation.
Reporting and preserved evidence
The MSP page retains its configured Seat expectations, signed billed Product costs and actual work-date labour costs. The July-onward contribution report retains invoices, credits, reviewed work ownership and source-drift checks. Xero remains the source of financial values; no invoice is created or changed in Xero. The six native MSP pilot invoices retain their item/source mappings.
config/commercial_service_attribution.json preserves 815 historical invoice
and credit ownership mappings across 159 documents, plus 106 reviewed ownership
links. It stores identities, Product/Quote-row references, coverage and source
fingerprints, not a financial ledger. The report obtains financial values from
Xero and rejects changed or missing source evidence. The retained work mapping
uses migration keys for the legacy timelog reader; new service lines contain no
Delivery Model or Qwilr reference. This bridge is historical, not a new CRM module.
All 71 exploratory terms and 79 labour budgets were Needs Review. They remain
in the private archive and are not promoted into approved shared-line budgets.
The original-baseline and cumulative historical-position extension is retired
from live collection. Current MSP expectations remain available; the Tech Project
pilot will define its own labour amount and unit on the shared line.
Removed CRM structures
The Original Baseline lookup is absent from Commercial Services. Its 24 populated values are archived; live reporting does not consume it.
These custom modules are absent; counts refer to their archived active records:
- Service Labour Budgets (
Service_Labour_Budgets, 79 records). - Service Terms (
Service_Terms, 71 records). - Service Source Links (
Service_Source_Links, 106 records). - Service Invoice Lines (
Service_Invoice_Lines, 815 records).
The archive retains the Service_Labour_Budgets.Terms dependency; Budgets was
removed before Terms. Retained modules include MSP Invoice Lines,
Commercial Services,
Managed Services Plans, Invoices and Invoiced Items. There is no module
rename in this batch. Products, Deals, Delivery Models, Seats and Projects are
outside the deletion scope.
The selected Gidget invoice has no native CRM Invoice with that Xero ID in the capture. Its future mirror and Consulting line belong to the Tech Project pilot.
Verification and private archive
Private evidence is under .local/commercial-services/module-cleanup-20260909/,
excluded from Git and stored with owner-only permissions:
- Full source records, fields, layouts and workflows; exact module IDs and dependency scan; invoice before-images and reviewed lookup proposals.
- Per-record write journals, saved-record readbacks and retained-record checks.
- Notes, attachment, email and activity checks for the selected modules.
- Server code manifests, deployment results and verification controls.
The source metadata scan found the two Terms lookups described above and no workflows on the four selected modules. The CRM UI deletion was completed by Felix. The archive is not a claim that every CRM platform asset can be restored.
Verification confirms 112 Commercial Services, 26 Plans, 296 Invoices and 166 shared lines remain. All 296 invoice before-images and native items are preserved; 135 headers are linked, and all 166 shared lines retain Plan and service links. Plan is optional and Product remains required. Notes, attachments and email relationships were checked across all 1,071 selected records; no related records or linked Tasks, Events or Calls were found.
A fresh deployed MSP report passed after deletion, with both selected services, 45 invoice/credit rows and billed revenue of AUD 27,725.87 through 9 September. The authenticated dashboard and review endpoint return HTTP 200; unauthenticated requests return HTTP 401. The 773-test suite and strict documentation build pass.
The full-business export retains its source-drift guard. It flags INV-22223031, which is VOIDED in current Xero but was AUTHORISED in the pre-cleanup capture. The missing posted-source key is identical in the archive and reporting bridge, so the cleanup has not introduced or hidden this discrepancy. Its source delta requires a separate review; the two-service MSP page is unaffected.
Implementation: commercial_services/cleanup.py, retired.py,
app/commercial_margin/attribution.py, report.py, services.py, engine.py.
Process rules: shared service records.