Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions content/docs/guide/console-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ description: Internal architecture of the ObjectStack Console — data flow, rou

# Console Architecture

This document describes the internal architecture of the Console app (`apps/console`).
This document describes the internal architecture of the Console SPA.

`apps/console` is a thin host: it owns the Vite build, the outermost route tree, and plugin
registration. Almost everything named below is a **component exported by a package**, not a file
under `apps/console` — the shell (providers, layout, object and record views) ships from
`@object-ui/app-shell`, view rendering from `@object-ui/plugin-view`, and the app wizard from
`@object-ui/plugin-designer`. Packages are named where it matters; import from the package, never
from a path.

## Data Flow

Expand All @@ -14,7 +21,7 @@ This document describes the internal architecture of the Console app (`apps/cons
│ objectstack.config.ts │
│ (defineStack → apps, objects, views) │
└────────────────────┬────────────────────────────────────┘
MSW / Real Server
ObjectStack server (HTTP, VITE_SERVER_URL)
┌─────────────────────────────────────────────────────────┐
│ ObjectStackAdapter (@object-ui/data-objectstack) │
Expand All @@ -25,20 +32,20 @@ This document describes the internal architecture of the Console app (`apps/cons
│ DataSource interface
┌─────────────────────────────────────────────────────────┐
│ SchemaRendererProvider (@object-ui/react)
│ SchemaRendererProvider (@object-ui/react) │
│ • provides dataSource + registry to all children │
└────────────────────┬────────────────────────────────────┘
│ React Context
┌─────────────────────────────────────────────────────────┐
App.tsx
Console shell (@object-ui/app-shell)
│ ├── ExpressionProvider (user, app, evaluator) │
│ ├── ConsoleLayout │
│ │ ├── AppShell (@object-ui/layout) │
│ │ │ └── useAppShellBranding (CSS vars) │
│ │ ├── AppSidebar (navigation tree)
│ │ ├── sidebar nav (app switcher + nav tree)
│ │ └── AppHeader (breadcrumbs, status) │
│ └── Routes
│ └── Routes (mounted by apps/console at /apps/:appName)
│ ├── /apps/:appName/:objectName → ObjectView │
│ ├── /apps/:appName/:objectName/record/:id → Detail │
│ └── /apps/:appName → Home Page │
Expand All @@ -47,7 +54,12 @@ This document describes the internal architecture of the Console app (`apps/cons

## Routing

The console uses React Router DOM v7 with a simple flat route structure:
Routing is React Router DOM v7. `apps/console` mounts the per-app subtree at
`/apps/:appName/*`; the routes below are declared inside it by the console shell
(`@object-ui/app-shell`). Every component in the table is exported by `@object-ui/app-shell`,
except `CreateAppPage` / `EditAppPage`, which are lazy-loaded from `@object-ui/plugin-designer`.
These are the object-facing routes — the shell declares more (record create/edit, the metadata
admin subtree), and `apps/console` adds the unauthenticated auth surfaces outside this subtree.

| Route Pattern | Component | Purpose |
|---------------|-----------|---------|
Expand All @@ -73,7 +85,7 @@ Navigation items can be conditionally hidden using expressions:
}
```

The `ExpressionProvider` wraps the layout and provides an `ExpressionEvaluator` that resolves `${}` templates against context variables (`user`, `app`, `data`).
`ExpressionProvider` (`@object-ui/app-shell`) wraps the layout and provides an `ExpressionEvaluator` that resolves `${}` templates against context variables (`user`, `app`, `data`).

### 2. Action System

Expand All @@ -98,21 +110,24 @@ The `ActionRunner` supports:

### 3. Plugin ObjectView Delegation

The console's `ObjectView` is a **thin wrapper** around `@object-ui/plugin-view`'s `ObjectView`:
The shell's `ObjectView` — the one exported by `@object-ui/app-shell` and bound to the routes
above — is a **thin wrapper** around `@object-ui/plugin-view`'s `ObjectView`:

- Resolves views from the object definition's `list_views`
- Passes a `renderListView` callback for multi-view rendering (kanban, calendar, chart)
- Handles console-specific concerns: URL routing, MetadataInspector, record detail Sheet
- Handles shell-level concerns: URL routing, MetadataInspector, record detail overlay

### 4. App Creation & Editing

The console integrates the `AppCreationWizard` from `@object-ui/plugin-designer` for creating and editing apps:
App creation and editing are owned end to end by `@object-ui/plugin-designer`: it exports both
route pages and the `AppCreationWizard` they render. The console shell only lazy-loads them onto
routes.

- **Create App** — `CreateAppPage` at `/apps/:appName/create-app`. Passes metadata objects as `availableObjects`, handles `onComplete` (converts draft via `wizardDraftToAppSchema()`, navigates to new app), `onCancel` (navigate back), and `onSaveDraft` (localStorage persistence).
- **Edit App** — `EditAppPage` at `/apps/:appName/edit-app/:editAppName`. Loads existing app config as `initialDraft` and updates on completion.

**Entry Points:**
- AppSidebar app switcher → "Add App" / "Edit App" buttons
- Sidebar app switcher → "Add App" / "Edit App" buttons
- CommandPalette (⌘+K) → "Create New App" command in Actions group
- Empty state CTA → "Create Your First App" button when no apps are configured

Expand All @@ -131,13 +146,12 @@ Per-app branding is applied via `AppShell`'s `branding` prop:

This sets CSS custom properties (`--brand-primary`, `--brand-primary-hsl`, etc.) on the document root.

## MSW Mock Mode

In development, the console uses MSW (Mock Service Worker) to simulate an ObjectStack backend:
## Development Mode

1. `objectstack.config.ts` defines apps and objects via `@objectstack/spec`
2. `@objectstack/runtime` boots an `ObjectKernel` with `MSWPlugin`
3. MSW intercepts `/api/v1/*` requests and serves in-memory data
4. The `ObjectStackAdapter` connects to this mock server transparently
There is **no bundled mock backend** — offline development is not a thing here. In dev exactly as
in production, `ObjectStackAdapter` talks over HTTP to a live ObjectStack server at
`VITE_SERVER_URL`, and everything above the adapter in the data flow depends on that call
succeeding: no server, no discovery, no apps in the sidebar.

This allows full offline development without a real backend.
See [Console App → Quick Start](/docs/guide/console#quick-start) for the dev server port, the
default `VITE_SERVER_URL`, and how to point the console at a different backend.