Platform
The Orbital Platform is a composable application engine built on NATS JetStream. It provides the foundation for building applications declaratively through Γrbs.
Think of Orbital like Kubernetes: a platform that starts empty but gains capabilities as handlers register themselves. You then compose applications by applying Γrb specs.
Architecture
Section titled βArchitectureβββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Orbital Platform (monolith) ββ βββββββββββββββββββββββββββββββββββββββββββββββ ββ β Core Engine (internal/platform/core) β ββ β - Γrb/Module/Schema/Entry primitives β ββ β - Handler registry + dynamic routing β ββ β - Auto-CRUD from schemas β ββ β - JetStream event sourcing β ββ βββββββββββββββββββββββββββββββββββββββββββββββ ββ βββββββββββββββββββββββββββββββββββββββββββββββ ββ β Built-in Handlers β ββ β - auth.* (passkey, sessions) β ββ β - games.* (launch, sync, RTP) β ββ β - payments.* (deposit, withdraw) β ββ β - accounts.* (register, profile) β ββ βββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β NATS RPC (optional) ββββββββββββββΌβββββββββββββ βΌ βΌ βΌ βββββββββββ βββββββββββ βββββββββββ β Custom β β Special β β 3rd Pty β β Extensions (via NATS) β Handler β βProvider β β Integr. β βββββββββββ βββββββββββ βββββββββββMonolith-first architecture:
- All core capabilities are built into Orbital
- Single deployment, simple operations
- Extensions can register via NATS RPC without code changes
Key Principles
Section titled βKey Principlesβ- Γrbs are domain DATA - Schemas, entries, content you manage in backoffice
- Handlers are OPERATIONS - Custom logic, integrations, flows
- Γrbs declare what they USE - Services are orb-agnostic, routes are orb-prefixed
- Event-sourced - Complete revision history via JetStream
- Schema-driven - Declarative structure, auto-generated UI
- Loosely coupled - Handlers self-register, orbs compose them
Building Blocks
Section titled βBuilding Blocksβ| Kind | Purpose | Example |
|---|---|---|
| Orb | Application container | games, payments, access |
| Module | Feature module | catalog, providers, settings |
| Schema | Data structure | game, provider, transaction |
| Entry | Content instance | Auto-generated ID |
Module Types
Section titled βModule Typesβ| Type | Purpose |
|---|---|
CONTENT | Translatable content entries (games, pages, banners) |
CONFIG | Configuration data, market-specific but not translatable |
RULES | Business rules (evaluation engine) |
TRANSACTIONS | Transaction records and audit logs |
SETTINGS | Application and user preferences |
Service Binding (uses)
Section titled βService Binding (uses)βOrbs declare which service handlers they use via uses. Routes are generated at /api/{orbId}/{handler}:
id: casinouses: - service: auth handlers: [signup, login, logout] - service: games handlers: [launch, getSession] - service: payments handlers: [deposit, withdraw]Generated routes:
POST /api/casino/signup β auth.signup (orbId: casino)POST /api/casino/login β auth.login (orbId: casino)POST /api/casino/launch β games.launch (orbId: casino)POST /api/casino/deposit β payments.deposit (orbId: casino)The handler receives orbId in the request and can:
- Read orb-specific config (session TTL, allowed methods)
- Write to orb-specific streams (sessions, audit logs)
- Apply orb-specific business rules
Orb Definition
Section titled βOrb DefinitionβOrbs define domain data with schemas and field attributes:
id: gamesuses: - service: games handlers: [launch, getSession, syncCatalog]
modules: - id: catalog type: CONTENT schemas: - id: game fields: - name: title type: string translatable: true - name: providerId type: reference ref: games/providers/provider - name: rtp type: number - name: enabled type: boolean marketSpecific: true
- id: providers type: CONFIG schemas: - id: provider fields: - name: name type: string - name: apiKey type: string sensitive: trueField Attributes
Section titled βField Attributesβ| Attribute | Purpose |
|---|---|
translatable | Entry can be translated per language |
marketSpecific | Entry can vary per market |
sensitive | Encrypted at rest, masked in UI |
ref | Links to another schema for dropdowns |
enum | Allowed values list |
unique | Must be unique across entries |
default | Default value |
API Routes
Section titled βAPI RoutesβThe platform exposes three API groups:
| Prefix | Purpose |
|---|---|
/api/admin/ | Platform Management API (orbs, modules, schemas, entries) |
/api/{orbId}/ | Runtime API (dynamic routes from published orbs) |
/api/openapi, /api/discovery | API Discovery (public) |
Reserved Orb IDs
Section titled βReserved Orb IDsβThese IDs cannot be used as orb names (they conflict with platform routes):
admin- Platform managementopenapi- OpenAPI specdiscovery- API discoveryhealth- Health checksmetrics- Prometheus/OTEL
Platform Management API (/api/admin/)
Section titled βPlatform Management API (/api/admin/)βAdministrative endpoints for managing platform resources. Requires platform_admin role.
The Management API follows a document-oriented design:
- Structure (orbs/modules/schemas) = single document, atomic updates
- Content (entries) = granular CRUD, high volume
/api/admin/βββ registry[/{service}] # Handler registry discoveryβββ routes # Active route listingβββ orbs/ # Orb CRUD (document-oriented)β βββ {orbId}/β βββ publish # Publish orbβ βββ revisions[/{v}] # Revision historyβ βββ entries/ # Entry CRUD (granular)β βββ {entryId}/β βββ publish # Publish entryβ βββ revisions # Entry revisionsStructure Endpoints (Document-Oriented)
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/orbs | List all orbs |
| POST | /api/admin/orbs | Create orb (full document with modules/schemas) |
| GET | /api/admin/orbs/{id} | Get orb with all modules and schemas |
| PUT | /api/admin/orbs/{id} | Update orb (full document, server diffs) |
| DELETE | /api/admin/orbs/{id} | Delete orb and all content |
| POST | /api/admin/orbs/{id}/publish | Publish orb |
| GET | /api/admin/orbs/{id}/revisions | List revisions |
| GET | /api/admin/orbs/{id}/revisions/{v} | Get specific revision |
Content Endpoints (Granular)
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/orbs/{id}/entries | List entries (filter: ?module=&schema=) |
| POST | /api/admin/orbs/{id}/entries | Create entry (module/schema in body) |
| GET | /api/admin/orbs/{id}/entries/{eid} | Get entry |
| PUT | /api/admin/orbs/{id}/entries/{eid} | Update entry |
| DELETE | /api/admin/orbs/{id}/entries/{eid} | Delete entry |
| POST | /api/admin/orbs/{id}/entries/{eid}/publish | Publish entry |
| GET | /api/admin/orbs/{id}/entries/{eid}/revisions | Entry revisions |
Discovery Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/registry | List all registered handlers |
| GET | /api/admin/registry/{service} | Get handlers for specific service |
| GET | /api/admin/routes | List active routes |
Runtime API (/api/{orbId}/)
Section titled βRuntime API (/api/{orbId}/)βRoutes generated dynamically from published orbs:
/api/βββ openapi # OpenAPI 3.0 spec (all routes)βββ discovery # API discovery infoβββ {orbId}/β βββ call/{handler} # Service handlers (from uses)β βββ {moduleId}/β βββ {schemaId}/ # Auto-CRUD (multi-schema modules)β βββ {id}/ # Entry operationsAuto-Generated CRUD Routes
Section titled βAuto-Generated CRUD RoutesβEach CONTENT/CONFIG module automatically gets CRUD routes:
| Method | Path | Description |
|---|---|---|
| GET | /api/{orbId}/{moduleId}/{schemaId} | List entries |
| GET | /api/{orbId}/{moduleId}/{schemaId}/{id} | Get entry |
| POST | /api/{orbId}/{moduleId}/{schemaId} | Create entry |
| PUT | /api/{orbId}/{moduleId}/{schemaId}/{id} | Update entry |
| DELETE | /api/{orbId}/{moduleId}/{schemaId}/{id} | Delete entry |
| POST | /api/{orbId}/{moduleId}/{schemaId}/{id}/publish | Publish entry |
| POST | /api/{orbId}/{moduleId}/{schemaId}/{id}/archive | Archive entry |
Smart routing for single-schema modules: When a module has only one schema, the schemaId is omitted:
GET /api/games/catalog/game # Multi-schema: includes schemaIdGET /api/accounts/operators # Single-schema: schemaId omittedDiscovery Endpoints
Section titled βDiscovery Endpointsβ| Method | Path | Description |
|---|---|---|
| GET | /api/openapi | OpenAPI 3.0 spec (all Management + Runtime routes) |
| GET | /api/discovery | Quick overview of available orbs, modules, schemas |
Handler Registry
Section titled βHandler RegistryβHandlers self-register and are auto-discovered. Theyβre exposed as API endpoints automatically.
Registration Types
Section titled βRegistration Typesβ| Type | Description | Use Case |
|---|---|---|
Local | In-process handler function | Built-in capabilities |
NATS | Remote handler via NATS RPC | Extensions, microservices |
HTTP | Native HTTP handler | WebAuthn, OAuth flows |
// Local handler (in-process)core.RegisterLocal("games.launch", launchHandler, core.HandlerSpec{ Description: "Launch a game session", Auth: core.AuthRequired,})
// NATS RPC handler (remote service)core.RegisterNATS("payments.deposit", "orbital.payments.deposit", core.HandlerSpec{ Description: "Process a deposit", Auth: core.AuthRequired,})Discovery
Section titled βDiscoveryβ# CLIorbital registry list # List all registered handlersorbital registry get games # Handlers for games service
# APIGET /api/admin/registry # All handlersGET /api/admin/registry/games # Filter by serviceGET /api/openapi # OpenAPI 3.0 specGET /api/discovery # Quick API overviewExtension Architecture
Section titled βExtension ArchitectureβOrbital is a monolith with extension points. External services can register handlers via NATS:
βββββββββββββββ NATS RPC βββββββββββββββββ Orbital β βββββββββββββββββΊ β Payment Svc ββ (platform) β β (extends) ββββββββββββββββ ββββββββββββββββ β β ββββ orbital.payments.* βββββββββββTo extend Orbital:
- Create a service that connects to NATS
- Subscribe to handler subjects (e.g.,
orbital.payments.process) - Register with Orbitalβs registry (or let Orbital discover via NATS Micro)
- Handlers are automatically available to orbs
This allows:
- Custom integrations without modifying Orbital
- Third-party provider integrations
- Specialized processing (ML, analytics)
Lifecycle
Section titled βLifecycleβSAVED β PUBLISHED β UNPUBLISHED β ARCHIVED- SAVED: Draft state, not visible
- PUBLISHED: Live, routes active
- UNPUBLISHED: Offline, routes removed
- ARCHIVED: Soft-deleted
CLI Quick Reference
Section titled βCLI Quick Referenceβorbital serve # Start platformorbital serve --legacy # Start with legacy orchestrators
orbital orb ls # List orbsorbital orb get myapp # Get orborbital orb apply -f x.yaml # Apply configorbital orb pub myapp # PublishPackage Structure
Section titled βPackage Structureβinternal/platform/core/βββ item.go # Core Item type (Orb/Module/Schema/Entry) + ReservedOrbIDsβββ manager.go # NATS JetStream storageβββ router.go # Dynamic route engineβββ registry.go # Handler registryβββ reconciler.go # Stream/route synchronizationβββ service.go # Business logic layerβββ middleware.go # Middleware types and registrationβββ middleware_builtin.go # logging middlewareβββ system.go # Built-in system handlersβββ mgmt_handlers.go # Management API router (/api/admin/)βββ handlers_orbs.go # Orb CRUD handlersβββ handlers_modules.go # Module CRUD handlersβββ handlers_schemas.go # Schema CRUD handlersβββ handlers_entries.go # Entry CRUD handlersβββ runtime_handlers.go # Runtime API handlers (/api/{orbId}/)βββ openapi.go # OpenAPI spec generation + discoveryβββ rpc.go # RPC request/response typesDependencies
Section titled βDependenciesβThe core engine (internal/platform/core) has minimal dependencies:
| Package | Purpose |
|---|---|
internal/platform/gravity | NATS query engine |
internal/platform/httpx | HTTP utilities |
internal/platform/logger | Structured logging |
No database dependency - all state is in NATS JetStream.
Implementation Status
Section titled βImplementation Statusββ Implemented
Section titled ββ Implementedβ- Γrb/Module/Schema/Entry primitives
- Handler registry (Local, NATS, HTTP)
- Service binding (
uses) with route generation - Auto-CRUD routes from schemas
- JetStream event sourcing with revisions
- Middleware system (JWT, roles, logging)
- CLI commands (
serve,orb ls/get/apply/pub) - Management API (
/api/admin/) - Runtime API (
/api/{orbId}/) - API Discovery (
/api/openapi,/api/discovery) - Reserved orb IDs validation
- Field attributes (translatable, marketSpecific, sensitive, ref, etc.)
- ChangeLog with diff generation
π§ Planned
Section titled βπ§ Plannedβ- Scheduler service for
validFrom/validTo - Rule evaluation engine for RULES modules
- NATS Micro auto-discovery for extensions
See TODO.md for details.
NATS Stream Organization
Section titled βNATS Stream OrganizationβPlatform Stream (Global Configuration)
Section titled βPlatform Stream (Global Configuration)βThe orbital stream stores platform-level configuration and definitions:
| Stream Name | Purpose | Subject Pattern | Examples |
|---|---|---|---|
orbital | Platform configuration & definitions | orbital.* | orbital.orbs.*orbital.definitions.messages.*orbital.definitions.modules.* |
Orb Streams (Per-Orb Data)
Section titled βOrb Streams (Per-Orb Data)βEach Γrb gets its own stream with ΓΈ-prefix naming:
| Orb Name | Stream Name | Subject Pattern | Example Subjects |
|---|---|---|---|
| accounts | ΓΈaccounts | accounts.{module}.{role}.{schema}.{id} | accounts.content.admin.users.abc123accounts.config.owner.plans.def456 |
| payments | ΓΈpayments | payments.{module}.{role}.{schema}.{id} | payments.transactions.user.invoices.xyz789payments.config.admin.gateways.pay001 |
| games | ΓΈgames | games.{module}.{role}.{schema}.{id} | games.content.public.catalog.game123games.rules.admin.leaderboards.lb001 |
| game-platform | ΓΈgame-platform | game-platform.{module}.{role}.{schema}.{id} | game-platform.content.user.saves.save456game-platform.settings.admin.features.feat789 |
Subject Components:
{module}: Module type -content,config,rules,transactions,settings{role}: Access role -owner,admin,user,public{schema}: Schema name (kebab-case){id}: Entry ID (xid format)