Skip to main content

Core Tables

profiles

User profile information, automatically created on signup.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
user_idUUIDNO-Foreign key to auth.users.id (unique)
full_nameTEXTNO-User’s full name
avatar_urlTEXTYES-URL to user avatar image
created_atTIMESTAMPTZNOnow()Record creation timestamp
updated_atTIMESTAMPTZNOnow()Last update timestamp
Indexes:
  • Primary key on id
  • Unique index on user_id
Triggers:
  • update_profiles_updated_at - Auto-updates updated_at on row changes
  • Created automatically via handle_new_user() trigger on auth.users
RLS Policies:
  • Users can view and update their own profile
  • Super admins can view all profiles

user_roles

Role assignments for users. Separate from profiles for security.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
user_idUUIDNO-Foreign key to auth.users.id
roleapp_roleNO-Enum: super_admin, client, event_manager
Indexes:
  • Primary key on id
  • Unique constraint on (user_id, role)
RLS Policies:
  • Users can view their own roles
  • Super admins can manage all roles

organizations

Client organizations (tenants).
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
nameTEXTNO-Organization name
slugTEXTNO-URL-safe unique identifier
logo_urlTEXTYES-Organization logo URL
owner_idUUIDNO-Foreign key to auth.users.id
statusTEXTNO'active'Enum: active, suspended, deleted
event_tokensINTEGERNO0Available event tokens
attendee_tokensINTEGERNO0Available attendee tokens
created_atTIMESTAMPTZNOnow()Record creation timestamp
updated_atTIMESTAMPTZNOnow()Last update timestamp
Indexes:
  • Primary key on id
  • Unique index on slug
Constraints:
  • status must be in ('active', 'suspended', 'deleted')
Triggers:
  • update_organizations_updated_at - Auto-updates updated_at
RLS Policies:
  • Owners can view and update their organization
  • Organization members can view their organization
  • Super admins can view and manage all organizations
  • Authenticated users can create organizations (signup)

organization_members

Links event managers to organizations.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
organization_idUUIDNO-Foreign key to organizations.id
user_idUUIDNO-Foreign key to auth.users.id
roleapp_roleNO'event_manager'Typically event_manager
statusTEXTNO'active'Enum: active, suspended
created_atTIMESTAMPTZNOnow()Record creation timestamp
Indexes:
  • Primary key on id
  • Unique constraint on (organization_id, user_id)
Constraints:
  • status must be in ('active', 'suspended')
RLS Policies:
  • Organization owners can manage members
  • Members can view their own membership
  • Super admins can manage all members

events

Event configuration and content. Indexes:
  • Primary key on id
  • Unique constraint on (organization_id, slug)
Triggers:
  • update_events_updated_at - Auto-updates updated_at
RLS Policies:
  • Organization owners can manage their events
  • Organization members can view events
  • Super admins can manage all events
The draft/publish pattern allows clients to preview changes before making them live. Publish actions copy draft columns to published columns.

event_manager_assignments

Assigns event managers to specific events.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
event_idUUIDNO-Foreign key to events.id
user_idUUIDNO-Foreign key to auth.users.id
created_atTIMESTAMPTZNOnow()Assignment timestamp
Indexes:
  • Primary key on id
  • Unique constraint on (event_id, user_id)
RLS Policies:
  • Organization owners and super admins manage assignments
  • Event managers can view their own assignments

attendees

Event attendees and check-in status.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
event_idUUIDNO-Foreign key to events.id
unique_idTEXTNO-8-character alphanumeric ID (auto-generated)
nameTEXTNO-Attendee name
emailTEXTNO-Attendee email
custom_fieldsJSONBYES'{}'Custom attendee data
checked_inBOOLEANNOfalseCheck-in status
checked_in_atTIMESTAMPTZYES-Check-in timestamp
checkin_methodTEXTYES-Method: qr_scan, self_service, manual
portal_activeBOOLEANNOfalseAttendee portal access enabled
confirmation_email_sentBOOLEANNOfalseEmail sent status
created_atTIMESTAMPTZNOnow()Record creation timestamp
updated_atTIMESTAMPTZNOnow()Last update timestamp
Indexes:
  • Primary key on id
  • Unique constraint on (event_id, unique_id)
  • Unique constraint on (event_id, email)
Triggers:
  • update_attendees_updated_at - Auto-updates updated_at
  • generate_attendee_unique_id_trigger - Auto-generates unique 8-char ID on insert
  • trg_maintain_event_attendee_counts - Updates cached counts in events table
Realtime:
  • Enabled via ALTER PUBLICATION supabase_realtime ADD TABLE attendees
RLS Policies:
  • Organization owners can manage attendees
  • Event managers can view and update attendees (for check-in)
The unique_id is auto-generated using uppercase alphanumeric characters (A-Z, 0-9) and is guaranteed unique within each event.

Billing Tables

token_pricing

Tiered pricing configuration for token purchases.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
typeTEXTNO-Enum: event, attendee
min_quantityINTEGERNO-Tier minimum quantity
max_quantityINTEGERNO-Tier maximum quantity
price_per_unitDECIMAL(10,2)NO-Price per token in this tier
currencyTEXTNO'MYR'Currency code
updated_atTIMESTAMPTZNOnow()Last update timestamp
Constraints:
  • type must be in ('event', 'attendee')
Triggers:
  • update_token_pricing_updated_at - Auto-updates updated_at
RLS Policies:
  • Anyone authenticated can view pricing
  • Public (anon) can view pricing
  • Super admins can manage pricing
Example Data:
-- Event token pricing
(type='event', min=1, max=5, price=50.00)
(type='event', min=6, max=20, price=40.00)
(type='event', min=21, max=100, price=30.00)

-- Attendee token pricing
(type='attendee', min=1, max=100, price=1.00)
(type='attendee', min=101, max=500, price=0.80)
(type='attendee', min=501, max=2000, price=0.60)
(type='attendee', min=2001, max=10000, price=0.40)

token_transactions

Token purchase history.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
organization_idUUIDNO-Foreign key to organizations.id
typeTEXTNO-Enum: event, attendee
quantityINTEGERNO-Number of tokens purchased
amountDECIMAL(10,2)NO-Total amount paid
currencyTEXTNO'MYR'Currency code
payment_methodTEXTNO'stripe'Payment method
stripe_session_idTEXTYES-Stripe checkout session ID
statusTEXTNO'pending'Payment status
created_atTIMESTAMPTZNOnow()Transaction timestamp
Constraints:
  • type must be in ('event', 'attendee')
RLS Policies:
  • Organization owners can view their transactions
  • Organization owners can insert transactions
  • Super admins can view all transactions

Audit & Platform Tables

audit_logs

Activity audit trail for compliance and debugging.
ColumnTypeNullableDefaultDescription
idUUIDNOgen_random_uuid()Primary key
organization_idUUIDYES-Foreign key to organizations.id
user_idUUIDYES-User who performed the action
actionTEXTNO-Action name (e.g., ‘event.created’)
entity_typeTEXTYES-Entity type (e.g., ‘event’, ‘attendee’)
entity_idUUIDYES-Entity ID
detailsJSONBYES-Additional event details
created_atTIMESTAMPTZNOnow()Event timestamp
RLS Policies:
  • Organization owners can view their audit logs
  • Super admins can view all audit logs
  • All inserts go through log_audit_event() function (no direct INSERT policy)
Audit logs are written via the log_audit_event() security definer function, which validates authorization and prevents false attribution.

platform_settings

Global platform configuration (super admin only).
ColumnTypeNullableDefaultDescription
keyTEXTNO-Primary key (setting name)
valueJSONBNO-Setting value
updated_atTIMESTAMPTZNOnow()Last update timestamp
Default Settings:
{
  "default_event_tokens": 0,
  "default_attendee_tokens": 0,
  "checkin_deactivation_days": 1,
  "portal_deactivation_days": 3
}
RLS Policies:
  • Super admins can manage all settings

Storage Buckets

While not database tables, storage buckets are defined in migrations:

org-logos

  • Bucket ID: org-logos
  • Public: Yes
  • Folder structure: {user_id}/filename.ext
Policies:
  • Organization owners can upload/update/delete logos in their folder
  • Public read access

branding-assets

  • Bucket ID: branding-assets
  • Public: Yes
  • Folder structure: {event_id}/filename.ext
Policies:
  • Event owners and assigned event managers can upload/update/delete
  • Public read access (for rendering confirmation emails and public pages)

Next Steps

Schema Overview

High-level architecture and design principles

Relationships

Foreign keys and table relationships

Build docs developers (and LLMs) love