feat(api): complete phase 2.4 control plane
This commit is contained in:
@@ -113,6 +113,121 @@ export const MIGRATIONS: readonly Migration[] = [
|
||||
'CREATE INDEX idx_job_items_job_status ON job_items(job_id, status)',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'secret-cleanup-task-outbox',
|
||||
statements: [
|
||||
`CREATE TABLE secret_cleanup_tasks (
|
||||
reference TEXT PRIMARY KEY,
|
||||
instance_id TEXT NOT NULL,
|
||||
purpose TEXT NOT NULL,
|
||||
provider TEXT NOT NULL,
|
||||
generation INTEGER NOT NULL DEFAULT 1 CHECK (generation > 0),
|
||||
queued_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
)`,
|
||||
`INSERT INTO secret_cleanup_tasks (reference,instance_id,purpose,provider,generation,queued_at,updated_at)
|
||||
SELECT external_reference,instance_id,purpose,provider,1,updated_at,updated_at
|
||||
FROM (
|
||||
SELECT external_reference,instance_id,purpose,provider,updated_at,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY instance_id,purpose
|
||||
ORDER BY updated_at DESC,created_at DESC,id DESC
|
||||
) AS row_number
|
||||
FROM secret_references
|
||||
WHERE instance_id IS NOT NULL
|
||||
) ranked
|
||||
WHERE row_number > 1`,
|
||||
`DELETE FROM secret_references
|
||||
WHERE id IN (
|
||||
SELECT id FROM (
|
||||
SELECT id, ROW_NUMBER() OVER (
|
||||
PARTITION BY instance_id,purpose
|
||||
ORDER BY updated_at DESC,created_at DESC,id DESC
|
||||
) AS row_number
|
||||
FROM secret_references
|
||||
WHERE instance_id IS NOT NULL
|
||||
) ranked
|
||||
WHERE row_number > 1
|
||||
)`,
|
||||
'CREATE UNIQUE INDEX uq_secret_references_instance_purpose ON secret_references(instance_id, purpose) WHERE instance_id IS NOT NULL',
|
||||
'CREATE INDEX idx_secret_cleanup_tasks_queued_at ON secret_cleanup_tasks(queued_at)',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'current-status-snapshot-lifecycle',
|
||||
statements: [
|
||||
`DELETE FROM status_snapshots
|
||||
WHERE id IN (
|
||||
SELECT id FROM (
|
||||
SELECT id, ROW_NUMBER() OVER (
|
||||
PARTITION BY instance_id, category
|
||||
ORDER BY observed_at DESC, created_at DESC, id DESC
|
||||
) AS row_number
|
||||
FROM status_snapshots
|
||||
) ranked
|
||||
WHERE row_number > 1
|
||||
)`,
|
||||
'CREATE UNIQUE INDEX uq_status_snapshots_instance_category ON status_snapshots(instance_id, category)',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'r3-preparations-and-durable-job-lineage',
|
||||
statements: [
|
||||
'ALTER TABLE jobs ADD COLUMN root_job_id TEXT REFERENCES jobs(id) ON DELETE RESTRICT',
|
||||
'ALTER TABLE jobs ADD COLUMN retry_of_job_id TEXT REFERENCES jobs(id) ON DELETE RESTRICT',
|
||||
'UPDATE jobs SET root_job_id=id WHERE root_job_id IS NULL',
|
||||
`CREATE TABLE job_items_v4 (
|
||||
id TEXT PRIMARY KEY,
|
||||
job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
||||
instance_id TEXT NOT NULL,
|
||||
attempt_number INTEGER NOT NULL DEFAULT 1 CHECK (attempt_number > 0),
|
||||
status TEXT NOT NULL,
|
||||
result_code TEXT,
|
||||
error_json TEXT,
|
||||
source_job_item_id TEXT REFERENCES job_items_v4(id) ON DELETE RESTRICT,
|
||||
created_at TEXT NOT NULL,
|
||||
started_at TEXT,
|
||||
finished_at TEXT,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE (job_id, instance_id, attempt_number)
|
||||
)`,
|
||||
`INSERT INTO job_items_v4 (id,job_id,instance_id,attempt_number,status,result_code,created_at,started_at,finished_at,updated_at)
|
||||
SELECT id,job_id,instance_id,attempt_number,status,result_code,created_at,started_at,finished_at,updated_at FROM job_items`,
|
||||
'DROP TABLE job_items',
|
||||
'ALTER TABLE job_items_v4 RENAME TO job_items',
|
||||
'CREATE INDEX idx_job_items_job_status ON job_items(job_id, status)',
|
||||
`CREATE TABLE job_attempts (
|
||||
id TEXT PRIMARY KEY,
|
||||
job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
||||
status TEXT NOT NULL CHECK (status IN ('running','succeeded','failed','cancelled','unknown-result')),
|
||||
started_at TEXT NOT NULL,
|
||||
finished_at TEXT,
|
||||
created_at TEXT NOT NULL
|
||||
)`,
|
||||
'CREATE INDEX idx_job_attempts_job_started_at ON job_attempts(job_id, started_at)',
|
||||
`CREATE TABLE operation_preparations (
|
||||
id TEXT PRIMARY KEY,
|
||||
operation_id TEXT NOT NULL CHECK (operation_id = 'deleteInstance'),
|
||||
risk_level TEXT NOT NULL CHECK (risk_level = 'R3'),
|
||||
status TEXT NOT NULL CHECK (status IN ('prepared','consumed','expired','invalidated')),
|
||||
target_instance_id TEXT NOT NULL,
|
||||
target_revision INTEGER NOT NULL CHECK (target_revision > 0),
|
||||
parameter_schema_id TEXT NOT NULL,
|
||||
parameters_digest TEXT NOT NULL,
|
||||
token_digest TEXT NOT NULL CHECK (length(token_digest) = 64),
|
||||
requested_by TEXT NOT NULL,
|
||||
request_id TEXT NOT NULL,
|
||||
expires_at TEXT NOT NULL,
|
||||
consumed_at TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
)`,
|
||||
'CREATE INDEX idx_operation_preparations_status_expires_at ON operation_preparations(status, expires_at)',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const createMigrationsTable = `CREATE TABLE schema_migrations (
|
||||
|
||||
Reference in New Issue
Block a user