Skip to main content
This page is a lightweight ERD for documentation readers. The goal is not to expose every SQL detail, but to show how the main entities relate and why certain tables matter to the product.

Core relationships

auth.users
├─ 1:1 profiles
├─ 1:1 subscriptions
├─ 1:1 user_roles
├─ 1:N payments
├─ 1:N ai_usage
└─ storage.objects (avatars) via profiles.avatar_path

subscriptions
└─ 1:N payments

payments
└─ 1:N webhook_events (operationally via external_id + provider)

Identity and access entities

Table or areaPurposeWritten byRead by
auth.usersSupabase auth identitySupabase AuthEvery login-aware flow
profilesName, avatar, and profile metadatasignup trigger, POST /api/profiledashboard settings, avatar UI
user_rolesmember or admin rolessignup trigger, admin role update/admin, admin guards

Billing and payment entities

TablePurposeWritten byRead by
subscriptionsActive plan, status, billing period, cancel statesignup trigger, webhook, subscription managementdashboard billing, AI plan lookup
paymentsPayment history per orderPOST /api/payments, webhookdashboard billing, admin, order flow
webhook_eventsWebhook event ledgerMidtrans and Doku webhooksadmin dashboard, operational debugging

Growth and operations entities

TablePurposeWritten byRead by
waitlistPre-launch leadsPOST /api/waitlistgrowth operations
ai_usagePer-user AI token usageAI routesAI limit checks, usage analysis
rate_limit_bucketsPersistent rate-limit storagerate-limit RPCruntime rate limiting
audit_logsImportant operational historyadmin, profile, and payment flowsadmin dashboard, investigations

Avatar storage

AreaPurposeNotes
avatars bucketStore user avatar filespath ${userId}/avatar, max size 2 MB
profiles.avatar_pathStore the object pointerused for signed upload and cleanup
profiles.avatar_urlStore the avatar URL used in UImay change depending on signed URL use

Tables most often touched during customization

If you want to changeTables likely involved
admin roles and accessuser_roles
plan catalog or billing behaviorsubscriptions, payments
avatar or profile experienceprofiles, avatars storage
waitlist flowwaitlist
premium AI featuressubscriptions, ai_usage
operational visibilitywebhook_events, audit_logs

Design questions to answer before changing schema

  1. Does this change need a new entity, or only a new field in an existing table?
  2. Does the data belong to a user, a subscription, or an organization model that does not exist yet?
  3. Will this change also affect admin dashboards, audit logs, or webhook flows?
  4. Will RLS and access control still make sense after the schema change?
If you need the migration inventory and operational context behind these entities, go back to Database and storage.