feat: match fleet to blueprint targets exactly

Add an optional exact blueprint mode with keep/create/remove previews, atomic queueing, cancellation of unstarted excess creations, and persistent dependencies for safe port reuse. Track removals alongside creations and preserve fill mode as the default.

Validation: type check, production build, and 103 deployment tests passed. The full suite has one telemetry assertion failure also reproduced on the previous commit.

Fixes #42
This commit is contained in:
2026-09-27 13:36:08 -04:00
parent 1aa7f15371
commit 0b0e5b5bdb
13 changed files with 517 additions and 83 deletions
+20 -1
View File
@@ -467,7 +467,9 @@ CREATE TABLE IF NOT EXISTS server_launch_recipes (
CREATE TABLE IF NOT EXISTS server_launch_collections (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
created_at TEXT NOT NULL
created_at TEXT NOT NULL,
mode TEXT NOT NULL DEFAULT 'fill',
retained_servers TEXT NOT NULL DEFAULT '[]'
);
CREATE TABLE IF NOT EXISTS server_collection_members (
@@ -483,9 +485,26 @@ CREATE TABLE IF NOT EXISTS server_collection_previews (
blueprint_name TEXT NOT NULL,
entries TEXT NOT NULL,
servers TEXT NOT NULL,
mode TEXT NOT NULL DEFAULT 'fill',
fleet_snapshot TEXT,
collection_id TEXT REFERENCES server_launch_collections(id) ON DELETE CASCADE
);
-- A pending removal can be shared by multiple reviewed collection requests.
CREATE TABLE IF NOT EXISTS server_collection_removals (
collection_id TEXT NOT NULL REFERENCES server_launch_collections(id) ON DELETE CASCADE,
deployment_id TEXT NOT NULL REFERENCES server_deployments(id) ON DELETE CASCADE,
position INTEGER NOT NULL,
PRIMARY KEY (collection_id, deployment_id)
);
-- Reusing a port is safe only after the reviewed removal has completed.
CREATE TABLE IF NOT EXISTS server_creation_dependencies (
deployment_id TEXT NOT NULL REFERENCES server_deployments(id) ON DELETE CASCADE,
removal_id TEXT NOT NULL REFERENCES server_deployments(id) ON DELETE CASCADE,
PRIMARY KEY (deployment_id, removal_id)
);
-- Persist state transitions atomically, including changes made by background workers.
-- Polls with unchanged status/error do not produce duplicate activity entries.
CREATE TABLE IF NOT EXISTS beta_events (