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

15 KiB

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

// 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:

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

// 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

// 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:

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

-- 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

// 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

// 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