PR: #473: feat(matters): Filings tab — Main/Annexure/Exhibit registers [Story-1886] by @ankitmaheshwari-com
View PR →
Story-1886

Filings tab: every document, one home

A matter's Filings tab now opens on three read-only registers for the matter's Main proceeding — Main Filings, Annexure Register, and Exhibit Register — switched by a segmented control. A document is a noun with one home: its annexure label and its exhibit number describe the same file. Privileged work-product is excluded by the backend JOIN (DR-2), so it can never surface in a tenderable register. Lawyer vocabulary on the surface throughout: Record, Annexure, Exhibit, Filing.

What shipped

Three subtabs, real reads

/matters/[matterId]/filings renders the FilingsTab against the synced contract (Story-1882): appListMatterProceedingFilings, appGetProceedingExhibitRegister, and appListDocumentAnnexures. Reached from the matter Worknav (Filings) and the matter subnav, mirroring the Record sub-route.

Forum data pattern

The RSC server-prefetches Main Filings + Exhibit Register into a per-request QueryClient, dehydrates, and hydrates — the client reads through the generated TanStack hooks off a warm cache (no first-paint spinner; ADR-095). Read-only, so no mutations / no invalidation.

Two identities, one row

The Exhibit Register row shows the document, its exhibit number (exhibitLabel), and the party series as a display label + canonical token chip (e.g. "Claimant" / initiating_party), plus the marking lifecycle (Marked / Admitted / Rejected, DR-5).

Empty / zero first-run handled

A new firm with no filings, no markings, no annexures sees explicit empty states — never a broken-looking blank. Each register also has its own loading and error treatments. Verified in Storybook (RegisterStates) and against the real contract types.

Scope decisions (locked with the issue author)

Gated on pramaan-functions Story-1891

Two pieces of the brief are blocked on backend the synced contract does not yet expose — not faked here (HR-22):

Brief itemWhy deferred
Single-click exhibit renumber + duplicate-in-series 409 No renumber write endpoint exists; the exhibit register is read-only in src/gen. The Exhibit Register ships read-only with the renumber affordance deferred (caption notes it).
Full two-identity row (annexure label beside the exhibit number) DocumentExhibitMarkingView carries no filing_label / parentDocumentId, so the Annexure cell shows an em-dash. The exhibit identity + party render today; the annexure half lands after #1891 + a codegen-sync.

Trust boundary

New BFF proxies keep the browser on /api/internal/* only: /matters/{id}/proceedings/{pid}/filings and /exhibit-register (new proceedingProxyHandler), plus /documents/{doc}/annexures (existing documents proxy). Every gateway read parses the raw upstream through assertContract against the generated schema before it crosses back (HR-21). toBrowserRoute maps the new paths.

Verify

pnpm lint (0 errors), tsc --noEmit (clean), pnpm test (949 passing, incl. route-registry freshness), and pnpm build (new routes registered) all green. New surface matter.filings exported and gen:routes committed; Filings i18n added to both en and hi.

Files changed

24 file(s), +1121 / -7 lines

Path Role + -
messages/en.jsonConfig+58-2
messages/hi.jsonConfig+58-2
src/app/[locale]/(workspace)/matters/[matterId]/filings/page.tsxApp route+108-0
src/app/api/internal/documents/[docId]/annexures/route.tsApp route+4-0
src/app/api/internal/matters/[matterId]/proceedings/[proceedingId]/exhibit-register/route.tsApp route+4-0
src/app/api/internal/matters/[matterId]/proceedings/[proceedingId]/filings/route.tsApp route+4-0
src/components/matters/filings/annexure-register-table.stories.tsxComponent+29-0
src/components/matters/filings/annexure-register-table.tsxComponent+77-0
src/components/matters/filings/exhibit-register-table.stories.tsxComponent+33-0
src/components/matters/filings/exhibit-register-table.tsxComponent+87-0
src/components/matters/filings/filings-fixtures.tsComponent+131-0
src/components/matters/filings/filings-tab.tsxComponent+112-0
src/components/matters/filings/main-filings-table.stories.tsxComponent+29-0
src/components/matters/filings/main-filings-table.tsxComponent+65-0
src/components/matters/filings/register-states.stories.tsxComponent+51-0
src/components/matters/filings/register-states.tsxComponent+55-0
src/components/matters/live-matter-shell.tsxComponent+6-0
src/components/matters/matter-subnav.tsxComponent+1-0
src/components/matters/matter-tabs.tsxComponent+1-1
src/lib/filings/gateway.tsLibrary+90-0
src/lib/filings/presentation.tsLibrary+38-0
src/lib/filings/route-helper.tsLibrary+55-0
src/lib/kubb-client.tsLibrary+13-0
src/lib/surface-registry/route-registry.tsLibrary+12-2