Skip to main content

Full Table Reference

The complete public schema — every column of all 45 tables, the 11 views, and the one enum. The domain pages explain why; this page is the what. Use it as a lookup.

Notation

PK = primary key · FK → = foreign key to table.column · N in the Null column = the column is nullable. Types are the live Postgres types. This page is generated from the database and reflects the schema as deployed; when a migration changes a table, regenerate the affected section.

Row-level security is enabled on all 45 tables

A column being listed here does not mean a browser client can read it. Many tables are service-role-only / deny-all (reachable only via edge functions or the service key) — e.g. crm_user_roles, player_roles, steam_id_allowlist, device_auth_requests, upload_credentials, all four growth tables, lobby_join_events, permissions/role_permissions. The domain pages note the RLS posture per area; treat the relationships here as logical, not as a read grant.

Enums

EnumValues
game_storesteam · epic · gog · microsoft · other · riot · rockstar

Identity & Access

→ domain page: Identity & Access

playroll_users

The hub. Keyed by user_id (Supabase auth UUID).

ColumnTypeNullNotes
user_iduuidPK, FK → auth.users.id (ON DELETE CASCADE)
display_nametextN
avatar_urltextN
steam_idtextNUNIQUE
discord_idtextNUNIQUE
discord_usernametextN
contributor_tiertextCurrent program tier (value, not FK); default player.
credits_earnednumeric
credits_claimednumeric
created_attimestamptz
updated_attimestamptz
steam_usernametextN
steam_avatar_urltextN
steam_hoursintegerNSteam enrichment ↓
steam_games_ownedintegerN
steam_levelintegerN
steam_profile_publicbooleanN
steam_account_createdbigintNUnix ts
steam_account_age_daysintegerNTrigger-computed (playroll_users_fill_steam_age).
steam_vac_bannedbooleanN
steam_vac_bans_countintegerN
steam_game_bans_countintegerN
steam_days_since_last_banintegerN
steam_enriched_attimestamptzN
steam_friend_countinteger
steam_friends_publicbooleanN
friends_fetched_attimestamptzN
network_valueintegerRolled up from shadow_graph.
network_whale_countinteger
countrytextNAttribution ↓
languagetextN
utm_sourcetextN
utm_mediumtextN
utm_campaigntextN
referrertextN
device_typetextN
referral_codetextN
referred_bytextN
referral_countinteger
priority_scoreinteger

steam_id_allowlist

ColumnTypeNullNotes
steam_idtextPK
roletextFK → player_role_catalog.role; default pioneer.
notetextN
added_attimestamptz
added_bytextN
enabledboolean

auth_user_steam_lookup

ColumnTypeNullNotes
steam_idtextPK
user_iduuidFK → auth.users.id; UNIQUE. Maintained by auth_user_steam_lookup_sync_trg.
created_attimestamptz
updated_attimestamptz

steam_openid_nonces

ColumnTypeNullNotes
noncetextPK
seen_attimestamptz

player_role_catalog

ColumnTypeNullNotes
roletextPK
rankintegerHigher = more access.
descriptiontextN
created_attimestamptz

player_roles

ColumnTypeNullNotes
iduuidPK
user_iduuidFK → playroll_users.user_id
roletextFK → player_role_catalog.role
granted_attimestamptz
granted_bytextN

crm_user_roles

Staff RBAC, keyed by email.

ColumnTypeNullNotes
emailtextPK
roletextCHECK admin / cm / vc / sales. Links by value to role_permissions.role.
granted_attimestamptz
granted_bytextN
notestextN

permissions

ColumnTypeNullNotes
idintegerPK
resourcetext
actiontextCHECK read / write.
descriptiontextN
created_attimestamptz

role_permissions

ColumnTypeNullNotes
roletext
permission_idintegerFK → permissions.id
granted_bytextN
granted_attimestamptz

device_auth_requests

Legacy / superseded — 0 rows, deny-all RLS, replaced by the steam-login redirect flow.

ColumnTypeNullNotes
device_codetextPK
statustextDefault pending.
access_tokentextN
refresh_tokentextN
user_iduuidNNo FK.
user_profilejsonbN
created_attimestamptz
completed_attimestamptzN
expires_attimestamptzDefault now() + 10 min.

upload_credentials

Legacy / unused — 0 rows, no writer, deny-all RLS (service-key only).

ColumnTypeNullNotes
mac_hashtextPK
user_idtextUNIQUE (text, not a uuid FK to playroll_users).
created_attimestamptz
last_used_attimestamptzN
is_activeboolean

playroll_user_consents

Append-only consent log (no revoked column; withdrawals are new rows).

ColumnTypeNullNotes
iduuidPK
user_iduuidFK → auth.users.id (not playroll_users).
consent_typetextCHECK age_confirmation / tos / privacy / eula / edc_gameplay.
versiontext
accepted_attimestamptz
countrytextN
metadatajsonb{action:'withdrawal'} marks a revocation.
ip_addressinetN
user_agenttextN

contributor_status_projection

App-side projection written by redeem-activation-code. No PII. (The portal owns the source table contributor_app_links.)

ColumnTypeNullNotes
app_user_iduuidPK, FK → auth.users.id (ON DELETE CASCADE).
contributor_iduuid
link_statustextCHECK verified (only value).
source_link_iduuid
steam_idtextN
linked_attimestamptz
source_updated_attimestamptz
last_synced_attimestamptz

Recording Spine

→ domain page: Recording Spine

recording_sessions

Keyed by a text session_id (rec-<epoch-ms>).

ColumnTypeNullNotes
session_idtextPK
user_idtext
game_nametextN
chunk_countintegerN
statustextDefault uploading.
client_ended_attimestamptzN
server_verified_attimestamptzN
created_attimestamptzN
updated_attimestamptzNTrigger-maintained.
detected_resolutionjsonbN
game_slugtextN
recording_started_attimestamptzN
recording_ended_attimestamptzN
duration_secondsbigintNCanonical recording clock. CHECK ≥ 0.
required_artifact_modetextCHECK mp4_csv_json (default) / mp4_csv.
modetextRecording lane: quest (default) / free_play (EC-475). Populated end-to-end once the upload writer carries the lane; see Recording lanes.
uploadability_statustextNCHECK uploadable / blocked / NULL.
block_reasontextN
lobby_iduuidNBy value — no FK (lobby binding enforced by trigger).
hw_snapshot_iduuidNFK → device_hw_snapshots.id
core_versiontextN
ui_versiontextN
installer_versiontextN
transcript_expectedbooleanSet true at session end iff _mic.aac exists (EC-407).
transcript_skippedbooleanClient-writable via scoped GRANT + RLS (EC-409).
dismissedbooleanClient-writable "hide from Activity" (EC-411).

s3_uploads

One row per uploaded file. Links to a session by value on session_id.

ColumnTypeNullNotes
iduuidPK
s3_keytext
s3_buckettextDefault playroll-captures.
user_idtext
upload_yearintegerPartition key
upload_monthintegerCHECK 1–12.
upload_dayintegerCHECK 1–31.
session_idtextJoins to recording_sessions.session_id (value).
chunk_dirtextN
filenametext
file_typetextmp4 / csv / json / ogg (legacy).
size_bytesbigintN
etagtextN
uploaded_attimestamptz
statustextCHECK uploaded (default) / processing / completed / failed.
lobby_iduuidNFK → lobbies.id (NOT VALID).
recording_started_attimestamptzN
recording_ended_attimestamptzN
game_slugtextNChecked by the s3_uploads_enforce_lobby_game_match trigger (lobby-tagged only).
artifact_kindtextNNo CHECK; derived from suffix: video/input/meta/transcript; NULL = unclassified (EC-289).

device_hw_snapshots

Dedup key (user_id, hw_fingerprint).

ColumnTypeNullNotes
iduuidPK
created_attimestamptz
updated_attimestamptz
user_idtext
hw_fingerprinttext
cpu_modeltextN
cpu_architecturetextN
logical_processorsintegerN
physical_memory_mibbigintN
os_releasetextN
primary_gpu_vendortextN
primary_gpu_nametextN
primary_gpu_drivertextN
primary_gpu_driver_nvidiatextN
snapshotjsonbFull HW blob.
sourcetextui_login (login edge fn, dominant) / core_meta_json (upload Lambda); default core_meta_json.

pipeline_sessions

Composite PK (session_id, environment) — one row per session per environment.

ColumnTypeNullNotes
session_idtextPK (with environment)
environmenttextPK (with session_id); CHECK dev / prod (default prod).
user_idtext
game_slugtextN
s3_prefixtext
stagesmallintDefault 0.
statustextCHECK pending (default) / processing / verified / failed.
mp4_keytextN
csv_keytextN
ogg_keytextN
size_bytes_totalbigintN
errortextN
created_attimestamptz
verified_attimestamptzN

pipeline_runs

ColumnTypeNullNotes
run_iduuidPK
pipeline_nametext
session_idtextN
user_idtextN
trigger_typetextDefault manual.
created_bytextDefault prefect-ui.
statustextCHECK running (default) / pass / fail / skipped.
steps_executedtext[]N
step_durations_sjsonbN
params_usedjsonbN
output_prefixtextN
error_detailtextN
prefect_flow_run_idtextN
started_attimestamptz
completed_attimestamptzN

nvenc_known_contenders

ColumnTypeNullNotes
process_nametextPK
first_seentimestamptz
last_seentimestamptz
total_eventsbigint
total_usersinteger
sample_codecstext[]
sample_resolutionstext[]
ColumnTypeNullNotes
process_nametextFK → nvenc_known_contenders.process_name
user_idtext
first_seentimestamptz
last_seentimestamptz

bug_reports

ColumnTypeNullNotes
iduuidPK
created_attimestamptz
user_iduuid
steam_idtextN
hw_configjsonb
installer_versiontextN
ui_versiontextN
core_versiontextN
titletextCHECK length 1–200.
descriptiontextCHECK length 1–10000.
statustextCHECK logged (default) / in_progress / fixed / verified / wont_fix.
categorytextCHECK ui / recording / performance / onboarding / other.
imagestext[]
linear_tickettextNAuto-filled by bug_reports_to_linear trigger (AFTER INSERT).
updated_attimestamptz
steam_usernametextN
connectionjsonbN
electron_runtimejsonbN

Lobby & Catalog

→ domain page: Lobby & Catalog

lobbies

ColumnTypeNullNotes
iduuidPK
lobby_codetext
creator_idtext
game_slugtextFK → eligible_games.slug (ON UPDATE CASCADE / ON DELETE RESTRICT).
statustextCHECK active (default) / closed / expired.
max_playersintegerCHECK 2–16 (default 16).
created_attimestamptz
expires_attimestamptz

lobby_participants

Composite PK (lobby_id, user_id) — current membership.

ColumnTypeNullNotes
lobby_iduuidPK (with user_id); FK → lobbies.id
user_idtextPK (with lobby_id)
joined_attimestamptz
session_idtextNJoins to recording_sessions.
server_recording_started_attimestamptzN

lobby_join_events

Append-mostly history. INSERT on join; leave UPDATEs left_at (no new row). Driven by triggers on lobby_participants.

ColumnTypeNullNotes
idbigintPK
lobby_iduuidFK → lobbies.id
user_idtext
joined_attimestamptz
left_attimestamptzNStamped on leave.
sourcetextDefault participant_insert.

eligible_games

ColumnTypeNullNotes
igdb_idintegerPK
slugtext
display_nametext
enabledbooleanN
cover_urltextN
created_attimestamptzN
updated_attimestamptzN
tokensjsonbMatch tokens for library detection; NOT NULL, default {}.

game_store_ids

ColumnTypeNullNotes
iduuidPK
igdb_idintegerFK → eligible_games.igdb_id (ON DELETE CASCADE).
storegame_storeEnum (steam/epic/gog/microsoft/riot/rockstar/other).
store_idtext

game_runtime_profiles

ColumnTypeNullNotes
iduuidPK
game_store_iduuidFK → game_store_ids.id
exe_nametext
platformtextN
notestextN
enginetextNFK → engine_defaults.engine
settings_overridejsonbN
settings_enforcementjsonb

engine_defaults

ColumnTypeNullNotes
enginetextPK
settings_specjsonb
created_attimestamptz
updated_attimestamptz

user_game_library

ColumnTypeNullNotes
iduuidPK
user_iduuid
playnite_iduuid
plugin_iduuidN
providertext
provider_game_idtextN
nametext
is_installedbooleanN
is_hiddenbooleanN
is_favoritebooleanN
playtime_secondsbigintN
play_countbigintN
last_played_attimestamptzN
executablesjsonbN
genresjsonbN
developersjsonbN
publishersjsonbN
release_datetextN
cover_image_urltextN
platformtextN
install_size_bytesbigintN
game_registry_igdb_idintegerNFK → eligible_games.igdb_id
synced_attimestamptzN
created_attimestamptzN
updated_attimestamptzN

Growth & Network

→ domain page: Growth & Network

shadow_graph

ColumnTypeNullNotes
iduuidPK
source_user_iduuidFK → playroll_users.user_id
source_steam_idtext
target_steam_idtext
target_nametextN
target_avatar_urltextN
target_profile_urltextN
target_hoursintegerN
target_games_ownedintegerN
target_levelintegerN
target_profile_publicbooleanN
target_tiertextCHECK whale / regular / casual (default casual).
target_yearly_valueintegerRecruitment-value score.
recruitment_statustextCHECK none (default) / invited / converted.
invited_attimestamptzN
converted_attimestamptzN
converted_user_iduuidNFK → playroll_users.user_id (no cascade).
friend_sincebigintN
created_attimestamptz
updated_attimestamptzUNIQUE edge: (source_user_id, target_steam_id).

invite_codes

ColumnTypeNullNotes
codetextPK
pooltextDefault phase_0.
max_usesintegerCHECK > 0 (default 1).
usesintegerCHECK 0 ≤ uses ≤ max_uses.
activeboolean
notestextN
created_byuuidNFK → playroll_users.user_id
created_attimestamptz
expires_attimestamptzN

invite_code_consumptions

Composite PK (code, user_id) — a user consumes a given code at most once.

ColumnTypeNullNotes
codetextPK (with user_id); FK → invite_codes.code
user_iduuidPK (with code); FK → playroll_users.user_id
consumed_attimestamptz
ip_hashtextN
user_agenttextN

redeem_attempt_log

Rate-limiter log for the contributor activation-code flow (redeem-activation-code, EC-227) — not invite codes. app_user_id is an unconstrained uuid (soft reference, no FK).

ColumnTypeNullNotes
idbigintPK
app_user_iduuidNo FK.
iptextN
code_hashtextN
successbooleanDefault false.
attimestamptz

Releases

→ domain page: Releases & Notifications

app_releases_v2

ColumnTypeNullNotes
idbigintPK
release_keytext
installer_versiontext
core_versiontext
ui_versiontext
download_urltext
installer_sha256textN
release_notestextN
metadatajsonbDefault {}.
created_attimestamptz
release_tracktextCHECK stable / dev / test (no beta).
release_notes_technicaltextN
release_notes_user_facingtextN

app_rollouts_v2

ColumnTypeNullNotes
iduuidPK
nametext
release_idbigintFK → app_releases_v2.id
enabledboolean
priorityinteger
tracktext
force_updateboolean
percentageinteger
experiment_keytextN
ab_buckettextN
include_user_idsuuid[]
exclude_user_idsuuid[]
include_install_idstext[]
starts_attimestamptz
ends_attimestamptzN
created_attimestamptz
updated_attimestamptz

app_rollout_overrides_v2

ColumnTypeNullNotes
iduuidPK
target_typetext
target_idtext
release_idbigintFK → app_releases_v2.id
enabledboolean
force_updateboolean
reasontextN
expires_attimestamptzN
created_attimestamptz

app_update_resolve_audit_v1

One row per resolve call (25 columns).

ColumnTypeNullNotes
idbigintPK
created_attimestamptz
install_idtextN
user_iduuidN
request_tracktextN
installed_installer_versiontextN
installed_core_versiontextN
installed_ui_versiontextN
installed_tracktextNSource for user_current_track.
track_ordertext[]
assignment_sourcetextrollout / override / default
assignment_tracktextN
rollout_iduuidN
override_iduuidN
buckettextN
experiment_keytextN
target_release_idbigintN
target_installer_versiontextN
target_core_versiontextN
target_ui_versiontextN
update_availableboolean
update_requiredboolean
force_updateboolean
reasontextN
resolver_versiontext

app_update_resolve_rate_limit

ColumnTypeNullNotes
ip_sha256byteaPK (with window_start)
window_starttimestamptz60s-aligned window.
request_countinteger
last_seen_attimestamptz

Notifications

→ domain page: Releases & Notifications

notification_event

ColumnTypeNullNotes
iduuidPK
categorytext
typetext
urgency_tiertext
payloadjsonb
ctajsonbN
sourcetext
localetext
allowed_channelstext[]
audience_filterjsonbResolved by resolve_audience().
recipient_countinteger
created_attimestamptz
expires_attimestamptzN

notification_deliveries

ColumnTypeNullNotes
iduuidPK
event_iduuidFK → notification_event.id
user_iduuid
channeltext
statustext
error_codetextN
queued_attimestamptz
sent_attimestamptzN

notification_state

ColumnTypeNullNotes
event_iduuidFK → notification_event.id
user_iduuid
read_attimestamptzN
dismissed_attimestamptzN
acted_attimestamptzN
created_attimestamptz

notification_groups

ColumnTypeNullNotes
iduuidPK
slugtext
nametext
descriptiontextN
created_byuuidN
created_attimestamptz

notification_group_members

ColumnTypeNullNotes
group_iduuidFK → notification_groups.id
user_iduuid
added_attimestamptz
added_byuuidN

notification_user_prefs

ColumnTypeNullNotes
user_iduuidPK
enable_payment_and_validationboolean
enable_app_update_and_termsboolean
enable_catalog_and_announcementsboolean
enable_soundboolean
enable_emailboolean
updated_attimestamptz

Views

Eleven views project the tables above for specific consumers. They are security_invoker where they expose row-scoped data, so RLS on the underlying tables still governs visibility.

ViewBacked byPurpose
playroll_users_viewplayroll_users + auth.usersCanonical user read projection (profile + auth email).
investor_daily_recording_kpis_vc_viewrecording_sessionsVC/investor-safe daily KPIs from canonical duration. No PII.
daily_upload_statss3_uploadsDaily upload volumes.
upload_summary_by_users3_uploads + playroll_usersPer-user upload summary, identity-first.
player_recording_sessionsrecording_sessionsPer-player session listing.
session_completion_statusrecording_sessionsCompletion/terminal-state rollup per session.
complete_tripletss3_uploadsLegacy — requires mp4 + ogg + csv (no JSON term). OGG removed in EC-173 → matches only historical rows, not the modern validated set.
support_recording_sessionsrecording_sessions + s3_uploadsSupport/tester session view (canonical duration + file evidence).
support_recording_filess3_uploadsSupport file-level view (who uploaded each file, keys, URLs, status).
support_player_upload_summaryrecording_sessions + s3_uploadsSupport player lookup summary.
user_current_trackapp_update_resolve_audit_v1Per-user current release track; feeds resolve_audience() app_track filter.

The dashboards that consume these views are documented under Dashboards → Supabase Views and the Database → Monitoring Views page.


How this page is regenerated

This reference mirrors the live schema. To refresh it after a migration, the shape comes from three queries against the Playroll Supabase project (information_schema / pg_catalog): the table+column list, the foreign-key list, and the enum list. Re-run those, diff against the tables above, and update the affected section in the same change that ships the migration — per the workspace rule that playroll-docs is kept in sync with schema changes.