Skip to content

Control plane: projects.owner → org_id + admin API + migration #11

Description

@axelgar

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.ownerorg_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

  • projects keys off org_id; listProjects / admin API scope by org.
  • Dashboard "my projects" shows the active org's projects.
  • Existing projects migrated into personal orgs with no data loss; usage unaffected.
  • Migration is idempotent and verified by count.

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    readyTriaged and ready for an AFK agent to pick up

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions