Skip to main content

Player accounts and names

public.players connects a validated Auth0 identity to a local game account. Game data uses the local player UUID. Player Names provide display identity; the API reads roles and account lifecycle from PostgreSQL.

Account fields​

ColumnResponsibility
idStable local UUID used for ownership and account relationships.
auth_issuer, auth_subjectExact trusted Auth0 identity pair, unique across accounts.
player_nameNullable during supported social-account onboarding; unique when assigned.
roleLocal player or author permission.
lifecycle_statusAccount access state, normally active or deletion_pending.
deletion_request_idPending deletion request, where applicable.
created_at, updated_atAccount timestamps.

New accounts receive the player role. Resolving an existing identity preserves its local UUID and role; browser input and token role claims cannot grant Author access. See the Author guide for permissions and Integrations for authentication.

The schema still recognises the historical deleted lifecycle value. Completed deletion now removes the player row, rather than keeping an account tombstone.

Player Name assignment​

Auth0 database accounts supply their canonical username through the validated https://witsworld.co.za/player_name claim. Account resolution synchronises that claim with player_name.

Supported Google accounts start with no Player Name and choose one through PUT /api/v1/auth/me/player-name. The API trims and lowercases the proposal, then assigns it only while the stored name is null. Database accounts and already-named accounts cannot use this operation.

Names use the shared account policy: 3–20 characters, lowercase letters, numbers, and the supported username punctuation. Email-shaped and phone-shaped values are rejected. Database claims must already have canonical form.

A database check enforces the syntax, and a partial unique index on lower(player_name) reserves one namespace across providers while allowing onboarding nulls. A collision returns 409 PLAYER_NAME_CONFLICT without changing either account's identity binding or ownership.

GET /api/v1/auth/me exposes playerName and the derived playerNameSetupRequired flag. There is no player rename operation. API operations that require completed onboarding reject accounts without a name.

Profile storage​

Editable showcase data lives separately from identity:

RelationResponsibility
player_profilesVersioned bio, study details, avatar, temporary status, and visibility preferences.
player_profile_cardsUp to 4 ordered favourite owned-card references per player.

Profiles default to private, with activity sharing disabled. Favourites refer to owned copies rather than catalogue definitions. Transferring or consuming a showcased copy removes its reference; showcasing does not reserve the card.

The Profile guide owns the display and visibility rules. Profile preferences do not change authentication, ownership, or standings eligibility.

Deletion boundary​

Pending deletion disables normal account and developer-key access. Completion removes identity, Player Name, profile, and personal game data. The local name reservation is released with the completed purge, after the Auth0 deletion boundary succeeds.

Retained shared history uses a fresh profile-free actor reference. A later registration receives a new UUID and starting state. Account deletion and retained data defines the transaction and retention rules.

AI declaration: Prepared and updated with assistance from Codex-CLI[GPT-5], Codex[GPT-5], Codex-CLI[gpt-5.6-sol medium], Codex-CLI[GPT-6], and Codex[GPT-6].