Profiles & cities
organizer_subscriptions
--- Organizer subscriptions (RAZ-106) ---------------------------------------- An organizer profile can hold one active annual subscription plan. The Network plan (€199/year) covers unlimited events under a single annual price. Stripe runs the billing; this table mirrors the subscription state so entitlement checks stay inside the DB without a Stripe API call.
Columns
| Column | Type | Null | Default | Keys |
|---|---|---|---|---|
| id | uuid | no | gen_random_uuid() | PK |
| profile_id | uuid | no | — | |
| dancer_id | uuid | no | — | |
| plan | text network | no | — | |
| status | text activepast_duecanceledunpaid | no | "active" | |
| stripe_customer_id | text | yes | — | |
| stripe_subscription_id | text | yes | — | unique |
| current_period_start | timestamp | yes | — | |
| current_period_end | timestamp | yes | — | |
| canceled_at | timestamp | yes | — | |
| created_at | timestamp | yes | now() |
Value lists come from .$type<'a' | 'b'>() in the schema — enforced in TypeScript only, not by the database.
Keys, constraints & indexes
Used by
Code that reads or writes this table, found by static analysis of the tRPC routers and API handlers (including helpers they call).
REST & webhooks
- POST /api/stripe/webhook
- ANY /mcp
- ANY /mcp/public
Relations
Rendering diagram…
Diagram source
erDiagram
dancers {
uuid id PK
text email UK
text neon_auth_id UK
text username UK
}
organizer_subscriptions {
uuid id PK
uuid profile_id FK
uuid dancer_id FK
text stripe_subscription_id UK
}
profiles {
uuid id PK
text username UK
}
profiles ||--o{ organizer_subscriptions : "profile_id"
dancers ||--o{ organizer_subscriptions : "dancer_id" Defined at server/database/schema.ts:568 as organizerSubscriptions.