"""The unified post card — fold window, family window, and who linked a pair. Milestone 388, #4402 and #4401. A Patreon teaser's card shows the Discord drop it announced, and the rest of that piece's variants, by REFERENCE: nothing is absorbed, nothing changes owner, and every Discord post keeps its own place. Three columns: * `import_settings.discord_link_fold_hours` — a linked drop leaves the feed only when it is this close to its teaser (the same release, shown twice). * `import_settings.discord_family_window_days` — how far from the teaser the card reaches for variants. 60 is measured: named families spread up to 44 days on artist 8, every collision found over 500. * `post_association.linked_by` — "fc" or "operator", so a link FC made by itself can say so on the card and offer the undo the operator asked for. Revision ID: 0110 Revises: 0109 Create Date: 2026-09-24 """ import sqlalchemy as sa from alembic import op revision = "0110" down_revision = "0109" branch_labels = None depends_on = None def upgrade(): op.add_column( "import_settings", sa.Column( "discord_link_fold_hours", sa.Float(), nullable=False, server_default=sa.text("24"), ), ) op.add_column( "import_settings", sa.Column( "discord_family_window_days", sa.Float(), nullable=False, server_default=sa.text("60"), ), ) op.add_column( "post_association", sa.Column("linked_by", sa.String(length=16), nullable=True), ) def downgrade(): op.drop_column("post_association", "linked_by") op.drop_column("import_settings", "discord_family_window_days") op.drop_column("import_settings", "discord_link_fold_hours")