-- ============================================================ -- Omika Diagnostic Center — base dédiée omika_diagnostics (§14) -- Outil SUPPORT uniquement : jamais utilisé par le métier (§13). -- 100 % Windows / PostgreSQL. Aucune dépendance Linux/Docker. -- PostgreSQL est NON critique : Omika fonctionne sans cette base. -- ============================================================ -- ------------------------------------------------------------ -- Table principale des événements (§15) -- ------------------------------------------------------------ CREATE TABLE IF NOT EXISTS diagnostic_event ( id BIGSERIAL PRIMARY KEY, event_id UUID NOT NULL, -- clé de déduplication (§16) timestamp_utc TIMESTAMPTZ NOT NULL, priority TEXT, -- P0..P4 level TEXT, -- trace..critical event_code TEXT NOT NULL, component TEXT, trace_id UUID, -- X-Omika-TraceId conservé (§33) session_id UUID, operation_id UUID, app_version TEXT, platform TEXT, error_code TEXT, message TEXT, -- Phase 6 (crash reporting) exception_type TEXT, -- Phase 6 stack_trace TEXT, -- Phase 6 duration_ms BIGINT, source TEXT, -- mobile/api/worker/collector metadata_json JSONB, -- whitelist sécurité (§18/§19) ingested_at_utc TIMESTAMPTZ NOT NULL ); -- Déduplication at-least-once : INSERT ... ON CONFLICT (event_id) DO NOTHING (§16) CREATE UNIQUE INDEX IF NOT EXISTS ux_diagnostic_event_event_id ON diagnostic_event (event_id); -- Index utiles uniquement (§17) — pas d'index sur chaque colonne CREATE INDEX IF NOT EXISTS ix_diagnostic_event_timestamp_utc ON diagnostic_event (timestamp_utc); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_trace_id ON diagnostic_event (trace_id); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_operation_id ON diagnostic_event (operation_id); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_session_id ON diagnostic_event (session_id); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_event_code ON diagnostic_event (event_code); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_component ON diagnostic_event (component); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_level ON diagnostic_event (level); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_error_code ON diagnostic_event (error_code); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_app_version ON diagnostic_event (app_version); -- ------------------------------------------------------------ -- Métriques agrégées horaires (§28) — low-cardinality (§30) -- ------------------------------------------------------------ CREATE TABLE IF NOT EXISTS telemetry_metric_hourly ( id BIGSERIAL PRIMARY KEY, bucket_utc TIMESTAMPTZ NOT NULL, metric_name TEXT NOT NULL, component TEXT NOT NULL DEFAULT '', -- '' = métrique globale value DOUBLE PRECISION NOT NULL, count BIGINT NOT NULL, min_value DOUBLE PRECISION NOT NULL, max_value DOUBLE PRECISION NOT NULL, tags_json JSONB NOT NULL DEFAULT '{}'::jsonb ); -- Upsert : un agrégat unique par (bucket, métrique, composant, tags) CREATE UNIQUE INDEX IF NOT EXISTS ux_telemetry_metric_hourly ON telemetry_metric_hourly (bucket_utc, metric_name, component, tags_json); CREATE INDEX IF NOT EXISTS ix_telemetry_metric_hourly_bucket ON telemetry_metric_hourly (bucket_utc); -- ------------------------------------------------------------ -- Rétention (§45) — valeur configurable (Diagnostics:RetentionDays, défaut 60). -- NON exécutée automatiquement : à planifier en maintenance (purge destructive -- documentée). Exemple (à adapter) : -- DELETE FROM diagnostic_event -- WHERE timestamp_utc < now() - interval '60 days'; -- ------------------------------------------------------------