What to build
Re-scope projects from a single user to an org. Today projects.owner is a user id; it becomes org_id, and every "my projects" path re-scopes to "this org's projects". Includes a one-time migration so existing single-owner projects don't get orphaned.
- Schema:
projects.owner → org_id (services/counter/src/schema.ts).
- Control plane (
db.ts): createProject and listProjects(owner) → listProjects(orgId); admin GET /v1/projects?owner= → ?org=. The counter only needs org_id for billing attribution — member/role authz stays in the dashboard, which holds the better-auth session.
- Dashboard queries pass the active
org_id to the counter admin API (requireUser() / lib/session.ts gains an active-org notion).
- Migration: one-time, idempotent (Neon-http has no transactions) — for each existing project, ensure a personal org for the current owner, set
org_id, run once, verify counts.
Acceptance criteria
Blocked by
What to build
Re-scope projects from a single user to an org. Today
projects.owneris a user id; it becomesorg_id, and every "my projects" path re-scopes to "this org's projects". Includes a one-time migration so existing single-owner projects don't get orphaned.projects.owner→org_id(services/counter/src/schema.ts).db.ts):createProjectandlistProjects(owner)→listProjects(orgId); adminGET /v1/projects?owner=→?org=. The counter only needsorg_idfor billing attribution — member/role authz stays in the dashboard, which holds the better-auth session.org_idto the counter admin API (requireUser()/lib/session.tsgains an active-org notion).org_id, run once, verify counts.Acceptance criteria
projectskeys offorg_id;listProjects/ admin API scope by org.Blocked by