title: Impostazioni near-prod — migliorie da fare + handoff per sessione fresca date: 2026-06-07 owner: Gregorio (decisioni) · Claude (esecuzione) status: base = Multiverbe PR #342 (OPEN, CI verde, mergeable CLEAN) — split Account/Business + gating ruolo + inviti tabella/RLS. Da mergiare (founder). related: Multiverbe docs/settings-account-architecture.md (spec SSoT) · memory project_settings_account_redesign_2026_06_07 · operating_charter
Impostazioni · near-prod fatto + migliorie residue (handoff)
✅ Aggiornamento 2026-06-10 — PR #354 (CI-verde, NON merged, merge=founder)
Le 3 migliorie sono fatte (Multiverbe PR #354, segue #342):
- M2 Notifiche Fase 3 ✅ (decisione founder "Onesto + mute reale"): campanella always-on;
eventi reali per pianeta (oggi Booking nuova-prenotazione + Sales trattativa-vinta) silenziabili
nella propria campanella (mute per-utente nel reader); canali push/email "In arrivo" onesti.
Fixato il bug salvataggio (
notify_email_openedcolonna inesistente → PGRST204). - M3 Switch business ✅:
selectedWorkspaceIdpersistito +switchWorkspaceche azzera la cache react-query (anti data-bleed). ⚠️ richiede QA founder multi-tenant dal vivo prima del merge (testabile con l'account demo a 4 workspace). - M1 Accept-inviti ✅ ma SENZA bypass (decisione founder): trigger
privatesuauth.users, applicato in PROD via MCP, crea la membership all'accept ma NON tocca il ban → il founder-lock resta attivo (login bloccato fino al lancio). Il bypass del lock resta una decisione di lancio.
Verificato: tsc src+api · eslint 0 errori · 923 test · vite build · advisor security 0 errori.
Residui: QA founder switcher · posizione switcher globale (navbar) · bypass-lock al lancio ·
canali push/email reali (VAPID + UI iscrizione) · booking-cancellation→campanella (manca emitter) ·
flash ruolo in load · estrazione SettingsPage.tsx.
Cosa è già fatto e verde (PR #342, da mergiare)
Split Account / Business (scope switch) · gating per ruolo (sub-account solo Account, Business owner/admin, Billing solo owner, render-guard sugli 8 blocchi business, cap sub-account con CTA upgrade) · pulizia dark-only (via light mode + color picker + sessioni finte + 2FA dup + 6 griglie morte + colore Crea-Business + ruolo Marketing) · fix Team-UUID/email-read-only/a11y · inviti team (tabella team_invites + RLS owner/admin già in prod via MCP; UI record/lista/cancella, ruoli admin/member/viewer) · OAuth Google #335 preservato. Spec completa: docs/settings-account-architecture.md. CI verde, mergeable CLEAN.
Scoperte da tenere a mente (verificate via MCP, prod)
- App founder-locked:
public.auto_ban_non_founder_usersbanna a vita ogni signup la cui email non è inpublic.founder_emails. → nessun invitato può accedere finché c'è il lock. team_members.roleammette soloowner/admin/member/viewer— NONvenditore(i venditori sono un concetto del Pianeta Sales: team_member +sales_seller_subaccounts, promozione successiva).- Modello notifiche evoluto su master: #324/#333 hanno spostato "nuova prenotazione" alla campanella in-app (
notifyInApp/ai_notifications) e rimosso il path push/email staff (booking_new_to_business). Le preferenze per-evento del vecchio NotificationsTab vanno ri-mappate a questo modello.
Le migliorie da fare (in ordine di valore)
⚡ M1 — Inviti: accept-al-signup + bypass del launch-lock (task di LANCIO)
Oggi gli inviti si registrano (tabella+RLS+UI live) ma il membro non entra: si registrerebbe e verrebbe bannato dal founder-lock. Al lancio:
- Trigger additivo e fail-soft su
auth.users(NON toccarehandle_new_user): per ogniteam_invitespending che matchalower(new.email)→ inserisciteam_members(role dell'invito,on conflict do nothing), marca l'invitoaccepted, e togli il ban (banned_until = NULL) all'invitato (un invitato dall'owner è autorizzato).security definer,search_path='',exception when others then return new. - Decisione founder necessaria: gli invitati bypassano il lock pre-lancio? (sì = possono onboardare i venditori prima dell'apertura pubblica). È una modifica alla postura di sicurezza del lock → confermare.
- Opzionale: email d'invito (Brevo) così l'invitato sa di doversi registrare.
⚡ M2 — Notifiche Fase 3: riallinea il contenuto al modello in-app
Il redesign del contenuto di NotificationsTab è stato differito (il vecchio assumeva il push per-evento, ora obsoleto). Da fare, live-testabile:
- Decidi il modello: la campanella in-app è l'inbox always-on; le preferenze (push/email/SMS, quiet hours) governano i canali, non l'inbox. Allinea le categorie agli eventi reali dei 6 pianeti (booking/CRM/sales/sole) effettivamente emessi oggi.
- Verifica cosa leggono davvero le colonne
notification_preferencessu master (quali toggle gatano qualcosa) → niente toggle inerti (charter "zero finto"). - L'IA è già pronta: "Notifiche" sta sotto Account (è per-utente).
⚡ M3 — Switch business funzionale (multi-workspace)
Oggi il chip "Business attivo" è read-only (useWorkspace usa sempre memberships[0]). Da fare: selectedWorkspaceId nello store (persistito) + useWorkspace con queryKey ['workspace', selectedWorkspaceId] → i consumer ri-fetchano per workspace (cascade query-key). RICHIEDE live-test multi-tenant prima di shippare (rischio data-bleed se un consumer non keya per workspace_id). Alto valore per founder multi-business.
🗓️ Minori / futuro
notify_booking_cancellationverso lo staff: oggi nessun dispatchbooking_cancelled_to_business(toggle tenuto nascosto). Cablarlo se serve.- 2FA/MFA reale + sessioni attive reali (oggi "Prossimamente" onesto in Account → Sicurezza).
- Estrazione di
SettingsPage.tsxin componenti per scope (oggi un solo file ben organizzato; pulizia, non urgente).
PROMPT (incolla in una sessione fresca, quando si affronta una di queste)
Sei un senior staff full-stack (livello big-tech) che alza la qualità delle Impostazioni di MULTIVERBE (SaaS che dà a una PMI CH/UE sito, prenotazioni, contenuti, CRM, vendite, coordinati da un'AI). Standard = Engineering Charter (memory
operating_charter): verifica dal vivo con metodo esplicito · piccolo e coeso · zero hardcoded customer-facing (multi-tenant, ogni stringa per QUALSIASI tenant) · sicuro (filtraworkspace_id, RLS + ownership al data-layer; l'UI-gating è defense-in-depth, non sostituisce l'RLS) · advisor Supabase 0 errori · fix alla radice · merge solo a CI verde (squash, pattern del repo). Italiano ovunque. Mai DeepSeek/OpenRouter; pseudonimizza PII pre-Anthropic. Plan-first, proponi la scelta migliore con trade-off, verifica lo stato reale (DB via MCP/prod/CI) prima di agire; chiedi prima solo per schema-prod, pricing/canon, sicurezza, hard-to-revert. Cost-mode: verifica in locale (pnpm exec tsc+vite build+lint --max-warnings=560+vitest run) PRIMA di pushare, la PR nasce verde. Per scelte di stack valida sul web l'ultimo livello 2026. Riferimento dati live =src/types/supabase.ts(generato), NONdatabase/supabase_schema.sql(legacy non-applicato); ogni cambio schema → rigenera i types o il gate schema-drift fallisce.Stato (già fatto, NON rifare): PR #342 ha portato le Impostazioni a near-prod (split Account/Business, gating ruolo, pulizia dark-only, inviti tabella+RLS+UI). Spec =
frontend/multiverbe-app/docs/settings-account-architecture.md. App founder-locked (auto_ban_non_founder_users);team_members.role= owner/admin/member/viewer (no 'venditore'); notifiche booking→in-app (#324/#333).Missione: [scegli M1 inviti-accept / M2 notifiche-Fase3 / M3 business-switcher dall'handoff
ops/settings-near-prod-handoff-2026-06-07.md]. Chiudi con il blocco 🔴 DA FARE (🔄 Continuative · ⚡ Migliorative · 🗓️ Future) e persisti il pending in memoria + BOS.