Architecture overview
Customer Portal is a Nuxt application assembled from layers. The architecture keeps shared infrastructure stable while allowing business capabilities to evolve independently.
Three responsibilities
The host
The host is intentionally small. It owns the Nuxt entry point, branding, public site, layouts, error handling, and global assets. Migration order comes from installed provider manifests rather than a host-owned combined journal.
Portal core
packages/core is visually headless. It owns:
- session and active-organization state;
- authorization helpers and database access;
- the feature and surface registry;
- shared types for navigation, modules, widgets, audiences, and policies.
packages/ui owns neutral fallback layouts, dashboard rendering, menus, modals, notifications, and shell primitives. Hosts can override its presentation without replacing core infrastructure.
Feature layers
A feature layer owns a vertical slice of the product. It may contribute pages, components, composables, server routes, translations, shared types, tests, and tables in its own PostgreSQL schema.
Host application
├── core
│ ├── session, tenancy, and authorization
│ ├── database adapters
│ └── feature and surface registry
├── ui
│ └── neutral fallback shell
└── feature layers
├── service-requests
└── timesheets
├── timesheets module
└── invoices module
Runtime composition
Each feature registers a PortalFeatureDefinition through a Nuxt plugin. Core and UI collect those definitions and derive:
- global navigation;
- module-aware sidebars based on the current route;
- dashboard widgets grouped by area and order;
- role policies used by server authorization.
This means a feature can be installed or removed without adding imports to the shell.
Data ownership
Portal core and authentication tables live in PostgreSQL’s public schema. Each business feature owns a schema derived from its layer name, such as timesheets or service_requests.
Each database-backed package owns an immutable migration stream. The kit orders provider streams while keeping a separate journal table for each provider.
Continue with feature layers, core contracts, or tenancy and security.