apps/foundation-lab
liveDepends on 15 Foundation packages.
Impact
Foundation is a platform change, not a frontend refresh. It moved the shell out of every app, added a dedicated Unified API surface, tightened the tenant model, replaced the branding pipeline and gave modules a real sandbox.
3
apps consuming Foundation
verified from apps/*/package.json
32
Unified API routes
services/unified_api/foundation
7
platform tables
all keyed by company_id
8/13
migration waves shipped
2 in progress, 3 planned
Before and after
| Area | Before | With Foundation | Evidence |
|---|---|---|---|
| Frontend architecture | Every app carried its own shell, its own theme handling and its own session plumbing. Fixing a session bug meant fixing it n times. | One runtime, pinned per product. A shell or session fix ships once and rolls out through controlled rebuilds. | packages/foundation/* |
| Unified API | A narrower /api/v1/ui/* runtime served the old dashboard and nothing else. | A dedicated /api/v1/foundation/* surface serves bootstrap, manifests, navigation, widgets, commands, customization, dashboards, favorites, recents and actions for every consumer. | services/unified_api/foundation/ |
| Tenant isolation | Company scope was sometimes inferred from the first membership or the URL. | Company scope is derived from the verified token, validated server-side, and every Foundation table is keyed by company_id. | docs/TENANT_ISOLATION_AND_COMPANY_CONTEXT.md |
| White label | Per-customer branding meant per-customer CSS and a deployment risk each time. | A versioned customization record with draft, preview, publish and rollback, validated identically on client and server. | platform.foundation_customization_versions |
| Modules and extensions | The old Module SDK mixed installation, UI and backend concerns and had no sandbox story. | One extension runtime with signed manifests, compatibility ranges, a sandboxed host and a stable SDK. HQ Apps, product add-ons and integrations are three views of the same mechanism. | packages/foundation/extensions/ |
| Desktop and mobile | Desktop wrappers were separate builds with divergent behaviour. | A single platform adapter contract covers web, PWA, Tauri and Electron. | packages/foundation/platform/ |
Consumers
Read from the repository, not from a roadmap slide. An app appears here only if its package manifest actually depends on the framework.
Depends on 15 Foundation packages.
Depends on 13 Foundation packages.
Depends on 10 Foundation packages.
Listed honestly: these products are the target consumers from SoT §1.3 and have not been migrated yet.
Strangler migration — Wave 12
Chat-first shell + desktop adapter — Wave 11
Platform plumbing replacement — Wave 10
Tables, inspectors, events — Wave 10
Selective: tokens, primitives, localization
Data · tenant boundary
Foundation stores user preferences, published branding versions, dashboards, favorites, recents and extension installations. Company scope is part of the key, not a filter someone might forget to add.
platform.foundation_customization_versions
Append-only white-label versions with draft, published and archived states — the source for preview, publish, rollback and history.
platform.foundation_dashboards
Company-scoped dashboard layouts for the grid engine and widget runtime.
platform.foundation_extension_audit
Audit trail for extension install, activation, permission and lifecycle events.
platform.foundation_extension_installations
Which extensions are installed and activated for which company, with the granted permission set.
platform.foundation_favorites
Per-user favorites resolved into the sidebar and the command palette.
platform.foundation_recents
Recently visited records and routes, feeding recents and search ranking.
platform.foundation_user_preferences
Theme, density, locale, timezone and accessibility preferences, keyed by company_id and auth_user_id.
The canonical enforcement model — auth → PlatformContext → Unified API middleware → database RLS → a shared assert_same_company primitive — is documented in docs/TENANT_ISOLATION_AND_COMPANY_CONTEXT.md. Foundation consumes that model; it does not invent a second one.
Migration · SoT §39
The framework was not dropped into the platform in one release. Each wave has a gate, and a wave does not close until the gate is met.
Feature, route and API inventory · Session, context and error contracts · Package boundaries · Auth domain corrected to auth.ottili.one
pnpm workspace under packages/foundation · Foundation Lab reference app · Boundary and build graph
Tokens, themes, density, accessibility · Primitives, forms, tables, overlays, states · Component catalog
Redirect/callback, session, refresh, expired view · Company routes and switchers · Context revision, multi-tab
Topbar, sidebar, mobile · Breadcrumbs, favorites, recents, quick create · Console links
Search providers and palette · Workbench and command contract · Notification inbox, realtime, preferences
White label inheritance and lifecycle · Dashboard engine and widgets · Saved views, legacy import
AI, Files, Flows · Approvals, Activity/Audit, Jobs, Help
SDK, manifest, host, sandbox · Console installation · HQ App, LD3 add-on and integration samples
First complete product consumer · CRM, office and workspace surfaces on Foundation
Replace platform plumbing · Migrate product pages
Chat-first shell · Workbench and desktop adapter · Separate Coder terminal from Workbench
Strangler migration · Keep domain components, replace shell and plumbing · Route compatibility
Try the result Read the contracts
Figures generated from the repository on 2026-08-10 · 41 954 source lines · 24 397 test lines