Appearance
ADR-0024 · Enterprise operating model: divisions, oversight & assets
Status: 🟡 Proposed — authored 2026-08-08, awaiting owner approval · Extends: ADR-0023 (tree), ADR-0022 (sharing) · Depends on: ADR-0006, ADR-0021 · Related: QRS-395…QRS-397
The one-line thesis
Derived from the dealership's actual workflows rather than from a hierarchy: resource sharing flows DOWN the tree, oversight flows UP — two directions, two mechanisms, and only one was modelled. The customer belongs to the showroom, not to Sales or Service, so the dealership's single biggest pain point (not knowing a service customer bought from you) is solved by construction rather than by a report. And a serviced vehicle is an Asset — a tenth primitive, which the workflow analysis surfaced and the hierarchy analysis never would have.
0. Correcting my own statement first
I wrote "showroom manager → not billing", and the phrasing was ambiguous. Billing means two different things and I meant only one of them:
| Meaning | Who owns it | |
|---|---|---|
| Subscription billing | Who pays QRSETU for the platform — plan, seats, payment method, invoices from us | The organization only. A showroom manager must not be able to change the dealership's plan or card. This is what I meant. |
| Business financials | The showroom's own revenue, expenses, inventory value, targets, P&L | The showroom. You are right, and I should have said so. |
And the architecture already delivers the second, by the same property that gives a showroom its own catalogue and leads: it is a workspace, so revenue, expenses, inventory, leads, bookings and analytics are workspace-scoped. Nothing needed changing — my wording was wrong, not the model.
One genuine gap your list exposed: TARGETS. Nothing models a monthly sales target, a service-throughput target or an agent quota. Applying the ≥3-industry gate it passes easily (dealership sales · salon stylist · coaching admissions · retail store · MLM monthly volume, which is already noted as volume-banded and month-resetting). But it is not a primitive — a primitive owns a process, and a target is a value compared against a rollup. So: a feature over the analytics layer (targets(scope_workspace_id, user_id NULL, metric, period, value)). Recording that reasoning because it is the primitive gate working rather than being bypassed.
1. Starting from the workflows, not the hierarchy
You asked the right question. Here are the dealership's real pain points, and what each one demands:
| # | Pain point | What it demands | Status |
|---|---|---|---|
| P1 | Lead leakage — an enquiry lands on an agent's card, is never followed up, and nobody notices | Central visibility into child workspaces + lead aging/SLA | ⚠ needs oversight (D1) |
| P2 | Sales ↔ Service disconnect — "we don't know this service customer bought a car from us" | One customer identity across both operations | ⚠ needs D2 |
| P3 | Repeat-service revenue is unclaimed — next service due at 10,000 km or 6 months, nobody calls | Recurrence per vehicle + reminders | ✅ engine exists (QRS-380) |
| P4 | No vehicle service history — the same car returns and its past work is unknown | An entity for the customer's vehicle | ⚠ needs Asset (D3) |
| P5 | Advisor / agent performance is invisible | Per-user rollups + targets | ⚠ needs targets (§0) |
| P6 | Test-drive scheduling collides — two agents promise the same demo car | Schedule + Resource | ✅ designed |
| P7 | Post-service feedback never collected | Fulfilment → feedback trigger | ✅ concepts exist |
| P8 | Location-wise reporting | Path-prefix rollup | ✅ ADR-0023 D1 |
Five of eight already hold. The three that do not are the three additions below — and note that P2 and P4 are the highest-value items on the list, and neither would have been found by reasoning about hierarchy. That is the answer to your framing: workflows found what the org chart could not.
Decision
D1 — Resource sharing flows DOWN. Oversight flows UP. Two directions, two mechanisms
ADR-0022 modelled sharing down the tree (a showroom's stock is visible to its agents). P1 needs the opposite and I had not modelled it: the Sales Admin must see every lead created on every agent's card, even though the agent owns it.
These must stay separate mechanisms, because they answer different questions and must not be symmetric:
| Direction | Mechanism | Rule | |
|---|---|---|---|
| Sharing | parent → child | ADR-0022 sharing flags, default off | A child may use an ancestor's resources |
| Oversight | child → ancestor | RBAC subtree role scope (ADR-0023 D4) | An ancestor role may read descendants' operational data |
Never symmetric. An agent must not see a sibling agent's leads; the manager must see all of them. And oversight is read, not write — a manager reads Ravi's leads; they do not become Ravi's leads.
⚠ The privacy boundary that makes this safe, and it must be in the policy, not the convention: oversight applies ONLY to descendants with ownership_model = 'org_owned'. The same person may run a personal member_owned side business or hold a consumer identity; their employer must never see either (QRS-386). That is a third distinct job for ownership_model — a strong signal it is the right column.
So the lead flow you described works exactly as stated: a customer submits an enquiry on Ravi's card → the lead is created in Ravi's workspace (he owns and works it) → it is simultaneously visible in the Thane Sales dashboard and the central Sales Admin dashboard via oversight. No duplication, no sync, no "also flows into" write. One row, read at three levels.
D2 — The CUSTOMER belongs to the showroom, not to Sales or Service
This is the most valuable decision in this ADR, and it follows from P2 being the dealership's core pain rather than from any structural preference.
If Sales and Service are sibling workspaces each owning their own parties, then the same human is two rows — and the architecture bakes in the exact disconnect it should be removing. Sibling sharing cannot fix it either: allowing siblings to share would destroy the Thane↔Andheri isolation guarantee.
The tree solves it if the customer sits one level up:
Thane (showroom) ← OWNS parties/customers, locations, assets
├─ Thane Sales (Expertise) ← owns vehicle stock, leads, test drives
└─ Thane Service (Time) ← owns bookings, job cards, service historyBoth children resolve the parent's customers through ADR-0022's existing down-only sharing. The sales↔service join is then a property of the data model, not a report someone has to build — and "this service customer bought a car from us in 2023 and is due for replacement" becomes a query rather than a project.
Ownership placement is the general rule this establishes: put a resource at the lowest node that all its legitimate consumers descend from. Customers at the showroom. Vehicle stock at Sales (or corporate, if pooled). Brand assets at the root.
D3 — ASSET is a tenth primitive: a thing belonging to a Party, with a service history
P4 has no home. A customer's vehicle — VIN, registration, model, purchase date, odometer — is not a catalogue item (that is what you sell) and not a Party (that is who you serve). It is the object work is performed on, repeatedly, over years.
It passes the ≥3-industry gate decisively, and it unlocks the AMC business model generally:
| Industry | The Asset |
|---|---|
| Car dealership / service | The customer's vehicle |
| AC · appliance · RO repair | The installed unit — this is what an AMC is actually against |
| IT / mobile repair | The device |
| Property management | The flat or building |
| Equipment maintenance | The machine |
assets(workspace_id, party_id, kind, identifier, attributes jsonb, acquired_at) plus Fulfilment records referencing an asset. P3 then falls out for free: next-service-due is a Recurrence rule per asset (6 months or 10,000 km), which is the existing engine (QRS-380) with an odometer condition.
This is the clearest example so far of the primitive gate earning its keep — Asset is small, general, and was invisible from the hierarchy discussion. It also retro-explains why the AMC electrician case felt thin.
D4 — Sales and Service are DIVISIONS: ordinary tree nodes with different archetypes
Your instinct that these are two operational domains is right, and the model already expresses it — a division is a workspace with its own archetype:
- Sales → Expertise. An ₹8 lakh car is not bought on a card; the card generates the enquiry.
- Service → Time. A service booking is a slot against a bay and an advisor.
Different archetypes ⇒ different primitive compositions ⇒ different features, KPIs and screens with no per-domain code. A Sales Admin and a Service Admin are then the same role construct with different subtree assignments (several rows — one per showroom's Sales node, or one at a Sales division node).
D5 — The tree deliberately does NOT fix Brand, Division or Team as levels
Your proposed hierarchy is Organization → Brand → Showrooms → Business Domains → Teams → Users → Cards. Every one of those is expressible as a tree node, and fixing them in schema is the same mistake as making Location a level (QRS-396):
- A single-brand dealership would carry an empty Brand level.
- A dealership with no teams would carry an empty Team level.
- A group needing region between brand and showroom would have nowhere to put it.
- And dealerships genuinely differ in organising principle: some run location-P&L (
Thane → {Sales, Service}), others division-P&L (Sales → {Thane, Andheri}). A fixed hierarchy imposes one; the tree lets the customer choose, and D2's ownership rule adapts — customers sit at the showroom under location-first, at the root under division-first.
A Team is only a workspace if it has its own targets and P&L (a used-car team with its own quota). If it is merely a label on people, it is a membership attribute — not a level, and not in R1.
Consequence: raise the depth cap from 4 to 6. The realistic deep case is root → brand → region → showroom → division → agent = 6.
Options considered and rejected
| Option | Why rejected |
|---|---|
| Sales and Service as separate top-level organizations | Two subscriptions, two billing relationships, and it makes P2 structurally unsolvable — the disconnect becomes permanent. |
| One workspace per showroom with sales/service as a flag | One archetype for two genuinely different workflows; KPIs, features and screens then need per-domain conditionals — the exact sprawl ADR-0021 D4 lints against. |
| Duplicate leads upward into the admin dashboard | Two rows, divergence, and "which is authoritative?" Oversight is a read, and one row read at three levels is strictly better. |
| Symmetric visibility inside a subtree | An agent would see sibling agents' leads. Also breaches employee privacy (QRS-386) once member_owned workspaces exist in the same tree. |
| Vehicle-as-catalogue-item for service history | Conflates what you sell with what you service. A serviced car was often not bought from you — that is the whole point of P2. |
| Fixed Org→Brand→Location→Domain→Team→User schema | Empty levels for simple customers, no room for a seventh, and it imposes one organising principle on businesses that legitimately differ (D5). |
Consequences
Schema (additive, baseline): assets + Fulfilment reference · targets · role_assignments gains oversight semantics (read over org_owned descendants) · depth cap 4 → 6 · ADR-0022 ownership-placement rule documented.
pgTAP must prove the negatives — these are the failures that matter and none is caught by a functional test: an agent cannot read a sibling agent's leads · a manager cannot read a descendant's member_owned workspace · Service cannot read Sales' vehicle stock unless shared · a parent cannot write a child's leads (oversight is read-only) · Thane cannot see Andheri at any depth.
Cost: ~+1.25d (assets ~0.5 · oversight policies ~0.5 · targets ~0.25).
Accepted cost, stated plainly: oversight adds a second predicate to tenant-read policies on top of ADR-0022's sharing union, so a policy on leads now resolves own ∪ shared-from-ancestors ∪ oversight-over-descendants. QRS-382's index discipline is now the single highest-leverage performance item in the schema — three path-based predicates on the hottest tables. This must be benchmarked in CI, not assumed. It is the price of one mechanism serving solo vendors through multi-brand groups.
Recommendation
Adopt D1–D5. The substance of your model is right — enterprise → brand → showrooms → sales/service → teams → agents → cards — and the correction is that it should be a tree that can express that shape rather than a schema that mandates it, because dealerships genuinely organise differently and simple customers must not carry empty levels.
The two additions that make the Enterprise offering genuinely useful rather than just billing and seats are D2 (one customer across sales and service) and D3 (Asset with service history). Those two are the dealership's actual pain, and both were invisible from the hierarchy question — which validates deriving architecture from workflows.