|
| 1 | +-- ============================================================================== |
| 2 | +-- 01_meta/01_tables.sql |
| 3 | +-- Architecture ECS/DOD · Projet Marius · PostgreSQL 18 |
| 4 | +-- Contenu : meta.containment_intent (registre d'intention AOT) + migrations |
| 5 | +-- Source : meta_registry.sql v2.2 |
| 6 | +-- ============================================================================== |
| 7 | + |
| 8 | +-- ============================================================================== |
| 9 | +-- REGISTRE D'INTENTION (Source of Truth architecturale) |
| 10 | +-- ============================================================================== |
| 11 | +-- Chaque ligne déclare les invariants d'un composant ECS. L'outil compare |
| 12 | +-- cette intention à la réalité extraite de pg_catalog. |
| 13 | +-- |
| 14 | +-- component_id TEXT (pas regclass) : |
| 15 | +-- Stocke le nom qualifié ('schema.table'). to_regclass() est utilisé dans |
| 16 | +-- les vues pour la résolution — retourne NULL si la table n'existe pas encore |
| 17 | +-- au lieu de lever une erreur. Permet la pré-déclaration d'un composant avant |
| 18 | +-- sa création physique (workflow migration : intention déclarée → DDL appliqué |
| 19 | +-- → alerte component_not_found_alert passe de TRUE à FALSE). |
| 20 | +-- Contrepartie : un renommage de table n'est pas suivi automatiquement |
| 21 | +-- (contrairement à regclass qui stocke l'OID). Mise à jour manuelle requise. |
| 22 | +-- |
| 23 | +-- mutation_procedures TEXT[] (pas regprocedure) : |
| 24 | +-- Plusieurs procédures peuvent écrire le même composant (ex: identity.auth |
| 25 | +-- est écrit par create_account, record_login ET anonymize_person). Le modèle |
| 26 | +-- 1:1 est architecturalement incorrect pour un système ECS. Format attendu : |
| 27 | +-- signature complète avec types d'arguments pour to_regprocedure() : |
| 28 | +-- 'identity.record_login(integer)'. |
| 29 | +-- |
| 30 | +-- immutable_keys name[] : |
| 31 | +-- Colonnes scellées post-INSERT (FK spine, clés de tri BRIN...). Métadonnée |
| 32 | +-- documentaire — les triggers d'immuabilité correspondants sont vérifiés |
| 33 | +-- dans les tests pgTAP (11_meta_audit.sql). |
| 34 | +-- |
| 35 | +-- exempt_bloat_check BOOLEAN : |
| 36 | +-- Neutralise la contribution bloat dans le scoring de v_master_health_audit. |
| 37 | +-- Réservé aux tables de configuration structurelle (cardinalité fixe, mutations |
| 38 | +-- REVOKE'd en production). N'affecte pas v_performance_sentinel ni |
| 39 | +-- density_drift_alert — la réalité physique reste visible pour diagnostic. |
| 40 | +-- |
| 41 | +-- naive_density_bytes SMALLINT NULL (v2.2) : |
| 42 | +-- Taille du tuple padded si les colonnes étaient dans leur ordre naturel pré-DOD |
| 43 | +-- (non optimisé), produite par f_generate_dod_template sur la liste originale. |
| 44 | +-- NULL = non renseigné (métrique optionnelle, aucun effet sur les alertes). |
| 45 | +-- Le ratio dod_efficiency_ratio = naive / intent est exposé dans |
| 46 | +-- v_extended_containment_security_matrix comme KPI architectural. |
| 47 | + |
| 48 | +CREATE TABLE IF NOT EXISTS meta.containment_intent ( |
| 49 | + component_id TEXT NOT NULL PRIMARY KEY, |
| 50 | + intent_density_bytes SMALLINT NOT NULL, |
| 51 | + rls_guard_bitmask INT NULL, |
| 52 | + mutation_procedures TEXT[] NULL, |
| 53 | + immutable_keys name[] NULL, |
| 54 | + |
| 55 | + CONSTRAINT intent_density_positive CHECK (intent_density_bytes > 0), |
| 56 | + CONSTRAINT component_id_format CHECK (component_id ~ '^[a-z_]+\.[a-z_0-9]+$') |
| 57 | +); |
| 58 | + |
| 59 | +-- ── Migrations idempotentes ──────────────────────────────────────────────────── |
| 60 | +-- Chaque colonne ajoutée après la version initiale est déclarée via ADD COLUMN IF |
| 61 | +-- NOT EXISTS. Ce bloc est sans effet sur une base fraîche (les colonnes sont déjà |
| 62 | +-- présentes via CREATE TABLE IF NOT EXISTS qui aurait créé la table complète) et |
| 63 | +-- applique uniquement les colonnes manquantes sur une base existante à une version |
| 64 | +-- antérieure. |
| 65 | + |
| 66 | +-- v2.1 — exempt_bloat_check |
| 67 | +ALTER TABLE meta.containment_intent |
| 68 | + ADD COLUMN IF NOT EXISTS exempt_bloat_check BOOLEAN NOT NULL DEFAULT false; |
| 69 | + |
| 70 | +-- v2.2 — naive_density_bytes + contraintes associées |
| 71 | +ALTER TABLE meta.containment_intent |
| 72 | + ADD COLUMN IF NOT EXISTS naive_density_bytes SMALLINT NULL; |
| 73 | + |
| 74 | +-- Contraintes ajoutées en v2.2 — idempotentes via DO/EXCEPTION. |
| 75 | +-- pg_constraint n'a pas de IF NOT EXISTS ; on teste l'existence avant d'ajouter. |
| 76 | +DO $$ |
| 77 | +BEGIN |
| 78 | + IF NOT EXISTS ( |
| 79 | + SELECT 1 FROM pg_constraint |
| 80 | + WHERE conname = 'naive_density_positive' |
| 81 | + AND conrelid = 'meta.containment_intent'::regclass |
| 82 | + ) THEN |
| 83 | + ALTER TABLE meta.containment_intent |
| 84 | + ADD CONSTRAINT naive_density_positive |
| 85 | + CHECK (naive_density_bytes IS NULL OR naive_density_bytes > 0); |
| 86 | + END IF; |
| 87 | + |
| 88 | + IF NOT EXISTS ( |
| 89 | + SELECT 1 FROM pg_constraint |
| 90 | + WHERE conname = 'naive_gte_intent' |
| 91 | + AND conrelid = 'meta.containment_intent'::regclass |
| 92 | + ) THEN |
| 93 | + ALTER TABLE meta.containment_intent |
| 94 | + ADD CONSTRAINT naive_gte_intent |
| 95 | + CHECK (naive_density_bytes IS NULL OR naive_density_bytes >= intent_density_bytes); |
| 96 | + END IF; |
| 97 | +END; |
| 98 | +$$; |
0 commit comments