feat: add repository rename lifecycle API
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3
This commit is contained in:
parent
9e77a4a9a2
commit
82ea38b180
11 changed files with 2464 additions and 3 deletions
|
|
@ -0,0 +1,89 @@
|
|||
"""allow only operation-guarded alias restoration during rollback
|
||||
|
||||
Revision ID: a4d5e6f7b8c9
|
||||
Revises: f3c4d5e6a7b8
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision = "a4d5e6f7b8c9"
|
||||
down_revision = "f3c4d5e6a7b8"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# T02 made aliases immutable. Rollback needs exactly one controlled
|
||||
# exception: the alias created by this operation may become canonical while
|
||||
# that same operation is in rollback-preflight. Ownership, spelling,
|
||||
# protection, and provenance remain immutable.
|
||||
op.execute(
|
||||
sa.text(
|
||||
"""
|
||||
CREATE OR REPLACE FUNCTION guard_repository_slug_history()
|
||||
RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF TG_OP = 'DELETE' THEN
|
||||
RAISE EXCEPTION 'repository slug rows are durable';
|
||||
END IF;
|
||||
IF NEW.repo_id IS DISTINCT FROM OLD.repo_id
|
||||
OR NEW.slug IS DISTINCT FROM OLD.slug THEN
|
||||
RAISE EXCEPTION 'repository slug ownership is immutable';
|
||||
END IF;
|
||||
IF OLD.kind = 'alias' AND ROW(
|
||||
NEW.kind, NEW.protected, NEW.source_operation_id
|
||||
) IS DISTINCT FROM ROW(
|
||||
OLD.kind, OLD.protected, OLD.source_operation_id
|
||||
) THEN
|
||||
IF NOT (
|
||||
NEW.kind = 'canonical'
|
||||
AND NEW.protected
|
||||
AND NEW.source_operation_id = OLD.source_operation_id
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM repository_rename_operations operation
|
||||
WHERE operation.id = OLD.source_operation_id
|
||||
AND operation.repo_id = OLD.repo_id
|
||||
AND operation.phase = 'rollback-preflight'
|
||||
)
|
||||
) THEN
|
||||
RAISE EXCEPTION 'protected repository alias is immutable';
|
||||
END IF;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.execute(
|
||||
sa.text(
|
||||
"""
|
||||
CREATE OR REPLACE FUNCTION guard_repository_slug_history()
|
||||
RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF TG_OP = 'DELETE' THEN
|
||||
RAISE EXCEPTION 'repository slug rows are durable';
|
||||
END IF;
|
||||
IF NEW.repo_id IS DISTINCT FROM OLD.repo_id
|
||||
OR NEW.slug IS DISTINCT FROM OLD.slug THEN
|
||||
RAISE EXCEPTION 'repository slug ownership is immutable';
|
||||
END IF;
|
||||
IF OLD.kind = 'alias' AND ROW(
|
||||
NEW.kind, NEW.protected, NEW.source_operation_id
|
||||
) IS DISTINCT FROM ROW(
|
||||
OLD.kind, OLD.protected, OLD.source_operation_id
|
||||
) THEN
|
||||
RAISE EXCEPTION 'protected repository alias is immutable';
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql
|
||||
"""
|
||||
)
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue