Why
The runtime datasource experience now ships end-to-end:
But examples/app-showcase has no external-datasource example — its only datasource is the managed in-memory sqlite. So there is nothing in the canonical example app that demonstrates (or regression-guards) the federation + datasource-admin flow. New users can't see "connect an external DB → introspect → query its tables as objects", and contributors have no fixture to dogfm against.
This example is considered high-value: the datasource story is a flagship capability and the showcase is where people learn the platform.
Goal
A runnable, self-contained example in app-showcase that demonstrates the full external-datasource path without requiring an external server (so os dev just works):
- A code-defined external datasource (
*.datasource.ts, schemaMode: 'external') pointing at a second, pre-seeded sqlite file (or equivalent) so there are real remote tables to introspect.
- One or more external/federated objects bound to that datasource's remote tables (
external: { remoteName, remoteSchema? }), queryable through the normal ObjectQL/REST surface.
- Wiring in
objectstack.config.ts (+ a datasourceMapping rule if needed) and a short README/comment explaining the flow.
End state: boot showcase → the external datasource shows in Setup → Datasources; its objects appear and are queryable; and an admin can also reproduce the runtime flow (Setup → Datasources → Sync objects) against it.
Proposed shape (minimal, no external server)
examples/app-showcase/src/datasources/<name>.datasource.ts — sqlite, schemaMode: 'external', filename = a seeded fixture db (e.g. created at boot / committed fixture).
examples/app-showcase/src/objects/<remote>.object.ts — external object(s) binding the fixture's tables (e.g. customers, orders).
objectstack.config.ts — import the datasource + objects (+ mapping).
- Decide how the fixture tables get created (open question below).
Open questions / decisions for the implementer
- Fixture provisioning: how does the "external" sqlite get its tables at dev time? Options: a committed
.db fixture; a tiny boot/seed step that creates+populates a side sqlite; or a memory driver pre-seeded via a hook. Pick the one that keeps os dev zero-config.
- Showcase vs a dedicated example app: add to
app-showcase (conditionally imported so the default stays in-memory) vs. a new examples/app-showcase-external/. Lean toward in-showcase + clearly isolated, unless it muddies the default.
- Scope: code-defined only, or also document the runtime/UI sync flow (the wizard already exists)? At minimum the code-defined example; optionally a README note pointing at the Setup → Datasources sync UI.
- Secret demo: optionally include a driver that exercises a
secret credential field (e.g. a commented postgres variant) to showcase the masked secret widget — without making the default example require a real server.
Acceptance criteria
os dev on app-showcase boots with no extra setup; the external datasource + its federated objects are present.
- The external datasource appears in Setup → Datasources and
GET /api/v1/datasources / GET /api/v1/meta/datasource.
- The federated objects are listable/queryable via REST.
- Short docs/comment explaining the example and pointing at the sync UI.
- (Nice) a smoke test asserting the external objects resolve.
References
Why
The runtime datasource experience now ships end-to-end:
GET /datasources/drivers(feat(datasource): expose driver catalog with config JSON Schema #2083),GET /datasources/:name/remote-tables,POST /datasources/:name/object-draft,POST /datasources/:name/test,GET /datasources/:name(feat(datasource): read-only introspection routes + by-name test for Studio sync #2085, feat(datasource): GET /datasources/:name detail for Studio edit form #2086).secret+dynamic-configSchemaForm widgets (objectui#1853).But
examples/app-showcasehas no external-datasource example — its only datasource is the managed in-memory sqlite. So there is nothing in the canonical example app that demonstrates (or regression-guards) the federation + datasource-admin flow. New users can't see "connect an external DB → introspect → query its tables as objects", and contributors have no fixture to dogfm against.This example is considered high-value: the datasource story is a flagship capability and the showcase is where people learn the platform.
Goal
A runnable, self-contained example in
app-showcasethat demonstrates the full external-datasource path without requiring an external server (soos devjust works):*.datasource.ts,schemaMode: 'external') pointing at a second, pre-seeded sqlite file (or equivalent) so there are real remote tables to introspect.external: { remoteName, remoteSchema? }), queryable through the normal ObjectQL/REST surface.objectstack.config.ts(+ adatasourceMappingrule if needed) and a short README/comment explaining the flow.End state: boot showcase → the external datasource shows in Setup → Datasources; its objects appear and are queryable; and an admin can also reproduce the runtime flow (Setup → Datasources → Sync objects) against it.
Proposed shape (minimal, no external server)
examples/app-showcase/src/datasources/<name>.datasource.ts— sqlite,schemaMode: 'external', filename = a seeded fixture db (e.g. created at boot / committed fixture).examples/app-showcase/src/objects/<remote>.object.ts— external object(s) binding the fixture's tables (e.g.customers,orders).objectstack.config.ts— import the datasource + objects (+ mapping).Open questions / decisions for the implementer
.dbfixture; a tiny boot/seed step that creates+populates a side sqlite; or a memory driver pre-seeded via a hook. Pick the one that keepsos devzero-config.app-showcase(conditionally imported so the default stays in-memory) vs. a newexamples/app-showcase-external/. Lean toward in-showcase + clearly isolated, unless it muddies the default.secretcredential field (e.g. a commented postgres variant) to showcase the masked secret widget — without making the default example require a real server.Acceptance criteria
os devon app-showcase boots with no extra setup; the external datasource + its federated objects are present.GET /api/v1/datasources/GET /api/v1/meta/datasource.References
packages/services/service-datasource/README.md(Federation + Runtime admin halves).