Schema Overview
Core Prisma entities, relationships, and enum-driven state models.
Domain entities
| Model | Purpose | Key fields |
|---|---|---|
User | Account profile and ownership context | email, stripeCustomerId, timestamps |
Account | OAuth provider link (NextAuth) | provider, providerAccountId |
Session | Session persistence | sessionToken, expires |
| Model | Purpose | Key fields |
|---|---|---|
Group | Shared subscription unit | ownerId, joinCode, maxMembers, status |
GroupMember | Membership relation + role | groupId, userId, role, status |
Invitation | Email invite token and lifecycle | groupId, senderId, email, expiresAt |
| Model | Purpose | Key fields |
|---|---|---|
SubscriptionService | Catalog entry | monthlyPriceCents, maxUsers, isActive |
GroupSubscription | Group-selected plan state | groupId, serviceId, status, billing period fields |
Payment | Member-level payment event | amountCents, status, stripePaymentIntentId |
Primary relationships
User1:NGroupMemberGroup1:NGroupMemberGroup1:1GroupSubscriptionSubscriptionService1:NGroupSubscriptionGroupSubscription1:NPaymentGroup1:NInvitation
Uniqueness and integrity constraints
Group.joinCodeunique@@unique([groupId, userId])onGroupMemberprevents duplicate joinsGroupSubscription.groupIdunique enforces single selected service per groupPayment.stripePaymentIntentIdunique supports webhook idempotency
Enum state machines
| Enum | Values |
|---|---|
GroupStatus | ACTIVE, PAUSED, DISSOLVED |
MemberRole | OWNER, ADMIN, MEMBER |
MemberStatus | ACTIVE, REMOVED, LEFT |
SubStatus | PENDING, ACTIVE, PAST_DUE, CANCELLED |
PaymentStatus | PENDING, PROCESSING, SUCCEEDED, FAILED, REFUNDED |
InviteStatus | PENDING, ACCEPTED, EXPIRED, REVOKED |
Data conventions
- Timestamp fields are persisted in UTC.
- Monetary values are integer cents.
- IDs use CUID by default.