Skip to content

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:

MeaningWho owns it
Subscription billingWho pays QRSETU for the platform — plan, seats, payment method, invoices from usThe organization only. A showroom manager must not be able to change the dealership's plan or card. This is what I meant.
Business financialsThe showroom's own revenue, expenses, inventory value, targets, P&LThe 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 pointWhat it demandsStatus
P1Lead leakage — an enquiry lands on an agent's card, is never followed up, and nobody noticesCentral visibility into child workspaces + lead aging/SLA⚠ needs oversight (D1)
P2Sales ↔ Service disconnect — "we don't know this service customer bought a car from us"One customer identity across both operations⚠ needs D2
P3Repeat-service revenue is unclaimed — next service due at 10,000 km or 6 months, nobody callsRecurrence per vehicle + reminders✅ engine exists (QRS-380)
P4No vehicle service history — the same car returns and its past work is unknownAn entity for the customer's vehicle⚠ needs Asset (D3)
P5Advisor / agent performance is invisiblePer-user rollups + targets⚠ needs targets (§0)
P6Test-drive scheduling collides — two agents promise the same demo carSchedule + Resource✅ designed
P7Post-service feedback never collectedFulfilment → feedback trigger✅ concepts exist
P8Location-wise reportingPath-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:

DirectionMechanismRule
Sharingparent → childADR-0022 sharing flags, default offA child may use an ancestor's resources
Oversightchild → ancestorRBAC 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 history

Both 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:

IndustryThe Asset
Car dealership / serviceThe customer's vehicle
AC · appliance · RO repairThe installed unit — this is what an AMC is actually against
IT / mobile repairThe device
Property managementThe flat or building
Equipment maintenanceThe 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 ​

OptionWhy rejected
Sales and Service as separate top-level organizationsTwo subscriptions, two billing relationships, and it makes P2 structurally unsolvable — the disconnect becomes permanent.
One workspace per showroom with sales/service as a flagOne 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 dashboardTwo rows, divergence, and "which is authoritative?" Oversight is a read, and one row read at three levels is strictly better.
Symmetric visibility inside a subtreeAn 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 historyConflates 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 schemaEmpty 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.