Skip to content

Frontend Architecture ​

React SPA (Vite + TypeScript strict + React Router + TanStack Query).

Principles ​

  • Operational workspace UI, not CRUD admin panels.
  • UI standard: ui-standard.md — entry point.
  • Design system: design-system.md — tokens, components, financial rules.
  • Icons: icon-system.md — Tabler registry only.
  • Migration: ui-migration.md · Audit: ui-audit.md.
  • Canonical UI: frontend/src/shared/ui (@/shared/ui). Single UI entrypoint — components/ui removed.
  • API layer in src/api.
  • Business-readable statuses via shared/ui/domain resolvers + src/shared/statusMessages.ts.
  • Role-aware navigation with Platform / Organization / Syrve / Operations separation.
  • Frontend visibility is not authorization; backend scoped checks remain the source of truth.

The accepted navigation and tenancy structure is defined in ADR: Navigation & Tenancy Information Architecture v1.

Route Groups ​

Operations ​

Outlet-scoped operational routes:

  • /dashboard — operational dashboard / requires attention.
  • /review-queue — redirect to accountant workbench (?state=attention).
  • /accountant-workbench — accountant workbench.
  • /bank-statements — hub: tabs imports (upload + import list), matching (client-wide counterparty matching; optional importId filter), rules (counterparty rules).
  • /bank-statements/:id — import detail (transactions, quality, duplicates, recognition, …).
  • /bank-statements/list — redirect → /bank-statements?tab=imports.
  • /name-matching, /matching — redirect → hub matching tab (preserve importId / status query).
  • /counterparty-rules — redirect → /bank-statements?tab=rules.
  • /manual-corrections and /manual-corrections/:id — routes kept; hidden from sidebar (foundation / audit deep-links).
  • /syrve/reconciliation — route kept for CSV/deep-links; hidden from sidebar.
  • /audit-log — scoped audit log (localized actions/messages, detail drawer with detailsJson highlights).

Reconciliation / Allocation / Posting ​

Payment workflow routes remain Outlet-scoped and outside /syrve/connections/:id:

  • /payment-allocations — allocation list.
  • /payment-allocations/:id — allocation detail.
  • /payment-allocations/preview — allocation preview workspace.
  • /payment-candidates/:bankTransactionId — payment candidates for a bank transaction.
  • /syrve/documents — Syrve documents list with tabs: All / Unpaid / Partially paid / Paid (?status=Unpaid|PartiallyPaid|Paid).
  • Legacy paths /syrve/documents/unpaid|partially-paid|paid redirect to query-tab URLs.
  • /syrve/documents/:id
  • /syrve/postings — posting queue.
  • /syrve/postings/:id — posting detail.
  • /syrve/reconciliation — reconciliation workflow.
  • /payment-anomalies and /payment-anomalies/:id — anomaly list/detail.

These routes may use active organization/Outlet context and backend scoped filtering, but they are not moved under the active Syrve connection route tree.

Syrve Connection Registry and Scoped Read Screens ​

Organization-level Syrve connection routes:

  • /syrve/connections — connection registry.
  • /syrve/connections/:connectionId — connection overview, health, credentials actions where permitted.
  • /syrve/connections/:connectionId/sync-runs — document sync runs for the selected connection.
  • /syrve/connections/:connectionId/references — accounts and cash-flow references for the selected connection.

Legacy read URLs remain transition-compatible:

  • /syrve/document-sync-runs redirects to /syrve/connections/:connectionId/sync-runs.
  • /syrve/references redirects to /syrve/connections/:connectionId/references.

Redirect resolution prefers remembered frontend syrveConnectionId when it still exists in the loaded connection list, then the default connection, then the first available connection, then /syrve/connections when no connection exists.

Frontend active connection selection is UI/navigation context only. It extends active organization/Outlet context and must not be described as backend authorization scope.

Organization ​

  • /settings — organization settings, quotas, and organization-scoped administration where permitted.

Platform ​

  • /settings/bank-adapters — platform bank adapter catalog.
  • /platform/users — platform user management.
  • /admin/workers — worker dashboard for platform/mega support roles.

Active Context ​

Frontend active context contains:

  • required organizationId after login/context selection;
  • optional locationId / Outlet context for operational workflows;
  • optional syrveConnectionId for connection-scoped Syrve screens.

syrveConnectionId is not an RBAC scope and is not sent as a backend authorization scope. Backend APIs must continue to validate organization/Outlet access and selected connection ownership.

Screenshots can be generated via Playwright into docs/public/screenshots.

Document recognition review workspace ​

BankStatementsPage accepts existing statement formats plus PDF/JPEG/PNG/WEBP, offers file and rear-camera actions, previews the selection, and routes document uploads to ?tab=recognition. TanStack Query polls pending/processing runs and stops at NeedsReview, Confirmed, Rejected, or Failed.

Reusable components/bank-recognition provide a desktop 55/45 independent-scroll layout and mobile Document/Data tabs. Authenticated PDFs load as Blob into react-pdf, render one page, support zoom/rotate and revoke object URLs. Images support fit, zoom, rotate and scroll/pan. Row selection and overlay clicks synchronize source and editor; a null box shows source text and an explicit fallback.

Each field retains immutable model baseline beside editable current value. Critical changes require a reason, row versions protect concurrency, and unsaved drafts register a navigation warning. Scoped permissions gate correct/confirm/retry actions. No transaction exists before backend confirmation.