- Delivery handler now signs/delivers using the per-app domain that matches the follower's subscription (not always federation domain) - app_domain is NOT NULL with default 'federation' (sentinel replaces NULL to avoid uniqueness constraint edge case) - Aggregate actor advertises per-app actors via alsoKnownAs - Migration backfills existing NULL rows to 'federation' Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Add app_domain to ap_followers for per-app AP actors
|
|
|
|
Revision ID: t0r8n4o6p7
|
|
Revises: s9q7n3o5p6
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
revision = "t0r8n4o6p7"
|
|
down_revision = "s9q7n3o5p6"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade():
|
|
# Add column as nullable first so we can backfill
|
|
op.add_column(
|
|
"ap_followers",
|
|
sa.Column("app_domain", sa.String(64), nullable=True),
|
|
)
|
|
# Backfill existing rows: all current followers are aggregate
|
|
op.execute("UPDATE ap_followers SET app_domain = 'federation' WHERE app_domain IS NULL")
|
|
# Now make it NOT NULL with a default
|
|
op.alter_column(
|
|
"ap_followers", "app_domain",
|
|
nullable=False, server_default="federation",
|
|
)
|
|
# Replace old unique constraint with one that includes app_domain
|
|
op.drop_constraint("uq_follower_acct", "ap_followers", type_="unique")
|
|
op.create_unique_constraint(
|
|
"uq_follower_acct_app",
|
|
"ap_followers",
|
|
["actor_profile_id", "follower_acct", "app_domain"],
|
|
)
|
|
op.create_index(
|
|
"ix_ap_follower_app_domain",
|
|
"ap_followers",
|
|
["actor_profile_id", "app_domain"],
|
|
)
|
|
|
|
|
|
def downgrade():
|
|
op.drop_index("ix_ap_follower_app_domain", table_name="ap_followers")
|
|
op.drop_constraint("uq_follower_acct_app", "ap_followers", type_="unique")
|
|
op.create_unique_constraint(
|
|
"uq_follower_acct",
|
|
"ap_followers",
|
|
["actor_profile_id", "follower_acct"],
|
|
)
|
|
op.alter_column("ap_followers", "app_domain", nullable=True, server_default=None)
|
|
op.drop_column("ap_followers", "app_domain")
|