Files
DDI/server/internal/store/migrations/00004_push.sql
T
beug.k@beugsiud.deandClaude Opus 5.5 28dc177310 feat(store): migration 00004 for push deployments, target revisions and revision sources
Agents get a target revision (manual mode), revisions store their
generator input (jsonb) for rollbacks, deployments gain the outcomes
pending and superseded, a nullable end and the requesting user. The
duplicate protection now covers agent reports only. Transactions can
register hooks that run after the commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:23:45 +02:00

66 lines
3.7 KiB
SQL

-- SPDX-License-Identifier: LicenseRef-DDI-Proprietary
-- Pull and push (M4, ADR 0022): operating modes with a target revision,
-- pending push deployments created by the server, and the generator input of
-- every revision (for rollbacks with a new SOA serial).
-- +goose Up
-- Last revision pushed explicitly; the desired revision of agents in manual
-- mode (0 = none).
ALTER TABLE agents ADD COLUMN target_revision bigint NOT NULL DEFAULT 0;
ALTER TABLE agents ADD CONSTRAINT agents_target_revision CHECK (target_revision BETWEEN 0 AND 4294967295);
-- Generator input (configgen.Source as JSON) the revision was rendered from;
-- NULL for revisions created before M4 (they cannot be rolled back to).
-- Adding a column does not fire the immutability trigger.
ALTER TABLE config_revisions ADD COLUMN source jsonb;
ALTER TABLE config_revisions ADD CONSTRAINT config_revisions_source_object
CHECK (source IS NULL OR jsonb_typeof(source) = 'object');
-- New outcomes: pending (pushed, no report yet) and superseded (replaced by a
-- newer push before the agent reported). A new enum type instead of ALTER
-- TYPE ... ADD VALUE, whose values cannot be used in the same transaction.
ALTER TYPE deployment_outcome RENAME TO deployment_outcome_m3;
CREATE TYPE deployment_outcome AS ENUM ('pending', 'succeeded', 'rejected', 'rolled_back', 'failed', 'superseded');
ALTER TABLE deployments ALTER COLUMN outcome TYPE deployment_outcome USING outcome::text::deployment_outcome;
DROP TYPE deployment_outcome_m3;
-- Pending deployments have no end yet.
ALTER TABLE deployments ALTER COLUMN finished_at DROP NOT NULL;
ALTER TABLE deployments ADD CONSTRAINT deployments_finished
CHECK ((outcome = 'pending') = (finished_at IS NULL));
-- Push deployments created by the server record who requested them. Rows
-- reported by agents (pulls, M3 pushes) have requested_by_name NULL.
ALTER TABLE deployments ADD COLUMN requested_by uuid REFERENCES users (id) ON DELETE SET NULL;
ALTER TABLE deployments ADD COLUMN requested_by_name text;
ALTER TABLE deployments ADD CONSTRAINT deployments_requested_by
CHECK (requested_by IS NULL OR requested_by_name IS NOT NULL);
-- Duplicate protection applies to reports only: an agent may resend a report
-- after a crash, the copy is dropped. Server-created rows are matched by ID.
ALTER TABLE deployments DROP CONSTRAINT deployments_report_unique;
CREATE UNIQUE INDEX deployments_report_unique ON deployments (agent_id, revision, started_at)
WHERE requested_by_name IS NULL;
CREATE INDEX deployments_pending ON deployments (agent_id, id DESC) WHERE outcome = 'pending';
-- +goose Down
DROP INDEX deployments_pending;
DROP INDEX deployments_report_unique;
DELETE FROM deployments WHERE requested_by_name IS NOT NULL AND outcome IN ('pending', 'superseded');
ALTER TABLE deployments ADD CONSTRAINT deployments_report_unique UNIQUE (agent_id, revision, started_at);
ALTER TABLE deployments DROP CONSTRAINT deployments_requested_by;
ALTER TABLE deployments DROP COLUMN requested_by_name;
ALTER TABLE deployments DROP COLUMN requested_by;
ALTER TABLE deployments DROP CONSTRAINT deployments_finished;
DELETE FROM deployments WHERE outcome IN ('pending', 'superseded');
ALTER TABLE deployments ALTER COLUMN finished_at SET NOT NULL;
ALTER TYPE deployment_outcome RENAME TO deployment_outcome_m4;
CREATE TYPE deployment_outcome AS ENUM ('succeeded', 'rejected', 'rolled_back', 'failed');
ALTER TABLE deployments ALTER COLUMN outcome TYPE deployment_outcome USING outcome::text::deployment_outcome;
DROP TYPE deployment_outcome_m4;
ALTER TABLE config_revisions DROP CONSTRAINT config_revisions_source_object;
ALTER TABLE config_revisions DROP COLUMN source;
ALTER TABLE agents DROP CONSTRAINT agents_target_revision;
ALTER TABLE agents DROP COLUMN target_revision;