-- Bind browser accounts to Alibaba ECS Windows hosts and persist signed-in -- browser extension releases/update orchestration. The updater remains part of -- the control-plane process; target hosts only run one-shot Cloud Assistant -- commands after every browser worker on that host reports an idle state. ALTER TABLE users ADD COLUMN IF NOT EXISTS extension_ecs_region_id text, ADD COLUMN IF NOT EXISTS extension_ecs_instance_id text; ALTER TABLE users DROP CONSTRAINT IF EXISTS users_extension_ecs_binding_pair_check; ALTER TABLE users ADD CONSTRAINT users_extension_ecs_binding_pair_check CHECK ( (extension_ecs_region_id IS NULL AND extension_ecs_instance_id IS NULL) OR ( extension_ecs_region_id ~ '^[a-z0-9][a-z0-9-]{0,63}$' AND extension_ecs_instance_id ~ '^i-[A-Za-z0-9]{6,64}$' ) ); CREATE INDEX IF NOT EXISTS users_extension_ecs_host_idx ON users (organization_id, extension_ecs_region_id, extension_ecs_instance_id) WHERE extension_ecs_region_id IS NOT NULL AND extension_ecs_instance_id IS NOT NULL; CREATE TABLE IF NOT EXISTS extension_releases ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), organization_id uuid NOT NULL REFERENCES organizations(id), version text NOT NULL, object_key text NOT NULL, sha256 text NOT NULL, byte_size integer NOT NULL, extension_manifest jsonb NOT NULL, is_active boolean NOT NULL DEFAULT false, published_by uuid NOT NULL REFERENCES users(id), created_at timestamptz NOT NULL DEFAULT now(), UNIQUE (organization_id, version), UNIQUE (organization_id, object_key), CHECK (version ~ '^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$'), CHECK (sha256 ~ '^[a-f0-9]{64}$'), CHECK (byte_size BETWEEN 1 AND 50000000), CHECK (char_length(object_key) BETWEEN 1 AND 500) ); CREATE UNIQUE INDEX IF NOT EXISTS extension_releases_one_active_idx ON extension_releases (organization_id) WHERE is_active = true; CREATE INDEX IF NOT EXISTS extension_releases_created_idx ON extension_releases (organization_id, created_at DESC); CREATE TABLE IF NOT EXISTS extension_host_updates ( organization_id uuid NOT NULL REFERENCES organizations(id), ecs_region_id text NOT NULL, ecs_instance_id text NOT NULL, release_id uuid NOT NULL REFERENCES extension_releases(id), status text NOT NULL, attempt_count integer NOT NULL DEFAULT 0, invocation_id text, error_code text, error_message text, started_at timestamptz, deployed_at timestamptz, verified_at timestamptz, updated_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (organization_id, ecs_region_id, ecs_instance_id), CHECK (status IN ('waiting_for_idle', 'running', 'deployed', 'verified', 'failed')), CHECK (attempt_count BETWEEN 0 AND 3), CHECK (ecs_region_id ~ '^[a-z0-9][a-z0-9-]{0,63}$'), CHECK (ecs_instance_id ~ '^i-[A-Za-z0-9]{6,64}$'), CHECK (error_code IS NULL OR char_length(error_code) <= 120), CHECK (error_message IS NULL OR char_length(error_message) <= 2000) ); CREATE INDEX IF NOT EXISTS extension_host_updates_release_status_idx ON extension_host_updates (organization_id, release_id, status, updated_at DESC);