-- ============================================================ -- Omika Diagnostic Center -- 006_diagnostics_device_license.sql -- Tâche 17-B : dimensions appareil + licence (additif). -- ============================================================ -- IDEMPOTENT : ADD COLUMN IF NOT EXISTS + CREATE INDEX IF NOT EXISTS. -- AUCUN DROP, AUCUNE suppression, AUCUNE migration destructive. -- PostgreSQL 18 compatible (syntaxe disponible depuis 9.6). -- -- Ajoute au diagnostic_event les dimensions appareil/licence, TOUTES NULLABLES : -- les événements antérieurs restent parfaitement valides (toutes nouvelles colonnes -- à NULL), AUCUN backfill, AUCUNE valeur inventée (« UNKNOWN »/« N/A » interdits). -- -- license_number : numéro de licence fonctionnel = Licence.LI_Numero, -- dérivé SERVEUR du token authentifié -- (MobileTokenIdentity.NumeroLicence). JAMAIS la PK HFSQL -- LI_PKID, JAMAIS un secret, JAMAIS fourni par le mobile. -- device_key : pseudonyme d'appareil HMAC-SHA256 calculé SERVEUR = -- HMAC("v1|tenant:|device:"). -- JAMAIS le DeviceId brut. -- device_key_version : version de l'algorithme DeviceKey (1 aujourd'hui). -- device_manufacturer : fabricant (mobile, déclaratif). -- device_model : modèle d'appareil (mobile, déclaratif). -- operating_system : nom de l'OS (mobile, déclaratif). -- operating_system_version : version de l'OS (mobile, déclaratif). -- app_build : numéro de build applicatif (mobile, déclaratif). -- screen_width : largeur d'écran physique (px, >= 0). -- screen_height : hauteur d'écran physique (px, >= 0). -- logical_width : largeur d'écran logique (unités indépendantes densité). -- logical_height : hauteur d'écran logique. -- display_scale : facteur d'échelle (ex. 1, 1.25, 1.5, 2, 3). -- -- CHOIX DE TYPE (cohérence schéma) : le schéma existant utilise TEXT sans VARCHAR -- pour les chaînes (priority, level, component, app_version…) ; on reste cohérent. -- Les dimensions écran physiques/logiques sont des entiers non négatifs (INTEGER) ; -- display_scale est un réel (DOUBLE PRECISION, valeurs décimales 1.25/1.5/2.75/3). -- La validation (longueur, bornes, non-négativité) est portée par le code au moment -- de la résolution (T17-C), comme pour les autres champs. -- ============================================================ ALTER TABLE diagnostic_event ADD COLUMN IF NOT EXISTS license_number TEXT, ADD COLUMN IF NOT EXISTS device_key TEXT, ADD COLUMN IF NOT EXISTS device_key_version INTEGER, ADD COLUMN IF NOT EXISTS device_manufacturer TEXT, ADD COLUMN IF NOT EXISTS device_model TEXT, ADD COLUMN IF NOT EXISTS operating_system TEXT, ADD COLUMN IF NOT EXISTS operating_system_version TEXT, ADD COLUMN IF NOT EXISTS app_build TEXT, ADD COLUMN IF NOT EXISTS screen_width INTEGER, ADD COLUMN IF NOT EXISTS screen_height INTEGER, ADD COLUMN IF NOT EXISTS logical_width INTEGER, ADD COLUMN IF NOT EXISTS logical_height INTEGER, ADD COLUMN IF NOT EXISTS display_scale DOUBLE PRECISION; -- Index composés immédiatement justifiés (recherche support « tous les diagnostics -- d'un appareil / d'une licence »), alignés sur le style de -- ix_diagnostic_event_actor_key_timestamp (002) et -- ix_diagnostic_event_client_code_timestamp (005). CREATE INDEX IF NOT EXISTS ix_diagnostic_event_device_key_timestamp ON diagnostic_event (device_key, timestamp_utc DESC); CREATE INDEX IF NOT EXISTS ix_diagnostic_event_license_number_timestamp ON diagnostic_event (license_number, timestamp_utc DESC); -- PAS d'index dédié sur device_manufacturer / device_model / operating_system / -- operating_system_version / app_build / screen_* : dimensions de filtrage/agrégation -- futures (T17-E) mais sans usage immédiat justifiant le coût d'écriture/maintenance. -- PAS d'index sur display_scale (valeur continue, jamais filtrée par égalité). -- À réévaluer en T17-E lorsque les statistiques de parc seront définies.