costi-ricorrenti.md: §4 diviso in spese legate a un requisito in attesa di risposta del cliente e spese facoltative, senza toccare cifre. architettura.md: tolta l'indicazione che D11 avesse deciso le ore di manutenzione dal secondo anno, mai decise. Riformulato in tono più formale il documento di domande per il cliente, non ancora inviato. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
20 KiB
Architettura del software
Progetto: Gestionale per enti del Terzo Settore
Documento: architettura.md
Versione: 0.4.4 · Data: 27/09/2026 · Stato: Bozza, proposta da confermare; uso interno
Allineato a: richiesta.md v0.4 · Schema di versione: vedi indice-documenti.md
Cosa contiene: come si costruisce il software: forma dell'applicazione, componenti, dati, permessi, stack, sicurezza, infrastruttura e rilascio. I requisiti non si ripetono: si citano con il codice. Servizi e prezzi di riferimento sono in costi-ricorrenti.md, le scelte ancora aperte (B) in domande-cliente.md §3, l'ordine di realizzazione in blueprint.md.
Le proposte 🔸 di questo documento diventano decisioni (Dn in richiesta.md §7) quando Davide le approva.
1. Vincoli di partenza
Ogni scelta dei paragrafi successivi nasce da uno di questi vincoli.
| Vincolo | Da dove | Conseguenza per l'architettura |
|---|---|---|
| Un solo sviluppatore (Davide, con Claude) | Contesto di progetto | Poche parti in movimento: un'applicazione, un database, strumenti maturi e documentati |
| Budget vincolato e rendicontabile (bando) | Contesto di progetto | Solo software open source senza licenze; servizi a pagamento solo dove li impone la legge o un requisito (firma, marca, conservazione) |
| Circa 100 utenti, uso da gestionale d'ufficio | RT-11 (⏳ Q1) | Un server per ambiente basta; nessuna scalabilità orizzontale |
| Applicazione web da computer | RT-12 | Un'unica interfaccia web; nessuna app, nessun adattamento a smartphone |
| Ogni ente vede solo i propri dati | RT-1, RT-2, D2 | Separazione per ente nell'applicazione e nel database (§4) |
| PostgreSQL e migrazioni | ✅ D12, RT-16 | Struttura dei dati modificata solo con migrazioni versionate (§4, §8) |
| Hosting nell'UE | RT-13 | Server e servizi esterni con dati nell'UE |
| Servizi trasferibili al cliente a fine primo anno | RT-15, D10, D11 | Configurazione descritta nel repository, fornitori che trasferiscono account, nessun servizio difficile da spostare |
| Valore probatorio dei libri sociali | RF-4.5–4.7, RT-9 | Documenti archiviati non modificabili; registro delle operazioni |
| Dati personali di molte persone, antiriciclaggio, possibili dati art. 9 | richiesta.md §5, RT-10 |
Privacy by design (§7) |
2. Forma dell'applicazione 🔸 (B2.6)
2.1 Proposta
Un'unica applicazione web (monolite modulare) con pagine generate dal server e interattività leggera nel browser, un solo database PostgreSQL e un processo in background per i lavori lenti o pianificati.
- I moduli M1–M9 sono parti separate dello stesso codice e comunicano con chiamate interne, non attraverso la rete.
- Il processo in background invia le email, chiede firme e marche temporali, genera i PDF e importa i file; il pianificatore lancia alert e solleciti (§3).
2.2 Perché
- RT-11: con circa 100 utenti un'applicazione su un server regge il carico; nessuna parte deve crescere separatamente dalle altre.
- Un solo sviluppatore: un linguaggio, un rilascio, un registro degli errori.
- Natura dei moduli: schede, tabelle, procedure guidate (RF-6.1, RF-7.1) e flussi di approvazione (RT-3). Non c'è interattività da applicazione (modifica contemporanea, uso offline) che giustifichi un'applicazione browser separata.
- RT-15: un'applicazione sola si documenta e si consegna più facilmente.
Eccezione da tenere d'occhio: se Q19 ha risposta (c) (ente e studio lavorano insieme sullo stesso documento), le pagine di M6 e M7 richiedono la modifica contemporanea in tempo reale. La forma dell'applicazione resta la stessa, ma serve un componente in più, da stimare a parte (B1.2).
2.3 Alternative scartate
| Alternativa | Perché no |
|---|---|
| Microservizi (un servizio per modulo) | Nessun requisito di scalabilità separata; moltiplica rilasci, monitoraggio e punti di guasto per un solo sviluppatore |
| Applicazione browser separata (SPA) + API | Due applicazioni da sviluppare, versionare e consegnare; nessuna app mobile (RT-12) né API per terzi richieste |
| Funzioni serverless | Firma, importazione e PDF sono lavori con stato e tentativi ripetuti, più semplici con un processo sempre attivo; legano a un fornitore (RT-15) |
| Un database per ente | La separazione (RT-1) si ottiene nello stesso database con la row-level security (D12); più database moltiplicano migrazioni (RT-16) e backup |
Non si prepara nulla "per il futuro" (es. più studi sulla stessa piattaforma): D2 prevede un solo studio. Se cambiasse, sarebbe una nuova versione dei requisiti.
3. Componenti comuni
Servono a più moduli e si costruiscono una volta sola (pacchetti P2 e P3 di blueprint.md).
| Componente | Cosa fa | Requisiti | Scelta |
|---|---|---|---|
| Accesso | Login, seconda verifica con codice da app (TOTP), recupero password via email. Il referente dell'ente riceve un link di attivazione a scadenza, mai una password per email (W1 passo 6) | RT-2, RT-10 | 🔸 Seconda verifica obbligatoria per lo studio (vede tutti gli enti), consigliata per gli enti |
| Ruoli e permessi | Chi può fare quale azione su quale ente (§5) | RT-1, RT-2 | 🔸 |
| Flusso di approvazione | Un solo componente a stati per M4, M5 (chiusura annuale), M6 e M7: ammette solo i passaggi di stato previsti e li registra tutti | RT-3; W4, W5, W6, W8 | 🔸 B2.4 |
| Procedura guidata a sezioni | Compilazione per sezioni, salvataggio di ogni sezione, ripresa del lavoro | RF-5.7, RF-6.1, RF-7.1 | 🔸 |
| Notifiche | Un solo servizio: scrive la notifica nell'app, mette in coda l'email, registra la lettura. Email senza dati personali, solo un link all'applicazione (§7) | RT-4, RF-8.2 | 🔸 B2.3 |
| Pianificatore | Alert sulle scadenze di pagamento, alert per il caricamento dei documenti, solleciti | RF-1.9, RF-5.1; W2, W5 | 🔸 |
| Lavori in background | Esegue i lavori lenti. Se un fornitore non risponde, riprova con attese crescenti e lascia il documento in uno stato esplicito (es. "in attesa di firma"), mai a metà | RT-5–RT-8 | 🔸 |
| Firma elettronica | Componente sostituibile: firma simulata in sviluppo, sandbox del fornitore negli ultimi 40 giorni, fornitore reale in produzione (costi-ricorrenti.md §3, nota 3) |
RT-5 (⏳ Q4) | ✅ Firma simulata in sviluppo; fornitore: B1.4 |
| Marca temporale e conservazione | Marca via API sull'impronta del documento. La conservazione digitale è richiesta da [D]: a norma presso un conservatore se Q9 lo richiede, altrimenti archivio interno con marca temporale | RT-6 (⏳ Q9) | B1.4; ⚖️ C4, C6 |
| Generazione documenti | PDF da modelli HTML per ciò che si stampa (offerte, proforma, libri, verbali, Modello D); Word modificabile per progetti e relazioni, a partire dai modelli del cliente | RT-7, RF-5.7, RF-6.3 (⏳ Q13) | 🔸 Librerie open source dello stack (§6) |
| Importazione | Excel (🔸 anche CSV, formato non citato nelle fonti) con mappatura delle colonne salvata per ente e banca, riusata nei trimestri successivi; controllo riga per riga con l'elenco degli errori, nessuna riga scartata in silenzio; il PDF resta un allegato | RT-8, RF-5.2–5.3 (⏳ Q10) | 🔸 B1.3 |
| Registro delle operazioni | Chi, cosa, quando, valore prima e dopo, per i dati con valore probatorio e per i dati personali; l'applicazione non lo può modificare | RT-9 | 🔸 B2.5; anche la consultazione dei dati antiriciclaggio (⚖️ C3) |
| Archivio file | Documenti caricati e generati, fuori dalla cartella dell'applicazione e compresi nei backup; antivirus sui file caricati dagli enti | RT-8, RT-10, RT-15 | 🔸 |
| Tabelle di configurazione | Valori che lo studio cambia senza sviluppo: catalogo servizi, voci del Modello D, calendario delle scadenze con eccezioni per ente, tariffe orarie del volontariato | RF-1.1, RF-5.1, RF-5.5, RF-9.3 | 🔸 B2.2 |
4. Dati
| Tema | Scelta | Perché |
|---|---|---|
| Database | ✅ PostgreSQL, struttura modificata solo con migrazioni | D12, RT-16 |
| Separazione per ente | ✅ Colonna dell'ente su ogni tabella con dati di un ente, più row-level security: il database rifiuta le righe di altri enti anche se l'applicazione sbaglia un filtro. 🔸 L'applicazione imposta l'ente dell'utente all'inizio di ogni transazione e si collega con un utente del database che non è proprietario delle tabelle e non può ignorare la row-level security (altrimenti la protezione non si applica) | RT-1, D12, B2.1 |
| Persone | 🔸 Una scheda per persona con più ruoli; libro soci e registro volontari fanno riferimento alla scheda | RF-3.3, W3 |
| Documenti archiviati | 🔸 Nessuna modifica né cancellazione dopo l'archiviazione, bloccata anche nel database (un trigger rifiuta le modifiche alle righe archiviate); correzioni e cessazioni sono nuove voci collegate | W4 passi 5 e 7, RT-9 |
| Nuove categorie o campi | Con una migrazione | RF-3.2, D12 |
| Cancellazione di dati personali | Gli utenti si disattivano, non si cancellano: il registro deve poter dire chi ha fatto cosa. Tempi di conservazione degli altri dati personali: ⚖️ C1, C3 | RT-9, RT-10 |
| Dati in test | Solo dati finti, mai copie della produzione | RT-10 |
5. Ruoli e permessi
- Due tipi di utente (D1): studio (interno), che vede tutti gli enti, ed ente (esterno), legato 🔸 a un solo ente (RT-1).
- Permessi per azione, non solo per modulo: vedere, creare, modificare, inviare in revisione, approvare. Chi fa cosa deriva dalla colonna "Operatore" di [X] e dalle colonne "Chi inserisce" e "Chi controlla" di
richiesta.md§2; il dettaglio passo per passo è nella colonna "Chi" diworkflow.md. - 🔸 Tra gli utenti dello studio, un ruolo di amministratore crea e disattiva gli utenti (W1 passo 6).
flowchart TD
U[Richiesta di un utente autenticato] --> T{Tipo di utente}
T -->|studio| S[Tutti gli enti]
T -->|ente| E[Solo il proprio ente<br/>filtro dell'applicazione + row-level security]
S --> P{Azione permessa<br/>a questo utente?}
E --> P
P -->|sì| OK[Eseguita e registrata<br/>RT-9]
P -->|no| KO[Rifiutata]
6. Stack applicativo ⏳ B1.10
Linguaggio e framework non sono ancora scelti. Qui ci sono i criteri, ricavati dai requisiti, e il confronto.
6.1 Criteri
| Criterio | Da dove |
|---|---|
| Framework "completo": accesso, permessi, migrazioni, coda, pianificatore, email e validazione dei moduli già inclusi | RT-2, RT-4, RT-16, RF-1.9, RF-5.1; un solo sviluppatore |
| Supporto maturo a PostgreSQL e alla row-level security | D12, RT-1 |
| Librerie open source per PDF, Word ed Excel | RT-7, RT-8; budget |
| Diffusione: chi subentra (il cliente, un altro sviluppatore) deve trovare competenze | RT-15; rischio di dipendenza da una sola persona |
| Conoscenza di Davide | Controllare con competenza il codice scritto con Claude |
6.2 Confronto
| Laravel (PHP) | Django (Python) | |
|---|---|---|
| Accesso, permessi, migrazioni | Inclusi | Inclusi (i permessi sul singolo record richiedono una libreria) |
| Coda e pianificatore | Inclusi; la coda può usare PostgreSQL | Con librerie aggiuntive (alcune usano PostgreSQL, altre Redis) |
| Notifiche nell'app con stato di lettura (RF-8.2) | Incluse (notifiche salvate nel database) | Da sviluppare o con una libreria |
| Pannello per le tabelle di configurazione (§3) | Con una libreria open source (es. Filament) | Incluso (admin di Django) |
| PDF / Word / Excel | dompdf o Chrome headless / PHPWord / PhpSpreadsheet | WeasyPrint / python-docx o docxtpl / openpyxl |
| Pagine dal server con interattività leggera | Blade + Livewire | Template + htmx |
| Row-level security | Ente impostato a ogni transazione | Stesso meccanismo |
Rails, .NET e Node.js possono coprire gli stessi requisiti; il confronto si limita alle due opzioni più aderenti ai criteri del §6.1 e si estende se Davide conosce uno di questi stack.
Orientamento 🔸: sui requisiti Laravel e Django si equivalgono; decide la conoscenza di Davide, perché nel controllo del codice conta più di qualunque differenza tecnica. A parità di conoscenza, Laravel ha un piccolo vantaggio: coda, pianificatore e notifiche con stato di lettura sono inclusi, quindi ci sono meno componenti da scegliere, aggiornare e consegnare.
In entrambi i casi:
- 🔸 niente Redis: con circa 100 utenti coda e cache sul database bastano, e c'è un servizio in meno da gestire, salvare e trasferire (RT-15). Si aggiunge solo se le misure in produzione lo richiedono;
- nessun adattamento a smartphone (RT-12).
7. Sicurezza e privacy by design
Per ogni misura: cosa protegge e da quale requisito nasce. ⚖️ Le misure finali dipendono dalle verifiche C1, C2, C3 e C13 (valutazione d'impatto, da chiudere prima dello sviluppo).
| Misura | Cosa protegge | Rif. |
|---|---|---|
| HTTPS su tutto | Dati in transito | RT-10 |
| Seconda verifica all'accesso (§3) | Account dello studio, che vede tutti gli enti | RT-1, RT-10 |
| Row-level security (§4) | Dati di un ente dagli utenti di un altro, anche con un errore nel codice | RT-1 |
| Limite ai tentativi di accesso, sessioni a scadenza | Accessi non autorizzati | RT-10 |
Backup cifrati, con una copia fuori dal server (costi-ricorrenti.md §3, nota 5) |
Perdita o furto dei dati | RT-10, RT-15 |
| 🔸 Documenti d'identità antiriciclaggio cifrati nell'archivio | Dati antiriciclaggio | ⚖️ C3 |
| Email, notifiche e log senza dati personali, solo link | Dati che escono dal sistema | RT-4, RT-10 |
Monitoraggio degli errori in regione UE, con i dati personali filtrati prima dell'invio (costi-ricorrenti.md §3, nota 6) |
Dati personali contenuti negli errori | RT-10, RT-13 |
| Antivirus sui file caricati | Server e utenti dello studio | RT-8 |
| Test con dati finti ed email intercettate | Persone reali durante i test | RT-10 |
| Registro delle operazioni (§3) | Valore probatorio, controllo degli accessi | RT-9 |
| 🔸 Misure aggiuntive per i possibili dati art. 9 | Categorie particolari di dati | ⚖️ C2 |
| Aggiornamenti di sicurezza di sistema e librerie | Vulnerabilità note | RT-10; dal secondo anno rientra nel contratto di manutenzione separato (D11), termini e ore non ancora decisi |
8. Infrastruttura e rilascio
8.1 Ambienti
Sviluppo, test e produzione come in costi-ricorrenti.md §1, dove sono anche servizi e dimensioni di riferimento.
🔸 B2.7: un server per ambiente, con applicazione, database e processo in background in container descritti nel repository (Docker Compose).
- RT-16: test e produzione hanno la stessa configurazione, quindi le migrazioni si applicano identiche.
- RT-15: chi riceve i servizi ricrea l'ambiente dalla configurazione del repository, senza istruzioni a memoria.
- Perché non servizi cloud gestiti (database gestito, container gestiti): con 100 utenti non servono, costano di più con importi meno prevedibili (budget del bando) e legano al fornitore.
- Perché non Kubernetes: serve a coordinare molti server; qui ce n'è uno per ambiente.
8.2 Ciclo di rilascio
flowchart LR
A[Sviluppo] --> B[Invio al repository]
B --> C[Test automatici]
C -->|falliti| A
C -->|superati| D[Rilascio in test<br/>con le migrazioni]
D --> E[Collaudo]
E -->|problemi| A
E -->|ok| F[Backup della produzione]
F --> G[Rilascio in produzione<br/>con le stesse migrazioni]
G --> H[Verifica dopo il rilascio]
H -->|errore| I[Ripristino della versione<br/>precedente e del backup]
H -->|ok| J[Rilascio concluso]
- Repository e rilascio automatico sul server Git di Davide (
costi-ricorrenti.md§3, nota 2). - Nessuna correzione a mano in produzione: un errore si corregge con un nuovo rilascio o con il ripristino (RT-16).
- 🔸 Prova di ripristino del backup su un ambiente separato, almeno una volta a trimestre: un backup mai provato non dà garanzie.
- Monitoraggio di errori e disponibilità:
costi-ricorrenti.md§3. - Le procedure operative (rilascio, ripristino, fornitore che non risponde) si scrivono quando lo stack è scelto: fanno parte del documento di consegna richiesto da RT-15 (P16 in
blueprint.md).
9. Moduli e componenti
| Modulo | Componenti del §3 | Servizi esterni |
|---|---|---|
| M1 Gestione cliente | Generazione documenti, firma, pianificatore, notifiche, configurazione (catalogo) | Firma, email |
| M2 Anagrafica enti | Registro delle operazioni | — |
| M3 Anagrafica stakeholder | Registro delle operazioni | — |
| M4 Libri sociali | Flusso di approvazione, firma (⏳ Q4), marca, conservazione (⏳ Q9), generazione documenti | Firma, marca, conservazione |
| M5 Contabilità | Importazione, pianificatore, configurazione (Modello D, calendario), procedura guidata, flusso di approvazione, generazione documenti | |
| M6 Progettazione | Procedura guidata, flusso di approvazione (⏳ Q19), generazione Word (⏳ Q13) | — |
| M7 Rendicontazione sociale | Procedura guidata che legge i dati di M2, M3 e M5 (RF-7.2), flusso di approvazione, generazione documenti | — |
| M8 Circolari | Notifiche con stato di lettura | |
| M9 Valutazione volontariato | Configurazione (tariffe, ⏳ Q15) | — |
10. Fuori perimetro
Per evitare aggiunte non richieste durante lo sviluppo:
- app per smartphone e adattamento a schermi piccoli (RT-12);
- motore di flussi configurabile dall'utente: un solo flusso a stati nel codice (RT-3);
- firma, marca e conservazione costruite in proprio: servono fornitori qualificati (B1.4, ⚖️ C4);
- lettura automatica dei PDF finché Q10 non la chiede (B1.3);
- fattura elettronica sviluppata da zero (B1.5, ⏳ Q5);
- importazione di dati esistenti all'avvio (RT-14);
- più lingue, più studi sulla stessa piattaforma (D2), API per terzi: nessun requisito.
11. Cosa può cambiare l'architettura
| Punto aperto | Effetto |
|---|---|
| Q1 numero di enti | Dimensione del server di produzione e spazio disco (costi-ricorrenti.md §4) |
| Q4 tipo di firma | Implementazione del componente di firma |
| Q9, ⚖️ C6 conservazione | Conservatore con o senza API; un archivio o uno per ente; eventuale passo manuale in W4 |
| Q10 estratti conto PDF | Componente di lettura dei PDF |
| Q5 fattura elettronica | Integrazione con un servizio esterno |
| Q13 schema dei progetti | Struttura dei dati di M6 e formato di esportazione |
| Q19 risposta (c) | Modifica contemporanea in tempo reale per M6 e M7 (§2.2) |
| ⚖️ C2, C13 | Misure di sicurezza aggiuntive (§7) |
Registro delle modifiche
| Versione | Data | Allineato a | Modifiche |
|---|---|---|---|
| 0.4 | 27/09/2026 | richiesta.md v0.4 |
Prima stesura, ricostruita da architettura.md e dai §5–6 di flussi-di-lavoro.md della cartella software.old (24/09/2026). Rispetto all'originale: lo stack passa da scelta fatta a confronto con orientamento (B1.10); codici allineati al repository (RNF → RT, circolari in M8, valutazione del volontariato in M9, fasi secondo D3); tolti Redis, la predisposizione per più studi e l'adattamento a smartphone, che nessun requisito chiede; aggiunti la row-level security (D12), la firma simulata in sviluppo e la risposta (c) di Q19 tra i punti che possono cambiare l'architettura |
| 0.4.1 | 27/09/2026 | richiesta.md v0.4 |
Verifica sulle fonti: la conservazione digitale è richiesta da [D], quindi Q9 decide solo se va fatta a norma (prima sembrava facoltativa); il CSV nell'importazione è segnato 🔸 perché le fonti citano solo Excel e PDF |
| 0.4.2 | 27/09/2026 | richiesta.md v0.4 |
Nome di M3 allineato a richiesta.md v0.4.4 ("Anagrafica stakeholder", da [X]) |
| 0.4.3 | 27/09/2026 | richiesta.md v0.4 |
§1: il vincolo "un solo sviluppatore" non indica più chi segue la manutenzione dal secondo anno (richiesta di Davide) |
| 0.4.4 | 27/09/2026 | richiesta.md v0.4 |
§7: tolta l'indicazione che D11 decida le "ore di manutenzione" dal secondo anno; D11 decide solo che la gestione tecnica resta a Davide con contratto separato, non termini e ore, ancora aperti |
Stato
- Fase corrente: analisi dei requisiti; architettura in bozza v0.4.4.
- Decisioni prese: D12 (PostgreSQL, migrazioni, row-level security); firma simulata in sviluppo (
costi-ricorrenti.md). Il resto è proposta 🔸. - Prossimo passo: Davide sceglie lo stack (B1.10) e conferma le proposte 🔸; quelle approvate diventano decisioni in
richiesta.md§7 (versione 0.5, con allineamento dei documenti derivati).