Summary
KilatKoding stores its main application state in Supabase PostgreSQL. In addition to user-facing tables such as profiles, subscriptions, and payments, the repository already includes operational tables for webhook events, audit logs, and persistent rate limits.Available migrations
The most important tables
Source of truth for access control
The source of truth for admin access is theuser_roles table, not ADMIN_EMAILS.
ADMIN_EMAILS is only used as a bootstrap list so certain email addresses can be upserted into the admin role the first time they sign in.
Avatar storage
The repository uses theavatars bucket in Supabase Storage.
Important rules
- maximum avatar size: 2 MB
- supported file types:
image/jpeg,image/png,image/webp,image/gif - object path:
${userId}/avatar - avatar URLs are signed and short-lived
Webhook ledger
Thewebhook_events table is used to:
- prevent duplicate processing,
- store raw event payloads,
- record
processedorfailedstatus, - support debugging from the admin dashboard.
Audit logs
Theaudit_logs table records events such as:
- profile changes,
- admin actions,
- successful or failed payments,
- subscription changes.
Persistent rate limits
IfSUPABASE_SERVICE_ROLE_KEY is available, KilatKoding uses Supabase for persistent rate limiting on:
- the contact form,
- waitlist signups,
- payment creation,
- AI routes.
How to apply migrations
How to regenerate database types
If you want a faster-read relationship overview instead of reading migrations one by one, open Database map.