Here’s a tight design plan that gets us from “client-first demo” to a self‑building admin UI, without disrupting current momentum.
Vision
- Server publishes capabilities via discovery; client ingests and renders an admin UI automatically
- Core stays the shared source of truth (schemas/constants/error codes); client+server never diverge from protocol
Why keep this in the monorepo initially
- Atomic changes across core/client/server/admin with single CI matrix
- Stable, end‑to‑end tests on every PR (less release choreography)
- Fast iteration on discovery/ui metadata shape
Proposed packages
- packages/rdcp-admin-ui
- Headless builder library that consumes discovery (+ optional ui) and returns a render spec or components
- Peer deps: @rdcp.dev/core ^1.0.0, @rdcp.dev/client ^1.0.0
- Publish: yes (public) so others can embed it
- Optionally split framework renderers later (e.g., rdcp-admin-ui-react)
- packages/rdcp-admin-app
- Demo web app serving /admin using rdcp-admin-ui (not necessarily published; can be a template)
Discovery: optional, backward‑compatible UI metadata
- Keep current discovery stable; add optional
ui section
- Do not duplicate protocol semantics; only publish presentation and constraints the client can’t infer
- Version
ui independently (ui.version) for safe evolution
Example (illustrative only)
{
"protocol": "rdcp/1.0",
"capabilities": {
"categories": ["DATABASE", "API_ROUTES", "CACHE", "REPORTS"],
"auth_methods": ["api-key", "bearer", "mtls"],
"tenants": ["tenant-A", "tenant-B"],
"ttl_support": true,
"rate_limits": { "control": "10/min" }
},
"ui": {
"version": "1.0",
"category_descriptions": {
"DATABASE": "SQL query logging",
"CACHE": "Redis operations"
},
"groups": [
{ "id": "logging", "label": "Logging & Tracing", "categories": ["DATABASE", "API_ROUTES"] }
],
"constraints": {
"ttl": { "min": "30s", "max": "15m", "default": "2m" }
},
"preferred_auth": "bearer",
"multi_tenant": true
}
}
Client-side builder (deterministic & testable)
- Map capabilities to widgets via a small registry:
- categories → ToggleGroup
- ttl_support → DurationInput (constrained by ui.constraints.ttl)
- tenants → Select (only if provided)
- auth_methods → AuthPicker (default to ui.preferred_auth if present)
- Stateless rendering: a function that takes (discovery, ui) → component tree/spec
- Initial widget set: ToggleGroup, Select, DurationInput, StatusPanel, SubmitBar, Toast
Real-time status
- Start with polling via client.getStatus() + jitter/backoff
- Add SSE/WebSocket later; include correlation id to reduce server fan‑out
Security & configuration
- No secrets in discovery; only safe capability metadata
- .env (server): enable auth methods, demo tenants; .env (client): baseUrl & demo flags (never secrets in frontend)
Validation & versioning
- Tiny
core-ui schema to validate the optional ui block
- Graceful degradation: when
ui is absent, render a minimal generic UI
A11y/i18n/theming
- Roles/labels, keyboard navigation, high-contrast
- i18n-ready strings; allow injection of translations
- Theming via CSS variables or tokens; no complex runtime theming initially
Incremental delivery (under milestone: Client-first demo integration (v1.0/v2.1))
P0 – Foundation (fast)
- RFC + example
ui contract
- /admin route that renders via client + builder (toggles/TTL/tenant/status)
- Docs: “Admin UI (self‑building)” overview
P1 – Tests & polish
- Headless tests of builder mapping; E2E smoke for /admin flows
- Status polling with loading/error states; screenshots & GIF
P2 – Observability
- Trace client→server control ops with OTEL; doc a short how‑to
P3 – Optional follow‑ups
- SSE/WebSocket status
- Minimal CLI that mirrors the UI via prompts
- Multi‑server selector
Acceptance criteria
- /admin renders entirely from discovery (+ui when present); no hard‑coded categories
- Tenant selector and TTL controls render only when supported
- Control flows (discovery/status/control/health) work from the UI
- Tests pass locally and in CI; docs have a quickstart and screenshots
Monorepo vs new repo (decision now: stay here)
- Start in this repo for velocity and atomic CI
- Revisit split once UI/brand/governance needs diverge
- Keep rdcp-admin-ui here close to core/client; move admin-app to its own repo if/when productized
Open questions
- Do we want an official React renderer package up front or keep it headless first?
- Any additional metadata you want in
ui v1 besides descriptions/groups/constraints/preferred_auth?
- Minimum browser support target if we add a browser demo?
Links
Here’s a tight design plan that gets us from “client-first demo” to a self‑building admin UI, without disrupting current momentum.
Vision
Why keep this in the monorepo initially
Proposed packages
Discovery: optional, backward‑compatible UI metadata
uisectionuiindependently (ui.version) for safe evolutionExample (illustrative only)
{ "protocol": "rdcp/1.0", "capabilities": { "categories": ["DATABASE", "API_ROUTES", "CACHE", "REPORTS"], "auth_methods": ["api-key", "bearer", "mtls"], "tenants": ["tenant-A", "tenant-B"], "ttl_support": true, "rate_limits": { "control": "10/min" } }, "ui": { "version": "1.0", "category_descriptions": { "DATABASE": "SQL query logging", "CACHE": "Redis operations" }, "groups": [ { "id": "logging", "label": "Logging & Tracing", "categories": ["DATABASE", "API_ROUTES"] } ], "constraints": { "ttl": { "min": "30s", "max": "15m", "default": "2m" } }, "preferred_auth": "bearer", "multi_tenant": true } }Client-side builder (deterministic & testable)
Real-time status
Security & configuration
Validation & versioning
core-uischema to validate the optionaluiblockuiis absent, render a minimal generic UIA11y/i18n/theming
Incremental delivery (under milestone: Client-first demo integration (v1.0/v2.1))
P0 – Foundation (fast)
uicontractP1 – Tests & polish
P2 – Observability
P3 – Optional follow‑ups
Acceptance criteria
Monorepo vs new repo (decision now: stay here)
Open questions
uiv1 besides descriptions/groups/constraints/preferred_auth?Links