Design history
The design specs behind Chelabase, grouped by area, with a link and one line for each.
Each feature began as a written design spec in docs/superpowers/specs. The pages in this section describe how things work today; the specs record why they were designed that way, and the decisions made along the way. Where a spec and a page disagree, the page (checked against the code) is current.
The same folder also holds brainstorm and research notes for some areas. They are not listed here.
Foundations
- Control-plane skeleton: the local-only monorepo, with compiling service stubs and local infrastructure.
- Create-database vertical slice: the first end-to-end path, from an API call to a provisioned database record.
- API gateway: the Pingora front door, its fixed request pipeline and the internal identity token.
- Product rename: moving every name the product shows or uses to Chelabase.
Identity and sign-in
- The identity service: accounts in an internal service on Better Auth with a schema per pool, Studio signed in with auth's session cookie and short-lived member tokens, and access revoked inline. Designed in the epic's milestone issues rather than a spec.
- Projects and app users: projects as a resource, and end-user sign-up and sign-in with tokens issued by Chelabase.
Neon and databases
- Neon data plane in Compose: running Neon's storage stack locally.
- The Neon crate: the library of Neon-facing building blocks the control plane uses.
- Internal control-plane listener and Neon's proxy: the machine-to-machine routes Neon calls, and the proxy with its cache invalidation.
- Switching provisioning to Neon: creating databases as Neon computes instead of plain containers.
- Database lifecycle: statuses, deletion, credential reset and reconcile.
- Branching: branches at a point in time, reset and restore.
- Hard fork of Neon: the
chelabase/neonandchelabase/postgresforks and how images are published. - Login roles: roles and databases managed from SQL through the proxy.
Data API
- Data API: the JSON query language, keys, roles and the
restengine. - Data API across databases and schemas: serving any database of a branch, key allow-lists and Studio's console.
- Data API on tokio-postgres: one-round-trip pipelining, and the benchmark that justified it.
Studio and clients
- Generated API client and TanStack Query: OpenAPI documents from the Rust handlers, generated clients and typed data fetching in Studio.
- SQL editor: streamed SQL runs, the guard, saved queries and completion.
Documentation
- Docs site: this site, organized by reader and checked against the code.
Benchmarks
- Data API pipelining benchmark: latency and throughput of the data API paths at several network round-trip times.
Security
Trust boundaries, what each credential can do, and the security notes kept in the repository.
Accept Invite POST
Accepts a member invite and signs in (the HttpOnly session cookie). With `user` and `code` (the code from the invite email), the code sets the first password and verifies the email; an account someone else registered without proving the email has its old password replaced and every session ended. With `email` (an existing account, from the invite notice), the account's own password signs in and no password is set. The link's token `t` must match an open invite. A removed member's ban is lifted only then; any other ban is `member_suspended`. If a step after the code fails, the error is `invite_incomplete` with `error.accept_ticket`: send it back in place of `code`, with the same password, to finish. A weak password is refused before the code is used.