Skip to content

ADR-0011: Per-Portal Controller Isolation

Status: ACCEPTED Date: 2026-03-22 Supersedes: N/A Superseded by: N/A

Context

The original codebase used shared controllers with @GatewayValidation(portals={...}) annotations to serve multiple portals. This caused method-level portal override errors, ambiguous API surface per portal, and tight coupling between portal-specific endpoints. Five methods on InstitutionController had class-level S,T but overrode to S-only at the method level, creating audit risk.

Source: docs/archive/specs/2026-03-22-portal-controller-split-system-design.md, docs/archive/specs/2026-03-23-portal-controller-split-consumer-design.md, docs/archive/specs/2026-03-23-portal-controller-split-tenant-design.md

Decision

Each portal gets its own controller package (com.slaunchx.core.portal.{system,tenant,consumer,partner}.web) with dedicated controllers per domain. Portal scope is declared once at class level (@GatewayValidation(portals = {10010101})) with no method-level portals override. Each portal has its own URL prefix (/web/v1/system/, /web/v1/tenant/, etc.). Controllers are thin delegation shells that call existing Service/Facade beans.

Consequences

  • Each portal's endpoint set is immediately visible from its package contents.
  • No method-level portal override eliminates the class of annotation-mismatch bugs.
  • Documentation generation (DevPortal) can enumerate endpoints per portal by scanning the corresponding package.
  • Code duplication across portal controllers for similar endpoints (mitigated by thin delegation to shared services).
  • Old shared controllers are marked @Deprecated and retained until all four portal phases complete.

Alternatives Considered

  • Keep shared controllers with stricter annotation validation: Rejected because method-level overrides are inherently fragile and the audit surface remains ambiguous.
  • Runtime portal filtering (single controller, response varies by portal): Rejected because it hides the endpoint contract in runtime logic rather than explicit source code declarations.

Internal Handbook