490 lines
19 KiB
PL/PgSQL
490 lines
19 KiB
PL/PgSQL
-- ============================================================
|
|
-- SCHÉMA SUPABASE — Application Marchand de Biens
|
|
-- À exécuter dans Supabase > SQL Editor
|
|
-- ============================================================
|
|
|
|
-- Extensions
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
CREATE EXTENSION IF NOT EXISTS "unaccent";
|
|
|
|
-- ============================================================
|
|
-- TABLES PRINCIPALES
|
|
-- ============================================================
|
|
|
|
-- Profil utilisateur (complète auth.users de Supabase)
|
|
CREATE TABLE public.profiles (
|
|
id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
nom TEXT,
|
|
prenom TEXT,
|
|
telephone TEXT,
|
|
raison_sociale TEXT, -- Nom de la société (SCI, SARL, etc.)
|
|
siret TEXT,
|
|
taux_credit_defaut DECIMAL(5,3) DEFAULT 3.5, -- Taux crédit par défaut en %
|
|
taux_impot_defaut DECIMAL(5,3) DEFAULT 25.0, -- Taux IS par défaut en %
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- MODULE PROSPECTION / BIENS
|
|
-- ============================================================
|
|
|
|
-- Étapes du pipeline (customisables)
|
|
CREATE TABLE public.etapes_pipeline (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
nom TEXT NOT NULL,
|
|
ordre INTEGER NOT NULL,
|
|
couleur TEXT DEFAULT '#6B7280',
|
|
is_terminal BOOLEAN DEFAULT FALSE, -- Étape finale (Vendu, Abandonné)
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Biens immobiliers
|
|
CREATE TABLE public.biens (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
etape_id UUID REFERENCES public.etapes_pipeline(id),
|
|
|
|
-- Identification
|
|
titre TEXT, -- Nom court ex: "T3 Bordeaux Caudéran"
|
|
reference TEXT UNIQUE, -- Référence interne auto-générée
|
|
type_bien TEXT, -- appartement, maison, immeuble, terrain, local_commercial, parking
|
|
|
|
-- Localisation
|
|
adresse TEXT,
|
|
code_postal TEXT,
|
|
ville TEXT,
|
|
departement TEXT,
|
|
latitude DECIMAL(10,7),
|
|
longitude DECIMAL(10,7),
|
|
|
|
-- Caractéristiques physiques
|
|
surface_habitable DECIMAL(8,2), -- m² loi Carrez
|
|
surface_totale DECIMAL(8,2), -- m² totaux
|
|
nb_pieces INTEGER,
|
|
nb_chambres INTEGER,
|
|
nb_etages INTEGER,
|
|
etage INTEGER,
|
|
annee_construction INTEGER,
|
|
dpe_lettre TEXT, -- A, B, C, D, E, F, G
|
|
dpe_valeur INTEGER, -- kWh/m²/an
|
|
ges_lettre TEXT,
|
|
ges_valeur INTEGER,
|
|
|
|
-- Source
|
|
source TEXT, -- particulier, agence, notaire, tribunal, succession, autre
|
|
source_contact_id UUID, -- Lien vers contact (notaire, agent...)
|
|
url_annonce TEXT,
|
|
|
|
-- Statut
|
|
statut TEXT DEFAULT 'actif', -- actif, abandonné, vendu
|
|
priorite INTEGER DEFAULT 2, -- 1=haute, 2=normale, 3=basse
|
|
is_off_market BOOLEAN DEFAULT FALSE,
|
|
|
|
-- Dates importantes
|
|
date_premiere_visite DATE,
|
|
date_offre DATE,
|
|
date_compromis DATE,
|
|
date_acte DATE,
|
|
date_mise_en_vente DATE,
|
|
date_acte_revente DATE,
|
|
|
|
-- Notes
|
|
description TEXT,
|
|
points_forts TEXT,
|
|
points_faibles TEXT,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Analyse financière par bien
|
|
CREATE TABLE public.analyses_financieres (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
-- Acquisition
|
|
prix_achat DECIMAL(12,2),
|
|
type_bien_fiscal TEXT DEFAULT 'ancien', -- ancien (7.5%) ou neuf (2%)
|
|
frais_notaire DECIMAL(12,2), -- calculé ou saisi manuellement
|
|
frais_agence_achat DECIMAL(12,2),
|
|
frais_agence_achat_pct DECIMAL(5,2),
|
|
|
|
-- Financement
|
|
apport DECIMAL(12,2),
|
|
montant_emprunt DECIMAL(12,2),
|
|
taux_credit DECIMAL(5,3),
|
|
duree_credit_mois INTEGER,
|
|
mensualite DECIMAL(10,2),
|
|
|
|
-- Travaux
|
|
budget_travaux DECIMAL(12,2),
|
|
reserve_imprevus_pct DECIMAL(5,2) DEFAULT 10,
|
|
|
|
-- Portage
|
|
duree_portage_mois INTEGER DEFAULT 12,
|
|
taxe_fonciere_annuelle DECIMAL(10,2),
|
|
charges_copropriete_mensuelle DECIMAL(10,2),
|
|
assurance_mensuelle DECIMAL(10,2),
|
|
frais_divers_mensuel DECIMAL(10,2),
|
|
|
|
-- Revente
|
|
prix_revente_cible DECIMAL(12,2),
|
|
frais_agence_vente_pct DECIMAL(5,2) DEFAULT 5,
|
|
frais_agence_vente DECIMAL(12,2),
|
|
taux_impot DECIMAL(5,2) DEFAULT 25,
|
|
|
|
-- Résultats calculés (mis à jour automatiquement)
|
|
prix_revient DECIMAL(12,2),
|
|
frais_portage_total DECIMAL(12,2),
|
|
marge_brute DECIMAL(12,2),
|
|
marge_brute_pct DECIMAL(7,2),
|
|
marge_nette DECIMAL(12,2),
|
|
marge_nette_pct DECIMAL(7,2),
|
|
|
|
-- Scénarios
|
|
scenario_pessimiste_prix DECIMAL(12,2),
|
|
scenario_optimiste_prix DECIMAL(12,2),
|
|
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- MODULE CONTACTS / ANNUAIRE
|
|
-- ============================================================
|
|
|
|
CREATE TABLE public.contacts (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
-- Identité
|
|
nom TEXT NOT NULL,
|
|
prenom TEXT,
|
|
societe TEXT,
|
|
poste TEXT,
|
|
|
|
-- Catégorie
|
|
categorie TEXT NOT NULL, -- notaire, agent_immo, artisan_gros_oeuvre, artisan_second_oeuvre,
|
|
-- artisan_finitions, banquier, courtier, diagnostiqueur,
|
|
-- geometre, avocat, comptable, vendeur, acheteur, autre
|
|
specialite TEXT, -- ex: "Plomberie chauffage", "Électricité", "Charpente"
|
|
|
|
-- Coordonnées
|
|
telephone TEXT,
|
|
telephone_2 TEXT,
|
|
email TEXT,
|
|
adresse TEXT,
|
|
code_postal TEXT,
|
|
ville TEXT,
|
|
zone_intervention TEXT, -- ex: "Bordeaux 33000-33100"
|
|
|
|
-- Qualité
|
|
note INTEGER CHECK (note BETWEEN 1 AND 5), -- Note de 1 à 5 étoiles
|
|
fiabilite TEXT, -- excellent, bon, moyen, mauvais
|
|
recommande BOOLEAN DEFAULT FALSE,
|
|
|
|
-- Tarification artisans
|
|
taux_horaire DECIMAL(8,2),
|
|
remise_habituelle_pct DECIMAL(5,2),
|
|
|
|
notes TEXT,
|
|
is_favori BOOLEAN DEFAULT FALSE,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Lien bien ↔ contact (ex: notaire assigné à ce dossier)
|
|
CREATE TABLE public.biens_contacts (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
|
|
contact_id UUID NOT NULL REFERENCES public.contacts(id) ON DELETE CASCADE,
|
|
role TEXT, -- notaire_vendeur, notaire_acheteur, agent_vendeur, artisan_principal, banque
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
UNIQUE(bien_id, contact_id, role)
|
|
);
|
|
|
|
-- ============================================================
|
|
-- MODULE VISITES
|
|
-- ============================================================
|
|
|
|
CREATE TABLE public.visites (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
date_visite TIMESTAMPTZ NOT NULL,
|
|
duree_minutes INTEGER DEFAULT 60,
|
|
type_visite TEXT DEFAULT 'premiere', -- premiere, seconde, expert, contradiction
|
|
|
|
-- Notes brutes pendant la visite
|
|
notes_brutes TEXT,
|
|
|
|
-- Rapport généré par IA
|
|
rapport_genere TEXT,
|
|
rapport_genere_at TIMESTAMPTZ,
|
|
|
|
-- Estimations sur place
|
|
estimation_travaux_min DECIMAL(12,2),
|
|
estimation_travaux_max DECIMAL(12,2),
|
|
estimation_duree_travaux_mois INTEGER,
|
|
|
|
-- Avis global
|
|
avis_global TEXT, -- coup_de_coeur, interessant, neutre, a_eviter
|
|
score_opportunite INTEGER CHECK (score_opportunite BETWEEN 1 AND 10),
|
|
|
|
contacts_presents TEXT[], -- Noms des personnes présentes
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Check-list de visite (items configurables)
|
|
CREATE TABLE public.checklist_items (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
categorie TEXT NOT NULL, -- structure, toiture, electricite, plomberie, isolation, humidite, exterieur, administratif
|
|
question TEXT NOT NULL,
|
|
description TEXT, -- Aide / explication
|
|
ordre INTEGER DEFAULT 0,
|
|
is_actif BOOLEAN DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Réponses à la check-list pour une visite
|
|
CREATE TABLE public.checklist_reponses (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
visite_id UUID NOT NULL REFERENCES public.visites(id) ON DELETE CASCADE,
|
|
item_id UUID NOT NULL REFERENCES public.checklist_items(id),
|
|
reponse TEXT, -- ok, attention, probleme, non_verifie
|
|
note TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
UNIQUE(visite_id, item_id)
|
|
);
|
|
|
|
-- ============================================================
|
|
-- MODULE DOCUMENTS & MÉDIAS
|
|
-- ============================================================
|
|
|
|
CREATE TABLE public.photos_biens (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
|
|
visite_id UUID REFERENCES public.visites(id),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
storage_path TEXT NOT NULL, -- chemin dans Supabase Storage
|
|
nom TEXT,
|
|
legende TEXT,
|
|
categorie TEXT, -- facade, interieur, travaux, avant, apres
|
|
ordre INTEGER DEFAULT 0,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE public.documents_biens (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
storage_path TEXT NOT NULL,
|
|
nom TEXT NOT NULL,
|
|
type_document TEXT, -- compromis, acte, dpe, diagnostics, devis, facture, titre_propriete, autre
|
|
date_document DATE,
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- MODULE AGENDA / TÂCHES
|
|
-- ============================================================
|
|
|
|
CREATE TABLE public.taches (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
bien_id UUID REFERENCES public.biens(id) ON DELETE SET NULL,
|
|
contact_id UUID REFERENCES public.contacts(id) ON DELETE SET NULL,
|
|
|
|
titre TEXT NOT NULL,
|
|
description TEXT,
|
|
type_tache TEXT, -- visite, appel, email, relance, administratif, travaux, banque, autre
|
|
priorite INTEGER DEFAULT 2,
|
|
statut TEXT DEFAULT 'a_faire', -- a_faire, en_cours, fait, annule
|
|
|
|
date_echeance TIMESTAMPTZ,
|
|
date_rappel TIMESTAMPTZ,
|
|
date_realisation TIMESTAMPTZ,
|
|
|
|
recurrence TEXT, -- null, quotidien, hebdomadaire, mensuel
|
|
is_urgent BOOLEAN DEFAULT FALSE,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Notes libres
|
|
CREATE TABLE public.notes_biens (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
contenu TEXT NOT NULL,
|
|
type_note TEXT DEFAULT 'libre', -- libre, contact_vendeur, negociation, info_marche
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- MODULE TRAVAUX
|
|
-- ============================================================
|
|
|
|
CREATE TABLE public.devis_travaux (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
bien_id UUID NOT NULL REFERENCES public.biens(id) ON DELETE CASCADE,
|
|
contact_id UUID REFERENCES public.contacts(id), -- L'artisan
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
|
|
lot TEXT NOT NULL, -- Gros œuvre, Électricité, Plomberie, Menuiserie, etc.
|
|
description TEXT,
|
|
montant_ht DECIMAL(12,2),
|
|
taux_tva DECIMAL(5,2) DEFAULT 10,
|
|
montant_ttc DECIMAL(12,2),
|
|
|
|
statut TEXT DEFAULT 'en_attente', -- en_attente, refuse, accepte, en_cours, termine, paye
|
|
date_devis DATE,
|
|
date_debut_prevu DATE,
|
|
date_fin_prevu DATE,
|
|
date_fin_reel DATE,
|
|
|
|
storage_path_pdf TEXT,
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- DONNÉES PAR DÉFAUT
|
|
-- ============================================================
|
|
|
|
-- Étapes pipeline par défaut (seront copiées pour chaque nouvel utilisateur)
|
|
-- (géré via trigger ou Edge Function à l'inscription)
|
|
|
|
-- Check-list de visite par défaut
|
|
INSERT INTO public.checklist_items (user_id, categorie, question, description, ordre)
|
|
VALUES
|
|
-- Sera remplacé par un trigger, voici la structure des items par défaut
|
|
-- Ces items sont créés via la Edge Function on-user-create
|
|
('00000000-0000-0000-0000-000000000000', 'structure', 'Fissures visibles sur les murs porteurs ?', 'Observer les fissures en H ou diagonales, signe de mouvement de structure', 1),
|
|
('00000000-0000-0000-0000-000000000000', 'toiture', 'État général de la toiture ?', 'Tuiles manquantes, mousse, faîtage, chéneaux', 2),
|
|
('00000000-0000-0000-0000-000000000000', 'electricite', 'Tableau électrique aux normes ?', 'Vérifier disjoncteurs, présence de terre, type de tableau', 3),
|
|
('00000000-0000-0000-0000-000000000000', 'plomberie', 'Type de canalisations (plomb, cuivre, PVC) ?', 'Canalisations en plomb = remplacement obligatoire', 4),
|
|
('00000000-0000-0000-0000-000000000000', 'humidite', 'Traces d''humidité ou de moisissures ?', 'Vérifier les angles, sous les fenêtres, la cave', 5),
|
|
('00000000-0000-0000-0000-000000000000', 'isolation', 'Type et état de l''isolation ?', 'Combles, murs, sol. DPE cohérent avec le ressenti', 6),
|
|
('00000000-0000-0000-0000-000000000000', 'exterieur', 'État des menuiseries extérieures ?', 'Simple ou double vitrage, état des joints, volets', 7),
|
|
('00000000-0000-0000-0000-000000000000', 'administratif', 'Charges de copropriété et procédures en cours ?', 'Demander les 3 derniers PV d''AG, montant des charges', 8);
|
|
|
|
-- ============================================================
|
|
-- ROW LEVEL SECURITY (RLS)
|
|
-- ============================================================
|
|
|
|
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.biens ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.etapes_pipeline ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.analyses_financieres ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.contacts ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.biens_contacts ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.visites ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.checklist_items ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.checklist_reponses ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.photos_biens ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.documents_biens ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.taches ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.notes_biens ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.devis_travaux ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Politique : chaque utilisateur voit uniquement ses propres données
|
|
CREATE POLICY "user_own_data" ON public.profiles FOR ALL USING (auth.uid() = id);
|
|
CREATE POLICY "user_own_data" ON public.biens FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.etapes_pipeline FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.analyses_financieres FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.contacts FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.visites FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.taches FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.notes_biens FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.devis_travaux FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.photos_biens FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.documents_biens FOR ALL USING (auth.uid() = user_id);
|
|
CREATE POLICY "user_own_data" ON public.checklist_items FOR ALL USING (auth.uid() = user_id);
|
|
|
|
-- biens_contacts : visible si l'utilisateur possède le bien
|
|
CREATE POLICY "user_own_biens_contacts" ON public.biens_contacts FOR ALL
|
|
USING (EXISTS (SELECT 1 FROM public.biens WHERE id = bien_id AND user_id = auth.uid()));
|
|
|
|
-- checklist_reponses : visible si l'utilisateur possède la visite
|
|
CREATE POLICY "user_own_checklist_reponses" ON public.checklist_reponses FOR ALL
|
|
USING (EXISTS (SELECT 1 FROM public.visites WHERE id = visite_id AND user_id = auth.uid()));
|
|
|
|
-- ============================================================
|
|
-- TRIGGER : updated_at automatique
|
|
-- ============================================================
|
|
|
|
CREATE OR REPLACE FUNCTION update_updated_at()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN NEW.updated_at = NOW(); RETURN NEW; END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.biens FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.contacts FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.visites FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.taches FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.analyses_financieres FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.devis_travaux FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.profiles FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
|
|
-- ============================================================
|
|
-- TRIGGER : Créer profil + données par défaut à l'inscription
|
|
-- ============================================================
|
|
|
|
CREATE OR REPLACE FUNCTION handle_new_user()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
etape_ids UUID[];
|
|
BEGIN
|
|
-- Créer le profil
|
|
INSERT INTO public.profiles (id) VALUES (NEW.id);
|
|
|
|
-- Créer les étapes du pipeline par défaut
|
|
INSERT INTO public.etapes_pipeline (user_id, nom, ordre, couleur) VALUES
|
|
(NEW.id, 'Piste', 1, '#6B7280'),
|
|
(NEW.id, 'En analyse', 2, '#3B82F6'),
|
|
(NEW.id, 'Offre faite', 3, '#F59E0B'),
|
|
(NEW.id, 'Compromis signé', 4, '#8B5CF6'),
|
|
(NEW.id, 'Acte signé', 5, '#10B981'),
|
|
(NEW.id, 'En travaux', 6, '#F97316'),
|
|
(NEW.id, 'En vente', 7, '#EC4899'),
|
|
(NEW.id, 'Vendu', 8, '#22C55E'),
|
|
(NEW.id, 'Abandonné', 9, '#EF4444');
|
|
|
|
-- Copier la check-list de visite par défaut
|
|
INSERT INTO public.checklist_items (user_id, categorie, question, description, ordre)
|
|
SELECT NEW.id, categorie, question, description, ordre
|
|
FROM public.checklist_items
|
|
WHERE user_id = '00000000-0000-0000-0000-000000000000';
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
CREATE TRIGGER on_auth_user_created
|
|
AFTER INSERT ON auth.users
|
|
FOR EACH ROW EXECUTE FUNCTION handle_new_user();
|
|
|
|
-- ============================================================
|
|
-- INDEX pour les performances
|
|
-- ============================================================
|
|
|
|
CREATE INDEX idx_biens_user_id ON public.biens(user_id);
|
|
CREATE INDEX idx_biens_etape_id ON public.biens(etape_id);
|
|
CREATE INDEX idx_biens_ville ON public.biens(ville);
|
|
CREATE INDEX idx_contacts_user_id ON public.contacts(user_id);
|
|
CREATE INDEX idx_contacts_categorie ON public.contacts(categorie);
|
|
CREATE INDEX idx_taches_user_id ON public.taches(user_id);
|
|
CREATE INDEX idx_taches_date_echeance ON public.taches(date_echeance);
|
|
CREATE INDEX idx_visites_bien_id ON public.visites(bien_id);
|