Skip to content

Latest commit

 

History

History
175 lines (129 loc) · 7.71 KB

File metadata and controls

175 lines (129 loc) · 7.71 KB
//////////////////////////////////////////////////////////////////////////////////////////////
// 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                                            //
//////////////////////////////////////////////////////////////////////////////////////////////

Index / Models / Subscription

🗃️ Subscription Model

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. The currentPeriodStart and currentPeriodEnd fields are synced from the Stripe webhook invoice.paid event 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

🧩 Mixins

Reusable field groups mixed into this model.

📋 Fields

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

🔗 Relationships

Foreign key relationships to other models in the schema.

Field Related Model Type
invoices Invoice One→Many
workspace Workspace Many→One

diagram

🔐 Access Policies

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

📇 Indexes

Database indexes defined on this model for query performance.

Fields Type
[workspaceId] Index
[stripeSubscriptionId] Index

✅ Validation Rules

Field-level and model-level validation constraints enforced at the ORM layer.

Field Rule
planName @length
currency @length
currency @lower

⚡ Used in Procedures

Procedures that reference this entity as a parameter or return type.


📚 References


Previous: NotificationPreference · Next: User