# KeluargaMart Financial Closing, Access Isolation, and Dashboard Audit Plan ## Evidence baseline - Backend: Go/Chi modular monolith in `apps/backend`; PostgreSQL migrations in `apps/backend/migrations`; sqlc queries under `apps/backend/db/query`; route composition in `apps/backend/cmd/server/main.go`. - Application access already has server-side `RequireApp` middleware and explicit `users.application_access` support. Existing tests cover ERP/POS/e-commerce denial and tenant scope; frontend guards remain defense-in-depth only. - Accounting periods already exist as monthly `accounting_periods` rows with `open|locked` status. Existing finance hardening rejects cashflow mutations in locked periods, but no complete period preview/close snapshot API was found. - Financial primitives available: sales orders, returns, invoices, payments, cashflows, accounting journals/ledger, cashier shifts, inventory, and audit logs. Tenant scope is strongest for sales/cashflows/journals; several legacy tables lack direct outlet keys and must not be aggregated as tenant-scoped without a proven join. - ERP already has role/permission-filtered routes, role registry UI, dashboard API/store, and many concrete dashboard components. No centralized declarative widget policy/personal preference system was found. - POS and B2B already have application-aware frontend middleware/guards. Backend authorization remains authoritative; any frontend-only change is not a security control. - Verification commands: `pnpm test`, `pnpm build`, `pnpm lint`, `pnpm typecheck`, `pnpm drift:check`; backend additionally `go test ./...`, `go vet ./...`, and `go build ./...` from `apps/backend`. ## Work surface and dependencies 1. **Backend period closing** — extend the existing monthly accounting-period model only where source data and tenant scope are valid; add transactional preview/validation/close/detail/history behavior, immutable snapshot data, idempotency/concurrency protection, permission gates, OpenAPI/routes, migration, sqlc, and tests. 2. **Backend access isolation** — preserve and regression-test existing explicit application entitlements, identify only demonstrable uncovered routes, and avoid broad role semantics changes without data evidence. 3. **ERP period UI** — depends on the backend endpoint contract; add list/preview/confirm/detail/history states with server-confirmed results and conflict handling. 4. **ERP dashboard widgets** — use existing dashboard APIs/components; add declarative registry and persisted policy/preferences only if an existing backend persistence seam supports it. Never grant permissions through widget configuration. 5. **Frontend route audit/fixes** — verify ERP/POS/B2B guards and correct only concrete gaps; backend denial tests remain required. 6. **Documentation and verification** — update this plan with actual implementation, limitations, tests, and Git/CI evidence after changes. ## Acceptance matrix | Area | Acceptance evidence | |---|---| | Period summary | Backend computes from authoritative rows and documented date/time rules; no frontend totals trusted | | Period close | Transactional state transition, duplicate/concurrent close rejected or returns existing result, immutable snapshot and actor metadata persisted | | Financial safety | Locked-period mutation protections remain; unsupported accounting claims are not introduced | | Authorization | Every new endpoint has auth + app + permission gates; tenant/resource scope enforced server-side | | Access isolation | ERP/POS/B2B negative cases are backend-denied, not merely redirected | | Dashboard | Widget visibility is permission-derived; role policy cannot grant API permission; user preferences cannot select disallowed widgets | | UI behavior | Loading, empty, error, retry, conflict, and double-submit handling are observable | | Compatibility | OpenAPI/contracts/permission catalogs, generated code, migration checks, and existing callers remain synchronized | | Verification | Targeted tests plus repository-required test/build/lint/typecheck/drift checks are run and failures classified | ## Known limitations to report unless resolved with evidence - Existing monthly accounting periods do not by themselves prove a complete double-entry close workflow. - Legacy finance/inventory tables without outlet keys cannot safely produce per-store snapshots without an explicit, tested join. - Production database, remote push, and CI status require accessible credentials and must not be claimed without command evidence.