This commit is contained in:
Bastien COIGNOUX
2026-05-03 20:18:33 +02:00
parent ffc2e6b895
commit bd325fe456
113 changed files with 29532 additions and 220 deletions

View File

@ -0,0 +1,100 @@
-- MDB-PREDATOR — cœur données (Supabase)
create type public.property_status as enum (
'sourcing',
'visited',
'under_offer',
'sold'
);
create table if not exists public.properties (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references auth.users (id) on delete cascade,
title text not null default 'Property',
address_line text,
city text,
postal_code text,
insee_code text,
latitude double precision,
longitude double precision,
surface_m2 numeric(12, 2),
status public.property_status not null default 'sourcing',
asking_price_eur numeric(14, 2),
resale_estimate_eur numeric(14, 2),
dvf_street_median_m2 numeric(14, 2),
works_estimate_eur numeric(14, 2) not null default 0,
distress_score smallint,
scout_payload jsonb,
engineer_payload jsonb,
financial_payload jsonb,
deal_maker_payload jsonb,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
create index if not exists properties_user_idx on public.properties (user_id);
create index if not exists properties_status_idx on public.properties (status);
create table if not exists public.renovation_templates (
id uuid primary key default gen_random_uuid(),
slug text not null unique,
label text not null,
tier text not null check (tier in ('light', 'medium', 'heavy')),
cost_per_m2_eur numeric(12, 2) not null,
default_misc_eur numeric(12, 2) not null default 0,
sort_order int not null default 0
);
insert into public.renovation_templates (slug, label, tier, cost_per_m2_eur, default_misc_eur, sort_order)
values
('cosmetic', 'Rafraîchissement / léger', 'light', 450, 5000, 10),
('standard', 'Rénovation standard', 'medium', 950, 12000, 20),
('structural', 'Lourd / structure + toiture', 'heavy', 1800, 35000, 30)
on conflict (slug) do nothing;
create table if not exists public.buyers_portfolio (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references auth.users (id) on delete cascade,
display_name text not null,
budget_min_eur numeric(14, 2),
budget_max_eur numeric(14, 2),
sectors jsonb,
min_yield_pct numeric(6, 3),
min_net_margin_pct numeric(5, 2) default 12,
notes text,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
create index if not exists buyers_user_idx on public.buyers_portfolio (user_id);
create or replace function public.predator_set_updated_at()
returns trigger language plpgsql as $$
begin
new.updated_at = now();
return new;
end;
$$;
drop trigger if exists tr_properties_updated on public.properties;
create trigger tr_properties_updated
before update on public.properties
for each row execute procedure public.predator_set_updated_at();
drop trigger if exists tr_buyers_updated on public.buyers_portfolio;
create trigger tr_buyers_updated
before update on public.buyers_portfolio
for each row execute procedure public.predator_set_updated_at();
alter table public.properties enable row level security;
alter table public.buyers_portfolio enable row level security;
alter table public.renovation_templates enable row level security;
create policy properties_owner on public.properties
for all using (auth.uid() = user_id) with check (auth.uid() = user_id);
create policy buyers_owner on public.buyers_portfolio
for all using (auth.uid() = user_id) with check (auth.uid() = user_id);
create policy renovation_read on public.renovation_templates
for select to authenticated using (true);