netgescon-master/docs/02-architettura-laravel/03-anagrafica-condomini/ANALISI-ANAGRAFICA.md
Pikappa2 480e7eafbd 🎯 NETGESCON - Setup iniziale repository completo
📋 Commit iniziale con:
-  Documentazione unificata in docs/
-  Codice Laravel in netgescon-laravel/
-  Script automazione in scripts/
-  Configurazione sync rsync
-  Struttura organizzata e pulita

🔄 Versione: 2025.07.19-1644
🎯 Sistema pronto per Git distribuito
2025-07-19 16:44:47 +02:00

441 lines
15 KiB
Markdown

# NETGESCON - ANALISI ANAGRAFICA CONDOMINI
## 📋 OVERVIEW
L'anagrafica è il cuore del sistema: una **rubrica generale centralizzata** che evita duplicazioni. Una persona fisica può essere proprietaria di multiple unità immobiliari in diversi stabili, ma i suoi dati anagrafici sono memorizzati una sola volta.
## 👤 PRINCIPI FONDAMENTALI
### Unicità della Persona
- **Una persona = Un record anagrafico**
- **Identificatori univoci**: Codice Fiscale, Telefono principale
- **Relazioni multiple**: Una persona può avere N proprietà/contratti
- **Dati condivisi**: Contatti, anagrafica base
- **Dati specifici**: Ruolo diverso per ogni unità/stabile
### Controlli Anti-Duplicazione
```php
// Controlli all'inserimento nuova persona
1. Codice Fiscale già esistente? -> ERRORE o FORZATURA con log
2. Telefono principale già esistente? -> ERRORE o FORZATURA con log
3. Email principale già esistente? -> WARNING (possibile ma non ideale)
4. Nome+Cognome+Data Nascita uguali? -> WARNING (possibile omonimia)
```
## 👥 STRUTTURA ANAGRAFICA PERSONE
### Dati Identificativi
- **ID Persona** (Primary Key, Auto-increment)
- **Codice Interno** (Generated: es. "ANA000001")
- **Tipologia Persona**
- Persona Fisica
- Persona Giuridica (Società, Enti)
- Ditta Individuale
### Dati Anagrafici Base
- **Cognome** (obbligatorio)
- **Nome** (obbligatorio)
- **Codice Fiscale** (UNIVOCO, validato con algoritmo)
- **Partita IVA** (se presente, validata)
- **Data di Nascita**
- **Luogo di Nascita** (Comune + Provincia, linkato a DB comuni)
- **Sesso** (M/F/Altro)
- **Cittadinanza**
- **Stato Civile**
### Dati di Residenza
- **Indirizzo Residenza**
- Via/Piazza
- Numero civico
- CAP
- Comune (linkato a DB comuni)
- Provincia
- Regione
- Nazione (default: Italia)
- **Indirizzo Domicilio** (se diverso da residenza)
- **Indirizzo Corrispondenza** (se diverso da residenza)
### Contatti (Hierarchy System)
**Telefoni** (ordinati per priorità):
1. **Telefono Principale** (UNIVOCO nel sistema)
2. Telefono Secondario
3. Telefono Ufficio
4. Telefono Emergenza
**Email** (ordinate per priorità):
1. **Email Principale**
2. Email Secondaria
3. Email Lavoro
4. Email PEC (Posta Elettronica Certificata)
**Altri Contatti**:
- Fax
- Skype/Teams
- WhatsApp (numero)
- Telegram
- Social (Facebook, LinkedIn, etc)
### Preferenze Comunicazione
- **Modalità Preferita**: Email, SMS, WhatsApp, Telefono, Posta
- **Lingua Preferita**: Italiano, Inglese, Francese, etc
- **Orari Contatto**: Mattino, Pomeriggio, Sera, Weekend OK/NO
- **Privacy Consensi**:
- Consenso Trattamento Dati Base
- Consenso Marketing
- Consenso Comunicazioni Automatiche
- Consenso Condivisione Emergenze
## 🏢 PERSONE GIURIDICHE
### Dati Aggiuntivi per Società
- **Ragione Sociale**
- **Forma Giuridica** (SRL, SPA, SAS, SNC, etc)
- **Codice REA**
- **Capitale Sociale**
- **Sede Legale** (può essere diversa da operativa)
- **Sede Operativa**
### Rappresentanti Legali
- **Amministratore Delegato** (linkato a persona fisica)
- **Rappresentante Legale** (linkato a persona fisica)
- **Procuratori** (possono essere multipli)
- **Referente Amministrativo** (per pratiche condominiali)
## 🔗 RELAZIONI CON UNITÀ IMMOBILIARI
### Tabella Ponte: Persone ↔ Unità
Ogni persona può avere **ruoli diversi** in **unità diverse**:
```sql
CREATE TABLE persone_unita_ruoli (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
persona_id BIGINT NOT NULL,
unita_id BIGINT NOT NULL,
tipo_relazione ENUM('proprietario','inquilino','usufruttuario','delegato','referente','altro'),
quota_proprieta DECIMAL(5,2), -- Solo se proprietario
data_inizio DATE NOT NULL,
data_fine DATE, -- NULL = relazione attiva
attivo BOOLEAN DEFAULT TRUE,
note TEXT
);
```
### Esempi di Relazioni Multiple
**Mario Rossi**:
- Proprietario 100% di Stabile A, Unità 12
- Comproprietario 50% di Stabile B, Unità 5
- Delegato assemblea per Stabile C, Unità 8 (di sua madre)
- Referente per Stabile A, Unità 15 (inquilino sordo)
## 📞 GESTIONE CONTATTI AVANZATA
### Validazione Automatica
```php
// Validazione Codice Fiscale
function validaCodiceFiscale($cf, $nome, $cognome, $dataNascita, $comuneNascita) {
// Algoritmo calcolo CF + verifica con dati anagrafici
$cfCalcolato = calcolaCodiceFiscale($nome, $cognome, $dataNascita, $comuneNascita);
return $cf === $cfCalcolato;
}
// Validazione numero telefono
function validaTelefono($telefono) {
// Verifica formato internazionale/nazionale
// Verifica esistenza numero (API?)
return preg_match('/^(\+39|0039|39)?[0-9]{9,10}$/', $telefono);
}
```
### Sistema di Conferma Identità
- **SMS con codice OTP** per conferma numero
- **Email di verifica** per conferma email
- **WhatsApp Business API** per conferma WA
- **Chiamata automatica** con codice vocale
### Gestione Duplicati
```php
// Quando viene inserita una persona con CF/Tel già esistente
function gestioneDuplicati($nuoviDati) {
$esistente = trovaPersonaEsistente($nuoviDati);
if ($esistente) {
// Proponi merge dei dati
return [
'azione' => 'merge_proposto',
'persona_esistente' => $esistente,
'differenze' => confrontaDati($esistente, $nuoviDati),
'suggerimento' => 'aggiorna_persona_esistente'
];
}
}
```
## 📋 AUDIT E TRACCIABILITÀ
### Log Modifiche Anagrafiche
Ogni modifica ai dati anagrafici deve essere tracciata:
```sql
CREATE TABLE audit_anagrafica (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
persona_id BIGINT NOT NULL,
campo_modificato VARCHAR(100),
valore_precedente TEXT,
valore_nuovo TEXT,
data_modifica TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
utente_id INT NOT NULL, -- Chi ha fatto la modifica
ip_address VARCHAR(45),
motivo_modifica TEXT,
tipo_modifica ENUM('inserimento','aggiornamento','cancellazione','merge')
);
```
### Campi Sensibili da Auditare
- **Codice Fiscale** (modifica molto critica)
- **Telefono Principale** (critico per identificazione)
- **Email Principale** (importante per comunicazioni)
- **Indirizzo Residenza** (importante per corrispondenza)
- **Dati Bancari** (se presenti, molto sensibili)
## 🏗️ SCHEMA DATABASE COMPLETO
```sql
-- Tabella principale persone
CREATE TABLE persone (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
codice_interno VARCHAR(20) UNIQUE NOT NULL,
tipologia ENUM('fisica','giuridica','ditta_individuale') NOT NULL,
-- Dati anagrafici base
cognome VARCHAR(100) NOT NULL,
nome VARCHAR(100) NOT NULL,
codice_fiscale VARCHAR(16) UNIQUE, -- Unique but nullable for foreign persons
partita_iva VARCHAR(11),
data_nascita DATE,
luogo_nascita_comune_id INT, -- FK a comuni
sesso ENUM('M','F','Altro'),
cittadinanza VARCHAR(100) DEFAULT 'Italiana',
stato_civile ENUM('celibe/nubile','coniugato/a','vedovo/a','divorziato/a','separato/a'),
-- Residenza
residenza_via VARCHAR(255),
residenza_civico VARCHAR(10),
residenza_cap VARCHAR(5),
residenza_comune_id INT, -- FK a comuni
-- Domicilio (se diverso)
domicilio_via VARCHAR(255),
domicilio_civico VARCHAR(10),
domicilio_cap VARCHAR(5),
domicilio_comune_id INT,
-- Corrispondenza (se diverso)
corrispondenza_via VARCHAR(255),
corrispondenza_civico VARCHAR(10),
corrispondenza_cap VARCHAR(5),
corrispondenza_comune_id INT,
-- Contatti principali
telefono_principale VARCHAR(20) UNIQUE, -- UNIVOCO
telefono_secondario VARCHAR(20),
telefono_ufficio VARCHAR(20),
telefono_emergenza VARCHAR(20),
email_principale VARCHAR(255),
email_secondaria VARCHAR(255),
email_lavoro VARCHAR(255),
email_pec VARCHAR(255),
-- Altri contatti
fax VARCHAR(20),
whatsapp VARCHAR(20),
telegram VARCHAR(100),
skype VARCHAR(100),
-- Preferenze
modalita_comunicazione_preferita ENUM('email','sms','whatsapp','telefono','posta'),
lingua_preferita VARCHAR(10) DEFAULT 'it',
orari_contatto VARCHAR(255),
-- Privacy e consensi
consenso_privacy BOOLEAN DEFAULT FALSE,
consenso_marketing BOOLEAN DEFAULT FALSE,
consenso_comunicazioni_auto BOOLEAN DEFAULT FALSE,
data_consenso_privacy TIMESTAMP,
-- Dati società (se tipologia = giuridica)
ragione_sociale VARCHAR(255),
forma_giuridica VARCHAR(50),
codice_rea VARCHAR(20),
capitale_sociale DECIMAL(12,2),
-- Audit
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT,
updated_by INT,
-- Indici
INDEX idx_cognome_nome (cognome, nome),
INDEX idx_codice_fiscale (codice_fiscale),
INDEX idx_telefono (telefono_principale),
INDEX idx_email (email_principale),
INDEX idx_comune_residenza (residenza_comune_id),
-- Vincoli
CONSTRAINT chk_cf_length CHECK (codice_fiscale IS NULL OR LENGTH(codice_fiscale) = 16),
CONSTRAINT chk_piva_length CHECK (partita_iva IS NULL OR LENGTH(partita_iva) = 11)
);
-- Rappresentanti legali per persone giuridiche
CREATE TABLE rappresentanti_legali (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
persona_giuridica_id BIGINT NOT NULL,
persona_fisica_id BIGINT NOT NULL,
tipo_rappresentanza ENUM('amministratore_delegato','rappresentante_legale','procuratore','referente_amministrativo'),
data_inizio DATE NOT NULL,
data_fine DATE,
poteri VARCHAR(500), -- Descrizione poteri/limitazioni
attivo BOOLEAN DEFAULT TRUE,
FOREIGN KEY (persona_giuridica_id) REFERENCES persone(id),
FOREIGN KEY (persona_fisica_id) REFERENCES persone(id),
INDEX idx_giuridica (persona_giuridica_id),
INDEX idx_fisica (persona_fisica_id)
);
-- Relazioni persone-unità con ruoli
CREATE TABLE persone_unita_relazioni (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
persona_id BIGINT NOT NULL,
unita_id BIGINT NOT NULL,
tipo_relazione ENUM('proprietario','comproprietario','inquilino','usufruttuario','nudo_proprietario','delegato_assemblea','referente','amministratore_sostegno','altro'),
quota_relazione DECIMAL(5,2), -- % proprietà o altra quota
data_inizio DATE NOT NULL,
data_fine DATE, -- NULL = relazione attiva
attivo BOOLEAN DEFAULT TRUE,
note TEXT,
-- Preferenze per questa relazione specifica
riceve_comunicazioni BOOLEAN DEFAULT TRUE,
riceve_convocazioni BOOLEAN DEFAULT TRUE,
vota_assemblea BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (persona_id) REFERENCES persone(id) ON DELETE CASCADE,
FOREIGN KEY (unita_id) REFERENCES unita_immobiliari(id) ON DELETE CASCADE,
INDEX idx_persona (persona_id),
INDEX idx_unita (unita_id),
INDEX idx_attivo (attivo),
INDEX idx_tipo (tipo_relazione),
-- Constraint: non duplicare relazioni attive stesso tipo per stessa unità
UNIQUE KEY unique_relazione_attiva (persona_id, unita_id, tipo_relazione, attivo)
);
-- Conferme identità (SMS, Email, etc)
CREATE TABLE conferme_identita (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
persona_id BIGINT NOT NULL,
tipo_conferma ENUM('sms','email','whatsapp','chiamata'),
contatto_confermare VARCHAR(255), -- numero o email da confermare
codice_otp VARCHAR(10),
data_invio TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
data_conferma TIMESTAMP NULL,
stato ENUM('inviato','confermato','scaduto','fallito'),
tentativi_falliti TINYINT DEFAULT 0,
FOREIGN KEY (persona_id) REFERENCES persone(id) ON DELETE CASCADE,
INDEX idx_persona (persona_id),
INDEX idx_stato (stato),
INDEX idx_data_invio (data_invio)
);
```
## 🔍 FUNZIONALITÀ AVANZATE
### Ricerca Intelligente Persone
```php
// Ricerca multi-campo con AI/fuzzy matching
function ricercaPersone($query) {
return Persona::where(function($q) use ($query) {
$q->where('cognome', 'LIKE', "%$query%")
->orWhere('nome', 'LIKE', "%$query%")
->orWhere('codice_fiscale', '=', $query)
->orWhere('telefono_principale', 'LIKE', "%$query%")
->orWhere('email_principale', 'LIKE', "%$query%");
})
->with(['unitaImmobiliari', 'stabili'])
->paginate(20);
}
```
### Import Automatico da Fonti Esterne
- **Import da file Excel/CSV**: Batch upload con verifica duplicati
- **API Agenzia Entrate**: Verifica dati catastali e anagrafici
- **API Comune**: Verifica residenze e stato civile
- **API Camera Commercio**: Dati società e rappresentanti legali
### Comunicazioni di Massa
```php
// Invio comunicazione a gruppo target
function inviaComuncazione($stabileId, $tipoDestinatari, $messaggio) {
$destinatari = Persona::whereHas('unitaImmobiliari', function($q) use ($stabileId) {
$q->where('stabile_id', $stabileId);
})
->where('consenso_comunicazioni_auto', true)
->get();
foreach ($destinatari as $persona) {
match($persona->modalita_comunicazione_preferita) {
'email' => inviaEmail($persona->email_principale, $messaggio),
'sms' => inviaSMS($persona->telefono_principale, $messaggio),
'whatsapp' => inviaWhatsApp($persona->whatsapp, $messaggio),
default => inviaEmail($persona->email_principale, $messaggio)
};
}
}
```
### Dashboard Anagrafica
- **Statistiche generali**: Totale persone, tipologie, distribuzione geografica
- **Contatti mancanti**: Persone senza email/telefono
- **Consensi privacy**: % consensi dati, scadenze
- **Verifiche identità**: Numeri/email non confermati
- **Duplicati sospetti**: Algoritmo detection automatico
## 🚀 ROADMAP ANAGRAFICA
### Fase 1 - Base (Sprint 1-2)
- [ ] Struttura database completa
- [ ] CRUD persone con validazioni
- [ ] Sistema anti-duplicazione
- [ ] Import da Excel/CSV
### Fase 2 - Validazioni (Sprint 3-4)
- [ ] Algoritmo calcolo/verifica Codice Fiscale
- [ ] Validazione numeri telefono
- [ ] Sistema conferma SMS/Email
- [ ] Audit completo modifiche
### Fase 3 - Integrazioni (Sprint 5-6)
- [ ] API verifica dati anagrafici
- [ ] Sistema comunicazioni multi-canale
- [ ] Dashboard analytics anagrafica
- [ ] Import automatico da fonti esterne
### Fase 4 - AI e Automazioni (Sprint 7-8)
- [ ] Ricerca intelligente fuzzy
- [ ] Detection automatico duplicati
- [ ] Suggerimenti merge persone
- [ ] Analisi preferenze comunicazione
---
**Data Analisi:** 14/07/2025
**Stato:** BOZZA - In Definizione
**Prossimo Step:** Integrazione con Codice Fiscale + API Comuni