03 / Develop · Core concepts
Core concepts
The vocabulary this section assumes — in the order the pieces actually connect. Read the flow once to build the mental model, then use the reference below to look a term up. Ready to build? Start Build a satellite.
The model in one line
VENI-AI is a set of Self-Contained Systems (SCS): the Shell owns identity and hosts the launchpad; each satellite is a full app — its own UI, API and database — that plugs in and owns its whole stack (repo, data and deploy). You build a satellite. Architecture →
How a satellite works
The path from a user opening your app to your API answering a request. Each step names the concepts it leans on:
- Federation — your UI is a Module Federation remote that exposes
./ShellEntry. The Shell imports it and mounts it at/<slug>at runtime — it hands your app a DOM container and your app callsReactDOM.createRoot()into it — so a user moves between apps with no full page reload. - Sign-in — the Shell signs the user in (local, Google, or any OIDC provider) and issues a Shell token: an RS256 JWT it broadcasts to your UI over a
BroadcastChannel. A late-mounting remote must callrequestToken()or it misses that broadcast. - Token exchange — your API never trusts the Shell token directly. It verifies it against the Shell's JWKS (public keys at
/api/.well-known/jwks.json— no shared secret) and exchanges it (POST /api/auth/exchange) for its own service token: an HS256 JWT carrying your local user's id, roles and permissions. A local user is provisioned on first sign-in. The handshake → - Authorization — your handlers enforce access with guards from
utils/auth-guards(requireAuth,requirePermission, …) against the token'srolesandresource:actionpermission codes, resolved from your database at exchange time. Authorization → - Data — your app owns its data in its own Postgres, defined and migrated with Drizzle — no shared tables. Every token carries an
organizationId(the tenant): scope every query by it, and extendAuditedRepositorysocreated_by/updated_byfill themselves. Multi-tenancy → - Talking to other systems — for a live answer, call another app over Connect RPC (synchronous, plain HTTP with a Protobuf/JSON body). To stay in sync without calling on the hot path, publish and consume domain events on the Redis Streams event bus and keep a local read model — a satellite never reads another system's database. Integration →
Term reference
Quick lookup once the flow makes sense.
The platform
| Term | What it is |
|---|---|
| SCS (Self-Contained System) | The platform's first rule — each app owns its whole stack (repo, database, deploy) and stays independent of the others. |
| Shell | The host app. Owns identity (users, organizations, roles), signs people in, and hosts the launchpad every app federates into. Shell → |
| Satellite (remote app) | An app you build that plugs into the Shell — its own repo, DB and deploy, but rendered inside the Shell UI. |
| Launchpad | The Shell's home screen that lists and opens the registered apps. |
Frontend
| Term | What it is |
|---|---|
| Module Federation | The Vite feature that loads your UI into the Shell at runtime. Your app exposes ./ShellEntry; the Shell mounts it at /<slug>. |
| Mount pattern | How a remote renders — the Shell passes a DOM container and your app calls ReactDOM.createRoot() into it, so the two React instances never collide. |
Authentication
| Term | What it is |
|---|---|
| Shell token (RS256) | The JWT the Shell issues at sign-in, signed with an RSA private key. Your app verifies and exchanges it — never trusts it directly. |
| Service token (HS256) | Your app's own JWT, minted during the exchange, carrying your local user's id, roles and permissions. This is what your API checks. |
| JWKS | The Shell's public keys, at /api/.well-known/jwks.json. Your API verifies a Shell token against them, with no shared secret. |
| Token exchange | The one call (POST /api/auth/exchange) that turns a Shell token into your service token, provisioning a local user on first sign-in. Generated for you. |
| Token broadcast | How a federated UI receives the Shell's token — over a BroadcastChannel. A late-mounting remote must call requestToken() or it misses the broadcast. |
Backend stack
| Term | What it is |
|---|---|
| Bun | The JavaScript runtime + package manager the platform runs on. bun install, bun run dev. |
| Hono | The lightweight web framework your API's routes are built on. |
| Ignis | VENI's framework layer over Hono — the BaseApplication composition root, decorators (@controller, @get), the auth strategy, the health endpoint. |
| Drizzle | The type-safe SQL toolkit for defining tables (pgTable) and running migrations against Postgres. |
| Repository | The data-access layer — a class that owns the queries for one table. Extend AuditedRepository so audit columns fill themselves. The repository → |
Authorization & data
| Term | What it is |
|---|---|
| Roles & permissions | The RBAC model in the token — roles (e.g. admin) and resource:action codes (e.g. events:write), resolved from your DB at exchange time. |
| Guards | Functions from utils/auth-guards (requireAuth, requirePermission, requireOwnerOrAdmin, …) that enforce roles/permissions at the top of a handler. |
organizationId | The tenant every token carries. Scope every query by it so one org never sees another's rows. |
Cross-system
| Term | What it is |
|---|---|
| Connect RPC (gRPC) | Synchronous server-to-server calls — plain HTTP with a JSON/Protobuf body. Use it to fetch live data from another system. |
| Redis Streams event bus | Asynchronous messaging — an app publishes events (XADD), others subscribe (XREADGROUP) and keep a local copy. |
| Read model | Your local copy of another system's data, kept fresh off the event bus, so your app is fast and still works when that system is down. |
See also
- Develop — the developer hub: how-to, reference and projects.
- Build a satellite — put these concepts to work, end to end.
- Platform architecture — the full model behind these terms.