-- Ticket #194 — Module Cartes SYSTEM (collecte absences/congés/arrêt) -- Idempotent. DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'card_response_mode_type') THEN CREATE TYPE card_response_mode_type AS ENUM ( 'none', 'ack', 'accept_refuse' ); END IF; IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'card_instance_statut_type') THEN CREATE TYPE card_instance_statut_type AS ENUM ( 'ouverte', 'refusee', 'traitee' ); END IF; IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'card_operation_type') THEN CREATE TYPE card_operation_type AS ENUM ('create', 'update'); END IF; IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'card_response_action_type') THEN CREATE TYPE card_response_action_type AS ENUM ( 'accept', 'refuse', 'ack' ); END IF; END $$; CREATE TABLE IF NOT EXISTS card_types ( code VARCHAR(64) PRIMARY KEY, system BOOLEAN NOT NULL DEFAULT true, titre VARCHAR(120) NOT NULL, emitter_roles TEXT[] NOT NULL, recipient_roles TEXT[] NOT NULL, audience_resolver VARCHAR(64) NOT NULL, response_mode card_response_mode_type NOT NULL, retention_days INT NOT NULL DEFAULT 14, couleur VARCHAR(32), cree_le TIMESTAMPTZ NOT NULL DEFAULT now(), modifie_le TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE TABLE IF NOT EXISTS card_instances ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), type_code VARCHAR(64) NOT NULL REFERENCES card_types(code), id_placement UUID NOT NULL REFERENCES enfants_assistantes_maternelles(id) ON DELETE CASCADE, id_absence UUID REFERENCES absences_garde(id) ON DELETE SET NULL, cree_par UUID REFERENCES utilisateurs(id) ON DELETE SET NULL, operation card_operation_type NOT NULL DEFAULT 'create', statut card_instance_statut_type NOT NULL DEFAULT 'ouverte', payload JSONB NOT NULL DEFAULT '{}'::jsonb, purge_at TIMESTAMPTZ NOT NULL, cree_le TIMESTAMPTZ NOT NULL DEFAULT now(), modifie_le TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_card_instances_placement ON card_instances (id_placement, statut, cree_le DESC); CREATE INDEX IF NOT EXISTS idx_card_instances_purge ON card_instances (purge_at); CREATE INDEX IF NOT EXISTS idx_card_instances_absence ON card_instances (id_absence) WHERE id_absence IS NOT NULL; CREATE TABLE IF NOT EXISTS card_audience_members ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), id_card UUID NOT NULL REFERENCES card_instances(id) ON DELETE CASCADE, id_utilisateur UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE, role_snapshot VARCHAR(64) NOT NULL, is_creator BOOLEAN NOT NULL DEFAULT false, UNIQUE (id_card, id_utilisateur) ); CREATE INDEX IF NOT EXISTS idx_card_audience_user ON card_audience_members (id_utilisateur, id_card); CREATE TABLE IF NOT EXISTS card_responses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), id_card UUID NOT NULL REFERENCES card_instances(id) ON DELETE CASCADE, id_utilisateur UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE, action card_response_action_type NOT NULL, comment TEXT, cree_le TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_card_responses_card ON card_responses (id_card, cree_le DESC); -- Seeds SYSTEM INSERT INTO card_types ( code, system, titre, emitter_roles, recipient_roles, audience_resolver, response_mode, retention_days, couleur ) VALUES ( 'absence_enfant', true, 'Absence enfant', ARRAY['parent'], ARRAY['assistante_maternelle'], 'couple_am', 'none', 7, 'peach' ), ( 'absence_enfant_modif', true, 'Absence enfant modifiée', ARRAY['parent'], ARRAY['assistante_maternelle'], 'couple_am', 'ack', 7, 'peach' ), ( 'conge_am', true, 'Congé AM', ARRAY['assistante_maternelle'], ARRAY['parent'], 'couple_parents', 'accept_refuse', 14, 'lavender' ), ( 'arret_maladie_am', true, 'Arrêt maladie AM', ARRAY['assistante_maternelle'], ARRAY['parent'], 'couple_parents', 'ack', 14, 'pink' ) ON CONFLICT (code) DO UPDATE SET titre = EXCLUDED.titre, emitter_roles = EXCLUDED.emitter_roles, recipient_roles = EXCLUDED.recipient_roles, audience_resolver = EXCLUDED.audience_resolver, response_mode = EXCLUDED.response_mode, retention_days = EXCLUDED.retention_days, couleur = EXCLUDED.couleur, modifie_le = now(); COMMENT ON TABLE card_types IS 'Catalogue types de cartes (SYSTEM seeds #194 ; OPTIONNEL plus tard).'; COMMENT ON TABLE card_instances IS 'Bulles / file d’attention — collecte, pas vérité métier absences.';