Skip to content

Latest commit

 

History

History
58 lines (54 loc) · 12.2 KB

File metadata and controls

58 lines (54 loc) · 12.2 KB

Memory Index — Multi-Tenant Platform

Project-scoped memory for D:\Projects\mtp\mtp-docs (GitHub: paramhq/mtp-docs).

Feedback / preferences

  • Check Radix first (standing rule) — Before building ANY interactive control, check Radix UI for a primitive; wrap it in @mtp/ui. Don't reinvent the wheel.
  • Reuse-first / extract-when-repeated gate — Before hand-rolling: search Radix/@mtp/lib first; when hand-rolling something structural, extract a primitive that OWNS the invariant so per-screen bugs can't recur. Register it.
  • Interactive fidelity — Full-fidelity = every tab switches, every button navigates/toasts, every toggle changes state. Rendering a control without wiring it is a stub. Verify each in the browser.
  • URL-driven tabs (no duplicate strip) — Screen tabs in nav.ts are rendered once by AppShell; read ?tab= via useSearchParams, never render a second in-page strip. Match nav labels exactly.
  • Full-fidelity ports, no stubs — Port EVERY section + EVERY tab's real content + ALL forms. "In totality" = full cross-repo pipeline (mockup/ADR→data→page→wire→verify→docs→push both repos). DoD box in 12-build-plan.html.
  • Verify data-grid layouts — After any custom CSS Grid table, read gridTemplateColumns + per-cell width in chrome-devtools. 0px tracks render no pixels and pass eyeball inspection. Lint + manual inspection together.
  • No native datepicker — Never <input type="date|time|...">. Use @mtp/ui <DatePicker> (Radix Popover + react-day-picker, token-styled, controlled ISO string; Controller in RHF).
  • Drawer sticky footer — Drawer/dialog forms = fixed header + scrollable <DialogBody> + pinned <DialogFooter> (Cancel/Save always visible). Never let actions scroll away.
  • Keep docs in sync — At the END of a task, update ADRs/memory IF REQUIRED (new lib/pattern/rule → yes; trivial fix → no). Don't over-document.
  • Dense grids stay bespoke — Don't convert dense Tally-style editable grids (Voucher Entry lines, TDS challan) to the padded field kit; preserve their compact density. Field kit = normal-sized controls only.
  • Reports use native PDF/Excel libs — QuestPDF / ClosedXML directly. NEVER HTML→PDF, NEVER Puppeteer/headless browser.
  • Diagrams use light palette — Mermaid nodes must use pastel fills + dark outlines/text. No dark fills.
  • GNUMS data source default — Without a live connection string, study D:\Extractions\GNUMS_PU_2019\ (file dump). Live DB only when user supplies it or explicitly asks.
  • Scope is bigger than GNUMS — GNUMS archaic = study input/floor, NEVER ceiling. Design modern superset. Don't size aggregates from legacy. Finance = domain of ~8-10 modules, 25-35 aggregates.
  • Mockups use shared shell — New mockups MUST use _shell.js + _mockup.css + _nav-manifest.js, never inline/copy-paste chrome. Authority ADR-0010. Prevents drift.
  • No dropped-tech mentions in current docs — Skip "rejected libraries" / "alternatives considered" tables in current docs. State positive choices + principles only. Historical mentions OK inside superseded ADRs.
  • Consult ADRs first, don't ask — For features in documented modules, read the relevant ADRs + plan.html BEFORE any AskUserQuestion. Only ask when ADRs are genuinely silent/ambiguous on that specific point.
  • Detail views open in a drawer — Drill-through (voucher/bill/document/ledger-line/account detail) = drawer over the list, never a full-page route. Convert /finance/document/:id to a drawer; preserves worklist + filters.
  • Aggregate-rooted master-detail nav — No entity-per-menu sprawl. Child entities / config sub-objects / pipeline stages live as a detail tab/drawer on their parent, never a separate top-level menu item. Signatory Master → Bank Accounts › Signatories (done). Principle app-wide.

Project facts

  • MSW → real API breeze — mocks mirror routes/payloads/response shapes/error envelopes exactly; live swap touches only the network layer

  • React Query optimistic updates required — useMutation with onMutate/onError/onSettled, no local state overrides

  • No placeholder toasts — every button does what its label says: navigate, mutate, open drawer, download

  • Build status / resume pointread first when resuming build. mtp-web at D:\Projects\mtp-web: scaffold+tokens+AppShell+full component library done+Voucher Entry & Day Book pages live+CSS tokenized with stylelint guard. Pushed to github.com/paramhq/mtp-web (PRIVATE, main). Next: more Finance pages (COA/Ledger/Approvals).

  • Postgres 17+ and ltree — DB is PostgreSQL 17+ exclusively; ltree for hierarchical data.

  • Tenancy model (DB-per-client) — Each client owns its Postgres DB. Client code in JWT/header resolves connection string per request. Single API + single frontend deployment, subdomain per client.

  • Stack — ASP.NET Core Web API + React 19 + Radix Primitives (headless) + CSS Modules + native CSS Grid/container queries + TanStack Table/Virtual + Zod/RHF/TanStack Query/Zustand + Vite. Authoritative: ADR-0007.

  • Data layer (demo API + Query + Zustand) — Fetch via apiGet (real fetch); MSW serves mocks/ fixtures in dev (visible in Network), real API via one env flag; TanStack Query + query-key-factory; one Zustand store. Hard rules: filtering = POST (apiSearch) never GET params; route names always camelCase. Pin ADR-0011.

  • UI decisions (consolidated) — stack, monorepo (pnpm, no npm publish, github.com/paramhq private), design-system (faithful port of shell, two-tier light-first tokens), state (TanStack+Zustand, no Redux), TS-only, responsive container-query-first. ADRs 0007/0008/0010/0019/0020/0021. Read before any frontend work.

  • Component authoring — Native HTML default; Radix only for non-trivial behaviour. JSX renames, uncontrolled RHF inputs, Radix asChild, headless tables. Page layout MUST come from @mtp/ui primitives (<Sidebar> etc.); never hand-rolled grid in page CSS — enforced by stylelint. Authoritative: ADR-0008.

  • List pagination (keyset + infinite + virtual) — Unbounded lists/ledgers use keyset cursor pagination + useInfiniteQuery + TanStack Virtual + bounded default dateRange (POST apiSearch). Ledger is the reference. Pins ADR-0025.

  • PascalCase DB — Database, table, and column names ALWAYS in PascalCase. Raw SQL must double-quote identifiers in Postgres.

  • DB constraint naming — Predictable, industry-standard prefixes: PK_/FK_/UQ_/CK_/IX_/UX_/SQ_/TR_/TFN_/FN_. No Postgres auto-names.

  • Persistence model (hybrid) — Relational (EF Core + Dapper) AND event sourcing (Marten) coexist. Choice is per-entity, not global.

  • Excel/CSV stack — DocumentFormat.OpenXml (bulk) / ClosedXML (formatted) / NPOI (legacy .xls) / ExcelDataReader (ingest). CSV: CsvHelper default, Sep/Sylvan hot path. EPPlus banned.

  • Authz model (ADR-0004) — One Permission concept (no Menu/Operation split), single-column ltree+jsonb scope, JWT claims, IPermissionFilter in service layer. Replaces GNUMS SEC_ sprawl.

  • GNUMS legacy conventions — Table/SP/ASPX/App_Code four-namespace mirror, prefix→folder rollup, LOG_/LOJ_ audit shadows (1,320 tables!), code-gen Base+override pattern, the 5 cross-FK gravity wells (SEC_User/STU_Student/STF_Staff/INS_*/SUB_Subject).

  • GNUMS business logic in SPsHard rule: ~9,000 of 34,547 GNUMS procs contain custom business logic. C# code is mostly thin wrappers. Any module study that ignores SPs is incomplete.

  • Student Phase A decisions — Resolved 2026-05-18. Medium-shape Student (~50 cols, not slim 15) · Student module owns StudentExam projection (Exam-result state splits to Exam) · 3 aggregates (Identity + Enrolment + Profile), not 1.

  • Rule engine v1 — v1 cut of page 04: Blocking-only, field rules only, no cross-field/stepper/sections. Concepts borrowed from + improved over GNWebSoft.Forms.

  • Repo topology + no Module Federation — 3 repos at build start (mtp-docs · mtp-api · mtp-web). Contracts repo + mobile deferred. Single Vite bundle with feature-module pattern; no MF. Pins ADR-0005 + ADR-0006.

  • Module naming: HCM not HRMS — New people module = "HCM / Human Capital". Legacy study stays "HR-Payroll" (don't rename gnums/hr-payroll/). "HRMS" deprecated.

  • Navigation depth (4-level) — mtp-web shell = module(rail) → group(submenu header) → page(submenu item) → view(in-page tab). Collapsible groups, Ctrl-K palette, never 5-deep. 360-hubs add vtab rail.

  • Finance frontend CA-readiness (2026-05-29) — mtp-web Finance = design-complete demo shell, NOT usable by a CA; ~30% there. Write spine unwired (Voucher Entry submit = toast only), GST/TDS/BankRecon are demo-only. Punch list P0/P1/P2 in docs/audits/finance-frontend-readiness-audit.html. Build contract: mtp-web/docs/conventions/04-wiring-compliance-contract.md; golden slice = Voucher Entry useCreateVoucher.

  • Conventions precedence (mtp-web wins) — global ~/.claude/conventions target a different project; mtp-web/docs/conventions + CLAUDE.md authoritative. Mirror real neighbours, not global templates.

  • Display formatting in @/lib/format/* — money.ts + date.ts are the ONE home for currency/number/date formatting. Never inline Intl/toLocaleString/toISOString. Codemod retained at scripts/. Inline-style-with-literals is the next anti-pattern (~150 sites).

  • Accounting module study (2026-05-20) — 19 clusters + 4 cross-cuts complete. Non-obvious legacy gaps: NO period close, NO base-currency/locale, GST is rate-master only, no Trial Balance/BS/P&L in legacy, OPD is copy-paste of Fee Collection Bank. Source: gnums/accounting/scope.html.

  • Staff module study (2026-05-20) — 12 clusters + 4 cross-cuts complete. Non-obvious legacy quirks: 2 hardcoded backdoors (StaffID 1281/31782 + Absconding), 3 duplicate 'PO' status UDFs, citation DBs manual-entry only, all statutory submissions absent, 125+ RDLCs in reports. Source: gnums/staff/scope.html.

  • Design invariants (2026-05-22 review) — statements in GL not Tax; JournalEntry EntryType stamped not created; HR owns 24Q; masters relational; Punch=VO; OffCyclePayment; no HR payment rail; AR/AP factored. Honor in all module plans.

  • Mockup × Aggregate audit (2026-05-22) — 30 mockups vs aggregates + 4-level nav. Accounting needs amend (add Budgeting agg, 7 cross-write red flags, dedupe approvals/recon); HR-Payroll confirms ADR-0009. Doc: docs/audits/mockup-aggregate-audit.html.

  • HR-Payroll module study (2026-05-21) — 13 clusters + 4 cross-cuts complete. 5 sibling prefixes (HRP+HRA+HRL+HRT+HRC, HRA/HRL/HRC procedure-only). 314 custom SPs studied (no skipping). 51 KB UPSERTSalary + 57 KB SelectForReturnIncome are load-bearing. EPF.cs broken; Davda is an OEM not a tenant; 30+ legacy typos in domain names; no statutory e-filing wires. Source: gnums/hr-payroll/scope.html.