Operations
Questa pagina riassume come eseguire e gestire il repo attuale del Contributor Portal.
Sviluppo Locale
Installazione ed esecuzione:
npm install
npm run dev
Il dev server di Vite usa di default:
http://localhost:5173
Ambiente browser richiesto:
VITE_SUPABASE_URL
VITE_SUPABASE_PUBLISHABLE_KEY
Ambiente locale server-only:
SUPABASE_SECRET_KEY
SUPABASE_SERVICE_ROLE_KEY
SUPABASE_ACCESS_TOKEN
CONTRIBUTOR_LINK_INTENT_SECRET
PLAYROLL_APP_SUPABASE_URL
PLAYROLL_APP_SUPABASE_SERVICE_ROLE_KEY
Non esporre chiavi server-only attraverso variabili VITE_ o codice React. Vite include nel bundle del browser tutte le variabili VITE_.
Progetto Supabase
URL Supabase attualmente documentato:
https://xlsjwlmsqonllvtyplml.supabase.co
URL Supabase correlato dell'app Playroll:
https://vtyolotvuvlbvqbgbzde.supabase.co
Allowlist auth di produzione:
Site URL:
https://playroll.extrinsiccognition.com
Redirect URLs:
https://playroll.extrinsiccognition.com/**
http://127.0.0.1:5173/**
http://localhost:5173/**
L'app usa il login email Supabase PKCE. Evita i fragment hash in emailRedirectTo; gli hash possono interferire con il parsing del callback e i token impliciti espongono valori sensibili nel fragment dell'URL.
Template Email di Auth
Supabase invia email diverse per utenti nuovi ed esistenti:
new email address -> Confirm signup
existing user -> Magic Link
Entrambi i template devono rimanere brandizzati:
supabase/email-templates/confirm-signup.html
supabase/email-templates/magic-link.html
Script di deployment:
npm run deploy:auth-email
npm run deploy:smtp
Deployment del rate-limit di auth:
npm run deploy:auth-rate-limits
Deployment dello Schema
Applica il deployment completo dello schema configurato:
npm run deploy:schema
Applica una singola migrazione:
SUPABASE_MIGRATION_FILE=supabase/migrations/<file>.sql npm run deploy:schema
L'identity link richiede migrazioni in entrambi i progetti Supabase:
# App project: playroll_supa_new / vtyolotvuvlbvqbgbzde
$env:SUPABASE_PROJECT_REF = 'vtyolotvuvlbvqbgbzde'
$env:SUPABASE_MIGRATION_FILE = 'C:\EC\playroll-cpp\supabase\migrations\20260511160000_add_contributor_status_projection.sql'
npm run deploy:schema
# Portal project: playroll_contributor_portal / xlsjwlmsqonllvtyplml
$env:SUPABASE_PROJECT_REF = 'xlsjwlmsqonllvtyplml'
$env:SUPABASE_MIGRATION_FILE = 'supabase/migrations/20260511161000_add_contributor_app_links.sql'
npm run deploy:schema
Shortcut utili:
npm run deploy:schema:validation-payout
npm run deploy:schema:time-milestones
npm run deploy:schema:payout-receiving
npm run deploy:schema:payout-iban-validation
Cloudflare Pages
Impostazioni Pages di produzione:
Project name: playroll-contributor-portal
Production branch: main
Build command: npm run build
Build output directory: dist
Custom domain: playroll.extrinsiccognition.com
Prima creazione del progetto:
npm run pages:create
Deploy:
npm run deploy:pages
npm run deploy:pages esegue prima la build, poi lancia il deploy di Wrangler Pages.
Edge Function
Deploy del creatore di intent lato app da C:\EC\playroll-cpp:
npx -y supabase@latest functions deploy create-contributor-link-intent \
--project-ref vtyolotvuvlbvqbgbzde \
--no-verify-jwt
Deploy dell'attivatore lato portale da C:\EC\playroll-contributor-portal:
npx -y supabase@latest functions deploy activate-contributor-app-link \
--project-ref xlsjwlmsqonllvtyplml \
--no-verify-jwt
Secret richiesti dalle function del progetto app:
CONTRIBUTOR_LINK_INTENT_SECRET
CONTRIBUTOR_PORTAL_URL
Secret richiesti dalle function del progetto portale:
CONTRIBUTOR_LINK_INTENT_SECRET
PLAYROLL_APP_SUPABASE_URL
PLAYROLL_APP_SUPABASE_SERVICE_ROLE_KEY
CONTRIBUTOR_LINK_INTENT_SECRET deve essere identico in entrambi i progetti. Conserva questi valori nei secret di progetto Supabase o in file di ambiente locali/server ignorati. Non committarli mai.
Preflight di Produzione
Prima di esporre il portale al pubblico:
npm run buildha successo.- Cloudflare Pages ha solo variabili d'ambiente browser-safe.
- Le Site URL e Redirect URL di auth Supabase includono URL di produzione e dev locale.
- I template di confirm signup e magic-link sono entrambi personalizzati.
- Le pagine pubbliche di privacy/legali risolvono sotto
/legal/. - La public application resta aperta; non limitarla agli utenti EC-domain.
- Le admin/review surface, se aggiunte in futuro, sono separate e ristrette all'EC-domain.
- Le migrazioni di schema sono applicate nell'ordine atteso.
- Le policy RLS richiedono ancora righe authenticated proprie per scritture/letture del contributor.
- La validazione IBAN SEPA esiste sia nel browser sia nel database.
- Le email di conferma del receiving-method tornano con
payout_confirm_token=<single-use 64-char hex token>; il portale consuma il token tramite la RPC SECURITY DEFINERconfirm_payout_receiving_method_with_token. Il flag nudopayout_confirm=1non è più accettato (audit 2026-05-16, EC-231 M1). - Gli app identity link possono essere creati soltanto attraverso intent firmato e gate di attivazione del portale.
create-contributor-link-intenteactivate-contributor-app-linkrestituisconorequest_idin caso di errore.
Controlli di Runbook
L'insert di una application deve fallire a meno che:
auth_user_id = auth.uid()
submitted email = verified Supabase email
email_verified_at is not null
status = new
source in playroll_public_page or playroll_referral_link
L'insert di onboarding deve fallire a meno che:
auth_user_id = auth.uid()
submitted email = verified Supabase email
city is a known ISTAT comune
required acceptances are true
Un receiving-method SEPA non deve diventare pagabile finché:
payout_receiving_methods.status = confirmed
payout_receiving_methods.email_confirmation_status = confirmed
I casi di manual review devono restare bloccati per il payout automatico finché un sistema ops/pagamento non approva un'alternativa supportata al di fuori di questo repo.
Smoke Check dell'Identity Link
Le chiamate non autenticate alle function devono fallire, ma dimostrano che le function deployate sono live:
POST https://vtyolotvuvlbvqbgbzde.supabase.co/functions/v1/create-contributor-link-intent
-> 401 missing_authorization with request_id
POST https://xlsjwlmsqonllvtyplml.supabase.co/functions/v1/activate-contributor-app-link
-> 401 missing_authorization with request_id
Il dominio custom deve rispondere 200 e servire l'ultimo bundle buildato:
GET https://playroll.extrinsiccognition.com