Skip to main content

ADR-006: Dual Portal Architecture

Status: Accepted | Date: 2026-03-12

Context

SA3 serves two distinct user populations:

  • System administrators (ADMIN role) who configure academic systems, manage staff/students, and access all data.
  • Operational staff (teachers, principals, vice-principals) who enter scores, view class lists, and generate reports.

A single UI would require complex conditional rendering and risk exposing administrative controls to non-admin staff.

Decision

Build a single Next.js app with two independent route segments:

PortalURL prefixRolesLayout file
System Admin/admin/**ADMIN onlysrc/app/admin/layout.tsx
Staff Portal/app/**All authenticated staffsrc/app/app/layout.tsx

Two independent layout files provide completely separate chrome:

  • Admin layout: dark slate sidebar, full-width configuration panels.
  • Staff layout: white sidebar, card-based operational views.

Portal Boundary

ConcernPortal
Academic system config/admin
User & role management/admin
School-year / term setup/admin
Score entry/app
Class lists/app
Report card preview/app

API Routes

All /api/admin/** routes serve both portals. The /api/admin/ prefix is a naming artifact -- not a permission gate. All handlers enforce access via resolvePermissionsForResource.

Consequences

Positive: Clean separation of concerns, independent layouts, straightforward middleware guards.

Negative: src/app/app/ double-nesting can cause confusion (valid Next.js App Router behaviour but requires awareness).

Alternatives Rejected

  • Separate Next.js apps -- over-engineered for single-school; doubles deployment surface
  • Single layout with role-conditional chrome -- deeply nested conditionals; harder to maintain