-- Migration 009: Plattform-Dimension im UpdateService
--
-- Additive Migration. Der Migrator toleriert 1050/1060/1061/1062/1091.

-- ---------------------------------------------------------------------------
-- Fuer welche Plattform gilt dieses Release?
-- ---------------------------------------------------------------------------
-- Der UpdateService kannte Produkt, Kanal und Version - aber keine Plattform.
-- Seit fuer mehrere Laufzeitkennungen gebaut wird (win-x64, linux-x64, ...)
-- landeten beide Pakete im selben Kanal unter derselben Version und
-- ueberschrieben sich gegenseitig; ein Linux-System zog sich das
-- Windows-Paket. Behelfe waren getrennte Produkt-Slugs oder zweckentfremdete
-- Kanaele - beides trug nicht weit.
--
-- 'any' ist der Wert fuer plattformunabhaengige Releases und zugleich der
-- Bestandsschutz: alles, was vor dieser Migration veroeffentlicht wurde, gilt
-- weiterhin fuer jeden Client, der keine Plattform mitschickt.
ALTER TABLE updateservice_releases
  ADD COLUMN platform VARCHAR(32) NOT NULL DEFAULT 'any' AFTER channel;

-- Die Eindeutigkeit muss die Plattform einschliessen, sonst verdraengt das
-- zuletzt veroeffentlichte Paket einer Version alle anderen Plattformen
-- derselben Version (ON DUPLICATE KEY UPDATE greift auf dem alten Schluessel).
ALTER TABLE updateservice_releases
  DROP INDEX uq_prod_ver_chan;

ALTER TABLE updateservice_releases
  ADD UNIQUE KEY uq_prod_ver_chan_plat (product_slug, version, channel, platform);

-- Die Abfrage lautet immer "Produkt + Kanal + passende Plattform".
ALTER TABLE updateservice_releases
  ADD KEY ix_us_lookup (product_slug, channel, platform);

-- ---------------------------------------------------------------------------
-- Signatur des Releases
-- ---------------------------------------------------------------------------
-- Der SHA256 eines Pakets stammt aus derselben Quelle wie das Paket selbst.
-- Das schuetzt gegen Uebertragungsfehler, nicht gegen einen manipulierten
-- Webroot oder gestohlene FTP-Zugangsdaten - ausgerechnet auf dem Pfad, der
-- fremden Code ausfuehrt.
--
-- Bewusst KEIN HMAC: Bei einem HMAC braucht der Pruefende denselben
-- geheimen Schluessel wie der Signierende. Der Agent laeuft auf fremden
-- Systemen; ein dort hinterlegter Schluessel koennte gestohlen und zum
-- Signieren beliebiger Pakete benutzt werden - die Signatur waere wertlos.
-- Beim Lizenzmodul geht HMAC auf, weil dort der Server prueft.
--
-- Stattdessen RSA-SHA256: der Server signiert mit dem privaten Schluessel
-- (security.release_private_key), der Agent prueft mit dem oeffentlichen aus
-- /api/updateservice/v1/pubkey. Base64 einer 2048-bit-Signatur sind 344
-- Zeichen, daher TEXT und nicht VARCHAR(64).
--
-- Optional: Releases ohne Signatur bleiben installierbar, der Agent warnt.
ALTER TABLE updateservice_releases
  ADD COLUMN manifest_signature TEXT NULL AFTER manifest_json;
