SS-11 · Backends from one declaration

BaaS application platform

Declare a backend; get collections, functions and an SDK.

21operations
5sub-capabilities
4endpoint groups
5services it composes

What it does

Declare a backend; get collections, functions and an SDK.

Provision a complete backend from a single declaration: schema-bound collections with fail-closed row policies, declared buckets, and Knative-semantics functions with scale-to-zero and per-invocation metering. Production engines — Hasura, Directus, Cosmo, Temporal, Authentik, RustFS — are composed automatically as fail-loud adapters (BAAS16), reused, never installed in parallel.

In-mesh base http://ss-11-baas.shared-services.svc.cluster.local:8011 · auth is an SS-01 bearer token + X-Tenant-Id on every /api/v1 route.

Sub-capabilities

The real building blocks.

Backend claims

One BackendClaim provisions collections, buckets and functions and returns an emitted SDK config (endpoint + API key + collection list). An existing app is rejected, not replaced.

POST /api/v1/claims

Schema-bound collections

Declared fields drive generated CRUD validation; row policies (tenant / owner / role) are enforced fail-closed on every read and write — a denied row reads as absent.

POST /api/v1/apps/{app}/collections

Functions as a product

Knative-semantics execution: scale-to-zero, at-least-once delivery deduped by event id, per-function DLQ and per-invocation metering.

POST /api/v1/apps/{app}/functions/{fn}/invoke

Plan & apply migrations

Diff a desired claim against current state, get a plan hash, then apply with optimistic concurrency; destructive actions need an explicit opt-in.

POST /api/v1/apps/{app}/apply

Composed engines

Collections track into Hasura, studio collections into Directus, subgraphs into the Cosmo federated graph — each recorded as an EngineBinding, run through the SS-12 workflow runner when wired.

POST /api/v1/apps/{app}/engines

Worked example

Claim a backend → define data → invoke a function

One declaration yields collections, buckets, functions and an SDK config. Row policies are enforced fail-closed the moment data flows.

  1. 1
    Provision the backendPOST/api/v1/claims

    Returns { endpoint, api_key, collections } and composes engines best-effort.

  2. 2
    Add a collectionPOST/api/v1/apps/{app}/collections

    Declared fields + an owner/tenant/role row policy.

  3. 3
    Write a recordPOST/api/v1/apps/{app}/collections/{coll}/records

    Owner field stamped from the caller's subject.

  4. 4
    Invoke a functionPOST/api/v1/apps/{app}/functions/{fn}/invoke

    Cold-start flag + compute ms; a failure lands on the DLQ.

  5. 5
    Read the meterGET/api/v1/apps/{app}/usage

    Invocations, cold starts, compute ms — deduped, never double-counted.

Endpoint catalog

21 documented endpoints of 21 operations.

Real method + path from services/baas/openapi.json. The full contract, including ops endpoints, is the 21-operation surface.

Backends & revisions

  • POST/api/v1/claimsidempotentProvision a complete backend from one declaration
  • POST/api/v1/appsCreate an empty tenant-scoped backend namespace
  • POST/api/v1/apps/{app}/planDiff a desired claim → the plan apply would take
  • POST/api/v1/apps/{app}/applyApply a plan, creating a new revision
  • GET/api/v1/apps/{app}/revisionsList the app's applied revisions

Collections & data API

  • POST/api/v1/apps/{app}/collectionsDefine a schema-bound collection with row policies
  • POST/api/v1/apps/{app}/collections/{coll}/recordsCreate a record (schema-validated, owner-stamped)
  • GET/api/v1/apps/{app}/collections/{coll}/recordsList records (PostgREST-style filters, policy-filtered)
  • GET/api/v1/apps/{app}/collections/{coll}/records/{id}Fetch a record (denied row reads as 404)
  • PUT/api/v1/apps/{app}/collections/{coll}/records/{id}Update a record (policy-enforced)
  • DELETE/api/v1/apps/{app}/collections/{coll}/records/{id}Delete a record (policy-enforced)
  • GET/api/v1/apps/{app}/collections/{coll}/feedPolicy-filtered change feed (resumable cursor)

Functions

  • GET/api/v1/apps/{app}/functionsList function statuses (0 instances = scaled to zero)
  • POST/api/v1/apps/{app}/functions/{fn}/invokeHTTP trigger with an optional JSON payload
  • POST/api/v1/apps/{app}/functions/{fn}/eventsBus→function delivery (dedup by event_id)
  • GET/api/v1/apps/{app}/functions/{fn}/invocationsA function's execution history
  • GET/api/v1/apps/{app}/functions/{fn}/dlqDead-lettered deliveries + reasons
  • GET/api/v1/apps/{app}/usagePer-function metering for the SS-10 usage line

Engines

  • GET/api/v1/enginesThe engine catalog (Hasura, Directus, Cosmo, …)
  • POST/api/v1/apps/{app}/enginesidempotentCompose/refresh the app's engine bindings
  • GET/api/v1/apps/{app}/enginesRead the app's stored engine bindings

Architecture placement

Where it sits in the platform.

BaaS application platform does not reimplement the platform — it composes it. These are the services it leans on and the seams between them.

SS-01 Authentik

Realm/JWT/role wiring on every claim; row policies key off the edge-stamped subject and roles.

SS-02 RustFS

Declared buckets are SS-02 bucket claims — storage is reused, never a parallel install.

SS-12 Temporal

Engine compose steps run through the existing SS-12 workflow bridge when wired (durable, idempotent).

SS-03 Bus / SS-16 Realtime

Bus-triggered functions dedupe on event id; the change feed's push delivery rides SS-16.

SS-47 SkyForge

A SkyForge app can front a BaaS backend as its data plane, deployed on the same governed spine.