0121 keeps the ARM_BORN date beside the constant it justifies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
3.0 KiB
Python
83 lines
3.0 KiB
Python
"""drop rulebook subscriptions and per-project suppressions
|
|
|
|
Revision ID: 0101
|
|
Revises: 0100
|
|
Create Date: 2026-09-15
|
|
|
|
A rule lives in a rulebook topic, where it is GLOBAL, or on one project, and
|
|
retrieval reads that home directly. Subscriptions were the last thing that
|
|
pretended a rulebook reached some projects and not others, and with no
|
|
always-on tier they changed nothing a session received — only what a
|
|
project's rule LISTING showed. Global and project-scoped rules cover what
|
|
subscriptions were for.
|
|
|
|
WHAT GOES
|
|
|
|
- ``project_rulebook_subscriptions`` (migration 0058).
|
|
- ``project_rule_suppressions`` and ``project_topic_suppressions``. They let a
|
|
project mute rules from a rulebook it subscribed to. With no subscription
|
|
there is nothing to mute; a project that departs from a global rule writes
|
|
a project rule with an ``overrides`` relation, which says why.
|
|
- The ``subscribe_rulebooks`` key inside ``projects.inception.choices``, and
|
|
the ``exclude_always_on_rulebooks`` key the retired always-on tier left
|
|
in the same place. Both describe decisions that can no longer be made; a stored
|
|
record carrying them would be read back as a choice the product offers.
|
|
|
|
IRREVERSIBLE, AND THE DOWNGRADE SAYS SO
|
|
|
|
The downgrade recreates the three tables empty. Which projects subscribed to
|
|
which rulebooks, and what they muted, is in what this drops. Restore a backup
|
|
taken before this ran if the prior state matters.
|
|
"""
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision = "0101"
|
|
down_revision = "0100"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.drop_table("project_topic_suppressions")
|
|
op.drop_table("project_rule_suppressions")
|
|
op.drop_table("project_rulebook_subscriptions")
|
|
op.execute(
|
|
"""
|
|
UPDATE projects
|
|
SET inception = jsonb_set(
|
|
inception, '{choices}',
|
|
(inception->'choices') - 'subscribe_rulebooks' - 'exclude_always_on_rulebooks'
|
|
)
|
|
WHERE inception IS NOT NULL
|
|
AND jsonb_typeof(inception->'choices') = 'object'
|
|
"""
|
|
)
|
|
|
|
|
|
def _join_table(name: str, other: str, other_table: str) -> None:
|
|
op.create_table(
|
|
name,
|
|
sa.Column(
|
|
"project_id", sa.BigInteger(),
|
|
sa.ForeignKey("projects.id", ondelete="CASCADE"),
|
|
primary_key=True, nullable=False,
|
|
),
|
|
sa.Column(
|
|
other, sa.BigInteger(),
|
|
sa.ForeignKey(f"{other_table}.id", ondelete="CASCADE"),
|
|
primary_key=True, nullable=False,
|
|
),
|
|
sa.Column(
|
|
"created_at", sa.DateTime(timezone=True),
|
|
server_default=sa.text("now()"), nullable=True,
|
|
),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Structure only. See the module docstring — the rows are gone."""
|
|
_join_table("project_rulebook_subscriptions", "rulebook_id", "rulebooks")
|
|
_join_table("project_rule_suppressions", "rule_id", "rules")
|
|
_join_table("project_topic_suppressions", "topic_id", "rulebook_topics")
|