//////////////////////////////////////////////////////////////////////////////////////////////
// DO NOT MODIFY THIS FILE //
// This file is automatically generated by ZenStack CLI and should not be manually updated. //
// Source: schema.zmodel · Generated: 2026-02-23 //
//////////////////////////////////////////////////////////////////////////////////////////////
A subscription linking a workspace to a billing plan.
Each workspace can have at most one active subscription at a time. When a workspace upgrades or downgrades, the current subscription is canceled and a new one is created with the updated plan details.
Subscriptions integrate with Stripe via
stripeSubscriptionId. ThecurrentPeriodStartandcurrentPeriodEndfields are synced from the Stripe webhookinvoice.paidevent and define the window during which the workspace has access to paid features.Canceled subscriptions retain access until
currentPeriodEnd. Past-due subscriptions enter a 7-day grace period before the system downgrades the workspace to the free tier.
Category: Billing · Since: 2.0 · Defined in: billing.zmodel
Declaration · billing.zmodel
model Subscription with Timestamps {
id String @id @default(cuid())
status SubscriptionStatus @default(TRIALING)
planName String @length(1, 100) @meta('doc:example', 'Team Pro')
priceAmountCents Int?
currency String @default("usd") @length(3, 3) @lower @meta('doc:example', 'usd')
billingInterval BillingInterval @default(MONTHLY)
currentPeriodStart DateTime
currentPeriodEnd DateTime
trialEndsAt DateTime?
canceledAt DateTime?
stripeSubscriptionId String? @unique @meta('doc:example', 'sub_1NqOAaLkdIwHu7ixeRlAkP7z')
stripeCustomerId String? @meta('doc:example', 'cus_OZnBhPLsNa3kJQ')
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
invoices Invoice[]
@@allow('read', workspace.members?[userId == auth().id])
@@allow('create,update', workspace.members?[role == 'OWNER'])
@@deny('delete', status == 'ACTIVE')
@@index([workspaceId])
@@index([stripeSubscriptionId])
@@meta('doc:category', 'Billing')
@@meta('doc:since', '2.0')
}On this page: Mixins · Fields · Relationships · Access Policies · Indexes · Validation Rules · Used in Procedures
Reusable field groups mixed into this model.
All fields defined on this entity, including inherited fields from mixins and parent models.
| Field | Type | Required | Default | Attributes | Source | Description |
|---|---|---|---|---|---|---|
createdAt |
DateTime |
Yes | now() |
— | Timestamps | When the record was first created. Immutable after insert. |
updatedAt |
DateTime |
Yes | — | @updatedAt |
Timestamps | When the record was last modified. Updated automatically. |
id |
String |
Yes | cuid() |
@id |
— | — |
status |
SubscriptionStatus | Yes | TRIALING |
— | — | Current lifecycle status of the subscription. |
planName |
String |
Yes | — | @length(1, 100) |
— | Example: Team Pro Human-readable plan name displayed in the billing UI. |
priceAmountCents |
Int? |
No | — | — | — | Billing amount in the smallest currency unit (e.g. cents for USD). |
| Null during trial periods. | ||||||
currency |
String |
Yes | "usd" |
@length(3, 3), @lower |
— | Example: usd ISO 4217 currency code for the subscription price. |
billingInterval |
BillingInterval | Yes | MONTHLY |
— | — | How often the subscription renews. |
currentPeriodStart |
DateTime |
Yes | — | — | — | Start of the current billing period. Updated on each renewal. |
currentPeriodEnd |
DateTime |
Yes | — | — | — | End of the current billing period. Access continues until this date |
| even after cancellation. | ||||||
trialEndsAt |
DateTime? |
No | — | — | — | When the trial period ends. Null if the subscription started |
| without a trial. | ||||||
canceledAt |
DateTime? |
No | — | — | — | When the subscription was canceled by the user or system. |
| Null if the subscription has not been canceled. | ||||||
stripeSubscriptionId |
String? |
No | — | @unique |
— | Example: sub_1NqOAaLkdIwHu7ixeRlAkP7z Stripe subscription ID for payment integration. |
| Used to reconcile webhook events with local records. | ||||||
stripeCustomerId |
String? |
No | — | — | — | Example: cus_OZnBhPLsNa3kJQ Stripe customer ID associated with this workspace's billing account. |
workspace |
Workspace | Yes | — | @relation(fields: [workspaceId], references: [id]) |
— | — |
workspaceId |
String |
Yes | — | — | — | — |
invoices |
Invoice[] | No | — | — | — | — |
Foreign key relationships to other models in the schema.
| Field | Related Model | Type |
|---|---|---|
invoices |
Invoice | One→Many |
workspace |
Workspace | Many→One |
ZenStack access control rules that determine who can read, create, update, or delete records.
Important
Operations are denied by default. @@allow rules grant access; @@deny rules override any allow.
| Operation | Rule | Effect |
|---|---|---|
| read | workspace.members?[userId == auth().id] |
Allow |
| create,update | workspace.members?[role == 'OWNER'] |
Allow |
| delete | status == 'ACTIVE' |
Deny |
Database indexes defined on this model for query performance.
| Fields | Type |
|---|---|
[workspaceId] |
Index |
[stripeSubscriptionId] |
Index |
Field-level and model-level validation constraints enforced at the ORM layer.
| Field | Rule |
|---|---|
planName |
@length |
currency |
@length |
currency |
@lower |
Procedures that reference this entity as a parameter or return type.
- cancelSubscription — mutation
Previous: NotificationPreference · Next: User