Implementation status
What has actually been built
This report separates working code from earlier UI work, uncommitted local changes, open tickets, and work that has not yet been deployed to Cloudflare.
Standardized model tickets
All nine tickets for the shared SaaS data-model pass are closed in Beads.
Automated verification
TypeScript test suite passed, plus 3 deployment tests.
Live production state
No live D1 migration or Cloudflare deployment was performed in this pass.
The core change
Grist is now treated as seed data, not the product model
The implementation defines a canonical Reorderly model first. Selva Grist data is transformed into that model through import and normalization code. The app is no longer supposed to copy every Grist table and column directly into D1.
Working code
What was implemented
- Shared contracts: organizations, suppliers, locations, planning windows, demand rates, and canonical product types such as
raw_material,finished_product,subassembly, andpackaging. - Source adapters: CSV support plus contracts for source artifacts, field mappings, unmapped columns, import previews, and import batches. Source identity remains traceable.
- Canonical normalization: source rows are converted into normalized customers, suppliers, products, inventory snapshots, supply events, stock movements, and BOM records. The normalization layer handles legacy Selva shapes for compatibility.
- Inventory snapshots: inventory is modeled as a time-stamped snapshot, so a missing SKU in a newer upload means it is absent from that snapshot rather than an instruction to keep carrying an old row forward.
- Planning and replenishment: planning windows are data-driven rather than hardcoded to a client-specific 3M/6M field. The shared model supports projection and replenishment calculations.
- Optional manufacturing: BOM support is capability-gated. A tenant can use the common inventory model without being forced to use manufacturing tables.
- Tenant capabilities: the platform now has a capability boundary for modules such as manufacturing, instead of treating BOM as universal for every tenant.
- Selva and Derwent validation: both tenant shapes have adapter/fixture validation against the shared contracts, without forking the app into two unrelated data models.
- Import identity fix: the Grist importer now preserves dataset identity in import results instead of losing it during processing.
- Optional BOM persistence test: there is explicit coverage proving BOM persistence is optional and does not break non-manufacturing paths.
Canonical data shape
How the main tables are intended to relate
| Area | Canonical role | What it is not |
|---|---|---|
| Items / products | One item master with ID, SKU, description, type, and shared identity fields. | Not a raw-material-only table and not a direct dump of one Grist table. |
| BOM lines | A parent item points to a component item with a quantity. This supports multi-level parent-child structures. | Not the ordering queue. It is only enabled for manufacturing tenants. |
| Locations | Warehouses and other stock locations are first-class records. | Not a market label hidden inside a product name. |
| Inventory snapshots | A dated upload records the stock state for a location and SKU at that point in time. | Not an accumulating transaction ledger. |
| Supply events | Incoming commitments such as purchase orders or expected receipts. | Not the same thing as the current stock snapshot. |
| Stock movements | Transactions that change stock, such as receipts, transfers, production consumption, and spoilage. | Not a replacement for accounting documents. Accounting documents can be mapped into movements. |
| Replenishment | A decision projection over the latest relevant inventory snapshot, demand rate, lead time, policy, and supply commitments. | Not a second copy of the inventory table. |
| Customers and sales | Canonical customer/account identities with sales lines linked through source mappings. | Not a requirement to query Xero or Zoho one account at a time in the UI. |
Tickets
Standardized SaaS-model pass
| Ticket | Delivered | Status |
|---|---|---|
SRD-czk.19 | Cross-client canonical data contracts and Selva/Derwent validation fixtures. | Closed |
SRD-czk.20 | Adapter and upload mapping contract. | Closed |
SRD-czk.21 | Customer, supplier, sales, and accounting identity normalization. | Closed |
SRD-czk.22 | Locations, inventory snapshots, supply events, and stock movements. | Closed |
SRD-czk.23 | Replenishment policies and planning projection. | Closed |
SRD-czk.24 | Optional manufacturing and BOM capability. | Closed |
SRD-czk.25 | Selva Grist seed-data migration path. | Closed |
SRD-czk.26 | Derwent data mapping. | Closed |
SRD-czk.27 | Organization capability and onboarding model. | Closed |
History and UI
What was already present before this architecture pass
The repository already contains earlier UI work for shared filters, snapshot controls, attached table filters, data tables, burn-window controls, saved views, raw D1 browsing, and Products/BOM presentation. Earlier commits include ffc0162, b5ee5ac, and 9d36652.
The current worktree also contains further UI edits to the table, saved views, burn-window toggle, raw-data browser, Products/BOM table, dashboard, buttons, and global styles. Those edits are present locally but are not part of the architecture commits listed above and have not been committed in this pass.
That distinction matters: the canonical backend/data-model work is verified in commits; the latest visual/UI changes still need a focused review and should not be treated as finished just because files changed.
Verification
What was checked
npm run lintpassed.npm run typecheckpassed.npm testpassed with 105 tests.- Deployment tests passed: 3 tests.
git diff --checkpassed.- A code-review pass confirmed the architecture commits did not accidentally include the unrelated UI worktree edits.
The build still reports the project’s existing chunk-size and dynamic-API classification warnings. They did not fail verification.
Not done yet
Remaining work and limits
- No live D1 migration: the schema migrations exist in the repository, but they have not been applied to a live Cloudflare D1 database in this pass.
- No live deployment: no production Worker deployment or live data cutover was performed.
- Authentication and authorization remain open: inventory writes need staff authentication before the app can safely become the system of record.
- Accounting-document mapping remains open: mapping Xero/Zoho invoices, purchase orders, receipts, and other documents into stock movements and commitments is still a separate ticket.
- Raw-artifact storage remains open: uploading canonical raw source files to R2 is still a separate ticket.
- Observability and data quality remain open: production import monitoring, reconciliation checks, and issue reporting are not complete.
- Shared UI extraction remains open: the Derwent browser app still needs to be mapped to the shared contracts and reusable UI primitives without a fork.
- Planning persistence needs a later cleanup: the shared contracts and projection logic are in place, while some underlying legacy planning columns remain for compatibility.
Open Beads work
The next backlog is not the same as the nine closed model tickets
| Ticket | Open work |
|---|---|
SRD-0du | Staff authentication for inventory writes. |
SRD-czk.12 | Observability and data-quality operations. |
SRD-czk.11 | Reorderly authentication and authorization. |
SRD-czk.7 | CI and Cloudflare/VPS release topology. |
SRD-82f | Map accounting documents to stock movements and commitments. |
SRD-kch | Upload canonical raw artifacts to Selva R2. |
SRD-czk.17 | Map the Derwent browser app to shared contracts without a fork. |
SRD-czk.15 | Extract shared Reorderly UI primitives from proven patterns. |
Bottom line
The foundation is implemented; the cutover is not
Selva now has a tested path from source-specific data into a reusable, capability-based SaaS model shared with Derwent. The important architectural decision is in place: connectors adapt into canonical records, while client-specific warehouse fields, upload formats, and manufacturing capability stay at the tenant or adapter layer.
The next real milestone is not another UI tweak. It is to finish the production boundary: authentication, live D1 migration, import/reconciliation controls, accounting-to-stock mapping, and a controlled Selva cutover. The UI worktree should then be reviewed and committed as a separate milestone.