SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; CREATE SCHEMA IF NOT EXISTS "public"; ALTER SCHEMA "public" OWNER TO "pg_database_owner"; COMMENT ON SCHEMA "public" IS 'standard public schema'; CREATE TYPE "public"."service_type" AS ENUM ( 'TER', 'TGV', 'Intercités', 'Fret' ); ALTER TYPE "public"."service_type" OWNER TO "postgres"; CREATE TYPE "public"."station_type" AS ENUM ( 'interurbaine', 'ville' ); ALTER TYPE "public"."station_type" OWNER TO "postgres"; CREATE TYPE "public"."transport_type" AS ENUM ( 'bus', 'tram', 'metro', 'tram-train', 'train' ); ALTER TYPE "public"."transport_type" OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."authenticate_user"("p_email" "text", "p_password" "text") RETURNS TABLE("id" "uuid", "email" "text", "nom" "text", "prenom" "text", "name" "text", "role" "text", "region_admin" boolean, "region_id" "text") LANGUAGE "plpgsql" STABLE SECURITY DEFINER AS $_$ DECLARE has_deleted_at boolean; sql text; BEGIN SELECT EXISTS( SELECT 1 FROM information_schema.columns WHERE table_schema='public' AND table_name='users_panel' AND column_name='deleted_at' ) INTO has_deleted_at; sql := 'SELECT u.id::uuid, u.email::text, u.nom::text, u.prenom::text, ' || '(COALESCE(u.nom, '''') || '' '' || COALESCE(u.prenom, ''''))::text as name, ' || 'u.role::text, ' || 'COALESCE(u.region_admin, false)::boolean as region_admin, ' || 'u.region_id::text ' || 'FROM public.users_panel u ' || 'WHERE lower(u.email) = lower($1) ' || 'AND u.password_hash IS NOT NULL ' || 'AND u.password_hash = crypt($2, u.password_hash) ' || 'AND coalesce(u.actif, true) = true'; IF has_deleted_at THEN sql := sql || ' AND u.deleted_at IS NULL'; END IF; RETURN QUERY EXECUTE sql USING p_email, p_password; END; $_$; ALTER FUNCTION "public"."authenticate_user"("p_email" "text", "p_password" "text") OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."create_user_with_password"("p_email" "text", "p_nom" "text", "p_prenom" "text", "p_role" "text" DEFAULT 'utilisateur'::"text", "p_actif" boolean DEFAULT true, "p_password" "text" DEFAULT NULL::"text", "p_photo_url" "text" DEFAULT NULL::"text", "p_region_admin" boolean DEFAULT false, "p_region_id" "text" DEFAULT NULL::"text") RETURNS TABLE("id" "uuid", "email" "text", "nom" "text", "prenom" "text", "role" "text", "actif" boolean, "photo_url" "text", "region_admin" boolean, "region_id" "text") LANGUAGE "plpgsql" SECURITY DEFINER AS $$ DECLARE new_id uuid; BEGIN INSERT INTO public.users_panel (email, nom, prenom, role, actif, password_hash, photo_url, region_admin, region_id, created_at) VALUES ( lower(p_email), p_nom, p_prenom, p_role, p_actif, CASE WHEN p_password IS NOT NULL AND p_password != '' THEN crypt(p_password, gen_salt('bf')) ELSE NULL END, p_photo_url, p_region_admin, p_region_id, NOW() ) RETURNING users_panel.id INTO new_id; RETURN QUERY SELECT u.id, u.email::text, u.nom::text, u.prenom::text, u.role::text, u.actif, u.photo_url::text, u.region_admin, u.region_id::text FROM public.users_panel u WHERE u.id = new_id; END; $$; ALTER FUNCTION "public"."create_user_with_password"("p_email" "text", "p_nom" "text", "p_prenom" "text", "p_role" "text", "p_actif" boolean, "p_password" "text", "p_photo_url" "text", "p_region_admin" boolean, "p_region_id" "text") OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."get_gare_details"("p_gare_id" "uuid") RETURNS TABLE("id" "uuid", "nom" "text", "type" "public"."station_type", "services" "public"."service_type"[], "quais" "jsonb", "transports" "jsonb", "created_at" timestamp with time zone, "updated_at" timestamp with time zone) LANGUAGE "plpgsql" STABLE SECURITY DEFINER AS $$ BEGIN RETURN QUERY SELECT g.id, g.nom, g.type, g.services, COALESCE( (SELECT jsonb_agg(jsonb_build_object('id', q.id, 'nom', q.nom, 'distance_metres', q.distance_metres)) FROM public.gare_quais q WHERE q.gare_id = g.id), '[]'::jsonb ) as quais, COALESCE( (SELECT jsonb_agg(jsonb_build_object('id', t.id, 'type', t.type, 'ligne', t.ligne)) FROM public.gare_transports t WHERE t.gare_id = g.id), '[]'::jsonb ) as transports, g.created_at, g.updated_at FROM public.gares g WHERE g.id = p_gare_id AND g.deleted_at IS NULL; END; $$; ALTER FUNCTION "public"."get_gare_details"("p_gare_id" "uuid") OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."get_station_details"("p_station_id" "uuid") RETURNS TABLE("id" "uuid", "nom" "text", "type" "public"."station_type", "services" "public"."service_type"[], "quais" "jsonb", "transports" "jsonb", "created_at" timestamp with time zone, "updated_at" timestamp with time zone) LANGUAGE "plpgsql" STABLE SECURITY DEFINER AS $$ BEGIN RETURN QUERY SELECT s.id, s.nom, s.type, s.services, COALESCE( (SELECT jsonb_agg(jsonb_build_object('id', q.id, 'nom', q.nom, 'distance_metres', q.distance_metres)) FROM public.station_quais q WHERE q.station_id = s.id), '[]'::jsonb ) as quais, COALESCE( (SELECT jsonb_agg(jsonb_build_object('id', t.id, 'type', t.type, 'ligne', t.ligne)) FROM public.station_transports t WHERE t.station_id = s.id), '[]'::jsonb ) as transports, s.created_at, s.updated_at FROM public.stations s WHERE s.id = p_station_id AND s.deleted_at IS NULL; END; $$; ALTER FUNCTION "public"."get_station_details"("p_station_id" "uuid") OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."handle_updated_at"() RETURNS "trigger" LANGUAGE "plpgsql" AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$; ALTER FUNCTION "public"."handle_updated_at"() OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."import_gtfs_rpc"("payload" json) RETURNS json LANGUAGE "plpgsql" AS $$ DECLARE res json := json_build_object('status', 'ok', 'created', 0, 'warnings', json_build_array()); BEGIN -- Exemple minimal : cette fonction doit être étendue selon vos règles métier. -- Ici on ne fait rien, juste renvoyer un résultat. RETURN res; EXCEPTION WHEN OTHERS THEN RETURN json_build_object('status', 'error', 'message', SQLERRM); END; $$; ALTER FUNCTION "public"."import_gtfs_rpc"("payload" json) OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."set_updated_at"() RETURNS "trigger" LANGUAGE "plpgsql" AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$; ALTER FUNCTION "public"."set_updated_at"() OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."update_travaux_updated_at"() RETURNS "trigger" LANGUAGE "plpgsql" AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$; ALTER FUNCTION "public"."update_travaux_updated_at"() OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."update_updated_at_column"() RETURNS "trigger" LANGUAGE "plpgsql" AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$; ALTER FUNCTION "public"."update_updated_at_column"() OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."update_user_password"("p_user_id" "uuid", "p_password" "text") RETURNS "void" LANGUAGE "plpgsql" SECURITY DEFINER AS $$ BEGIN IF p_password IS NULL OR p_password = '' THEN RAISE EXCEPTION 'Le mot de passe ne peut pas être vide'; END IF; UPDATE public.users_panel SET password_hash = crypt(p_password, gen_salt('bf')), updated_at = NOW() WHERE id = p_user_id; IF NOT FOUND THEN RAISE EXCEPTION 'Utilisateur non trouvé'; END IF; END; $$; ALTER FUNCTION "public"."update_user_password"("p_user_id" "uuid", "p_password" "text") OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."update_users_panel_updated_at"() RETURNS "trigger" LANGUAGE "plpgsql" AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$; ALTER FUNCTION "public"."update_users_panel_updated_at"() OWNER TO "postgres"; SET default_tablespace = ''; SET default_table_access_method = "heap"; CREATE TABLE IF NOT EXISTS "public"."actualites" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "titre" character varying(255) NOT NULL, "contenu" "text" NOT NULL, "resume" character varying(500), "categorie" character varying(50), "image_url" character varying(500), "date_publication" timestamp with time zone DEFAULT "now"() NOT NULL, "auteur" character varying(100), "actif" boolean DEFAULT true, "mise_en_avant" boolean DEFAULT false, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone, "region_id" character varying(100), "created_by" "uuid", "image_couverture" "text", CONSTRAINT "actualites_categorie_check" CHECK ((("categorie")::"text" = ANY ((ARRAY['general'::character varying, 'service'::character varying, 'promotion'::character varying, 'partenariat'::character varying, 'autre'::character varying])::"text"[]))) ); ALTER TABLE "public"."actualites" OWNER TO "postgres"; COMMENT ON TABLE "public"."actualites" IS 'Actualités et nouvelles du réseau'; COMMENT ON COLUMN "public"."actualites"."region_id" IS 'Identifiant de la région concernée par l''actualité'; COMMENT ON COLUMN "public"."actualites"."created_by" IS 'Utilisateur ayant créé l''actualité'; CREATE TABLE IF NOT EXISTS "public"."evenements" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "titre" character varying(255) NOT NULL, "description" "text", "lieu" character varying(255), "gare_id" "uuid", "date_debut" timestamp with time zone NOT NULL, "date_fin" timestamp with time zone, "image_url" character varying(500), "lien_externe" character varying(500), "actif" boolean DEFAULT true, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone, "region_id" character varying(100), "created_by" "uuid", "visible_site" boolean DEFAULT true ); ALTER TABLE "public"."evenements" OWNER TO "postgres"; COMMENT ON TABLE "public"."evenements" IS 'Événements à venir dans les gares ou sur le réseau'; COMMENT ON COLUMN "public"."evenements"."region_id" IS 'Identifiant de la région concernée par l''événement'; COMMENT ON COLUMN "public"."evenements"."created_by" IS 'Utilisateur ayant créé l''événement'; CREATE TABLE IF NOT EXISTS "public"."gare_quais" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "gare_id" "uuid" NOT NULL, "nom" "text" NOT NULL, "distance_metres" integer DEFAULT 0 NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL ); ALTER TABLE "public"."gare_quais" OWNER TO "postgres"; CREATE TABLE IF NOT EXISTS "public"."gare_transports" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "gare_id" "uuid" NOT NULL, "type" "public"."transport_type" NOT NULL, "ligne" "text", "created_at" timestamp with time zone DEFAULT "now"() NOT NULL ); ALTER TABLE "public"."gare_transports" OWNER TO "postgres"; CREATE TABLE IF NOT EXISTS "public"."gares" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "nom" "text" NOT NULL, "type" "public"."station_type" DEFAULT 'ville'::"public"."station_type" NOT NULL, "services" "public"."service_type"[] DEFAULT '{}'::"public"."service_type"[] NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, "updated_at" timestamp with time zone DEFAULT "now"() NOT NULL, "deleted_at" timestamp with time zone, "informations" "jsonb" DEFAULT '{}'::"jsonb", "quais_hall" "jsonb" DEFAULT \'[]\'::"jsonb" ); ALTER TABLE "public"."gares" OWNER TO "postgres"; COMMENT ON COLUMN "public"."gares"."informations" IS 'Informations enrichies de la gare au format JSON. Structure : { -- Informations Générales "adresse": "20 Bd Diderot, 75012 Paris", "horaires_guichet": "6h00 - 21h30", "horaires_gare": "5h00 - 00h30", "distributeur_ter": true, -- Accessibilité "service_assistance": true, -- Services "espace_attente": true, "distributeur_tgv": false, "objets_trouves": true, "toilettes": true, "wifi_gratuit": true, "photomaton": false, "defibrillateur": true, "galeries_marchandes": false, -- Voiture "depose_minute": true, "espace_taxis": true, "espace_vtc": false, "location_voiture": false, "parking": true, -- Vélo "velo_libre_service": true, "parking_velos": true, -- Transports en commun enrichis "lignes_bus": [{"nom": "29", "terminus_a": "Gare Saint-Lazare", "terminus_b": "Montempoivre"}], "lignes_metro": [{"nom": "1", "terminus_a": "La Défense", "terminus_b": "Château de Vincennes"}], "lignes_tramway": [], "lignes_car_regional": [] }'; CREATE TABLE IF NOT EXISTS "public"."horaires" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "numero_train" character varying(50) NOT NULL, "type_train" character varying(255), "type_train_id" bigint, "gare_depart_id" "uuid", "gare_depart_nom" character varying(255), "heure_depart" time without time zone, "gare_arrivee_id" "uuid", "gare_arrivee_nom" character varying(255), "heure_arrivee" time without time zone, "circule_lundi" boolean DEFAULT true, "circule_mardi" boolean DEFAULT true, "circule_mercredi" boolean DEFAULT true, "circule_jeudi" boolean DEFAULT true, "circule_vendredi" boolean DEFAULT true, "circule_samedi" boolean DEFAULT true, "circule_dimanche" boolean DEFAULT true, "circule_jours_feries" boolean DEFAULT false, "circule_dimanches_feries" boolean DEFAULT false, "jours_personnalises" "jsonb" DEFAULT '[]'::"jsonb", "jours_non_circulation" "jsonb" DEFAULT '[]'::"jsonb", "materiel_roulant_id" bigint, "ligne_id" "uuid", "ligne_nom" character varying(255), "service_annuel_id" "uuid", "service_annuel_nom" character varying(255), "est_substitution" boolean DEFAULT false, "motif_substitution" character varying(255), "actif" boolean DEFAULT true, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone, "gares_desservies" "jsonb" DEFAULT '[]'::"jsonb", "composition_train" "jsonb" DEFAULT '[]'::"jsonb", "substitution_disponible" boolean DEFAULT false, "region_id" character varying(100) ); ALTER TABLE "public"."horaires" OWNER TO "postgres"; COMMENT ON TABLE "public"."horaires" IS 'Table principale des horaires (sillons) de trains'; COMMENT ON COLUMN "public"."horaires"."numero_train" IS 'Numéro unique du train (ex: TER 12345)'; COMMENT ON COLUMN "public"."horaires"."type_train" IS 'Type de train (TER, TGV, Intercités, etc.)'; COMMENT ON COLUMN "public"."horaires"."type_train_id" IS 'Référence vers la table types_train pour le type de train'; COMMENT ON COLUMN "public"."horaires"."jours_personnalises" IS 'Dates spécifiques de circulation au format JSON'; COMMENT ON COLUMN "public"."horaires"."jours_non_circulation" IS 'Dates où le train ne circule pas au format JSON'; COMMENT ON COLUMN "public"."horaires"."ligne_id" IS 'Identifiant de la ligne associée au sillon'; COMMENT ON COLUMN "public"."horaires"."ligne_nom" IS 'Nom de la ligne associée (copie pour lecture)'; COMMENT ON COLUMN "public"."horaires"."service_annuel_id" IS 'Identifiant du service annuel associé (SA)'; COMMENT ON COLUMN "public"."horaires"."service_annuel_nom" IS 'Nom du service annuel associé (copie pour lecture)'; COMMENT ON COLUMN "public"."horaires"."est_substitution" IS 'Indique si ce sillon est une substitution autocar'; COMMENT ON COLUMN "public"."horaires"."motif_substitution" IS 'Motif de la substitution (travaux, etc.)'; COMMENT ON COLUMN "public"."horaires"."gares_desservies" IS 'Snapshot JSON des gares desservies (copie dénormalisée synchronisée avec horaires_gares_desservies). Format : [{"gare_id": "uuid", "gare_nom": "Nom Gare", "heure_arrivee": "HH:MM", "heure_depart": "HH:MM", "ordre": 1}, ...]'; COMMENT ON COLUMN "public"."horaires"."composition_train" IS 'Composition ordonnée du train : liste JSON des matériels roulants affectés au sillon. Format : [{"materiel_id": 1, "materiel_nom": "Régiolis", "materiel_nom_technique": "X73500", "materiel_image_url": "https://...", "position": 1}, ...]'; COMMENT ON COLUMN "public"."horaires"."substitution_disponible" IS 'Indique si cet horaire est disponible comme sillon de substitution'; COMMENT ON COLUMN "public"."horaires"."region_id" IS 'Identifiant de la région associée à cet horaire'; CREATE TABLE IF NOT EXISTS "public"."horaires_gares_desservies" ( "id" bigint NOT NULL, "gare_id" "uuid", "gare_nom" character varying(255) NOT NULL, "heure_arrivee" time without time zone, "heure_depart" time without time zone, "ordre" integer DEFAULT 0 NOT NULL, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "horaire_id" "uuid", "quai" character varying(50) DEFAULT NULL::character varying, "quai_id" "uuid" ); ALTER TABLE "public"."horaires_gares_desservies" OWNER TO "postgres"; COMMENT ON TABLE "public"."horaires_gares_desservies" IS 'Gares intermédiaires desservies par chaque horaire'; COMMENT ON COLUMN "public"."horaires_gares_desservies"."ordre" IS 'Position de la gare dans le parcours (1 = première après départ)'; COMMENT ON COLUMN "public"."horaires_gares_desservies"."quai" IS 'Numéro ou nom du quai attribué à cet arrêt (ex: "Voie 3", "Quai A")'; CREATE SEQUENCE IF NOT EXISTS "public"."horaires_gares_desservies_id_seq" START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE "public"."horaires_gares_desservies_id_seq" OWNER TO "postgres"; ALTER SEQUENCE "public"."horaires_gares_desservies_id_seq" OWNED BY "public"."horaires_gares_desservies"."id"; CREATE TABLE IF NOT EXISTS "public"."info_trafic" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "titre" character varying(255) NOT NULL, "description" "text", "type" character varying(50) NOT NULL, "severite" character varying(20) NOT NULL, "ligne" character varying(100), "gare_id" "uuid", "date_debut" timestamp with time zone DEFAULT "now"() NOT NULL, "date_fin" timestamp with time zone, "actif" boolean DEFAULT true, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone, "region_id" character varying(100), "created_by" "uuid", CONSTRAINT "info_trafic_severite_check" CHECK ((("severite")::"text" = ANY ((ARRAY['info'::character varying, 'warning'::character varying, 'critical'::character varying])::"text"[]))), CONSTRAINT "info_trafic_type_check" CHECK ((("type")::"text" = ANY ((ARRAY['perturbation'::character varying, 'travaux'::character varying, 'greve'::character varying, 'meteo'::character varying, 'autre'::character varying])::"text"[]))) ); ALTER TABLE "public"."info_trafic" OWNER TO "postgres"; COMMENT ON TABLE "public"."info_trafic" IS 'Informations de trafic (perturbations, travaux, etc.)'; COMMENT ON COLUMN "public"."info_trafic"."region_id" IS 'Identifiant de la région concernée par l''info trafic'; COMMENT ON COLUMN "public"."info_trafic"."created_by" IS 'Utilisateur ayant créé l''info trafic'; CREATE TABLE IF NOT EXISTS "public"."lignes" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "nom" character varying(255) NOT NULL, "code" character varying(50), "gare_depart_id" "uuid", "gare_arrivee_id" "uuid", "actif" boolean DEFAULT true, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone, "fh_url" "text", "region" character varying(100) ); ALTER TABLE "public"."lignes" OWNER TO "postgres"; COMMENT ON TABLE "public"."lignes" IS 'Lignes de train avec gares de départ et d''arrivée'; COMMENT ON COLUMN "public"."lignes"."fh_url" IS 'URL publique du fichier PDF de la fiche horaire de la ligne (stocké dans Supabase Storage)'; CREATE TABLE IF NOT EXISTS "public"."lignes_gares" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "ligne_id" "uuid", "gare_id" "uuid", "ordre" integer NOT NULL, "desserte" character varying(20) NOT NULL, "created_at" timestamp with time zone DEFAULT "now"(), CONSTRAINT "lignes_gares_desserte_check" CHECK ((("desserte")::"text" = ANY ((ARRAY['tous'::character varying, 'partielle'::character varying])::"text"[]))) ); ALTER TABLE "public"."lignes_gares" OWNER TO "postgres"; COMMENT ON TABLE "public"."lignes_gares" IS 'Gares présentes sur le tracé d''une ligne avec type de desserte'; CREATE TABLE IF NOT EXISTS "public"."materiel-roulant" ( "id" bigint NOT NULL, "nom" "text", "nom_technique" "text", "capacite" integer, "image_url" "text", "type_train" "text", "numero_serie" "text", "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone ); ALTER TABLE "public"."materiel-roulant" OWNER TO "postgres"; ALTER TABLE "public"."materiel-roulant" ALTER COLUMN "id" ADD GENERATED ALWAYS AS IDENTITY ( SEQUENCE NAME "public"."materiel-roulant_id_seq" START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1 ); CREATE TABLE IF NOT EXISTS "public"."menus_regionaux" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "nom" character varying(200) NOT NULL, "description" "text", "actif" boolean DEFAULT false, "structure" "jsonb" DEFAULT '[]'::"jsonb", "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "region_id" character varying(64) ); ALTER TABLE "public"."menus_regionaux" OWNER TO "postgres"; CREATE TABLE IF NOT EXISTS "public"."messagerie_messages" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "thread_id" "uuid" NOT NULL, "sender_id" "uuid" NOT NULL, "contenu" "text" NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL ); ALTER TABLE "public"."messagerie_messages" OWNER TO "postgres"; CREATE TABLE IF NOT EXISTS "public"."messagerie_participants" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "thread_id" "uuid" NOT NULL, "user_id" "uuid" NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL ); ALTER TABLE "public"."messagerie_participants" OWNER TO "postgres"; CREATE TABLE IF NOT EXISTS "public"."messagerie_threads" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, "updated_at" timestamp with time zone DEFAULT "now"() NOT NULL ); ALTER TABLE "public"."messagerie_threads" OWNER TO "postgres"; CREATE TABLE IF NOT EXISTS "public"."parametres" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "cle" character varying(100) NOT NULL, "valeur" "jsonb", "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"() ); ALTER TABLE "public"."parametres" OWNER TO "postgres"; CREATE TABLE IF NOT EXISTS "public"."perturbations" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "horaire_id" "uuid" NOT NULL, "type_perturbation" character varying(50) NOT NULL, "duree_retard_minutes" integer, "cause" character varying(100) NOT NULL, "cause_details" "text", "sillon_substitution_id" "uuid", "date_debut" timestamp with time zone DEFAULT "now"() NOT NULL, "date_fin" timestamp with time zone, "actif" boolean DEFAULT true, "notes" "text", "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone, "region_id" character varying(100), "created_by" "uuid", "perturbations_arrets" "jsonb", "jours_perturbation" "jsonb", CONSTRAINT "perturbations_cause_check" CHECK ((("cause")::"text" = ANY ((ARRAY['incident_technique'::character varying, 'accident_personne'::character varying, 'conditions_meteorologiques'::character varying, 'travaux'::character varying, 'mouvement_social'::character varying, 'intervention_police'::character varying, 'affluence'::character varying, 'malveillance'::character varying, 'autre'::character varying])::"text"[]))), CONSTRAINT "perturbations_type_perturbation_check" CHECK ((("type_perturbation")::"text" = ANY ((ARRAY['retard'::character varying, 'suppression'::character varying, 'modification_parcours'::character varying])::"text"[]))) ); ALTER TABLE "public"."perturbations" OWNER TO "postgres"; COMMENT ON TABLE "public"."perturbations" IS 'Table des perturbations affectant les horaires de trains'; COMMENT ON COLUMN "public"."perturbations"."type_perturbation" IS 'Type de perturbation: retard, suppression, ou modification_parcours'; COMMENT ON COLUMN "public"."perturbations"."duree_retard_minutes" IS 'Durée du retard en minutes (applicable uniquement pour type=retard)'; COMMENT ON COLUMN "public"."perturbations"."cause" IS 'Cause de la perturbation'; COMMENT ON COLUMN "public"."perturbations"."sillon_substitution_id" IS 'Train de substitution proposé (si suppression ou modification)'; COMMENT ON COLUMN "public"."perturbations"."region_id" IS 'Identifiant de la région concernée par la perturbation'; COMMENT ON COLUMN "public"."perturbations"."created_by" IS 'Utilisateur ayant créé la perturbation'; COMMENT ON COLUMN "public"."perturbations"."perturbations_arrets" IS 'Snapshot complet des perturbations par arrêt (état du formulaire). Format : [{ "index": 0, "gare_nom": "Paris Gare de Lyon", "heure_arrivee": null, "heure_depart": "07:30", "type_perturbation": "retard", "retard_minutes": 15, "retard_cumule": 0, "arret_prolonge_minutes": 0, "cause_arret": "Incident technique", "is_nouveau_terminus": false, "is_nouvelle_origine": false, "isFirst": true, "isLast": false, "manual_retard": true, "manual_arret_prolonge": false }, ...]'; COMMENT ON COLUMN "public"."perturbations"."jours_perturbation" IS 'Liste des jours/périodes de perturbation. Format : [{type: "jour"|"periode", date: "YYYY-MM-DD", dateDebut: "YYYY-MM-DD", dateFin: "YYYY-MM-DD"}]'; CREATE TABLE IF NOT EXISTS "public"."perturbations_modifications_parcours" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "perturbation_id" "uuid" NOT NULL, "type_modification" character varying(20) NOT NULL, "gare_id" "uuid", "gare_nom" character varying(255) NOT NULL, "nouvelle_heure_arrivee" time without time zone, "nouvelle_heure_depart" time without time zone, "ordre" integer, "created_at" timestamp with time zone DEFAULT "now"(), CONSTRAINT "perturbations_modifications_parcours_type_modification_check" CHECK ((("type_modification")::"text" = ANY ((ARRAY['gare_supprimee'::character varying, 'gare_ajoutee'::character varying, 'horaire_modifie'::character varying])::"text"[]))) ); ALTER TABLE "public"."perturbations_modifications_parcours" OWNER TO "postgres"; COMMENT ON TABLE "public"."perturbations_modifications_parcours" IS 'Détails des modifications de parcours pour les perturbations'; CREATE TABLE IF NOT EXISTS "public"."services_annuels" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "nom" character varying(255) NOT NULL, "code" character varying(50), "date_debut" "date" NOT NULL, "date_fin" "date" NOT NULL, "description" "text", "actif" boolean DEFAULT true, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone ); ALTER TABLE "public"."services_annuels" OWNER TO "postgres"; COMMENT ON TABLE "public"."services_annuels" IS 'Services annuels attribuables aux horaires'; CREATE TABLE IF NOT EXISTS "public"."tarifs" ( "id" integer NOT NULL, "nom" character varying(255) NOT NULL, "type" character varying(50) NOT NULL, "description" "text", "prix_minimum" numeric(10,2), "prix_par_km" numeric(10,3), "age_maximum" integer, "regions" "text"[] NOT NULL, "date_debut" "date", "date_fin" "date", "created_at" timestamp without time zone DEFAULT "now"(), "updated_at" timestamp without time zone DEFAULT "now"(), "ordre" integer DEFAULT 0 NOT NULL, "page_dediee" boolean DEFAULT false, "infos" "jsonb" DEFAULT '{}'::"jsonb" ); ALTER TABLE "public"."tarifs" OWNER TO "postgres"; CREATE SEQUENCE IF NOT EXISTS "public"."tarifs_id_seq" AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE "public"."tarifs_id_seq" OWNER TO "postgres"; ALTER SEQUENCE "public"."tarifs_id_seq" OWNED BY "public"."tarifs"."id"; CREATE TABLE IF NOT EXISTS "public"."travaux" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "titre" "text" NOT NULL, "description" "text", "date_debut" "date" NOT NULL, "date_fin" "date" NOT NULL, "jours_travaux" "text"[] NOT NULL, "heure_debut" time without time zone NOT NULL, "heure_fin" time without time zone NOT NULL, "actif" boolean DEFAULT true, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone, "ligne_id" "uuid", "region_id" character varying(100), "created_by" "uuid", "substitutions_attribuees" "jsonb" DEFAULT '[]'::"jsonb", "ligne_nom" "text", CONSTRAINT "valid_dates" CHECK (("date_fin" >= "date_debut")), CONSTRAINT "valid_hours" CHECK (("heure_fin" > "heure_debut")) ); ALTER TABLE "public"."travaux" OWNER TO "postgres"; COMMENT ON TABLE "public"."travaux" IS 'Table principale pour la gestion des travaux sur les lignes'; COMMENT ON COLUMN "public"."travaux"."jours_travaux" IS 'Jours de la semaine où les travaux ont lieu'; COMMENT ON COLUMN "public"."travaux"."actif" IS 'Indique si les travaux sont actifs'; COMMENT ON COLUMN "public"."travaux"."deleted_at" IS 'Date de suppression (soft delete)'; COMMENT ON COLUMN "public"."travaux"."region_id" IS 'Identifiant de la région concernée par les travaux'; COMMENT ON COLUMN "public"."travaux"."created_by" IS 'Utilisateur ayant créé les travaux'; CREATE TABLE IF NOT EXISTS "public"."travaux_substitutions" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "travaux_id" "uuid" NOT NULL, "horaire_id" "uuid" NOT NULL, "ordre" integer DEFAULT 0, "created_at" timestamp with time zone DEFAULT "now"() ); ALTER TABLE "public"."travaux_substitutions" OWNER TO "postgres"; COMMENT ON TABLE "public"."travaux_substitutions" IS 'Table de liaison entre travaux et horaires de substitution'; COMMENT ON COLUMN "public"."travaux_substitutions"."ordre" IS 'Ordre d''affichage des substitutions'; CREATE TABLE IF NOT EXISTS "public"."types_train" ( "id" bigint NOT NULL, "nom" character varying(255) NOT NULL, "code" character varying(50), "description" "text", "logo_url" "text", "couleur" character varying(20) DEFAULT '#0074d9'::character varying, "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "deleted_at" timestamp with time zone ); ALTER TABLE "public"."types_train" OWNER TO "postgres"; COMMENT ON TABLE "public"."types_train" IS 'Types de train configurables avec logos et couleurs'; CREATE SEQUENCE IF NOT EXISTS "public"."types_train_id_seq" START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE "public"."types_train_id_seq" OWNER TO "postgres"; ALTER SEQUENCE "public"."types_train_id_seq" OWNED BY "public"."types_train"."id"; CREATE TABLE IF NOT EXISTS "public"."users_panel" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "email" character varying(255) NOT NULL, "nom" character varying(100) NOT NULL, "prenom" character varying(100) NOT NULL, "role" character varying(50) DEFAULT 'utilisateur'::character varying NOT NULL, "actif" boolean DEFAULT true NOT NULL, "password_hash" character varying(255), "photo_url" "text", "region_admin" boolean DEFAULT false, "region_nom" character varying(255), "created_at" timestamp with time zone DEFAULT "now"(), "updated_at" timestamp with time zone DEFAULT "now"(), "region_id" character varying(100), "permissions" "jsonb" DEFAULT '{}'::"jsonb" NOT NULL ); ALTER TABLE "public"."users_panel" OWNER TO "postgres"; COMMENT ON TABLE "public"."users_panel" IS 'Utilisateurs de l''application avec leurs informations et rôles'; COMMENT ON COLUMN "public"."users_panel"."id" IS 'Identifiant unique de l''utilisateur'; COMMENT ON COLUMN "public"."users_panel"."email" IS 'Adresse email de l''utilisateur (unique)'; COMMENT ON COLUMN "public"."users_panel"."nom" IS 'Nom de famille de l''utilisateur'; COMMENT ON COLUMN "public"."users_panel"."prenom" IS 'Prénom de l''utilisateur'; COMMENT ON COLUMN "public"."users_panel"."role" IS 'Rôle de l''utilisateur (admin, gestionnaire, utilisateur)'; COMMENT ON COLUMN "public"."users_panel"."actif" IS 'Indique si l''utilisateur est actif ou désactivé'; COMMENT ON COLUMN "public"."users_panel"."password_hash" IS 'Hash du mot de passe (ne pas stocker en clair)'; COMMENT ON COLUMN "public"."users_panel"."photo_url" IS 'URL de la photo de profil'; COMMENT ON COLUMN "public"."users_panel"."region_admin" IS 'Indique si l''utilisateur administre une région'; COMMENT ON COLUMN "public"."users_panel"."region_nom" IS 'Nom de la région administrée (si applicable)'; COMMENT ON COLUMN "public"."users_panel"."created_at" IS 'Date de création de l''utilisateur'; COMMENT ON COLUMN "public"."users_panel"."updated_at" IS 'Date de dernière modification de l''utilisateur'; COMMENT ON COLUMN "public"."users_panel"."region_id" IS 'Identifiant de la région administrée par l''utilisateur'; ALTER TABLE ONLY "public"."horaires_gares_desservies" ALTER COLUMN "id" SET DEFAULT "nextval"('"public"."horaires_gares_desservies_id_seq"'::"regclass"); ALTER TABLE ONLY "public"."tarifs" ALTER COLUMN "id" SET DEFAULT "nextval"('"public"."tarifs_id_seq"'::"regclass"); ALTER TABLE ONLY "public"."types_train" ALTER COLUMN "id" SET DEFAULT "nextval"('"public"."types_train_id_seq"'::"regclass"); ALTER TABLE ONLY "public"."actualites" DROP CONSTRAINT IF EXISTS "actualites_pkey"; ALTER TABLE ONLY "public"."actualites" ADD CONSTRAINT "actualites_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."evenements" DROP CONSTRAINT IF EXISTS "evenements_pkey"; ALTER TABLE ONLY "public"."evenements" ADD CONSTRAINT "evenements_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."gare_quais" DROP CONSTRAINT IF EXISTS "gare_quais_pkey"; ALTER TABLE ONLY "public"."gare_quais" ADD CONSTRAINT "gare_quais_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."gare_transports" DROP CONSTRAINT IF EXISTS "gare_transports_pkey"; ALTER TABLE ONLY "public"."gare_transports" ADD CONSTRAINT "gare_transports_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."gares" DROP CONSTRAINT IF EXISTS "gares_pkey"; ALTER TABLE ONLY "public"."gares" ADD CONSTRAINT "gares_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."horaires_gares_desservies" DROP CONSTRAINT IF EXISTS "horaires_gares_desservies_pkey"; ALTER TABLE ONLY "public"."horaires_gares_desservies" ADD CONSTRAINT "horaires_gares_desservies_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."horaires" DROP CONSTRAINT IF EXISTS "horaires_pkey"; ALTER TABLE ONLY "public"."horaires" ADD CONSTRAINT "horaires_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."info_trafic" DROP CONSTRAINT IF EXISTS "info_trafic_pkey"; ALTER TABLE ONLY "public"."info_trafic" ADD CONSTRAINT "info_trafic_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."lignes_gares" DROP CONSTRAINT IF EXISTS "lignes_gares_pkey"; ALTER TABLE ONLY "public"."lignes_gares" ADD CONSTRAINT "lignes_gares_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."lignes" DROP CONSTRAINT IF EXISTS "lignes_pkey"; ALTER TABLE ONLY "public"."lignes" ADD CONSTRAINT "lignes_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."materiel-roulant" DROP CONSTRAINT IF EXISTS "materiel-roulant_numero_serie_key"; ALTER TABLE ONLY "public"."materiel-roulant" ADD CONSTRAINT "materiel-roulant_numero_serie_key" UNIQUE ("numero_serie"); ALTER TABLE ONLY "public"."materiel-roulant" DROP CONSTRAINT IF EXISTS "materiel-roulant_pkey"; ALTER TABLE ONLY "public"."materiel-roulant" ADD CONSTRAINT "materiel-roulant_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."menus_regionaux" DROP CONSTRAINT IF EXISTS "menus_regionaux_pkey"; ALTER TABLE ONLY "public"."menus_regionaux" ADD CONSTRAINT "menus_regionaux_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."messagerie_messages" DROP CONSTRAINT IF EXISTS "messagerie_messages_pkey"; ALTER TABLE ONLY "public"."messagerie_messages" ADD CONSTRAINT "messagerie_messages_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."messagerie_participants" DROP CONSTRAINT IF EXISTS "messagerie_participants_pkey"; ALTER TABLE ONLY "public"."messagerie_participants" ADD CONSTRAINT "messagerie_participants_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."messagerie_participants" DROP CONSTRAINT IF EXISTS "messagerie_participants_thread_id_user_id_key"; ALTER TABLE ONLY "public"."messagerie_participants" ADD CONSTRAINT "messagerie_participants_thread_id_user_id_key" UNIQUE ("thread_id", "user_id"); ALTER TABLE ONLY "public"."messagerie_threads" DROP CONSTRAINT IF EXISTS "messagerie_threads_pkey"; ALTER TABLE ONLY "public"."messagerie_threads" ADD CONSTRAINT "messagerie_threads_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."parametres" DROP CONSTRAINT IF EXISTS "parametres_cle_key"; ALTER TABLE ONLY "public"."parametres" ADD CONSTRAINT "parametres_cle_key" UNIQUE ("cle"); ALTER TABLE ONLY "public"."parametres" DROP CONSTRAINT IF EXISTS "parametres_pkey"; ALTER TABLE ONLY "public"."parametres" ADD CONSTRAINT "parametres_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."perturbations_modifications_parcours" DROP CONSTRAINT IF EXISTS "perturbations_modifications_parcours_pkey"; ALTER TABLE ONLY "public"."perturbations_modifications_parcours" ADD CONSTRAINT "perturbations_modifications_parcours_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."perturbations" DROP CONSTRAINT IF EXISTS "perturbations_pkey"; ALTER TABLE ONLY "public"."perturbations" ADD CONSTRAINT "perturbations_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."services_annuels" DROP CONSTRAINT IF EXISTS "services_annuels_pkey"; ALTER TABLE ONLY "public"."services_annuels" ADD CONSTRAINT "services_annuels_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."tarifs" DROP CONSTRAINT IF EXISTS "tarifs_pkey"; ALTER TABLE ONLY "public"."tarifs" ADD CONSTRAINT "tarifs_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."travaux" DROP CONSTRAINT IF EXISTS "travaux_pkey"; ALTER TABLE ONLY "public"."travaux" ADD CONSTRAINT "travaux_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."travaux_substitutions" DROP CONSTRAINT IF EXISTS "travaux_substitutions_pkey"; ALTER TABLE ONLY "public"."travaux_substitutions" ADD CONSTRAINT "travaux_substitutions_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."travaux_substitutions" DROP CONSTRAINT IF EXISTS "travaux_substitutions_travaux_id_horaire_id_key"; ALTER TABLE ONLY "public"."travaux_substitutions" ADD CONSTRAINT "travaux_substitutions_travaux_id_horaire_id_key" UNIQUE ("travaux_id", "horaire_id"); ALTER TABLE ONLY "public"."types_train" DROP CONSTRAINT IF EXISTS "types_train_pkey"; ALTER TABLE ONLY "public"."types_train" ADD CONSTRAINT "types_train_pkey" PRIMARY KEY ("id"); ALTER TABLE ONLY "public"."users_panel" DROP CONSTRAINT IF EXISTS "users_panel_email_key"; ALTER TABLE ONLY "public"."users_panel" ADD CONSTRAINT "users_panel_email_key" UNIQUE ("email"); ALTER TABLE ONLY "public"."users_panel" DROP CONSTRAINT IF EXISTS "users_panel_pkey"; ALTER TABLE ONLY "public"."users_panel" ADD CONSTRAINT "users_panel_pkey" PRIMARY KEY ("id"); DROP INDEX IF EXISTS "idx_actualites_actif"; CREATE INDEX "idx_actualites_actif" ON "public"."actualites" USING "btree" ("actif") WHERE ("deleted_at" IS NULL); DROP INDEX IF EXISTS "idx_actualites_created_by"; CREATE INDEX "idx_actualites_created_by" ON "public"."actualites" USING "btree" ("created_by"); DROP INDEX IF EXISTS "idx_actualites_publication"; CREATE INDEX "idx_actualites_publication" ON "public"."actualites" USING "btree" ("date_publication"); DROP INDEX IF EXISTS "idx_actualites_region_id"; CREATE INDEX "idx_actualites_region_id" ON "public"."actualites" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_evenements_actif"; CREATE INDEX "idx_evenements_actif" ON "public"."evenements" USING "btree" ("actif") WHERE ("deleted_at" IS NULL); DROP INDEX IF EXISTS "idx_evenements_created_by"; CREATE INDEX "idx_evenements_created_by" ON "public"."evenements" USING "btree" ("created_by"); DROP INDEX IF EXISTS "idx_evenements_dates"; CREATE INDEX "idx_evenements_dates" ON "public"."evenements" USING "btree" ("date_debut", "date_fin"); DROP INDEX IF EXISTS "idx_evenements_region_id"; CREATE INDEX "idx_evenements_region_id" ON "public"."evenements" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_gare_quais_gare_id"; CREATE INDEX "idx_gare_quais_gare_id" ON "public"."gare_quais" USING "btree" ("gare_id"); DROP INDEX IF EXISTS "idx_gare_transports_gare_id"; CREATE INDEX "idx_gare_transports_gare_id" ON "public"."gare_transports" USING "btree" ("gare_id"); DROP INDEX IF EXISTS "idx_gares_desservies_horaire"; CREATE INDEX "idx_gares_desservies_horaire" ON "public"."horaires_gares_desservies" USING "btree" ("horaire_id"); DROP INDEX IF EXISTS "idx_gares_desservies_ordre"; CREATE INDEX "idx_gares_desservies_ordre" ON "public"."horaires_gares_desservies" USING "btree" ("horaire_id", "ordre"); DROP INDEX IF EXISTS "idx_hgd_gare_id"; CREATE INDEX "idx_hgd_gare_id" ON "public"."horaires_gares_desservies" USING "btree" ("gare_id"); DROP INDEX IF EXISTS "idx_hgd_horaire_id"; CREATE INDEX "idx_hgd_horaire_id" ON "public"."horaires_gares_desservies" USING "btree" ("horaire_id"); DROP INDEX IF EXISTS "idx_horaires_actif"; CREATE INDEX "idx_horaires_actif" ON "public"."horaires" USING "btree" ("actif") WHERE ("deleted_at" IS NULL); DROP INDEX IF EXISTS "idx_horaires_gare_arrivee"; CREATE INDEX "idx_horaires_gare_arrivee" ON "public"."horaires" USING "btree" ("gare_arrivee_id"); DROP INDEX IF EXISTS "idx_horaires_gare_depart"; CREATE INDEX "idx_horaires_gare_depart" ON "public"."horaires" USING "btree" ("gare_depart_id"); DROP INDEX IF EXISTS "idx_horaires_ligne"; CREATE INDEX "idx_horaires_ligne" ON "public"."horaires" USING "btree" ("ligne_id"); DROP INDEX IF EXISTS "idx_horaires_materiel"; CREATE INDEX "idx_horaires_materiel" ON "public"."horaires" USING "btree" ("materiel_roulant_id"); DROP INDEX IF EXISTS "idx_horaires_numero_train"; CREATE INDEX "idx_horaires_numero_train" ON "public"."horaires" USING "btree" ("numero_train"); DROP INDEX IF EXISTS "idx_horaires_region_id"; CREATE INDEX "idx_horaires_region_id" ON "public"."horaires" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_horaires_service_annuel"; CREATE INDEX "idx_horaires_service_annuel" ON "public"."horaires" USING "btree" ("service_annuel_id"); DROP INDEX IF EXISTS "idx_horaires_substitution"; CREATE INDEX "idx_horaires_substitution" ON "public"."horaires" USING "btree" ("est_substitution"); DROP INDEX IF EXISTS "idx_horaires_type_train"; CREATE INDEX "idx_horaires_type_train" ON "public"."horaires" USING "btree" ("type_train_id"); DROP INDEX IF EXISTS "idx_info_trafic_actif"; CREATE INDEX "idx_info_trafic_actif" ON "public"."info_trafic" USING "btree" ("actif") WHERE ("deleted_at" IS NULL); DROP INDEX IF EXISTS "idx_info_trafic_created_by"; CREATE INDEX "idx_info_trafic_created_by" ON "public"."info_trafic" USING "btree" ("created_by"); DROP INDEX IF EXISTS "idx_info_trafic_dates"; CREATE INDEX "idx_info_trafic_dates" ON "public"."info_trafic" USING "btree" ("date_debut", "date_fin"); DROP INDEX IF EXISTS "idx_info_trafic_region_id"; CREATE INDEX "idx_info_trafic_region_id" ON "public"."info_trafic" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_lignes_actif"; CREATE INDEX "idx_lignes_actif" ON "public"."lignes" USING "btree" ("actif") WHERE ("deleted_at" IS NULL); DROP INDEX IF EXISTS "idx_lignes_fh_url"; CREATE INDEX "idx_lignes_fh_url" ON "public"."lignes" USING "btree" ("fh_url"); DROP INDEX IF EXISTS "idx_lignes_gares_ligne"; CREATE INDEX "idx_lignes_gares_ligne" ON "public"."lignes_gares" USING "btree" ("ligne_id"); DROP INDEX IF EXISTS "idx_lignes_gares_ordre"; CREATE INDEX "idx_lignes_gares_ordre" ON "public"."lignes_gares" USING "btree" ("ligne_id", "ordre"); DROP INDEX IF EXISTS "idx_menus_regionaux_region_id"; CREATE INDEX "idx_menus_regionaux_region_id" ON "public"."menus_regionaux" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_messagerie_messages_created_at"; CREATE INDEX "idx_messagerie_messages_created_at" ON "public"."messagerie_messages" USING "btree" ("created_at" DESC); DROP INDEX IF EXISTS "idx_messagerie_messages_thread_id"; CREATE INDEX "idx_messagerie_messages_thread_id" ON "public"."messagerie_messages" USING "btree" ("thread_id"); DROP INDEX IF EXISTS "idx_messagerie_participants_user_id"; CREATE INDEX "idx_messagerie_participants_user_id" ON "public"."messagerie_participants" USING "btree" ("user_id"); DROP INDEX IF EXISTS "idx_modif_parcours_gare"; CREATE INDEX "idx_modif_parcours_gare" ON "public"."perturbations_modifications_parcours" USING "btree" ("gare_id"); DROP INDEX IF EXISTS "idx_modif_parcours_perturbation"; CREATE INDEX "idx_modif_parcours_perturbation" ON "public"."perturbations_modifications_parcours" USING "btree" ("perturbation_id"); DROP INDEX IF EXISTS "idx_perturbations_actif"; CREATE INDEX "idx_perturbations_actif" ON "public"."perturbations" USING "btree" ("actif") WHERE ("deleted_at" IS NULL); DROP INDEX IF EXISTS "idx_perturbations_created_by"; CREATE INDEX "idx_perturbations_created_by" ON "public"."perturbations" USING "btree" ("created_by"); DROP INDEX IF EXISTS "idx_perturbations_dates"; CREATE INDEX "idx_perturbations_dates" ON "public"."perturbations" USING "btree" ("date_debut", "date_fin"); DROP INDEX IF EXISTS "idx_perturbations_horaire"; CREATE INDEX "idx_perturbations_horaire" ON "public"."perturbations" USING "btree" ("horaire_id"); DROP INDEX IF EXISTS "idx_perturbations_region_id"; CREATE INDEX "idx_perturbations_region_id" ON "public"."perturbations" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_perturbations_sillon_substitution"; CREATE INDEX "idx_perturbations_sillon_substitution" ON "public"."perturbations" USING "btree" ("sillon_substitution_id"); DROP INDEX IF EXISTS "idx_perturbations_type"; CREATE INDEX "idx_perturbations_type" ON "public"."perturbations" USING "btree" ("type_perturbation"); DROP INDEX IF EXISTS "idx_services_annuels_actif"; CREATE INDEX "idx_services_annuels_actif" ON "public"."services_annuels" USING "btree" ("actif") WHERE ("deleted_at" IS NULL); DROP INDEX IF EXISTS "idx_services_annuels_dates"; CREATE INDEX "idx_services_annuels_dates" ON "public"."services_annuels" USING "btree" ("date_debut", "date_fin"); DROP INDEX IF EXISTS "idx_tarifs_ordre"; CREATE INDEX "idx_tarifs_ordre" ON "public"."tarifs" USING "btree" ("ordre"); DROP INDEX IF EXISTS "idx_tarifs_regions"; CREATE INDEX "idx_tarifs_regions" ON "public"."tarifs" USING "gin" ("regions"); DROP INDEX IF EXISTS "idx_travaux_actif"; CREATE INDEX "idx_travaux_actif" ON "public"."travaux" USING "btree" ("actif"); DROP INDEX IF EXISTS "idx_travaux_created_by"; CREATE INDEX "idx_travaux_created_by" ON "public"."travaux" USING "btree" ("created_by"); DROP INDEX IF EXISTS "idx_travaux_dates"; CREATE INDEX "idx_travaux_dates" ON "public"."travaux" USING "btree" ("date_debut", "date_fin"); DROP INDEX IF EXISTS "idx_travaux_deleted"; CREATE INDEX "idx_travaux_deleted" ON "public"."travaux" USING "btree" ("deleted_at"); DROP INDEX IF EXISTS "idx_travaux_ligne_id"; CREATE INDEX "idx_travaux_ligne_id" ON "public"."travaux" USING "btree" ("ligne_id"); DROP INDEX IF EXISTS "idx_travaux_region_id"; CREATE INDEX "idx_travaux_region_id" ON "public"."travaux" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_travaux_substitutions_attribuees_gin"; CREATE INDEX "idx_travaux_substitutions_attribuees_gin" ON "public"."travaux" USING "gin" ("substitutions_attribuees"); DROP INDEX IF EXISTS "idx_travaux_substitutions_horaire"; CREATE INDEX "idx_travaux_substitutions_horaire" ON "public"."travaux_substitutions" USING "btree" ("horaire_id"); DROP INDEX IF EXISTS "idx_travaux_substitutions_travaux"; CREATE INDEX "idx_travaux_substitutions_travaux" ON "public"."travaux_substitutions" USING "btree" ("travaux_id"); DROP INDEX IF EXISTS "idx_types_train_code"; CREATE INDEX "idx_types_train_code" ON "public"."types_train" USING "btree" ("code"); DROP INDEX IF EXISTS "idx_types_train_deleted_at"; CREATE INDEX "idx_types_train_deleted_at" ON "public"."types_train" USING "btree" ("deleted_at"); DROP INDEX IF EXISTS "idx_users_panel_actif"; CREATE INDEX "idx_users_panel_actif" ON "public"."users_panel" USING "btree" ("actif"); DROP INDEX IF EXISTS "idx_users_panel_email"; CREATE INDEX "idx_users_panel_email" ON "public"."users_panel" USING "btree" ("email"); DROP INDEX IF EXISTS "idx_users_panel_region_id"; CREATE INDEX "idx_users_panel_region_id" ON "public"."users_panel" USING "btree" ("region_id"); DROP INDEX IF EXISTS "idx_users_panel_role"; CREATE INDEX "idx_users_panel_role" ON "public"."users_panel" USING "btree" ("role"); DROP INDEX IF EXISTS "users_panel_email_lower_idx"; CREATE UNIQUE INDEX "users_panel_email_lower_idx" ON "public"."users_panel" USING "btree" ("lower"(("email")::"text")); CREATE OR REPLACE TRIGGER "tr_gares_set_updated_at" BEFORE UPDATE ON "public"."gares" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"(); CREATE OR REPLACE TRIGGER "tr_users_panel_set_updated_at" BEFORE UPDATE ON "public"."users_panel" FOR EACH ROW EXECUTE FUNCTION "public"."set_updated_at"(); CREATE OR REPLACE TRIGGER "trigger_update_travaux_updated_at" BEFORE UPDATE ON "public"."travaux" FOR EACH ROW EXECUTE FUNCTION "public"."update_travaux_updated_at"(); CREATE OR REPLACE TRIGGER "trigger_update_users_panel_updated_at" BEFORE UPDATE ON "public"."users_panel" FOR EACH ROW EXECUTE FUNCTION "public"."update_users_panel_updated_at"(); CREATE OR REPLACE TRIGGER "update_actualites_updated_at" BEFORE UPDATE ON "public"."actualites" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); CREATE OR REPLACE TRIGGER "update_evenements_updated_at" BEFORE UPDATE ON "public"."evenements" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); CREATE OR REPLACE TRIGGER "update_horaires_gares_desservies_updated_at" BEFORE UPDATE ON "public"."horaires_gares_desservies" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); CREATE OR REPLACE TRIGGER "update_horaires_updated_at" BEFORE UPDATE ON "public"."horaires" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); CREATE OR REPLACE TRIGGER "update_info_trafic_updated_at" BEFORE UPDATE ON "public"."info_trafic" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); CREATE OR REPLACE TRIGGER "update_lignes_updated_at" BEFORE UPDATE ON "public"."lignes" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); CREATE OR REPLACE TRIGGER "update_perturbations_updated_at" BEFORE UPDATE ON "public"."perturbations" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); CREATE OR REPLACE TRIGGER "update_services_annuels_updated_at" BEFORE UPDATE ON "public"."services_annuels" FOR EACH ROW EXECUTE FUNCTION "public"."update_updated_at_column"(); ALTER TABLE ONLY "public"."evenements" DROP CONSTRAINT IF EXISTS "evenements_gare_id_fkey"; ALTER TABLE ONLY "public"."evenements" ADD CONSTRAINT "evenements_gare_id_fkey" FOREIGN KEY ("gare_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."horaires_gares_desservies" DROP CONSTRAINT IF EXISTS "fk_horaires_gares_horaire_id"; ALTER TABLE ONLY "public"."horaires_gares_desservies" ADD CONSTRAINT "fk_horaires_gares_horaire_id" FOREIGN KEY ("horaire_id") REFERENCES "public"."horaires"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."gare_quais" DROP CONSTRAINT IF EXISTS "gare_quais_gare_id_fkey"; ALTER TABLE ONLY "public"."gare_quais" ADD CONSTRAINT "gare_quais_gare_id_fkey" FOREIGN KEY ("gare_id") REFERENCES "public"."gares"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."gare_transports" DROP CONSTRAINT IF EXISTS "gare_transports_gare_id_fkey"; ALTER TABLE ONLY "public"."gare_transports" ADD CONSTRAINT "gare_transports_gare_id_fkey" FOREIGN KEY ("gare_id") REFERENCES "public"."gares"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."horaires" DROP CONSTRAINT IF EXISTS "horaires_gare_arrivee_id_fkey"; ALTER TABLE ONLY "public"."horaires" ADD CONSTRAINT "horaires_gare_arrivee_id_fkey" FOREIGN KEY ("gare_arrivee_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."horaires" DROP CONSTRAINT IF EXISTS "horaires_gare_depart_id_fkey"; ALTER TABLE ONLY "public"."horaires" ADD CONSTRAINT "horaires_gare_depart_id_fkey" FOREIGN KEY ("gare_depart_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."horaires_gares_desservies" DROP CONSTRAINT IF EXISTS "horaires_gares_desservies_gare_id_fkey"; ALTER TABLE ONLY "public"."horaires_gares_desservies" ADD CONSTRAINT "horaires_gares_desservies_gare_id_fkey" FOREIGN KEY ("gare_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."horaires_gares_desservies" DROP CONSTRAINT IF EXISTS "horaires_gares_desservies_quai_id_fkey"; ALTER TABLE ONLY "public"."horaires_gares_desservies" ADD CONSTRAINT "horaires_gares_desservies_quai_id_fkey" FOREIGN KEY ("quai_id") REFERENCES "public"."gare_quais"("id"); ALTER TABLE ONLY "public"."horaires" DROP CONSTRAINT IF EXISTS "horaires_ligne_id_fkey"; ALTER TABLE ONLY "public"."horaires" ADD CONSTRAINT "horaires_ligne_id_fkey" FOREIGN KEY ("ligne_id") REFERENCES "public"."lignes"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."horaires" DROP CONSTRAINT IF EXISTS "horaires_materiel_roulant_id_fkey"; ALTER TABLE ONLY "public"."horaires" ADD CONSTRAINT "horaires_materiel_roulant_id_fkey" FOREIGN KEY ("materiel_roulant_id") REFERENCES "public"."materiel-roulant"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."horaires" DROP CONSTRAINT IF EXISTS "horaires_service_annuel_id_fkey"; ALTER TABLE ONLY "public"."horaires" ADD CONSTRAINT "horaires_service_annuel_id_fkey" FOREIGN KEY ("service_annuel_id") REFERENCES "public"."services_annuels"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."horaires" DROP CONSTRAINT IF EXISTS "horaires_type_train_id_fkey"; ALTER TABLE ONLY "public"."horaires" ADD CONSTRAINT "horaires_type_train_id_fkey" FOREIGN KEY ("type_train_id") REFERENCES "public"."types_train"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."info_trafic" DROP CONSTRAINT IF EXISTS "info_trafic_gare_id_fkey"; ALTER TABLE ONLY "public"."info_trafic" ADD CONSTRAINT "info_trafic_gare_id_fkey" FOREIGN KEY ("gare_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."lignes" DROP CONSTRAINT IF EXISTS "lignes_gare_arrivee_id_fkey"; ALTER TABLE ONLY "public"."lignes" ADD CONSTRAINT "lignes_gare_arrivee_id_fkey" FOREIGN KEY ("gare_arrivee_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."lignes" DROP CONSTRAINT IF EXISTS "lignes_gare_depart_id_fkey"; ALTER TABLE ONLY "public"."lignes" ADD CONSTRAINT "lignes_gare_depart_id_fkey" FOREIGN KEY ("gare_depart_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."lignes_gares" DROP CONSTRAINT IF EXISTS "lignes_gares_gare_id_fkey"; ALTER TABLE ONLY "public"."lignes_gares" ADD CONSTRAINT "lignes_gares_gare_id_fkey" FOREIGN KEY ("gare_id") REFERENCES "public"."gares"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."lignes_gares" DROP CONSTRAINT IF EXISTS "lignes_gares_ligne_id_fkey"; ALTER TABLE ONLY "public"."lignes_gares" ADD CONSTRAINT "lignes_gares_ligne_id_fkey" FOREIGN KEY ("ligne_id") REFERENCES "public"."lignes"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."messagerie_messages" DROP CONSTRAINT IF EXISTS "messagerie_messages_sender_id_fkey"; ALTER TABLE ONLY "public"."messagerie_messages" ADD CONSTRAINT "messagerie_messages_sender_id_fkey" FOREIGN KEY ("sender_id") REFERENCES "public"."users_panel"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."messagerie_messages" DROP CONSTRAINT IF EXISTS "messagerie_messages_thread_id_fkey"; ALTER TABLE ONLY "public"."messagerie_messages" ADD CONSTRAINT "messagerie_messages_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "public"."messagerie_threads"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."messagerie_participants" DROP CONSTRAINT IF EXISTS "messagerie_participants_thread_id_fkey"; ALTER TABLE ONLY "public"."messagerie_participants" ADD CONSTRAINT "messagerie_participants_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "public"."messagerie_threads"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."messagerie_participants" DROP CONSTRAINT IF EXISTS "messagerie_participants_user_id_fkey"; ALTER TABLE ONLY "public"."messagerie_participants" ADD CONSTRAINT "messagerie_participants_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users_panel"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."perturbations" DROP CONSTRAINT IF EXISTS "perturbations_horaire_id_fkey"; ALTER TABLE ONLY "public"."perturbations" ADD CONSTRAINT "perturbations_horaire_id_fkey" FOREIGN KEY ("horaire_id") REFERENCES "public"."horaires"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."perturbations_modifications_parcours" DROP CONSTRAINT IF EXISTS "perturbations_modifications_parcours_gare_id_fkey"; ALTER TABLE ONLY "public"."perturbations_modifications_parcours" ADD CONSTRAINT "perturbations_modifications_parcours_gare_id_fkey" FOREIGN KEY ("gare_id") REFERENCES "public"."gares"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."perturbations_modifications_parcours" DROP CONSTRAINT IF EXISTS "perturbations_modifications_parcours_perturbation_id_fkey"; ALTER TABLE ONLY "public"."perturbations_modifications_parcours" ADD CONSTRAINT "perturbations_modifications_parcours_perturbation_id_fkey" FOREIGN KEY ("perturbation_id") REFERENCES "public"."perturbations"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."perturbations" DROP CONSTRAINT IF EXISTS "perturbations_sillon_substitution_id_fkey"; ALTER TABLE ONLY "public"."perturbations" ADD CONSTRAINT "perturbations_sillon_substitution_id_fkey" FOREIGN KEY ("sillon_substitution_id") REFERENCES "public"."horaires"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."travaux" DROP CONSTRAINT IF EXISTS "travaux_created_by_fkey"; ALTER TABLE ONLY "public"."travaux" ADD CONSTRAINT "travaux_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "public"."users_panel"("id"); ALTER TABLE ONLY "public"."travaux" DROP CONSTRAINT IF EXISTS "travaux_ligne_id_fkey"; ALTER TABLE ONLY "public"."travaux" ADD CONSTRAINT "travaux_ligne_id_fkey" FOREIGN KEY ("ligne_id") REFERENCES "public"."lignes"("id") ON DELETE SET NULL; ALTER TABLE ONLY "public"."travaux_substitutions" DROP CONSTRAINT IF EXISTS "travaux_substitutions_horaire_id_fkey"; ALTER TABLE ONLY "public"."travaux_substitutions" ADD CONSTRAINT "travaux_substitutions_horaire_id_fkey" FOREIGN KEY ("horaire_id") REFERENCES "public"."horaires"("id") ON DELETE CASCADE; ALTER TABLE ONLY "public"."travaux_substitutions" DROP CONSTRAINT IF EXISTS "travaux_substitutions_travaux_id_fkey"; ALTER TABLE ONLY "public"."travaux_substitutions" ADD CONSTRAINT "travaux_substitutions_travaux_id_fkey" FOREIGN KEY ("travaux_id") REFERENCES "public"."travaux"("id") ON DELETE CASCADE; CREATE POLICY "menus_delete" ON "public"."menus_regionaux" FOR DELETE USING (true); CREATE POLICY "menus_insert" ON "public"."menus_regionaux" FOR INSERT WITH CHECK (true); ALTER TABLE "public"."menus_regionaux" ENABLE ROW LEVEL SECURITY; CREATE POLICY "menus_select" ON "public"."menus_regionaux" FOR SELECT USING (true); CREATE POLICY "menus_update" ON "public"."menus_regionaux" FOR UPDATE USING (true); ALTER TABLE "public"."messagerie_messages" ENABLE ROW LEVEL SECURITY; CREATE POLICY "messagerie_messages_insert" ON "public"."messagerie_messages" FOR INSERT TO "anon" WITH CHECK ((EXISTS ( SELECT 1 FROM "public"."messagerie_participants" "p" WHERE (("p"."thread_id" = "messagerie_messages"."thread_id") AND ("p"."user_id" = "messagerie_messages"."sender_id"))))); CREATE POLICY "messagerie_messages_select" ON "public"."messagerie_messages" FOR SELECT TO "anon" USING ((EXISTS ( SELECT 1 FROM "public"."messagerie_participants" "p" WHERE ("p"."thread_id" = "messagerie_messages"."thread_id")))); ALTER TABLE "public"."messagerie_participants" ENABLE ROW LEVEL SECURITY; CREATE POLICY "messagerie_participants_insert" ON "public"."messagerie_participants" FOR INSERT TO "anon" WITH CHECK (true); CREATE POLICY "messagerie_participants_select" ON "public"."messagerie_participants" FOR SELECT TO "anon" USING (true); ALTER TABLE "public"."messagerie_threads" ENABLE ROW LEVEL SECURITY; CREATE POLICY "messagerie_threads_insert" ON "public"."messagerie_threads" FOR INSERT TO "anon" WITH CHECK (true); CREATE POLICY "messagerie_threads_select" ON "public"."messagerie_threads" FOR SELECT TO "anon" USING ((EXISTS ( SELECT 1 FROM "public"."messagerie_participants" "p" WHERE ("p"."thread_id" = "messagerie_threads"."id")))); CREATE POLICY "messagerie_threads_update" ON "public"."messagerie_threads" FOR UPDATE TO "anon" USING ((EXISTS ( SELECT 1 FROM "public"."messagerie_participants" "p" WHERE ("p"."thread_id" = "messagerie_threads"."id")))) WITH CHECK (true); ALTER TABLE "public"."parametres" ENABLE ROW LEVEL SECURITY; CREATE POLICY "parametres_delete_all" ON "public"."parametres" FOR DELETE USING (true); CREATE POLICY "parametres_insert_all" ON "public"."parametres" FOR INSERT WITH CHECK (true); CREATE POLICY "parametres_select_all" ON "public"."parametres" FOR SELECT USING (true); CREATE POLICY "parametres_update_all" ON "public"."parametres" FOR UPDATE USING (true); GRANT USAGE ON SCHEMA "public" TO "postgres"; GRANT USAGE ON SCHEMA "public" TO "anon"; GRANT USAGE ON SCHEMA "public" TO "authenticated"; GRANT USAGE ON SCHEMA "public" TO "service_role"; GRANT ALL ON FUNCTION "public"."authenticate_user"("p_email" "text", "p_password" "text") TO "anon"; GRANT ALL ON FUNCTION "public"."authenticate_user"("p_email" "text", "p_password" "text") TO "authenticated"; GRANT ALL ON FUNCTION "public"."authenticate_user"("p_email" "text", "p_password" "text") TO "service_role"; GRANT ALL ON FUNCTION "public"."create_user_with_password"("p_email" "text", "p_nom" "text", "p_prenom" "text", "p_role" "text", "p_actif" boolean, "p_password" "text", "p_photo_url" "text", "p_region_admin" boolean, "p_region_id" "text") TO "anon"; GRANT ALL ON FUNCTION "public"."create_user_with_password"("p_email" "text", "p_nom" "text", "p_prenom" "text", "p_role" "text", "p_actif" boolean, "p_password" "text", "p_photo_url" "text", "p_region_admin" boolean, "p_region_id" "text") TO "authenticated"; GRANT ALL ON FUNCTION "public"."create_user_with_password"("p_email" "text", "p_nom" "text", "p_prenom" "text", "p_role" "text", "p_actif" boolean, "p_password" "text", "p_photo_url" "text", "p_region_admin" boolean, "p_region_id" "text") TO "service_role"; GRANT ALL ON FUNCTION "public"."get_gare_details"("p_gare_id" "uuid") TO "anon"; GRANT ALL ON FUNCTION "public"."get_gare_details"("p_gare_id" "uuid") TO "authenticated"; GRANT ALL ON FUNCTION "public"."get_gare_details"("p_gare_id" "uuid") TO "service_role"; GRANT ALL ON FUNCTION "public"."get_station_details"("p_station_id" "uuid") TO "anon"; GRANT ALL ON FUNCTION "public"."get_station_details"("p_station_id" "uuid") TO "authenticated"; GRANT ALL ON FUNCTION "public"."get_station_details"("p_station_id" "uuid") TO "service_role"; GRANT ALL ON FUNCTION "public"."handle_updated_at"() TO "anon"; GRANT ALL ON FUNCTION "public"."handle_updated_at"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."handle_updated_at"() TO "service_role"; GRANT ALL ON FUNCTION "public"."import_gtfs_rpc"("payload" json) TO "anon"; GRANT ALL ON FUNCTION "public"."import_gtfs_rpc"("payload" json) TO "authenticated"; GRANT ALL ON FUNCTION "public"."import_gtfs_rpc"("payload" json) TO "service_role"; GRANT ALL ON FUNCTION "public"."set_updated_at"() TO "anon"; GRANT ALL ON FUNCTION "public"."set_updated_at"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."set_updated_at"() TO "service_role"; GRANT ALL ON FUNCTION "public"."update_travaux_updated_at"() TO "anon"; GRANT ALL ON FUNCTION "public"."update_travaux_updated_at"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."update_travaux_updated_at"() TO "service_role"; GRANT ALL ON FUNCTION "public"."update_updated_at_column"() TO "anon"; GRANT ALL ON FUNCTION "public"."update_updated_at_column"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."update_updated_at_column"() TO "service_role"; GRANT ALL ON FUNCTION "public"."update_user_password"("p_user_id" "uuid", "p_password" "text") TO "anon"; GRANT ALL ON FUNCTION "public"."update_user_password"("p_user_id" "uuid", "p_password" "text") TO "authenticated"; GRANT ALL ON FUNCTION "public"."update_user_password"("p_user_id" "uuid", "p_password" "text") TO "service_role"; GRANT ALL ON FUNCTION "public"."update_users_panel_updated_at"() TO "anon"; GRANT ALL ON FUNCTION "public"."update_users_panel_updated_at"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."update_users_panel_updated_at"() TO "service_role"; GRANT ALL ON TABLE "public"."actualites" TO "anon"; GRANT ALL ON TABLE "public"."actualites" TO "authenticated"; GRANT ALL ON TABLE "public"."actualites" TO "service_role"; GRANT ALL ON TABLE "public"."evenements" TO "anon"; GRANT ALL ON TABLE "public"."evenements" TO "authenticated"; GRANT ALL ON TABLE "public"."evenements" TO "service_role"; GRANT ALL ON TABLE "public"."gare_quais" TO "anon"; GRANT ALL ON TABLE "public"."gare_quais" TO "authenticated"; GRANT ALL ON TABLE "public"."gare_quais" TO "service_role"; GRANT ALL ON TABLE "public"."gare_transports" TO "anon"; GRANT ALL ON TABLE "public"."gare_transports" TO "authenticated"; GRANT ALL ON TABLE "public"."gare_transports" TO "service_role"; GRANT ALL ON TABLE "public"."gares" TO "anon"; GRANT ALL ON TABLE "public"."gares" TO "authenticated"; GRANT ALL ON TABLE "public"."gares" TO "service_role"; GRANT ALL ON TABLE "public"."horaires" TO "anon"; GRANT ALL ON TABLE "public"."horaires" TO "authenticated"; GRANT ALL ON TABLE "public"."horaires" TO "service_role"; GRANT ALL ON TABLE "public"."horaires_gares_desservies" TO "anon"; GRANT ALL ON TABLE "public"."horaires_gares_desservies" TO "authenticated"; GRANT ALL ON TABLE "public"."horaires_gares_desservies" TO "service_role"; GRANT ALL ON SEQUENCE "public"."horaires_gares_desservies_id_seq" TO "anon"; GRANT ALL ON SEQUENCE "public"."horaires_gares_desservies_id_seq" TO "authenticated"; GRANT ALL ON SEQUENCE "public"."horaires_gares_desservies_id_seq" TO "service_role"; GRANT ALL ON TABLE "public"."info_trafic" TO "anon"; GRANT ALL ON TABLE "public"."info_trafic" TO "authenticated"; GRANT ALL ON TABLE "public"."info_trafic" TO "service_role"; GRANT ALL ON TABLE "public"."lignes" TO "anon"; GRANT ALL ON TABLE "public"."lignes" TO "authenticated"; GRANT ALL ON TABLE "public"."lignes" TO "service_role"; GRANT ALL ON TABLE "public"."lignes_gares" TO "anon"; GRANT ALL ON TABLE "public"."lignes_gares" TO "authenticated"; GRANT ALL ON TABLE "public"."lignes_gares" TO "service_role"; GRANT ALL ON TABLE "public"."materiel-roulant" TO "anon"; GRANT ALL ON TABLE "public"."materiel-roulant" TO "authenticated"; GRANT ALL ON TABLE "public"."materiel-roulant" TO "service_role"; GRANT ALL ON SEQUENCE "public"."materiel-roulant_id_seq" TO "anon"; GRANT ALL ON SEQUENCE "public"."materiel-roulant_id_seq" TO "authenticated"; GRANT ALL ON SEQUENCE "public"."materiel-roulant_id_seq" TO "service_role"; GRANT ALL ON TABLE "public"."menus_regionaux" TO "anon"; GRANT ALL ON TABLE "public"."menus_regionaux" TO "authenticated"; GRANT ALL ON TABLE "public"."menus_regionaux" TO "service_role"; GRANT ALL ON TABLE "public"."messagerie_messages" TO "anon"; GRANT ALL ON TABLE "public"."messagerie_messages" TO "authenticated"; GRANT ALL ON TABLE "public"."messagerie_messages" TO "service_role"; GRANT ALL ON TABLE "public"."messagerie_participants" TO "anon"; GRANT ALL ON TABLE "public"."messagerie_participants" TO "authenticated"; GRANT ALL ON TABLE "public"."messagerie_participants" TO "service_role"; GRANT ALL ON TABLE "public"."messagerie_threads" TO "anon"; GRANT ALL ON TABLE "public"."messagerie_threads" TO "authenticated"; GRANT ALL ON TABLE "public"."messagerie_threads" TO "service_role"; GRANT ALL ON TABLE "public"."parametres" TO "anon"; GRANT ALL ON TABLE "public"."parametres" TO "authenticated"; GRANT ALL ON TABLE "public"."parametres" TO "service_role"; GRANT ALL ON TABLE "public"."perturbations" TO "anon"; GRANT ALL ON TABLE "public"."perturbations" TO "authenticated"; GRANT ALL ON TABLE "public"."perturbations" TO "service_role"; GRANT ALL ON TABLE "public"."perturbations_modifications_parcours" TO "anon"; GRANT ALL ON TABLE "public"."perturbations_modifications_parcours" TO "authenticated"; GRANT ALL ON TABLE "public"."perturbations_modifications_parcours" TO "service_role"; GRANT ALL ON TABLE "public"."services_annuels" TO "anon"; GRANT ALL ON TABLE "public"."services_annuels" TO "authenticated"; GRANT ALL ON TABLE "public"."services_annuels" TO "service_role"; GRANT ALL ON TABLE "public"."tarifs" TO "anon"; GRANT ALL ON TABLE "public"."tarifs" TO "authenticated"; GRANT ALL ON TABLE "public"."tarifs" TO "service_role"; GRANT ALL ON SEQUENCE "public"."tarifs_id_seq" TO "anon"; GRANT ALL ON SEQUENCE "public"."tarifs_id_seq" TO "authenticated"; GRANT ALL ON SEQUENCE "public"."tarifs_id_seq" TO "service_role"; GRANT ALL ON TABLE "public"."travaux" TO "anon"; GRANT ALL ON TABLE "public"."travaux" TO "authenticated"; GRANT ALL ON TABLE "public"."travaux" TO "service_role"; GRANT ALL ON TABLE "public"."travaux_substitutions" TO "anon"; GRANT ALL ON TABLE "public"."travaux_substitutions" TO "authenticated"; GRANT ALL ON TABLE "public"."travaux_substitutions" TO "service_role"; GRANT ALL ON TABLE "public"."types_train" TO "anon"; GRANT ALL ON TABLE "public"."types_train" TO "authenticated"; GRANT ALL ON TABLE "public"."types_train" TO "service_role"; GRANT ALL ON SEQUENCE "public"."types_train_id_seq" TO "anon"; GRANT ALL ON SEQUENCE "public"."types_train_id_seq" TO "authenticated"; GRANT ALL ON SEQUENCE "public"."types_train_id_seq" TO "service_role"; GRANT ALL ON TABLE "public"."users_panel" TO "anon"; GRANT ALL ON TABLE "public"."users_panel" TO "authenticated"; GRANT ALL ON TABLE "public"."users_panel" TO "service_role"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "postgres"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "service_role"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "postgres"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "service_role"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "postgres"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "service_role";