The portal-* Package Family
Roughly 35 workspace packages under packages/portal-* factor the portalâs concerns out of apps/portal. The rule of thumb: the app owns routes and wiring; the packages own logic. Anything reusable, testable in isolation, or security-sensitive (session crypto, permission evaluation, projection contracts) lives in a package with an explicit boundary. The split exists because CI gates can only enforce rules along package seams â the app stays a thin composition layer, and the display-only gate (see Data Access) has clean boundaries to check against.
Map by concern
| Concern | Packages | What they own |
|---|---|---|
| Session & identity | portal-session | Iron-session cookie sealing/unsealing, resolveForwardableSessionToken, the ActiveGrant async-context store (/active-grant export) â the substrate for both gates and every adapter. |
| Security posture | portal-security, portal-security-policy, portal-step-up | CSRF/origin policy, security headers, step-up authentication flows. |
| Authorization | portal-permissions, portal-permission-acceptance | Portal-side capability surfaces over @opsdna/permission-engine (ADR-0026/0027); grant acceptance flows. |
| Read contracts | portal-read-models, portal-projections | The typed projection shapes display code renders â the only data types routes may import at runtime (ADR-0015 posture). |
| Presentation | portal-ui, portal-formatting, portal-i18n, portal-a11y, portal-mobile, portal-static-data, portal-slugs, portal-route-refs | Component library per DESIGN.md, number/date formatting, accessibility helpers, URL slug/route-ref identity (guarded by the portal:check-url-slug-identity and portal:check-canonical-links gates). |
| Documents & sharing | portal-documents, portal-document-releases, portal-investor-request-templates, portal-legal | Document surfaces and the ADR-0015 release/share flows. |
| LP & audit surfaces | portal-lp-performance, portal-auditor-questions, portal-access-audit, portal-audit, portal-audit-export | LP performance views; auditor Q&A; access/audit trails and their exports. |
| Observability | portal-observability, portal-telemetry | Span helpers (withServerSpan consumers), client tracing, boot beacons. |
| Integrations & infra | portal-carta-adapter, portal-webhooks, portal-email-infra, portal-email-templates, portal-feature-flags, portal-release-gates, portal-seeds, portal-search, portal-support-console | External adapters, email, flags, release gating, seed/demo data, search, internal support tooling. |
(Authoritative list: ls packages | grep portal â this table is the map, not the territory; new packages appear as features land.)
Boundary discipline
Package boundaries are CI-enforced (bun run check:boundaries inside verify), and several portal gates key off this layout: portal:bundle-audit (AppShell bundle budget), portal:a11y-baseline-check (per-tag a11y rules), portal:trip-wire, and portal:display-only-check. When you add portal logic, the question is rarely âwhich file in the appâ â itâs âwhich package owns this concern.â
Donât confuse portal-projections with @opsdna/persistence read code. Projections are the serialized, display-safe contract; persistence rows are server-side substrates. Display code importing persistence at runtime â even âjust one type helperâ that isnât import type â fails the display-only gate. See Data Access.
Related
- Portal architecture ¡ Data Access ¡ /api ¡ /infra