Skip to content

Commit 34dc76f

Browse files
fix(schedules): use stable handles for run schedules
Move schedule authorization and mutations to immutable row identifiers while keeping name-based aliases for convenience. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2ffde24 commit 34dc76f

12 files changed

Lines changed: 754 additions & 166 deletions
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""move run schedule identity to row id
2+
3+
Revision ID: 9a4b8c7d6e5f
4+
Revises: e7f8a9b0c1d2
5+
Create Date: 2026-07-08 16:26:00.000000
6+
7+
Switches schedule names from reserved external handles to mutable labels by
8+
making the name uniqueness constraint apply only to active rows. Schema-only and
9+
idempotent: index creation/drop use CONCURRENTLY with IF EXISTS / IF NOT EXISTS.
10+
"""
11+
12+
from collections.abc import Sequence
13+
14+
from alembic import op
15+
16+
# revision identifiers, used by Alembic.
17+
revision: str = "9a4b8c7d6e5f"
18+
down_revision: str | None = "e7f8a9b0c1d2"
19+
branch_labels: str | Sequence[str] | None = None
20+
depends_on: str | Sequence[str] | None = None
21+
22+
23+
def upgrade() -> None:
24+
with op.get_context().autocommit_block():
25+
op.execute(
26+
"CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "
27+
"uq_agent_run_schedules_active_agent_name "
28+
"ON agent_run_schedules (agent_id, name) "
29+
"WHERE deleted_at IS NULL"
30+
)
31+
op.execute(
32+
"DROP INDEX CONCURRENTLY IF EXISTS uq_agent_run_schedules_agent_name"
33+
)
34+
35+
36+
def downgrade() -> None:
37+
with op.get_context().autocommit_block():
38+
op.execute(
39+
"CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "
40+
"uq_agent_run_schedules_agent_name "
41+
"ON agent_run_schedules (agent_id, name)"
42+
)
43+
op.execute(
44+
"DROP INDEX CONCURRENTLY IF EXISTS "
45+
"uq_agent_run_schedules_active_agent_name"
46+
)

0 commit comments

Comments
 (0)