Skip to content

UI: Auto-Rendered Admin & Custom Pages

Summary

The UI axis of an Aetos app is a published React client, not code written per application. Two npm packages carry the whole surface:

Package Role
@aetoskia/react-openapi Renders a complete admin panel (CRUD tables, forms, filters, sorting, pagination, uploads) from the app's openapi.yaml — zero UI code.
@aetoskia/react-auth Auth contexts and pages (login/register/me) wired to the auth-server, plus the axios client with token handling.

Both publish to the private registry https://npm.aetoskia.com. The server spec is the single source of truth: the same openapi.yaml that drives openapi-first routing drives the admin UI, through x- extension fields (see below).


Scaffold

1
2
3
4
cp -r <docs>/standards/src/templates/client apps/<your-app>-client
cd apps/<your-app>-client
npm install          # deps come from npm.aetoskia.com via .npmrc
npm run dev

The client template is a Vite + MUI app with:

  • src/openapi-config.ts — points the renderer at the app's spec and the auth-server's spec;
  • .env.example — VITE_API_BASE_URL (app API) and VITE_AUTH_BASE_URL (auth-server);
  • a Home page that auto-lists every resource the spec declares, and a Header/Footer/theme scaffold.

Custom pages are ordinary React routes layered on top; the auto-rendered admin is available per resource at #/resource/<name>.


x- extensions: how the spec steers the UI

The admin renderer reads a catalog of OpenAPI extension fields (x-resource, x-list-columns, x-display-format, x-label, x-order, x-hidden, x-sortable, x-filterable, x-autocomplete, x-fk, x-ui-type, x-upload, x-sse, x-profile, and the auth wiring x-server-url / x-login-path / x-me-path / …) declared on schemas and properties.

The catalog is canonical in the react-openapi source, not in this doc. Read it from the MCP bundle:

docs://modules/react-openapi        # module: specExtensions — the full catalog

The app's own spec carries the per-resource values; the catalog explains what each field does. The template's openapi.yaml shows the convention on the example Job schema.


Golden rules

  1. The spec owns the UI. Add a resource or rename a column in openapi.yaml; the admin follows. Never fork the renderer per app.
  2. Custom pages for workflows, auto-render for CRUD. Anything that is "list / create / edit / delete an entity" is a spec concern; anything that is a bespoke workflow is a React page.
  3. Auth is consumed, never re-implemented. @aetoskia/react-auth holds tokens and calls the auth-server endpoints declared by the x- wiring; pages read the context.
  4. Publish, don't vendor. UI shared across apps belongs in @aetoskia/react-openapi or @aetoskia/react-auth (SemVer, tag-triggered npm release), not copy-pasted into app trees.

Notes

  • The server template ships authless by default (see 22 – Auth Integration); the client template pairs with it and degrades to "no login" until a security scheme is declared.
  • The standards app + client templates are the full-stack reference: the server spec carries the x- extensions, and the client renders the admin from it. The wiki's Reference App walkthrough (06_reference_app) documents the pairing end to end.