Built-in dashboard
Load the DMS with zero pages of your own and you already have a working product: an onboarding wizard, login and account screens, a dashboard shell with navigation and search, a settings area covering profile, security, team, and roles, plus background housekeeping. Every piece works out of the box, and every piece has an extension point when you outgrow it.
The shell
Every page renders inside the same chrome:
- Sidebar — the search / command palette trigger and the navigation tree built from the three root groups (Pages, Modules, Settings) and whatever categories and modules your code registers (Navigation). Users can pin pages as favorites, and the sidebar collapses to icons.
- Header — the sidebar-collapse toggle, quick actions, the notification bell, and the user-avatar menu.
- Footer — copyright, locale switcher, and registered links.
A frontend layer extends every part of this shell through registries — header buttons, sidebar widgets, footer links, app widgets and overlays (Dashboard chrome) — and reskins it through app config (Theming & branding).
The command palette
The search (Ctrl/Cmd+K) opens a command palette aggregating several groups, all permission-gated and fuzzy-searchable:
- Quick actions — backend-registered shortcuts that navigate somewhere, open a form, or fire an event, grouped by category. Your modules add their own (Navigation).
- Favorites & recents — the user's pinned pages, and recently visited modules resuming at their last path.
- Navigation — every reachable page of the nav tree as a breadcrumbed link, broader than the sidebar.
- Session — profile, settings, account switching, a language submenu, copy-current-URL, and logout.
A frontend layer can contribute its own groups through the command-palette source registry (Dashboard chrome).
The notification center
The bell surfaces in-app notifications with an unread badge, live over the user's realtime stream — read one on your phone and the badge updates on your desktop. Your backend code sends notifications through the notification service (Backend services); users choose which subjects they receive in their settings.
First run: the onboarding wizard
A fresh instance has no users. Until one exists, every route funnels to /onboarding, a wizard that registers the first admin — created as platform owner, attached to the default tenant — and marks the instance onboarded. From then on the wizard locks itself (it answers 412 to anyone who returns) and new users arrive by invitation — or by self-registration when the optional cms-saas module is loaded.
The auth screens
Login, invite signup, two-factor challenge, email validation, password recovery, and the account picker all ship as public pages under /auth/*. The flows behind them — token rotation, 2FA methods, the password policy — are their own chapter: Built-in authentication.
The settings area
The Settings root group ships a user section out of the box:
| Page | What it does |
|---|---|
| Profile | Name, email, password, and interface language; two-factor enrollment (authenticator app, email codes, backup codes); the sessions list with per-device revocation and a "log out everywhere" switch. |
| Notifications | Toggle received notification subjects; browse, read, and delete past notifications. |
| Shortcuts | The keyboard-shortcut reference, aggregated from every loaded layer. |
| Members | The tenant's member table — invite by email (role, language, owner flag, optional first/last name — required when skipping email validation), promote/demote tenant owners, force email validation, remove members. Owner-safety guards prevent removing the last owner. |
| Invites | Pending invitations, with resend and cancel. |
| Roles | Create roles and grant permissions from the permission tree that your pages, components, and actions register (Auth & permissions). |
| Appearance | Color mode and interface density (small / normal / large). |
Your project can add its own settings pages by registering pages under settingsCategory (Navigation).
Housekeeping the platform runs for you
Two cron jobs ship with the module, each guarded by a distributed job lock so they run once per fleet:
- Invite cleanup — deletes expired invitations across all tenants every night.
- Export sweep — removes table-export artifacts older than 24 hours from storage every hour.
Add to that the default-tenant bootstrap on first database initialization, and session lastActiveAt tracking on refresh.