diff --git a/IdentityProvider_Design.md b/IdentityProvider_Design.md new file mode 100644 index 0000000..2878e81 --- /dev/null +++ b/IdentityProvider_Design.md @@ -0,0 +1,147 @@ +# Design — Identity Provider PoliNetwork + +**Documento collegato:** [`PRD_Admin_Dashboard_PoliNetwork.md`](./PRD_Admin_Dashboard_PoliNetwork.md) §2.6 · [`PRD_Classificazione_Feature.md`](./PRD_Classificazione_Feature.md) #0 +**Versione:** 1.0 +**Data:** 30 agosto 2026 +**Base tecnica:** Better Auth (già in uso in `@polinetwork/backend`, Drizzle/Postgres) + +## 0. Cosa esiste già (verificato nel codice) + +Prima di progettare da zero, questo è lo stato reale: + +- **Login attuale**: email OTP + passkey (`better-auth`, `emailOTPClient`, `@better-auth/passkey`) — `src/features/auth/login-page.tsx`. **Non è già legato a Telegram**: si accede con email personale o passkey. +- **Collegamento Telegram**: già esiste come step separato, post-login, a flusso opzionale — `src/features/onboarding/telegram-link-page.tsx`, `use-telegram-link.ts`. Meccanismo: `auth.telegram.link.start({telegramUsername})` genera un codice con TTL (tabella `tg.link` nel backend), l'utente lo usa lato Telegram, poi `auth.telegram.link.verify({code})` conferma. Il record `user` di Better Auth ha già le colonne `telegramId`/`telegramUsername`. +- **Il blocco**: `authorizeAdmin` (`src/server/auth.server.ts`) oggi **richiede** `telegramId` per accedere alla dashboard — se manca, ritorna `"telegram-unlinked"` e i ruoli/capacità vengono letti **solo** dalla tabella `permissions` del bot Telegram (keyed by Telegram user id). Quindi l'identità dashboard dipende ancora, di fatto, da Telegram per l'autorizzazione, anche se non per il login. +- **Email**: l'invio (OTP, notifiche) passa già da Microsoft Graph (`AZURE_EMAIL_SENDER=noreply@polinetwork.org`), non da un SMTP dedicato — riusabile as-is per nuovi flussi email. +- **Azure**: integrazione esistente solo per gestione directory/gruppi (Microsoft Graph), non per login — nessun "Sign in with Microsoft" oggi. +- **polinet.cc**: repository e dominio separati, non nel monorepo — niente cookie condivisibili di default. + +Il lavoro da fare, quindi, non è "costruire un IdP da zero" ma: **scollegare l'autorizzazione da Telegram, aggiungere il collegamento account Politecnico con lo stesso pattern già validato per Telegram, ed estendere la stessa identità Better Auth ad altri servizi via OIDC.** + +--- + +## 1. Principio guida + +Un'unica identità PoliNetwork per persona (`user.id` di Better Auth), a cui si **collegano** più identificativi verificati indipendenti — nessuno dei quali è obbligatorio per esistere come identità, ma alcuni sono richiesti per ottenere certe capacità: + +``` + ┌─────────────────────────┐ + │ Identità PoliNetwork │ (Better Auth user) + │ creata via email/passkey│ + └────────────┬────────────┘ + │ fatti/collegamenti indipendenti, aggiungibili in qualsiasi momento + ┌──────────────┬──────────┴──────────┬──────────────┐ + ▼ ▼ ▼ ▼ + Telegram account Affiliazione Record Socio Passkey + (già esistente, Politecnico (claim via (già esistente, + opzionale) (NUOVO — codice codice, NUOVO) 2FA/accesso rapido) + via mail @polimi) +``` + +Nessuno di questi collegamenti è "il" login: il login primario resta **sempre** email personale (OTP) o passkey — usato da chiunque, che sia uno studente sul sito pubblico, un socio, o un admin. I quattro collegamenti sono **fatti indipendenti** sulla stessa identità, nessuno implica gli altri (coerente con PRD §1.2 — Socio, Admin, membro di team sono già definite come categorie indipendenti; qui aggiungiamo "affiliazione Politecnico" come quarto asse, altrettanto indipendente): + +- **Telegram collegato** → prova di appartenenza al canale operativo Telegram, alimenta i ruoli legacy. +- **Politecnico verificato** → prova che la persona è o è stata studente del Politecnico. Non implica essere socio, non implica avere accesso alla dashboard. +- **Record Socio collegato** → prova che la persona è (o è stata) iscritta e in regola con la quota. Non implica essere admin, non implica essere del Politecnico (in linea di principio un socio potrebbe non esserlo). +- **Ruolo admin/team** (via `capability_grant`, §4 sotto) → prova di un ruolo organizzativo. Non implica essere socio né avere Telegram. + +Un'altra implicazione di questo modello: **la stessa identità e lo stesso login servono anche il sito pubblico PoliNetwork**, non solo la dashboard interna. Chiunque arrivi dal sito con la propria email personale ottiene la stessa identità — se poi verifica l'affiliazione Politecnico o risulta socio, sblocca le aree corrispondenti sul sito stesso. L'IdP non è quindi "l'accesso alla dashboard admin": è l'identità unica di chiunque interagisca con l'ecosistema PoliNetwork (sito pubblico, area soci, dashboard interna, polinet.cc, futuri servizi). + +--- + +## 2. Collegamento affiliazione Politecnico (nuovo) + +Stesso schema UX già validato per Telegram, invertito nel canale: invece di un codice generato in dashboard e inserito su Telegram, un codice inviato per email istituzionale e inserito in dashboard (identico, concettualmente, all'OTP di login già esistente). + +**Cosa significa questo collegamento, esattamente**: attesta il fatto "questa persona è o è stata studente del Politecnico" — un'affiliazione, non uno status di socio. Non fa fede su iscrizione, corso, anno o quota: è solo la prova che la persona ha accesso a una casella email istituzionale del Politecnico. Resta un fatto indipendente accanto a Socio e Admin (vedi diagramma in §1). + +### Flusso + +1. L'utente è già autenticato (sessione attiva) — sul sito pubblico o in dashboard, indifferentemente. Da un'area "Account"/"Il mio profilo" apre "Verifica il tuo account Politecnico". +2. Inserisce il proprio indirizzo istituzionale. L'input è validato contro un **allowlist di domini configurabile**: al momento **`@mail.polimi.it`** e **`@polimi.it`** (gli unici confermati). L'allowlist va tenuta come tabella/config, non hardcoded, per poter aggiungere altri atenei in futuro senza saperli oggi. +3. Il backend genera un codice a 6 cifre con TTL breve (10 minuti, stesso ordine di grandezza del TTL già usato in `tg.link`), lo salva in una nuova tabella `institutional_email_link` (`userId`, `email`, `code`, `expiresAt`, `verifiedAt`), e lo invia via Microsoft Graph — stesso canale email già in uso per l'OTP di login, nessuna nuova infrastruttura di invio. +4. L'utente inserisce il codice (stesso componente UI dell'OTP di login, riusato). +5. Il backend verifica codice e scadenza, marca l'indirizzo come verificato, scrive l'evento nell'audit unificato (§2.2 del PRD). +6. L'indirizzo verificato viene salvato su `user.institutionalEmail` / `institutionalEmailVerifiedAt` (stesso pattern delle colonne `telegramId`/`telegramUsername` già presenti sulla riga `user`). + +### Cosa sblocca + +- Un badge/flag "Politecnico verificato" utilizzabile sia sul sito pubblico (es. contenuti riservati agli studenti) sia come dato di supporto in fase di domanda di iscrizione a socio (§3.1 del PRD) — **non** un'iscrizione automatica: resta un operatore a validare la domanda. +- Base per un eventuale matching futuro con la directory Azure/Entra del Politecnico, se mai disponibile (oggi l'Azure esistente è il tenant di PoliNetwork, non quello dell'ateneo). +- **Non** sostituisce la firma della privacy policy (§2.5) né l'iscrizione a socio: resta un collegamento di identità, non un flusso di associazione. + +--- + +## 3. Collegamento al record Socio (claim tramite codice — terza istanza dello stesso pattern) + +**Perché non "usa la mail PoliNetwork per accedere all'area soci"**: non tutti quelli che accedono alla dashboard sono soci, e non tutti i soci hanno (o avranno mai) una casella @polinetwork.org. Usare quella mail come credenziale per l'area soci escluderebbe soci senza mail istituzionale e confonderebbe due categorie che il PRD tiene esplicitamente separate (§1.2). La stessa obiezione vale per "far validare l'account personale con la mail PoliNetwork": funziona solo per chi quella mail ce l'ha, cioè in pratica solo admin/team — non la popolazione dei soci in generale. + +**Soluzione proposta — un terzo codice, come per Telegram e Politecnico**: quando un socio viene approvato (flusso §3.1 del PRD: richiesta → verifica → deduplica → firma privacy → approvazione → numero associativo), il sistema invia all'indirizzo email fornito in fase di iscrizione un **codice di claim** legato al numero associativo appena generato — non un nuovo canale, lo stesso meccanismo di invio già usato per Telegram/Politecnico. + +### Flusso + +1. Il Direttivo (o ruolo autorizzato) approva l'iscrizione in Anagrafica Soci; viene generato il numero associativo (già previsto dal PRD §3.1). +2. Il backend crea un codice di claim con TTL più lungo del solito (es. alcuni giorni, dato che la persona potrebbe non avere ancora un account PoliNetwork), salvato in `membership_claim` (`numeroAssociativo`, `email`, `code`, `expiresAt`, `claimedByUserId`). +3. Il codice viene inviato via email all'indirizzo fornito in iscrizione (stesso invio Graph). +4. La persona, se non ha già un'identità PoliNetwork, si registra con la sua email personale (login standard, §"Principio guida"); se ce l'ha già, usa quella. +5. Da un'area "Collega il mio tesseramento", inserisce il codice ricevuto. Il backend verifica codice+TTL e collega `user.id` al record Socio corrispondente. +6. Da questo momento la persona ha lo stesso login di sempre, ma la sua identità risulta anche "Socio attivo" — con accesso all'area riservata soci sul sito e alle funzioni di rinnovo (§6 del PRD). + +Questo riusa esattamente l'infrastruttura di codice+TTL+email già scritta per Telegram e (dopo il punto 2) per Politecnico — non è un sistema nuovo, è la stessa primitiva applicata una terza volta a un caso diverso. + +--- + +## 4. RBAC indipendente da Telegram + +Oggi l'autorizzazione (`authorizeAdmin`) fallisce con `"telegram-unlinked"` se l'utente non ha un Telegram collegato, e i ruoli arrivano solo dalla tabella `permissions` del bot (keyed by Telegram id). Questo rende impossibile, per costruzione, dare accesso dashboard a chi non ha (o non vuole) un account Telegram — un problema per Capo Admin, HR, o futuri ruoli Finance (PRD §19, punto 9) che potrebbero non passare da Telegram. + +Proposta (coerente con PRD §2.1): + +- Nuova tabella `capability_grant`: `subjectUserId`, `capability` (es. `members.read`, `members.write`, `telegram.moderate`, `azure.manage`, `content.write`, `governance.read`, `audit.read`), `scopeType` (`none` / `course` / `team`), `scopeValue`, `grantedBy`, `grantedAt`, `revokedAt`. +- `authorizeAdmin` viene **esteso**, non sostituito: continua a leggere i ruoli Telegram esistenti quando presenti (retrocompatibilità esplicitamente richiesta dal PRD §2.1) e li mappa a capacità implicite (`owner`/`direttivo`/`president` → tutte le capacità; `hr` → sola lettura), poi li unisce alle eventuali `capability_grant` dirette sull'utente. +- Risultato: un utente **senza** Telegram collegato ma con una `capability_grant` diretta può comunque accedere alla dashboard con le capacità assegnate — Telegram diventa una delle fonti di autorizzazione, non l'unica. +- Il popolamento iniziale di `capability_grant` per gli owner/direttivo attuali è un one-off di migrazione, non un flusso utente. + +--- + +## 5. Single sign-on sugli altri servizi (sito pubblico, polinet.cc, futuri) + +`polinet.cc` è un repository e (presumibilmente) un dominio diverso da `polinetwork.org`: i cookie di sessione di Better Auth non attraversano domini diversi. Lo stesso vale, quasi certamente, per il sito pubblico se vive su un dominio o deploy separato dalla dashboard. Condividere solo il cookie non basta — serve un vero provider OAuth2/OIDC. + +Con la conferma che l'IdP serve **anche il sito pubblico** (non solo la dashboard interna), il sito pubblico è probabilmente il primo consumer reale di questo provider — più di polinet.cc — perché è lì che gli studenti verificano l'affiliazione Politecnico e i soci fanno il claim del tesseramento (§3 sopra). Va scoping-ato per primo con chi lavora al sito. + +### Proposta + +- Attivare il plugin **`oidcProvider`** di Better Auth sulla stessa istanza server già presente in `@polinetwork/backend` (quella usata oggi da `admin`), trasformandola in un Identity Provider OIDC standard con gli endpoint `/authorize`, `/token`, `/userinfo`, `/.well-known/openid-configuration` e JWKS. +- Ogni servizio (sito pubblico, Admin Dashboard, polinet.cc, futuri strumenti interni) viene registrato come **client OAuth2** con `client_id`/`client_secret` e redirect URI propri. +- Ogni servizio implementa "Accedi con PoliNetwork" come flusso standard Authorization Code + PKCE, invece di reimplementare email OTP/passkey/OTP Politecnico da zero — un solo posto dove vive la logica di autenticazione. +- L'ID token / `userinfo` espone claim minime e stabili: `sub`, `email`, eventualmente `telegramId`/`telegramUsername` se collegato. **Le capacità/ruoli non vanno incluse nel token**: cambiano più spesso di quanto un token duri, e obbligherebbero a invalidarlo ad ogni modifica di permesso. Ogni servizio le richiede al bisogno a un endpoint dedicato del backend (stesso pattern di `authorizeAdmin` oggi), passando lo scope che gli serve — polinet.cc, ad esempio, potrebbe aver bisogno solo di "socio sì/no", non delle capacità da dashboard admin. +- Con una sessione IdP già attiva (es. utente già loggato in dashboard), l'`/authorize` su un secondo servizio non richiede di reinserire email/OTP: è SSO silenzioso, non un secondo login. + +### Non-obiettivo + +Non si sposta la sessione applicativa di ogni servizio sull'IdP: ogni app mantiene il proprio cookie di sessione locale (dominio proprio) dopo lo scambio OIDC iniziale. L'IdP centralizza solo l'autenticazione, non lo stato di sessione di ogni app. + +--- + +## 6. Cosa cambia, cosa resta + +| | Oggi | Con questo design | +|---|---|---| +| Login primario | Email OTP / passkey | Invariato — usato anche da chi arriva dal sito pubblico | +| Telegram | Obbligatorio per autorizzazione dashboard | Opzionale — collegabile in qualsiasi momento, resta il canale operativo per il bot | +| Affiliazione Politecnico | Non esiste | Collegabile post-login, stesso pattern a codice del collegamento Telegram. Fatto indipendente, non implica Socio | +| Record Socio | Solo in Anagrafica Soci, non collegato a un'identità di login | Claim tramite codice (§3), fatto indipendente, non implica Admin né Politecnico | +| Ruoli/capacità | Solo da `permissions` Telegram, richiede `telegramId` | `capability_grant` diretta + ruoli Telegram come caso particolare (retrocompatibile) | +| Accesso da altri servizi | Nessuno (ogni servizio è isolato) | OIDC provider condiviso, "Accedi con PoliNetwork" su sito pubblico, polinet.cc e futuri servizi | + +--- + +## 7. Decisioni aperte (da aggiungere a PRD §19) + +1. ~~Quali domini email istituzionali sono ammessi al collegamento Politecnico~~ — **risolto**: `@mail.polimi.it` e `@polimi.it`. Resta aperto se/quando estendere ad altri atenei (allowlist va comunque tenuta configurabile, non hardcoded). +2. Chi genera il codice di claim del tesseramento (§3): è un'azione automatica all'approvazione dell'iscrizione, o un'azione manuale di chi approva? +3. Cosa succede se l'email usata in fase di iscrizione a socio (§3.1) è diversa dall'email con cui la persona poi crea/ha già la propria identità PoliNetwork? Il claim va comunque per codice indipendentemente dall'email di login, ma va deciso se re-inviare il codice a una nuova email è permesso e chi lo autorizza. +4. Chi assegna le prime `capability_grant` dirette e con quale processo (one-off di migrazione vs. richiesta tramite Onboarding, §8)? +5. Il plugin `oidcProvider` di Better Auth va verificato contro la versione installata (`better-auth@1.5.5`) per compatibilità, requisiti di persistenza (client registration, consent screen) e maturità, prima di confermare la stima di difficoltà in §1 della classificazione. +6. Il sito pubblico è il primo consumer reale dell'OIDC provider (probabile, vista la conferma che l'IdP lo serve): va scoping-ato con chi lavora al sito per definire l'ordine reale di implementazione della SSO multi-servizio, prima o insieme a polinet.cc. diff --git a/PRD_Admin_Dashboard_PoliNetwork.md b/PRD_Admin_Dashboard_PoliNetwork.md new file mode 100644 index 0000000..a215909 --- /dev/null +++ b/PRD_Admin_Dashboard_PoliNetwork.md @@ -0,0 +1,298 @@ +# PRD — Admin Dashboard PoliNetwork + +**Documento di prodotto per il Team IT** +**Versione:** 2.0 +**Data:** 29 agosto 2026 +**Stato:** Bozza per revisione + +## 0. Scopo + +Documento di riferimento per le funzionalità della Admin Dashboard di PoliNetwork. Le funzionalità interne (anagrafica soci, censimento admin/team, ruoli, governance, team) hanno priorità sulle aree pensate per soggetti esterni (associazioni partner, aziende, alloggi). + +--- + +## 1. Persone, ruoli e gerarchie + +### 1.1 Ruoli Telegram + +Il backend Telegram conosce sei ruoli: `admin`, `hr`, `president`, `direttivo`, `creator`, `owner`. + +| Ruolo | Accesso dashboard | Scrittura dashboard | +|---|---|---| +| `owner` | sì | sì | +| `direttivo` | sì | sì | +| `president` | sì | sì | +| `hr` | sì | no — sola lettura | +| `admin` | da estendere (§1.3) | no | +| `creator` | no, escluso esplicitamente anche se combinato con altri ruoli | no | + +I permessi sono binari e globali per ruolo: non esiste granularità per modulo/azione né scoping (es. "vede solo gli admin del proprio corso"). Va introdotta un'autorizzazione per capacità (§2.1) che estenda questo modello senza sostituirlo. + +### 1.2 Socio, Admin e membro di team — categorie indipendenti + +Socio, Admin e membro di un team interno (IT, Design & Social, International, HR, Events & Partnerships, ...) sono **tre categorie indipendenti**, non una gerarchia annidata: + +- **Socio**: chi risulta iscritto e in regola con la quota associativa (Anagrafica Soci, §3). +- **Admin**: chi ha un ruolo operativo/organizzativo su PoliNetwork. +- **Membro di team**: chi fa parte di un team interno (§7). + +Un admin può essere socio o no; un socio può essere admin o no; un membro di un team può essere admin, socio, entrambi o nessuno dei due: le tre categorie si intersecano liberamente e nessuna implica le altre. **Il Socio resta la categoria più rilevante per l'associazione**: è chi la costituisce formalmente. Admin e membro di team sono categorie organizzative/operative e non sostituiscono né presuppongono lo status di socio. + +- Un **Socio** è un record dell'Anagrafica Soci (§3), indipendente dall'essere admin o membro di team. +- Un **Admin** è una persona con un ruolo organizzativo (Admin, Capo Admin, Direttivo, Presidente, ...) tracciato dal Censimento Admin/Team (§3), con un'identità Telegram collegata se opera sui canali PoliNetwork. Non deve necessariamente essere anche Socio. +- Un **Capo Admin** è un Admin con uno scope aggiuntivo (es. corso di studi) e visibilità limitata al proprio ambito. + +### 1.3 Gerarchia organizzativa + +``` +Owner / Presidente / Direttivo — governance, accesso e scrittura completi + │ + Capo Admin (per corso/ambito) — visibilità e azioni limitate al proprio ambito + │ + Admin — operativo +``` + +Lo status di Socio e l'appartenenza a un team interno sono assi indipendenti (§1.2): possono coesistere con qualunque punto della gerarchia sopra, o con nessuno. + +Il Direttivo assegna e revoca il ruolo di Capo Admin (periodicità da definire). L'admin "semplice" deve ottenere accesso alla dashboard, con permessi determinati dal proprio scope. Resta da decidere se "Capo Admin" sia un nuovo ruolo Telegram/backend o un attributo applicativo (scope) gestito solo lato dashboard (§19). + +Una persona admin appartiene a **un solo corso di studi** come dato anagrafico personale, ma può essere admin/Capo Admin con **scope su gruppi di corsi diversi** contemporaneamente: il corso di appartenenza personale e lo scope di responsabilità sono due campi distinti. + +--- + +## 2. Fondamenta + +### 2.1 Autorizzazione per capacità (RBAC granulare) + +Permessi indipendenti per modulo: lettura/scrittura su soci, Telegram, Azure, contenuti, governance, audit. Un utente può avere più capacità (es. Content editor + Telegram moderator). Le azioni ad alto impatto (cancellazioni, assegnazione ruoli, rimozione da gruppi, export dati personali) mostrano il permesso richiesto e richiedono conferma esplicita. Resta retrocompatibile con i ruoli Telegram esistenti, che diventano un caso particolare del nuovo modello. + +### 2.2 Audit amministrativo unificato + +Ogni mutazione amministrativa produce una voce di audit con: attore, ruolo al momento dell'azione, timestamp, oggetto modificato, valori prima/dopo, motivo (obbligatorio per azioni sensibili), esito. Precondizione per esporre dati personali dell'Anagrafica/Censimento a più ruoli. + +### 2.3 Ricerca globale + +Command palette che cerca trasversalmente soci, utenti Telegram, gruppi, membri Azure, FAQ e contenuti. + +### 2.4 Home come centro operativo + +Indicatori azionabili: soci in scadenza, account non riconciliati, grant in scadenza, contenuti da pubblicare, attività recenti. Ogni indicatore è cliccabile e apre la lista filtrata corrispondente. + +### 2.5 Gestione dei consensi e firma della privacy policy in dashboard + +Oggi le autorizzazioni privacy vengono raccolte tramite vari form esterni inviati caso per caso: le domande possono cambiare o diventare obsolete nel tempo, e la perdita di un form comporta la perdita della possibilità di dimostrare/recuperare il consenso raccolto con quella versione. + +- La firma della privacy policy (e di altre informative) avviene **dentro il flusso della dashboard** (iscrizione socio, §3.1; onboarding/censimento admin, §8), non più solo tramite form esterni scollegati. +- Ogni consenso è legato a una **versione specifica del testo firmato**, con data e revoca tracciabili: un cambiamento futuro del testo non invalida né sovrascrive lo storico dei consensi già raccolti. +- La firma passa per l'audit unificato (§2.2). +- Richiede l'Identity Provider (§2.6) per autenticare con certezza chi sta firmando. + +### 2.6 Identity Provider PoliNetwork + +Identity/authentication provider proprio di PoliNetwork, distinto dal login attuale, come punto di ingresso unico per i flussi self-service: + +- autenticazione preventiva obbligatoria prima di qualunque flusso di censimento/onboarding (§8), firma documenti (§2.5) o consultazione delle proprie statistiche/riferimenti (es. Capo Admin di riferimento); +- base per assegnare permessi differenziati in base a cosa la persona fa/è in PoliNetwork — ogni persona ha comunque un livello minimo di accesso alle proprie informazioni; +- precondizione per un futuro accesso esterno multi-tenant (associazioni partner, §12). + +--- + +## 3. Anagrafica Soci e Censimento Admin/Team + +Due registri distinti, coerenti con l'indipendenza delle categorie di §1.2: + +- **Anagrafica Soci**: registro dei **soci attivi e paganti**, con **storico** dei soci passati. Per un socio l'azione ricorrente è il **rinnovo della quota associativa** (§6), non una rilevazione periodica di interesse. +- **Censimento Admin/Team**: rilevazione rivolta ad **admin e membri dei team**, il cui scopo è **rinnovare l'interesse/la disponibilità** a continuare il proprio ruolo — non una quota. Si integra con l'Onboarding (§8). + +Una persona può comparire in entrambi, in uno solo, o in nessuno dei due. + +### 3.1 Anagrafica Soci — campi + +| Blocco | Campi | Note | +|---|---|---| +| Identità | nome, cognome, email, telefono (opzionale) | | +| Identificativo | ID interno, numero associativo univoco | proprietà di questo registro (database PoliNetwork); Azure lo referenzia se presente | +| Stato | attivo pagante, sospeso, scaduto, ex socio | | +| Iscrizione | data ingresso, anno associativo (iscrizione annuale), data scadenza, stato rinnovo | | +| Profilo associativo | corso di studi, anno di corso, sede, competenze/interessi (opzionali) | | +| Consensi | consenso privacy policy, fonte, data, versione firmata, revoca | firma diretta in dashboard, §2.5 | + +Alcuni campi sono obbligatori, altri opzionali (l'elenco puntuale, incluso se serva il codice fiscale, resta da definire). HR può leggere l'Anagrafica Soci; il dettaglio dei permessi granulari campo per campo resta da definire. + +Vincoli: numero associativo univoco; storicizzazione degli stati (non sovrascrittura: i soci scaduti/ex soci restano nello storico); nessuna cancellazione bulk senza anteprima e conferma; ogni lettura/scrittura sensibile passa per l'audit (§2.2). + +Flusso: richiesta/iscrizione → verifica dati → deduplica → firma privacy policy → approvazione → numero socio → collegamento opzionale a Telegram/Azure → rinnovo annuale della quota (§6) → storico. + +### 3.2 Censimento Admin/Team — campi + +Rivolto a chi ha un ruolo organizzativo (Admin, Capo Admin, Direttivo, membro di team), indipendentemente dall'essere anche Socio. + +| Blocco | Campi | Note | +|---|---|---| +| Identità | nome, cognome, email, telefono | | +| Relazioni | ruolo organizzativo (§1.3), team (§7), Capo Admin/responsabile di riferimento | | +| Integrazioni | Telegram ID/username, Azure user ID, ultimo sync | collega senza duplicare | +| Rinnovo interesse | data ultima conferma, prossima scadenza conferma, esito | sostituisce il concetto di "quota" per questa popolazione | +| Consensi | consenso privacy policy, fonte, data, versione firmata | §2.5 | + +Flusso: rilevazione periodica (periodicità da definire, es. legata all'anno accademico) → conferma interesse/disponibilità tramite il flusso di Onboarding/Censimento in dashboard (§8) → aggiornamento stato → storico. + +### 3.3 Permessi + +Creazione/modifica: ruoli con `members.write` (Direttivo/Owner/President inizialmente). Lettura: `members.read`, assegnabile anche a HR in sola lettura. Un operatore può creare un socio o un record del Censimento Admin/Team senza dover prima creare un account Azure. + +--- + +## 4. Governance e Direttivo + +Non verrà realizzata come area dedicata separata. La composizione del Direttivo, il ruolo organizzativo e l'incarico sono coperti dal Censimento Admin/Team (§3.2) e dalla gerarchia ruoli (§1.3). + +--- + +## 5. Dashboard Admin e Capo Admin + +- Vista Capo Admin: elenco degli admin del proprio corso di studi con nome, cognome, anno di corso, data di ingresso, flag rappresentante, altre associazioni di appartenenza, telefono, username/contatto Telegram, link rapido WhatsApp/Telegram. +- Filtri: nome/cognome, anno, rappresentanza, altre associazioni. +- Sezione link ai gruppi Telegram di competenza del Capo Admin. +- Permessi: il Capo Admin vede **solo** i dati e i gruppi del proprio ambito (scoping, §2.1). + +Il modello dati separa il corso personale (Censimento Admin/Team, §3.2) dallo/dagli scope assegnati come Capo Admin (§1.3). + +--- + +## 6. Gestione Soci e Rinnovi + +Il pagamento della quota resta un **bonifico bancario fuori dashboard**; il flusso di verifica del pagamento è in-dashboard: + +- Il socio può caricare la ricevuta del bonifico in dashboard; il caricamento avvia una richiesta di approvazione. +- Il Direttivo/ruolo autorizzato approva la ricevuta caricata, oppure segna il rinnovo come effettuato manualmente se la ricevuta non viene caricata. +- **Ricevuta automatizzata**: quando un rinnovo viene approvato, la dashboard genera e invia automaticamente la ricevuta al socio. +- Per i rinnovi del Direttivo verso l'associazione stessa, la ricevuta viene generata/automatizzata allo stesso modo; quando è richiesta una firma, il flusso notifica il Presidente, che deve firmarla. +- Reminder via email poco prima della scadenza. +- Vista Direttivo sullo stato dei soci: da verificare, ricevuta caricata in attesa di approvazione, pagamento effettuato, pagamento non effettuato. +- Azioni: "Approva ricevuta"/"Segna come pagato" (aggiorna stato + genera ricevuta + email di conferma), "Invia reminder". +- Storico delle azioni (chi ha approvato/segnato pagato, reminder inviati, ricevute generate), tracciato nell'audit (§2.2). +- Resta da decidere se il permesso di segnare come pagato/approvare ricevute sia riservato al solo Direttivo o esteso a un futuro ruolo Finance dedicato. + +--- + +## 7. Aree Team interni + +Ogni team (IT, Design & Social, International, HR, Events & Partnerships, ...) è un'entità del Censimento Admin/Team (§3.2, blocco "Relazioni"), con pagina/area indipendente e permesso dedicato (§2.1). Obiettivo iniziale: struttura, ruoli e separazione degli accessi, non le funzionalità specifiche di ciascun team. + +--- + +## 8. Onboarding e Censimento Admin — flusso self-service in dashboard + +Sia il censimento di nuovi candidati admin, sia il censimento periodico di admin già attivi, avvengono tramite un **flusso automatizzato della dashboard**, attivabile tramite un link o una mail inviata alla persona — non più tramite Telegram e scambio di messaggi manuale. + +- Autenticazione preventiva obbligatoria sull'Identity Provider PoliNetwork (§2.6) prima di poter proseguire nel flusso — identifica la persona e determina il tipo di candidatura/censimento applicabile. +- Una volta autenticato, l'utente accede a un'area personale dove può: firmare i documenti richiesti (§2.5), consultare le proprie statistiche, vedere il proprio Capo Admin di riferimento. +- Permessi differenziati per ruolo: ogni membro di PoliNetwork ha un livello di accesso diverso in base a cosa fa/è, ma tutti hanno accesso a qualcosa nella propria area. +- Richieste che risalgono la gerarchia: un admin può presentare dalla propria area la richiesta di diventare admin di un determinato gruppo, e la richiesta arriva al proprio Capo Admin di riferimento per l'approvazione. + +Ambito: link/mail di attivazione → autenticazione (Identity Provider) → candidatura o conferma censimento periodico → firma documenti → colloquio/approvazione (per i nuovi) → creazione/aggiornamento profilo (Censimento Admin/Team) → assegnazione corso/ruoli/team → passaggi di ingresso operativo. Il dettaglio del processo (candidatura, colloquio, criteri) resta da definire con HR e Team IT. + +--- + +## 9. Email di compleanno + +Riguarda solo i soci. Dipende dall'Anagrafica Soci (data di nascita) e da un motore email. + +--- + +## 10. FAQ pubbliche + +Categorie e CRUD FAQ bilingue IT/EN, ricerca, riordino drag&drop, stato bozza/pubblicata. + +--- + +## 11. Miglioramenti alle aree esistenti + +- **Telegram grants**: storico dei grant terminati/interrotti; reminder sulle scadenze imminenti. +- **Telegram groups**: creazione/import di gruppi dalla dashboard, indicatori di salute (gruppo senza owner, invito rotto), statistiche. +- **Azure**: gestione licenze dalla UI; access review periodico sui gruppi. +- **Guide**: workflow bozza/pubblicazione, anteprima PDF, storico versioni invece di sola sostituzione. + +--- + +## 12. Area Associazioni Partner + +- Accesso e gestione account per decine di associazioni: si può creare l'account a **uno o più referenti** della stessa associazione fin dal MVP, e i referenti possono **nominare un successore trasferendo l'ownership** del proprio account. +- Richieste di pubblicazione nei gruppi Telegram: le associazioni presentano la richiesta dalla propria pagina/area e PoliNetwork approva. Le richieste possono riguardare più gruppi contemporaneamente; la dashboard mostra già l'elenco completo dei gruppi tra cui scegliere. Resta da chiarire se serva anche l'integrazione WhatsApp. +- Gestione della pagina pubblica dell'associazione con flusso di richiesta/approvazione, al posto dell'attuale CRUD diretto di PoliNetwork. +- Eventuale sistema a crediti: logica ancora non definita. +- Eventi delle associazioni / "PoliTamTam" (§13). + +Richiede l'Identity Provider PoliNetwork (§2.6) per l'accesso esterno multi-tenant. + +--- + +## 13. Eventi delle associazioni — PoliTamTam + +Le associazioni partner inseriscono gli eventi dalla propria pagina/area; PoliNetwork può inoltre aggiungere propri eventi, o eventualmente eventi per conto di altre associazioni. Ogni evento richiede approvazione prima di comparire pubblicamente — nessuna pubblicazione diretta. + +--- + +## 14. Area Aziende + +Da progettare in dettaglio prima dello sviluppo. + +--- + +## 15. Area proprietari di casa / Bacheca casa e coinquilini + +Riguarda esclusivamente soggetti esterni (proprietari, cercatori di stanza). + +--- + +## 16. Newsletter + +Dipende dall'Anagrafica Soci (segmentazione destinatari) ed eventualmente dagli eventi (§13) come fonte di contenuti. + +--- + +## 17. Vincoli + +- Nessuna azione distruttiva su più righe senza anteprima e conferma esplicita. +- Minimizzazione dei dati: ogni campo su soci/admin ha uno scopo dichiarato, un responsabile e un'ipotesi di retention; dati sensibili (es. codice fiscale) solo se realmente necessari. +- Audit prima di esporre dati personali a più ruoli. +- Interfaccia amministrativa bilingue IT/EN con preferenza impostabile per singolo utente. + +--- + +## 18. Fuori scope + +- Non ridefinisce lo statuto, gli organi sociali o le regole di voto dell'associazione. +- Non decide se e come integrare un gateway di pagamento (Stripe, altro): il pagamento resta un bonifico bancario eseguito fuori dashboard. È invece in scope la verifica del pagamento in dashboard (upload ricevuta, approvazione, ricevuta automatizzata, §6). +- Non propone una contabilità completa (fatture, bilanci). + +--- + +## 19. Decisioni aperte + +**§1 — Ruoli e gerarchie** +1. Il ruolo "Capo Admin" va modellato come nuovo ruolo Telegram/backend, o come attributo applicativo (scope) sopra il ruolo `admin` esistente, gestito solo lato dashboard? — da decidere. +2. Con quale periodicità viene rinnovato il ruolo di Capo Admin (es. legato all'anno accademico)? + +**§2 — Fondamenta** +3. Il nuovo Identity Provider PoliNetwork (§2.6) sostituisce integralmente l'attuale autenticazione, o si affianca ad essa come livello applicativo sopra le identità Telegram/Azure esistenti? +4. Il consenso privacy raccolto in dashboard (§2.5) sostituisce integralmente i form esterni oggi in uso, o convive con essi durante una fase di transizione? + +**§3 — Anagrafica Soci e Censimento Admin/Team** +5. Quali dati sono realmente necessari per il tesseramento (es. il codice fiscale è richiesto o va escluso)? +6. Un ruolo HR read-only può leggere tutti i campi del socio, o alcuni campi (es. dati di contatto personali) devono essere mascherati anche per HR? +7. Con quale periodicità si svolge il Censimento Admin/Team — es. una volta per anno accademico, o legato a un altro evento? + +**§5 — Dashboard Admin e Capo Admin** +8. Come si definisce "corso di studi" nel sistema (elenco chiuso dei corsi del Politecnico, testo libero, altro)? + +**§6 — Gestione Soci e Rinnovi** +9. Chi ha il permesso di segnare come pagato/approvare ricevute: solo Direttivo, o anche un ruolo Finance dedicato non ancora esistente? + +**§8 — Onboarding e Censimento Admin** +10. Il processo di candidatura/colloquio va definito nel dettaglio con HR e Team IT (criteri, colloquio, tempistiche). + +**§12 — Area Associazioni Partner** +11. Le richieste di pubblicazione riguardano solo Telegram, o resta necessaria anche l'integrazione WhatsApp? +12. Il sistema a crediti per le pubblicazioni resta previsto, e con quale logica di ricarica/consumo? diff --git a/PRD_Classificazione_Feature.md b/PRD_Classificazione_Feature.md new file mode 100644 index 0000000..43b6afb --- /dev/null +++ b/PRD_Classificazione_Feature.md @@ -0,0 +1,49 @@ +# Classificazione feature — Admin Dashboard PoliNetwork + +**Documento collegato:** [`PRD_Admin_Dashboard_PoliNetwork.md`](./PRD_Admin_Dashboard_PoliNetwork.md) +**Versione:** 1.0 +**Data:** 30 agosto 2026 + +## 0. Come leggere questa tabella + +Una riga per ogni sezione principale del PRD (§1–§16). Le sezioni §17–§19 (Vincoli, Fuori scope, Decisioni aperte) sono requisiti trasversali o meta-contenuti, non feature autonome, e non sono classificate. + +- **Priorità** — Low / Medium / High. Criterio guida: gli **strumenti e i dati interni** (anagrafica soci, censimento admin/team, ruoli, governance, team interni) vengono prima delle aree **accessorie** o rivolte a **soggetti esterni** (associazioni partner, aziende, alloggi). Questo riflette esplicitamente l'ordine dato nello Scopo del PRD (§0). +- **Difficoltà** — scala numerica 1–5 (1 = banale, 5 = molto complessa). Tiene conto di: quante parti del sistema tocca, se richiede nuove infrastrutture (es. Identity Provider), se dipende da decisioni ancora aperte (§19 del PRD), se è un flusso multi-step con approvazioni. +- **Dipende da** — altre righe di questa tabella che devono esistere prima (o in parallelo) perché la feature abbia senso. + +--- + +## 1. Tabella di classificazione + +| # | Feature (breve) | Sezione PRD | Priorità | Difficoltà (1-5) | Dipende da | Note | +|---|---|---|---|---|---|---| +| 0 | Identity Provider PoliNetwork | [§2.6 Identity Provider PoliNetwork](./PRD_Admin_Dashboard_PoliNetwork.md#26-identity-provider-polinetwork) · design dedicato: [`IdentityProvider_Design.md`](./IdentityProvider_Design.md) | High | 5 | — | **Primo punto**, prima di tutto il resto. Login proprio non legato a Telegram (già email OTP/passkey); Telegram, affiliazione Politecnico (dominio `@mail.polimi.it`/`@polimi.it` via codice email) e record Socio (claim via codice) sono tre collegamenti indipendenti sulla stessa identità, nessuno implica gli altri; RBAC indipendente da Telegram; base SSO via OIDC per **sito pubblico** (primo consumer reale, usato dagli studenti), polinet.cc e futuri servizi. Sblocca #2, #8, #12 e il sito pubblico. | +| 1 | Ruoli e gerarchia | [§1 Persone, ruoli e gerarchie](./PRD_Admin_Dashboard_PoliNetwork.md#1-persone-ruoli-e-gerarchie) | High | 4 | #0 | Modello dati di base: senza questo, RBAC granulare (§2.1) e scoping Capo Admin (§5) non hanno fondamenta. | +| 2 | Fondamenta piattaforma (resto) | [§2 Fondamenta](./PRD_Admin_Dashboard_PoliNetwork.md#2-fondamenta) | High | 4 | #0, #1 | RBAC per capacità, audit unificato, ricerca globale, home operativa, consensi/firma privacy — l'Identity Provider (§2.6) è ora #0 a parte per priorità e complessità proprie. | +| 3 | Anagrafica soci e censimento | [§3 Anagrafica Soci e Censimento Admin/Team](./PRD_Admin_Dashboard_PoliNetwork.md#3-anagrafica-soci-e-censimento-adminteam) | High | 4 | #0, #1, #2 | Due registri distinti ma con permessi e audit condivisi; è il cuore dei dati interni citato nello Scopo del PRD. | +| 4 | Governance/Direttivo | [§4 Governance e Direttivo](./PRD_Admin_Dashboard_PoliNetwork.md#4-governance-e-direttivo) | Low | 1 | #3 | Esplicitamente non un'area dedicata: già coperta da §3.2 e §1.3, nessuno sviluppo aggiuntivo previsto. | +| 5 | Vista Capo Admin | [§5 Dashboard Admin e Capo Admin](./PRD_Admin_Dashboard_PoliNetwork.md#5-dashboard-admin-e-capo-admin) | High | 3 | #1, #3 | Strumento operativo interno quotidiano per una figura chiave (Capo Admin); richiede lo scoping di §2.1. | +| 6 | Rinnovi e pagamenti soci | [§6 Gestione Soci e Rinnovi](./PRD_Admin_Dashboard_PoliNetwork.md#6-gestione-soci-e-rinnovi) | High | 4 | #3 | Flusso ricorrente più frequente sull'Anagrafica Soci (upload ricevuta, approvazione, ricevuta automatica, reminder). | +| 7 | Aree team interni | [§7 Aree Team interni](./PRD_Admin_Dashboard_PoliNetwork.md#7-aree-team-interni) | Medium | 2 | #3 | Obiettivo iniziale è solo struttura/permessi, non le funzionalità specifiche di ogni team: scope volutamente ridotto per ora. | +| 8 | Onboarding self-service | [§8 Onboarding e Censimento Admin](./PRD_Admin_Dashboard_PoliNetwork.md#8-onboarding-e-censimento-admin---flusso-self-service-in-dashboard) | High | 5 | #0, #2, #3 | Flusso multi-step (auth → firma → colloquio → assegnazione ruoli) che dipende dall'Identity Provider (#0). | +| 9 | Email di compleanno | [§9 Email di compleanno](./PRD_Admin_Dashboard_PoliNetwork.md#9-email-di-compleanno) | Medium | 2 | #3 | Interna e legata all'Anagrafica Soci, ma isolata e non bloccante: buon candidato "quick win" dopo §3. | +| 10 | FAQ pubbliche | [§10 FAQ pubbliche](./PRD_Admin_Dashboard_PoliNetwork.md#10-faq-pubbliche) | Low | 2 | — | Contenuto rivolto all'esterno, CRUD semplice e indipendente dal resto. | +| 11 | Miglioramenti aree esistenti | [§11 Miglioramenti alle aree esistenti](./PRD_Admin_Dashboard_PoliNetwork.md#11-miglioramenti-alle-aree-esistenti) | Medium | 3 | — | Telegram/Azure/Guide sono già in produzione: sono incrementi su strumenti interni esistenti, non nuove fondamenta. | +| 12 | Area associazioni partner | [§12 Area Associazioni Partner](./PRD_Admin_Dashboard_PoliNetwork.md#12-area-associazioni-partner) | Low | 5 | #0 (Identity Provider, accesso multi-tenant) | Primo accesso esterno multi-tenant: gestione referenti/ownership, richieste di pubblicazione, eventuale sistema a crediti (logica non definita). | +| 13 | Eventi PoliTamTam | [§13 Eventi delle associazioni — PoliTamTam](./PRD_Admin_Dashboard_PoliNetwork.md#13-eventi-delle-associazioni--politamtam) | Low | 3 | #12 | Flusso di inserimento/approvazione eventi, ha senso solo dopo che le associazioni hanno un'area propria. | +| 14 | Area aziende | [§14 Area Aziende](./PRD_Admin_Dashboard_PoliNetwork.md#14-area-aziende) | Low | — | — | Da progettare in dettaglio: nessuna difficoltà stimabile finché non esiste uno scope. | +| 15 | Bacheca casa | [§15 Area proprietari di casa / Bacheca casa e coinquilini](./PRD_Admin_Dashboard_PoliNetwork.md#15-area-proprietari-di-casa--bacheca-casa-e-coinquilini) | Low | 3 | — | Esclusivamente rivolta a soggetti esterni, nessuna dipendenza da dati interni PoliNetwork. | +| 16 | Newsletter | [§16 Newsletter](./PRD_Admin_Dashboard_PoliNetwork.md#16-newsletter) | Low | 2 | #3, opz. #13 | Accessoria: dipende dalla segmentazione dell'Anagrafica Soci e facoltativamente dagli eventi come fonte contenuti. | + +--- + +## 2. Lettura rapida per fase + +**Prima fase — fondamenta interne (High):** #0 Identity Provider PoliNetwork → #1 Ruoli e gerarchia → #2 Fondamenta piattaforma (resto) → #3 Anagrafica soci e censimento → #6 Rinnovi e pagamenti → #5 Vista Capo Admin → #8 Onboarding self-service. + +**Seconda fase — consolidamento interno (Medium):** #7 Aree team interni, #9 Email di compleanno, #11 Miglioramenti aree esistenti. + +**Terza fase — accessorie ed esterne (Low):** #10 FAQ pubbliche, #16 Newsletter, #12 Area associazioni partner, #13 Eventi PoliTamTam, #14 Area aziende, #15 Bacheca casa. + +Questo ordine ricalca l'indicazione dello Scopo del PRD (§0): le funzionalità interne hanno priorità sulle aree pensate per soggetti esterni. diff --git a/RBAC_Ruoli_Permessi.md b/RBAC_Ruoli_Permessi.md new file mode 100644 index 0000000..fb84ce1 --- /dev/null +++ b/RBAC_Ruoli_Permessi.md @@ -0,0 +1,98 @@ +# Ruoli e permessi — Admin Dashboard PoliNetwork + +**Documenti collegati:** [`PRD_Admin_Dashboard_PoliNetwork.md`](./PRD_Admin_Dashboard_PoliNetwork.md) §1, §2.1 · [`IdentityProvider_Design.md`](./IdentityProvider_Design.md) §4 (RBAC) +**Versione:** 1.0 +**Data:** 30 agosto 2026 +**Esclusioni:** pagine di caricamento annunci (§15 Bacheca casa e coinquilini) — assumo sia questo il riferimento; segnalamelo se intendevi altro. + +## 0. Principio + +Non ruoli monolitici, ma **capacità granulari per modulo** (lettura/scrittura/approvazione), come richiesto dal PRD §2.1. I "ruoli" qui sotto sono **preset** di capacità pensati per velocizzare l'assegnazione — restano assegnabili anche singolarmente e in combinazione libera (es. Content Editor + Telegram Moderator, esempio già citato nel PRD). Nessun ruolo è esclusivo: una persona può averne più di uno. + +Due famiglie di ruoli: +- **Ruoli di gerarchia** (§1.3 del PRD) — legati alla posizione organizzativa, ampiezza dei permessi decrescente. +- **Ruoli funzionali** — legati a una competenza/team, indipendenti dalla gerarchia, combinabili liberamente. + +--- + +## 1. Catalogo capacità (per pagina/modulo) + +| Capacità | Pagine coperte | Livelli | +|---|---|---| +| `members` | Anagrafica Soci (§3.1) | read / write | +| `members.sensitive` | Campi sensibili anagrafica (contatti personali, eventuale codice fiscale) | read / write — sotto-permesso di `members`, non implicito | +| `admin_census` | Censimento Admin/Team (§3.2) | read / write | +| `capoadmin_view` | Vista Capo Admin (§5) | read, **sempre scoped** al proprio corso/ambito | +| `renewals` | Gestione Soci e Rinnovi (§6): coda ricevute, approvazione, reminder | read / approve | +| `teams` | Aree Team interni (§7) | read / write, **scoped** al team | +| `onboarding` | Onboarding self-service, richieste in ingresso (§8) | read / approve | +| `telegram.users` | Telegram → Users (esistente) | read / write | +| `telegram.groups` | Telegram → Groups (esistente) | read / write | +| `telegram.grants` | Telegram → Grants (esistente) | read / write | +| `azure.groups` | Azure → Groups (esistente) | read / write | +| `azure.members` | Azure → Members / licenze (esistente) | read / write | +| `content.guides` | Web → Guides (esistente, + workflow bozza/pubblicazione §11) | read / write / publish | +| `content.faq` | FAQ pubbliche (§10) | read / write / publish | +| `content.projects` | Web → Projects (esistente) | read / write | +| `associations.accounts` | Gestione account/referenti associazioni partner (§12) | read / write | +| `associations.requests` | Approvazione richieste pubblicazione e pagina pubblica associazioni (§12) | read / approve | +| `events.politamtam` | Approvazione eventi PoliTamTam (§13) | read / approve | +| `companies` | Area Aziende (§14) — placeholder, da definire con lo scope | read / write | +| `newsletter` | Composizione/invio newsletter (§16) | write / send | +| `audit.read` | Log di audit (§2.2) | read | +| `rbac.manage` | Assegnazione capacità dirette, scope Capo Admin, ruoli di gerarchia | write — **la capacità più sensibile, richiede sempre conferma esplicita** | +| `membership.self` | Propria scheda in Anagrafica Soci: dati, storico, stato rinnovo (§3.1) | read (solo il proprio record) | +| `membership.self.renew` | Caricamento propria ricevuta di bonifico, stato della propria richiesta di rinnovo (§6) | write (solo sul proprio record) | +| `membership.self.consents` | Firma/consultazione dei propri consensi privacy (§2.5) | read / write (solo i propri) | + +Non hanno una capacità dedicata: **Home/Overview** e **Account personale** — sempre accessibili a chiunque abbia un'identità autenticata, indipendentemente dalle capacità possedute (ognuno vede sempre qualcosa di suo, come richiesto dal PRD §8). + +--- + +## 2. Ruoli di gerarchia (§1.3 del PRD) + +| Ruolo | Capacità di default | Note | +|---|---|---| +| **Owner** | Tutte, incluso `rbac.manage` | Unico livello con pieno controllo su chi ha accesso a cosa. | +| **Direttivo** | Tutte tranne `rbac.manage` | Accesso e scrittura completi come da PRD §1.1; l'assegnazione di capacità dirette resta riservata a Owner (o delegabile, §19 punto 4 del design IdP). | +| **Presidente** | Come Direttivo | Più la firma esplicita dei rinnovi Direttivo→associazione quando richiesta (§6). | +| **Capo Admin** | `capoadmin_view` (scoped), `admin_census` read (scoped), `telegram.groups`/`telegram.users` read (scoped ai gruppi di competenza), `onboarding` approve (solo per richieste che risalgono a lui, §8) | Tutto **scoped** al proprio corso/ambito — mai visibilità globale. | +| **Admin (operativo)** | Solo Account personale + propria area Onboarding | Nessuna capacità di lettura/scrittura su altri moduli finché non riceve capacità funzionali aggiuntive. | +| **HR** | `members` read, `admin_census` **read/write**, `onboarding` **read/write (approve)** | Scrittura su Censimento Admin/Team e su Onboarding (colloqui, candidature — coerente con PRD §8, dove il processo di candidatura va definito "con HR e Team IT"). Resta **sola lettura** sull'Anagrafica Soci, come esplicitamente richiesto dal PRD §3.3 — il dettaglio su `members.sensitive` resta comunque una decisione aperta (PRD §19 punto 6). | +| **Socio** | `membership.self`, `membership.self.renew`, `membership.self.consents` | **Non è un livello della gerarchia amministrativa**: è l'asse indipendente definito dal PRD §1.2. Lo includo qui perché, in termini di accesso alla dashboard, un Socio senza alcun ruolo admin ha comunque capacità concrete e proprie (vedere la propria scheda, caricare la ricevuta di rinnovo, firmare i consensi) — più di un Admin operativo "nudo" senza capacità funzionali aggiuntive. Una persona può essere Socio e Admin insieme: le capacità si sommano, non si sostituiscono (§1.2 del PRD). | + +`creator` (ruolo Telegram) resta escluso da qualunque accesso dashboard, come già specificato nel PRD §1.1 — non compare qui perché non è un ruolo dashboard. + +--- + +## 3. Ruoli funzionali (indipendenti dalla gerarchia, combinabili) + +| Ruolo | Capacità | Tipicamente assegnato a | +|---|---|---| +| **Content Editor** | `content.guides` write/publish, `content.faq` write/publish, `content.projects` write, `newsletter` write | Team Design & Social | +| **Telegram Moderator** | `telegram.users` write, `telegram.groups` write, `telegram.grants` write | Team IT / admin operativi con delega specifica | +| **Azure Manager** | `azure.groups` write, `azure.members` write | Team IT | +| **Membership Officer** ("Finance", PRD §19 punto 9) | `renewals` approve | Direttivo di default; ruolo dedicato se PoliNetwork decide di scorporarlo (decisione ancora aperta nel PRD) | +| **Team Lead** | `teams` write, **scoped al proprio team** | Responsabile di uno dei team interni (IT, Design & Social, International, HR, Events & Partnerships) | +| **Association Liaison** | `associations.accounts` write, `associations.requests` approve, `events.politamtam` approve | Team Events & Partnerships | +| **Onboarding Reviewer** | `onboarding` approve (non scoped) | Direttivo/HR per i colloqui, o delegabile | +| **Auditor** | `audit.read` | Direttivo/Owner di default; assegnabile a chi deve verificare la conformità senza avere capacità di scrittura altrove | + +--- + +## 4. Regole trasversali + +- **Conferma esplicita obbligatoria** (PRD §2.1) su ogni azione ad alto impatto: cancellazioni, assegnazione/revoca ruoli, rimozione da gruppi, export dati personali, qualunque uso di `rbac.manage`. +- **Scoping**: `capoadmin_view`, `admin_census` (per Capo Admin) e `teams` (per Team Lead) non sono mai capacità globali — portano sempre un `scopeType`/`scopeValue` (corso, team). Questo è già il modello dati proposto in `IdentityProvider_Design.md` §4. +- **Nessuna capacità implica le altre**: avere `members` non dà `members.sensitive`; avere `teams` su un team non dà visibilità sugli altri team; avere `content.guides` non dà `content.faq`. Le combinazioni vanno assegnate esplicitamente. +- **Le capacità `self`** (`membership.self*`) sono strutturalmente diverse dalle altre: non richiedono un `rbac.manage` per essere assegnate, derivano automaticamente dal collegamento dell'identità al proprio record Socio (claim tramite codice, `IdentityProvider_Design.md` §3) — chiunque abbia claim-ato un tesseramento le ottiene sul proprio record, mai su quello di altri. +- **Audit obbligatorio** prima di esporre dati personali a più ruoli (PRD §17) — vale in particolare per `members.sensitive` e `admin_census`. + +--- + +## 5. Cosa resta da decidere con voi + +1. `members.sensitive` — quali campi rientrano davvero (codice fiscale sì/no è ancora aperto nel PRD, §19 punto 5) e se HR li vede o restano mascherati anche per HR (PRD §19 punto 6). +2. Se "Membership Officer/Finance" diventa un ruolo reale distinto o resta capacità del solo Direttivo (PRD §19 punto 9). +3. Se `onboarding` approve per le candidature nuove (non i rinnovi di interesse) richiede un ruolo dedicato (es. HR + un membro del Direttivo insieme) invece che essere una capacità singola. +4. Se `companies` (Area Aziende, §14) merita un ruolo funzionale proprio — dipende dallo scope, ancora da progettare.