init
This commit is contained in:
489
schema.sql
Normal file
489
schema.sql
Normal file
@ -0,0 +1,489 @@
|
||||
-- ============================================================
|
||||
-- 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);
|
||||
Reference in New Issue
Block a user