# Architecture Hardening Backlog **Date:** 2026-03-30 **Purpose:** Keep the remaining cleanup work for the current quality/security scope in a single prioritized list, so small hardening slices can be completed before larger redesign work. ## Recently Completed - SSE audience model narrowed to canonical `user:*`, `permission:*`, and `resource:*` scopes only - CI architecture guardrail added for SSE audience scoping - import boundaries hardened for server dispo workbooks and browser spreadsheet uploads - AI and SMTP runtime diagnostics sanitized before they reach logs or admin-facing error messages - transitive audit hotspots for `flatted` and `picomatch` pinned through root `pnpm.overrides` - `apps/web` export paths migrated from direct `xlsx` usage to a shared `exceljs` workbook export helper - `packages/application` workbook reading and `packages/engine` XLSX export serialization migrated from `xlsx` to `exceljs` - `pnpm audit --audit-level=high` no longer reports high-severity dependency findings - `apps/web` now has focused Vitest coverage for browser spreadsheet parsing and skill-matrix workbook parsing - cron routes, Redis helpers, reminder scheduling, webhook dispatching, and SSE fallback paths now use structured logger calls instead of raw `console.*` - `packages/api` now has focused Vitest coverage for reminder scheduler and webhook dispatcher logging failures - `apps/web` typecheck is now decoupled from generated `.next-e2e` artifacts via a dedicated `tsconfig.typecheck.json` - comment entity support is now centralized across shared constants, API registry policy, assistant tool metadata, and the web comment target API without pretending a second consumer exists - `resource` is now onboarded as the second real comment entity, reusing the same ownership and staff-visibility rules as the resource detail route - comment mention autocomplete now uses a dedicated entity-scoped API route instead of inheriting the narrower `user.listAssignable` audience - runtime secret handling is now environment-first end to end: admin updates no longer persist new operational secrets, runtime status is surfaced explicitly, and legacy database secret copies can be cleared through a dedicated cleanup path - `apps/web` system settings UI is now decomposed into section components with shared secret/runtime helpers, bringing all files in that slice back under the file-size guardrail - the first API-side `assistant-tools` extraction is in place: settings, system-role config, webhooks, audit log access, and shoring ratio now live in a dedicated domain module with shared assistant-tool types - the advanced timeline assistant toolset now lives in its own domain module, keeping the high-risk read/mutation pairings out of the monolithic router without changing the assistant contract - the adjacent allocation planning assistant helpers now live in their own domain module, covering allocation listing, budget status, and the core allocation create/cancel/status mutations without changing the assistant contract - the neighboring vacation and holiday assistant helpers now live in their own domain module, covering vacation-balance reads, regional/resource holiday inspection, and holiday calendar admin mutations without changing the assistant contract - the adjacent roles, skill-search, and lightweight analytics assistant helpers now live in their own domain module, covering role CRUD plus `search_by_skill`, `get_statistics`, and `get_chargeability` without changing the assistant contract - the neighboring client and org-unit admin mutations now live in their own domain module, keeping more CRUD wiring out of the monolithic router without changing the assistant contract - the adjacent chargeability/computation read helpers now live in their own domain module, keeping the advanced financial transparency read models out of the monolithic router without changing the assistant contract - the neighboring country and metro-city admin mutations now live in their own domain module, keeping more settings-side CRUD wiring out of the monolithic router without changing the assistant contract - the adjacent management-level, utilization, calculation-rule, effort-rule, and experience-multiplier read helpers now live in their own domain module, further shrinking the monolithic assistant router without changing the assistant contract - the remaining assistant user-admin helper cluster now lives in its own domain module, covering admin listing, user lifecycle mutations, permission overrides, resource linking, and MFA overrides without changing the assistant contract - the authenticated user self-service assistant helpers now live in their own domain module, covering assignable users, dashboard preferences, favorites, column preferences, and MFA self-service without changing the assistant contract - the embedded notification, task, reminder, and broadcast assistant helpers now live in their own domain module, keeping the collaboration workflow wiring out of the monolithic router without changing the assistant contract - the estimate read and mutation helpers now live in their own domain module, keeping estimate lifecycle orchestration out of the monolithic assistant router without changing the assistant contract ## Next Up Pin the next structural cleanup on the API side: continue splitting `packages/api/src/router/assistant-tools.ts` into domain-oriented tool modules without changing the public tool contract. The next clean slice should stay adjacent to the extracted domains and target one cohesive block such as the remaining project admin/helper clusters that are still in the monolithic router. ## Remaining Major Themes The small hardening slices are effectively exhausted. The remaining work is now structural rather than another quick batch: 1. secrets and runtime configuration policy 2. oversized router decomposition 3. production-grade rate limiting 4. canonical image-based production delivery 5. performance hotspot reduction ## Working Rule For the next batches, prefer work in this order: 1. remove or isolate known-risk runtime dependencies 2. add guardrails and tests around already-hardened code 3. only then expand architecture surface area