Anatomy of this starter

Three ideas carry the whole kit.

One tenancy contract

Every request under /app/[orgSlug] resolves getAppContext(orgSlug): session → user → org → membership. No membership and no org look identical — a 404, never a 403, so workspace existence never leaks. Feature queries take that context, get their database through the getOrgDb(ctx) seam, and filter by ctx.org.id. Per-tenant databases later become a config change, not a rewrite.

Durable work without a vendor

Jobs live in a table. The runner claims them with an optimistic update, retries with exponential backoff, dead-letters with the error kept, and supports continuations — a handler can reschedule itself with a new payload, which turns any job into a multi-phase state machine. That's the substrate provider Batch APIs need, at fifty percent token cost.

A deletable example

features/example-notes exists to be read and then removed in one commit. It demonstrates the query pattern, the orgAction pipeline, plan limits, a metered AI call with versioned prompts, and the isolation tests every feature is expected to extend. Your product starts at docs/product-spec-template.md.