Skip to content

Latest commit

 

History

History
40 lines (34 loc) · 2.7 KB

File metadata and controls

40 lines (34 loc) · 2.7 KB

Aggregate-rooted master-detail navigation (no entity-per-menu sprawl)

Navigation must be rooted in aggregates/masters, not flattened into one menu item per backend entity. A child entity, a configuration sub-object, or a pipeline stage is reached by drilling into its parent (a detail tab/drawer), never by a separate top-level menu item.

Why: the user flagged "Signatory Master" as a separate Banking menu item — but a signatory is a child of a bank account. A CA thinks "I'm working on this bank account," not "now I go to the Signatory module and re-find the account." One-menu-item-per-table produces menu sprawl, the wrong mental model, and data drift (the two surfaces had diverged onto different account ids/banks — same concept, two divergent models). Pairs with [[feedback_detail_views_in_drawer]] and [[project_mtp_nav_depth]] (rail → group → page → in-page tab).

How to apply:

  • Top-level menu = workspaces a user navigates to: masters (Bank Accounts, Chart of Accounts), registers, reports, and action-workflows (Cheque Issuance, Fund Transfer — verbs, not children).
  • Children / config sub-objects / pipeline stages → a detail tab or drawer on the parent.
  • One data model per concept; don't let a child get a second divergent fixture/page.
  • Precedent already in the code: routes/pages.ts maps fiscalYear/periodClose/periodDashboard → one PeriodDashboard page.

Pinned as an ADR: mtp-web/docs/adr/0035-aggregate-rooted-navigation.md (the principle + the 6 dependency-ordered consolidations + decision rules). Grounded in platform ADR-0011 (Finance = 10 modules, one posting kernel, reads are projections). Principle is app-wide (HR/Students/ Exam follow it).

Progress (2026-05-30, mtp-web):

  • Signatory Master → Bank Accounts › Signatories (b09973a).
  • ITC Ledger + e-Way Bill → GST tabs (614352d) — both are facets of the GstReturn aggregate.
  • Statement Import + Match → Bank Reconciliation tabs (cfee1ed).
  • Fiscal Year + Period Close + Period Dashboard → one "Periods" (fe4891e).
  • Deferred (need review-while-merging, not unattended): Outstanding → Aging (?tab= param collision + two heavy virtualized pages); Cost Projects + Budget → Cost Centres (ThreePane hub + resolve the duplicate Setup "Budgets"); Purchase Invoice → Purchase Register (two mature pages, combined Purchases workspace). See ADR-0035 §Progress.

Mechanics that worked: fold X into Y as a ?tab= panel when Y already drives off useSearchParams (GST, Bank Rec did); remove X from nav.ts + routes/pages.ts; keep X's data layer/mock/key (now consumed by Y); reconcile Y's own derived fields (counts, audit) so the merged surface has one data model.