Passa al contenuto principale

Crescita e Rete

Riassunto in linguaggio semplice. Questo dominio riguarda l'acquisizione attraverso i giocatori che già abbiamo. Ogni utente Playroll ha una lista di amici Steam; quegli amici sono lead. Rispecchiamo quella rete nello shadow graph, le assegniamo un punteggio e portiamo in primo piano gli amici di maggior valore non ancora reclutati nella vista headhunter. Due meccanismi più piccoli — codici invito e referral — regolano e premiano le iscrizioni effettive.

Mappa

shadow_graph — la rete di amici

Il motore di reclutamento. Ogni riga è un arco orientato da un utente Playroll registrato (source_user_id / source_steam_id) verso uno dei suoi amici Steam (target_steam_id) che può o meno essere già un utente Playroll.

Ogni arco è univoco su (source_user_id, target_steam_id). Il lato "target" porta uno snapshot completo di arricchimento di quell'amico, così che la vista headhunter possa classificarlo senza una seconda chiamata API: target_name, target_avatar_url, target_profile_url, target_hours, target_games_owned, target_level, target_profile_public, più due colonne di scoring — target_tier (whale | regular | casual, default casual, assegnato da calculate_shadow_tier) e target_yearly_value (il valore stimato del loro reclutamento).

Il funnel di reclutamento è tracciato inline. recruitment_status è un enum chiuso:

ColonnaSignificato
recruitment_statusnone (default) → invitedconverted.
invited_atQuando li abbiamo contattati.
converted_atQuando l'amico è diventato un utente Playroll.
converted_user_idFK nullable alla riga playroll_users che sono diventati — chiude il ciclo da lead a membro.
friend_sinceEtà dell'amicizia riportata da Steam (un timestamp Unix).

Il grafo aggrega sull'utente sorgente come playroll_users.network_value, network_whale_count e steam_friend_count — ma questo non è automatico: viene ricalcolato dalla RPC SECURITY DEFINER update_network_stats(p_user_id) (nessun trigger la innesca) e conta solo le righe dove recruitment_status = 'none' (lead ancora aperti) — quindi gli amici invitati/convertiti escono da network_value.

Questi sono i dati "headhunter"

La vista rete-di-amici / headhunter nelle dashboard è una proiezione di shadow_graph. Quando qualcuno chiede "chi dovremmo reclutare dopo?", la risposta è una query su questa tabella ordinata per target_yearly_value dove recruitment_status = 'none'.

Codici invito — gating della Fase 0

Un pool fisso di codici che regola l'accesso a playroll.gg durante le fasi a solo invito.

  • invite_codes — il pool. Ogni code appartiene a un pool (default phase_0), consente max_uses riscatti (CHECK max_uses > 0, tracciando uses nell'intervallo 0..max_uses), può essere disattivato (active), opzionalmente expires_at, e registra chi lo ha coniato (created_by → un utente).
  • invite_code_consumptionsPK composita (code, user_id), così un utente può consumare un dato codice al massimo una volta. È il log dei successi: la RPC consume_invite_code controlla if exists(...) return 'already' prima di inserire, quindi un successo ripetuto è impossibile e non produce mai una seconda riga. Cattura consumed_at e il contesto di abuso (ip_hash, user_agent). Nota che il flusso di invito non registra i fallimenti da nessuna parte — consume_invite_code restituisce semplicemente stringhe sentinella ('already', 'expired', …) senza scrivere.

consume_invite_code è una RPC SECURITY DEFINER: impone auth.uid() = p_user_id (altrimenti errore 42501), normalizza il codice, prende un lock di riga SELECT ... FOR UPDATE, controlla active/scadenza/duplicato/uses < max_uses, poi atomicamente inserisce il consumo e incrementa invite_codes.uses sotto quel lock.

redeem_attempt_log non fa parte del flusso di invito

Nonostante la somiglianza del nome, redeem_attempt_log supporta il flusso del codice di attivazione del contributor (edge function redeem-activation-code, EC-227), non i codici invito. È il log del rate-limiter per quel flusso (per app_user_id, per ip, per code_hash). È documentato con il dominio contributor/attivazione, non qui. (app_user_id è un uuid senza vincoli — un riferimento soft, deliberatamente non una FK.)

Modello di accesso

RLS è attivo su tutte le tabelle di crescita e sono solo service-role: shadow_graph, invite_codes e invite_code_consumptions portano policy di deny-anon + deny-authenticated con accesso completo per il service-role. L'accesso utente avviene solo tramite la RPC consume_invite_code (sopra) — mai letture dirette delle tabelle.

Referral

Il ciclo di referral vive come colonne su playroll_users anziché come tabella propria:

  • referral_code — il codice condivisibile del giocatore stesso.
  • referred_by — il codice (o utente) che lo ha portato dentro.
  • referral_count — quante iscrizioni ha generato.

Combinato con la colonna referrer e le colonne di attribuzione utm_* (vedi Identità e Accesso), questo è il quadro completo di come è arrivato un dato giocatore.


Vedi anche: riferimento completo delle colonne per queste tabelle.