Auth & Users
Auth & Users
User authentication, profiles, roles, sessions, and device management.
29 tables in this group.
users
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | uuid_generate_v4() |
email | text | No | |
display_name | text | Yes | |
avatar_url | text | Yes | |
timezone | text | Yes | 'UTC'::text |
locale | text | Yes | 'en'::text |
subscription_tier | text | Yes | 'free'::text |
api_quota_remaining | int4 | Yes | 1000 |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
last_login_at | timestamptz | Yes | |
preferences | jsonb | Yes | '{}'::jsonb |
is_active | bool | Yes | true |
RLS Policies:
Admins or users can delete profiles— DELETE for {public}Admins or users can update profiles— UPDATE for {public}Admins or users can view profiles— SELECT for {public}
Indexes:
users_email_keyusers_pkey
user
Better Auth user accounts - main user table for authentication
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
email | text | No | |
email_verified | bool | Yes | false |
name | text | Yes | |
image | text | Yes | |
username | text | Yes | |
phone | text | Yes | |
phone_verified | bool | Yes | false |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
banned | bool | Yes | false |
ban_reason | text | Yes | |
ban_expires_at | timestamptz | Yes | |
subscription_tier | text | Yes | 'free'::text |
subscription_status | text | Yes | 'inactive'::text |
stripe_customer_id | text | Yes | |
stripe_subscription_id | text | Yes | |
subscription_expires_at | timestamptz | Yes | |
trial_ends_at | timestamptz | Yes | |
api_calls_today | int4 | Yes | 0 |
trades_today | int4 | Yes | 0 |
last_usage_reset | timestamptz | Yes | now() |
RLS Policies:
Users can update their own profile— UPDATE for {public}Users can view their own profile— SELECT for {public}
Indexes:
idx_user_stripe_customeridx_user_stripe_subscriptionidx_user_subscription_expiresidx_user_subscription_statusidx_user_subscription_tieruser_email_keyuser_pkeyuser_username_key
account
OAuth and social provider linked accounts
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
provider | text | No | |
provider_account_id | text | No | |
provider_user_id | text | Yes | |
access_token | text | Yes | |
refresh_token | text | Yes | |
id_token | text | Yes | |
expires_at | timestamptz | Yes | |
token_type | text | Yes | |
scope | text | Yes | |
account_linked | bool | Yes | true |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
RLS Policies:
Users can delete their own linked accounts— DELETE for {public}Users can view their own linked accounts— SELECT for {public}
Indexes:
account_pkeyaccount_provider_provider_account_id_key
session
Active user sessions with expiration management
| Column | Type | Nullable | Default |
|---|---|---|---|
id | text | No | |
user_id | uuid | No | |
expires_at | timestamptz | No | |
ip_address | text | Yes | |
user_agent | text | Yes | |
token | text | No | |
active_token | text | Yes | |
fresh | bool | Yes | true |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
RLS Policies:
Users can delete their own sessions— DELETE for {public}Users can view their own sessions— SELECT for {public}
Indexes:
idx_session_activesession_pkeysession_token_key
passkey
WebAuthn/Passkey credentials for passwordless authentication
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
credential_id | text | No | |
public_key | text | No | |
counter | int4 | Yes | 0 |
device_type | text | Yes | |
name | text | Yes | |
transports | _text | Yes | |
authenticator_aaguid | text | Yes | |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
last_used_at | timestamptz | Yes |
RLS Policies:
Users can manage their own passkeys— ALL for {public}
Indexes:
passkey_credential_id_keypasskey_pkey
magic_link
Magic link tokens for passwordless email authentication
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
email | text | No | |
token | text | No | |
expires_at | timestamptz | No | |
used | bool | Yes | false |
used_at | timestamptz | Yes | |
user_id | uuid | Yes | |
request_ip | text | Yes | |
request_user_agent | text | Yes | |
created_at | timestamptz | Yes | now() |
RLS Policies:
Users can view own magic links— SELECT for {public}
Indexes:
idx_magic_link_user_idmagic_link_pkeymagic_link_token_key
verification
Email verification and password reset tokens
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
identifier | text | No | |
value | text | No | |
expires_at | timestamptz | No | |
type | text | No | |
user_id | uuid | Yes | |
used | bool | Yes | false |
used_at | timestamptz | Yes | |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
RLS Policies:
Users can view their own verification tokens— SELECT for {public}
Indexes:
verification_pkey
two_factor
Two-factor authentication settings and backup codes
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
secret | text | No | |
backup_codes | _text | Yes | |
enabled | bool | Yes | false |
recovery_email | text | Yes | |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
RLS Policies:
Users can update their own 2FA settings— UPDATE for {public}Users can view their own 2FA settings— SELECT for {public}
Indexes:
two_factor_pkeytwo_factor_user_id_key
profiles
User profiles with RLS enabled. Users can only access their own profile unless they are admin/superadmin.
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | |
full_name | text | Yes | |
username | text | Yes | |
avatar_url | text | Yes | |
website | text | Yes | |
updated_at | timestamptz | Yes | |
created_at | timestamptz | Yes | now() |
two_factor_enabled | bool | Yes | false |
two_factor_secret | text | Yes | |
last_login | timestamptz | Yes | |
login_count | int4 | Yes | 0 |
is_verified | bool | Yes | false |
verification_token | text | Yes | |
kyc_tier | int4 | Yes | 0 |
country | text | Yes | |
kyc_tier_updated_at | timestamptz | Yes | |
bio | text | Yes | |
location | text | Yes | |
address_line | text | Yes | |
city | text | Yes | |
state | text | Yes | |
zipcode | text | Yes | |
phone | text | Yes | |
phone_country_code | text | Yes | '+1'::text |
role | text | No | 'user'::text |
notification_preferences | jsonb | Yes | '{"news": false, "push": false, "email": true, "price_ale... |
email | text | Yes | |
onboarding_completed | bool | Yes | false |
onboarding_completed_at | timestamptz | Yes | |
onboarding_step | text | Yes | 'welcome'::text |
email_verified | bool | Yes | false |
email_verified_at | timestamptz | Yes |
RLS Policies:
profiles_delete_own— DELETE for {authenticated}profiles_insert_own— INSERT for {authenticated}profiles_select_own— SELECT for {authenticated}profiles_service_role_all— ALL for {service_role}profiles_update_own— UPDATE for {authenticated}
Indexes:
idx_profiles_emailidx_profiles_id_lookupidx_profiles_roleprofiles_pkeyprofiles_username_key
user_roles
User role assignments and trading limits for RBAC
| Column | Type | Nullable | Default |
|---|---|---|---|
id | int8 | No | |
user_id | uuid | No | |
role | app_role | No | 'user'::app_role |
kyc_status | kyc_status | No | 'pending'::kyc_status |
kyc_verified_at | timestamptz | Yes | |
kyc_expires_at | timestamptz | Yes | |
trade_limit_daily | numeric | No | 1000.00 |
trade_limit_weekly | numeric | No | 5000.00 |
trade_limit_monthly | numeric | No | 20000.00 |
withdrawal_limit_daily | numeric | No | 500.00 |
withdrawal_limit_weekly | numeric | No | 2000.00 |
withdrawal_limit_monthly | numeric | No | 8000.00 |
account_tier | account_tier | No | 'free'::account_tier |
tier_expires_at | timestamptz | Yes | |
is_active | bool | No | true |
notes | text | Yes | |
last_kyc_check | timestamptz | Yes | |
created_at | timestamptz | No | now() |
updated_at | timestamptz | No | now() |
created_by | uuid | Yes | |
updated_by | uuid | Yes |
RLS Policies:
Admins can update user roles— UPDATE for {public}Users can view their own role— SELECT for {public}
Indexes:
user_roles_pkeyuser_roles_user_id_key
role_permissions
Permission mappings for each role
| Column | Type | Nullable | Default |
|---|---|---|---|
id | int8 | No | |
role | app_role | No | |
permission | app_permission | No | |
description | text | Yes | |
created_at | timestamptz | No | now() |
RLS Policies:
Everyone can view role permissions— SELECT for {public}
Indexes:
role_permissions_pkeyrole_permissions_role_permission_key
admin_roles
Tracks admin users and their permissions
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | uuid_generate_v4() |
user_id | uuid | No | |
role_type | text | No | |
permissions | jsonb | No | '[]'::jsonb |
granted_by | uuid | Yes | |
granted_at | timestamptz | No | now() |
expires_at | timestamptz | Yes | |
is_active | bool | No | true |
created_at | timestamptz | No | now() |
updated_at | timestamptz | No | now() |
RLS Policies:
Admins can view all admin roles— SELECT for {authenticated}Super admins can delete admin roles— DELETE for {authenticated}Super admins can grant admin roles— INSERT for {authenticated}Super admins can update admin roles— UPDATE for {authenticated}
Indexes:
admin_roles_pkeyadmin_roles_user_id_role_type_key
admin_allowlist
Allowlist of email addresses authorized for admin access
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
email | text | No | |
added_by | text | Yes | |
notes | text | Yes | |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
RLS Policies:
Admin allowlist viewable by admins— SELECT for {public}Only super admin can delete allowlist— DELETE for {public}Only super admin can insert allowlist— INSERT for {public}Only super admin can update allowlist— UPDATE for {public}
Indexes:
admin_allowlist_email_keyadmin_allowlist_pkey
user_sessions
| Column | Type | Nullable | Default |
|---|---|---|---|
session_id | uuid | No | uuid_generate_v4() |
user_id | uuid | No | |
vault_unlocked | bool | No | false |
vault_unlocked_at | timestamptz | Yes | |
status | varchar(20) | No | 'active'::character varying |
ip_address | inet | No | |
user_agent | text | Yes | |
device_fingerprint | text | Yes | |
geo_country | varchar(2) | Yes | |
geo_city | varchar(100) | Yes | |
created_at | timestamptz | No | now() |
last_activity_at | timestamptz | No | now() |
expires_at | timestamptz | No | |
idle_timeout_minutes | int4 | No | 60 |
vault_unlock_attempts | int4 | Yes | 0 |
failed_auth_attempts | int4 | Yes | 0 |
termination_reason | text | Yes |
RLS Policies:
rls_user_sessions_delete— DELETE for {public}rls_user_sessions_insert— INSERT for {public}rls_user_sessions_select— SELECT for {public}rls_user_sessions_update— UPDATE for {public}
Indexes:
idx_user_sessions_user_ididx_user_sessions_user_statususer_sessions_pkey
supabase_sessions
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | |
user_id | uuid | No | |
access_token | text | No | |
refresh_token | text | Yes | |
token_type | varchar(20) | Yes | |
expires_in | int4 | Yes | |
expires_at | timestamp | Yes | |
provider_token | text | Yes | |
provider_refresh_token | text | Yes | |
user_agent | varchar(500) | Yes | |
ip_address | varchar(45) | Yes | |
created_at | timestamp | No | |
updated_at | timestamp | Yes | |
last_accessed_at | timestamp | Yes | |
revoked_at | timestamp | Yes |
RLS Policies:
supabase_sessions_delete_own— DELETE for {public}supabase_sessions_insert_own— INSERT for {public}supabase_sessions_select_own— SELECT for {public}supabase_sessions_update_own— UPDATE for {public}
Indexes:
ix_supabase_sessions_user_idsupabase_sessions_pkey
supabase_users
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | |
aud | varchar(255) | No | |
role | varchar(255) | No | |
email | varchar(255) | No | |
email_confirmed_at | timestamp | Yes | |
phone | varchar(15) | Yes | |
phone_confirmed_at | timestamp | Yes | |
last_sign_in_at | timestamp | Yes | |
confirmation_token | varchar(255) | Yes | |
confirmation_sent_at | timestamp | Yes | |
recovery_token | varchar(255) | Yes | |
recovery_sent_at | timestamp | Yes | |
email_change_token_new | varchar(255) | Yes | |
email_change | varchar(255) | Yes | |
email_change_sent_at | timestamp | Yes | |
provider | varchar(50) | Yes | |
provider_id | varchar(255) | Yes | |
encrypted_password | varchar(255) | Yes | |
is_sso_user | bool | Yes | |
is_anonymous | bool | Yes | |
banned_until | timestamp | Yes | |
deleted_at | timestamp | Yes | |
app_metadata | json | Yes | |
user_metadata | json | Yes | |
raw_app_meta_data | json | Yes | |
raw_user_meta_data | json | Yes | |
created_at | timestamp | No | |
updated_at | timestamp | Yes |
RLS Policies:
supabase_users_delete_own— DELETE for {public}supabase_users_insert_own— INSERT for {public}supabase_users_select_own— SELECT for {public}supabase_users_update_own— UPDATE for {public}
Indexes:
ix_supabase_users_emailsupabase_users_pkey
trusted_devices
Stores trusted device information for "remember this device" MFA functionality. Devices are trusted for 30 days.
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
device_fingerprint | text | No | |
device_name | text | Yes | |
trusted_at | timestamptz | No | now() |
expires_at | timestamptz | No | |
last_used_at | timestamptz | Yes | now() |
user_agent | text | Yes | |
ip_address | inet | Yes | |
revoked | bool | Yes | false |
created_at | timestamptz | No | now() |
updated_at | timestamptz | No | now() |
RLS Policies:
Users can create their own trusted devices— INSERT for {public}Users can delete their own trusted devices— DELETE for {public}Users can update their own trusted devices— UPDATE for {public}Users can view their own trusted devices— SELECT for {public}
Indexes:
idx_trusted_devices_expiryidx_trusted_devices_expiry_cleanupidx_trusted_devices_lookupidx_trusted_devices_user_fingerprinttrusted_devices_pkeytrusted_devices_user_id_device_fingerprint_key
signup_attempts
Log of all signup attempts for rate limiting and fraud detection
| Column | Type | Nullable | Default |
|---|---|---|---|
id | int8 | No | |
email | text | No | |
ip_address | text | No | |
user_agent | text | Yes | |
success | bool | No | false |
failure_reason | text | Yes | |
blocked_by_hook | bool | Yes | false |
attempted_at | timestamptz | No | now() |
metadata | jsonb | Yes |
RLS Policies:
Admins can view signup attempts— SELECT for {public}Auth admin can insert signup attempts— INSERT for {supabase_auth_admin}
Indexes:
signup_attempts_pkey
password_history
Password history for rotation policy enforcement
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
password_hash | text | No | |
created_at | timestamptz | Yes | now() |
RLS Policies:
Users can view own password history— SELECT for {public}
Indexes:
password_history_pkey
password_failed_verification_attempts
Track failed password attempts for rate limiting and account protection
| Column | Type | Nullable | Default |
|---|---|---|---|
id | int8 | No | |
user_id | uuid | Yes | |
email | text | No | |
ip_address | text | No | |
user_agent | text | Yes | |
failure_reason | text | No | |
attempted_at | timestamptz | No | now() |
metadata | jsonb | Yes | '{}'::jsonb |
triggered_account_lock | bool | No | false |
RLS Policies:
Admins or users can view password failures— SELECT for {public}Auth admin can insert password failures— INSERT for {supabase_auth_admin}
Indexes:
idx_password_failed_verification_attempts_user_idpassword_failed_verification_attempts_pkey
user_preferences
| Column | Type | Nullable | Default |
|---|---|---|---|
user_id | uuid | No | |
theme | text | Yes | 'dark'::text |
language | text | Yes | 'en'::text |
currency | text | Yes | 'USD'::text |
timezone | text | Yes | 'UTC'::text |
notifications | jsonb | Yes | '{"sms": false, "push": true, "email": true}'::jsonb |
risk_tolerance | text | Yes | 'medium'::text |
trading_preferences | jsonb | Yes | '{}'::jsonb |
ui_preferences | jsonb | Yes | '{}'::jsonb |
created_at | timestamptz | Yes | now() |
updated_at | timestamptz | Yes | now() |
RLS Policies:
Users can manage their own preferences— ALL for {public}
Indexes:
user_preferences_pkey
user_permissions
User-specific permission overrides
| Column | Type | Nullable | Default |
|---|---|---|---|
id | int8 | No | |
user_id | uuid | No | |
permission | app_permission | No | |
granted | bool | No | true |
granted_by | uuid | Yes | |
granted_at | timestamptz | No | now() |
expires_at | timestamptz | Yes | |
reason | text | Yes |
RLS Policies:
Admins can delete user permissions— DELETE for {public}Admins can insert user permissions— INSERT for {public}Admins can update user permissions— UPDATE for {public}Admins or users can view permissions— SELECT for {public}
Indexes:
idx_user_permissions_granted_byidx_user_permissions_user_iduser_permissions_pkeyuser_permissions_user_id_permission_key
user_views
Stores user-specific view configurations and preferences
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
view_name | text | No | |
view_data | jsonb | Yes | '{}'::jsonb |
created_at | timestamptz | No | now() |
updated_at | timestamptz | No | now() |
RLS Policies:
Users can create their own views— INSERT for {public}Users can delete their own views— DELETE for {public}Users can update their own views— UPDATE for {public}Users can view their own views— SELECT for {public}
Indexes:
user_views_pkeyuser_views_user_id_view_name_key
user_notifications
In-app notifications shown in the notification center
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
type | notification_type | No | 'info'::notification_type |
title | text | No | |
message | text | No | |
metadata | jsonb | Yes | '{}'::jsonb |
link | text | Yes | |
read_at | timestamptz | Yes | |
created_at | timestamptz | No | now() |
RLS Policies:
Service role can create notifications— INSERT for {service_role}Users can update their own notifications— UPDATE for {public}Users can view their own notifications— SELECT for {public}
Indexes:
idx_user_notifications_created_atidx_user_notifications_read_atidx_user_notifications_typeidx_user_notifications_user_ididx_user_notifications_user_unreaduser_notifications_pkey
push_subscriptions
Web Push notification subscriptions for browser notifications
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
endpoint | text | No | |
p256dh_key | text | No | |
auth_key | text | No | |
user_agent | text | Yes | |
device_name | text | Yes | |
subscription_metadata | jsonb | Yes | '{}'::jsonb |
created_at | timestamptz | No | now() |
updated_at | timestamptz | No | now() |
last_used_at | timestamptz | Yes |
RLS Policies:
Service role can manage push subscriptions— ALL for {service_role}Users can create their own push subscriptions— INSERT for {public}Users can delete their own push subscriptions— DELETE for {public}Users can update their own push subscriptions— UPDATE for {public}Users can view their own push subscriptions— SELECT for {public}
Indexes:
idx_push_subscriptions_created_atidx_push_subscriptions_endpointidx_push_subscriptions_user_idpush_subscriptions_endpoint_keypush_subscriptions_pkey
user_devices
Tracks user devices for security, device trust, and suspicious activity detection
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
device_fingerprint | text | No | |
device_name | text | Yes | |
device_type | text | Yes | |
user_agent | text | No | |
browser_name | text | Yes | |
browser_version | text | Yes | |
os_name | text | Yes | |
os_version | text | Yes | |
last_ip_address | inet | Yes | |
last_country_code | text | Yes | |
last_city | text | Yes | |
last_latitude | numeric | Yes | |
last_longitude | numeric | Yes | |
is_trusted | bool | Yes | false |
trust_level | int4 | Yes | 0 |
first_seen_at | timestamptz | No | now() |
last_seen_at | timestamptz | No | now() |
last_authenticated_at | timestamptz | Yes | |
failed_login_attempts | int4 | Yes | 0 |
suspicious_activity_count | int4 | Yes | 0 |
is_blocked | bool | Yes | false |
blocked_at | timestamptz | Yes | |
blocked_reason | text | Yes | |
total_logins | int4 | Yes | 1 |
created_at | timestamptz | No | now() |
updated_at | timestamptz | No | now() |
RLS Policies:
Admins can manage all devices— ALL for {public}Service role can insert devices— INSERT for {public}Users can update own devices— UPDATE for {public}Users can view own devices— SELECT for {public}
Indexes:
idx_user_devices_fingerprintidx_user_devices_is_trustedidx_user_devices_last_seenidx_user_devices_suspiciousidx_user_devices_user_idunique_user_deviceuser_devices_pkey
device_login_audit
Comprehensive audit log of all authentication attempts with device and location tracking
| Column | Type | Nullable | Default |
|---|---|---|---|
id | uuid | No | gen_random_uuid() |
user_id | uuid | No | |
device_id | uuid | Yes | |
login_status | text | No | |
login_method | text | Yes | |
device_fingerprint | text | Yes | |
user_agent | text | Yes | |
ip_address | inet | Yes | |
country_code | text | Yes | |
city | text | Yes | |
latitude | numeric | Yes | |
longitude | numeric | Yes | |
is_new_device | bool | Yes | false |
is_new_location | bool | Yes | false |
is_suspicious | bool | Yes | false |
risk_score | int4 | Yes | 0 |
anomaly_reasons | _text | Yes | |
geolocation_distance_km | numeric | Yes | |
time_since_last_login_seconds | int4 | Yes | |
session_id | uuid | Yes | |
access_token_jti | text | Yes | |
alert_sent | bool | Yes | false |
alert_sent_at | timestamptz | Yes | |
alert_method | text | Yes | |
created_at | timestamptz | No | now() |
RLS Policies:
Admins can view all audit logs— SELECT for {public}Service role can insert device audit logs— INSERT for {public}Users can view own audit logs— SELECT for {public}
Indexes:
device_login_audit_pkeyidx_device_login_audit_device_ididx_device_login_audit_ipidx_device_login_audit_new_deviceidx_device_login_audit_sessionidx_device_login_audit_statusidx_device_login_audit_suspiciousidx_device_login_audit_user_id
role_change_log
Audit log for role changes
| Column | Type | Nullable | Default |
|---|---|---|---|
id | int8 | No | |
user_id | uuid | No | |
old_role | app_role | Yes | |
new_role | app_role | No | |
changed_by | uuid | No | |
reason | text | Yes | |
created_at | timestamptz | No | now() |
RLS Policies:
Admins or users can view role changes— SELECT for {public}
Indexes:
idx_role_change_log_changed_byrole_change_log_pkey
allowed_email_domains
Whitelist of allowed email domains (optional - if empty, all non-blocked domains allowed)
| Column | Type | Nullable | Default |
|---|---|---|---|
id | int8 | No | |
domain | text | No | |
description | text | Yes | |
added_by | uuid | Yes | |
is_active | bool | No | true |
added_at | timestamptz | No | now() |
RLS Policies:
Admins can manage allowed email domains— ALL for {public}
Indexes:
allowed_email_domains_domain_keyallowed_email_domains_pkeyidx_allowed_email_domains_added_by