Qubital API Contract Redesign
Date: 2026-06-13
Status: In progress — conventions + taxonomy drafting
Parent plan: ../openapi-huma-migration-plan.md
What this is
The target wire contract for the Huma/OpenAPI migration. The migration plan covers
mechanics (Huma, middleware, codegen pipeline). This folder covers shape: what every
endpoint's method/path/tag is, and what every request/response DTO looks like — with the
type decisions captured per resource ahead of the first published @qubital/api-contract.
Several cross-cutting decisions are still open (see migration plan §8a), so nothing here is
frozen yet.
This supersedes the current ad-hoc shapes. It is the blueprint that migration Phase 2 (feature conversion) implements against, and it folds in the deferred module-cohesion audit.
Locked decisions
- Endpoint-shape lane: RPC-commit. Uniform
POST, resource-noun paths, colon-verbs for non-CRUD actions, consistent envelopes. Rationale: dual IPC+axios transport (desktop is IPC — zero HTTP semantics to lose), TanStack Query owns caching/retry at the app layer, adapter staysinvoke(action, body) → response. Stays fully OpenAPI-native. See research findings + the conversation that produced this. - gRPC-Web / Connect: ruled out. Huma is OpenAPI/JSON-first; a future public API is a separate curated REST layer regardless. Performance is a non-factor (LiveKit is the data plane).
- Tag = resource, not Go-module. The accidental
organization-owns-everything grouping gets fixed; tags reflect resources and modules get split to match (Part 1).
Approach — one resource at a time
Do not big-bang all resources. Sequence (each is a deep, self-contained pass):
- Part 0 — Conventions (
00-conventions.md) — decide once, blocks all. - Part 1 — Taxonomy + module layout (
01-taxonomy-and-modules.md). - Recording (reference resource — establishes the DTO patterns everyone copies).
- Spaces (was Office/Rooms) → Org/Invitations/Members cluster → Calendar → Auth/Session → Chat → Realtime → User/Avatar → (Analytics/Metrics/Webhooks).
Resource status
| Resource | Blueprint | Module move needed | Notes |
|---|---|---|---|
| Recording | draft done (resources/recording.md) | consolidate /livekit/* + /recordings/* | reference resource; recordingId-keyed (opaque, egress-backed); list filters (name/people/date) |
| Spaces (+ Layouts, Tags) | draft done (resources/space.md) | split out of organization | Space (UUID, was Office — N1 settled to Space 2026-06-15); reified SpaceLayout; new SpaceTags; presence snapshot |
| Invitations (+ invite-link) | draft done (resources/invitations.md) | split out of membership/organization | WorkOS-backed; cursor pagination; public accept |
| Members | draft done (resources/members.md) | shrink membership to members | presenceStatus string enum; role enum; stringified user id |
| Organizations | draft done (resources/organizations.md) | shrink to org-only | WorkOS org id; domains[] replaces SDK leak; switch→Auth; preview-org deferred |
| Calendar | draft done (resources/calendar.md) | wire drops /google/ | OAuth connect/finalize; batch event reads; state on User.integrations; provider-ready ({provider} selector + merged reads) for Outlook |
| Auth / Session | draft done (resources/auth.md) | merge authentication+session; signups in from user | cookie tokens ({user} body); multi-org selection; switch-org moved in |
| Chat | draft done (resources/chat.md) | Centrifugo migration | messaging only; endpoint map aligned to conventions; detail owned by centrifugo_chat_poc.md |
| Realtime | draft done (resources/realtime.md) | — | transport tokens: A/V conference token (LiveKit today, vendor off the wire) + Centrifugo connection token (shared by chat & presence) |
| Presence | draft done (resources/presence.md) | split from chat | user-status (heartbeat / manual-status / snapshot) over Centrifugo status: channels; cross-cutting |
| User / Avatar | draft done (resources/user.md) | profile+avatar; signups → auth | canonical User DTO; shared image-upload pattern |
| Analytics / Metrics / Webhooks | out of scope | — | stay plain gin (N5) — internal/signature-verified, not in the typed client contract |