"""feed_posts.client_token — server-side idempotency for post creation ``POST /feed/posts`` had no idempotency at all. The year-in-review's "share my recap" guarded itself with a ``localStorage`` flag, which is per-browser-tab and invisible to curl and to the ``feed_create_post`` MCP tool; two tabs (or one double-click that outran the disabled state) published two identical recaps and fanned out two rounds of mention pushes. The token is unique **per author**, not globally: two people may legitimately send the same deterministic token (``wrapped:2026``). NULL is exempt — MySQL allows unlimited NULLs in a unique index — so every existing row, every celebration post, and every announcement keeps working untouched. Revision ID: 457 Revises: 456 """ from __future__ import annotations import sqlalchemy as sa from alembic import op revision = "457" down_revision = "456" branch_labels = None depends_on = None def upgrade() -> None: op.add_column( "feed_posts", sa.Column("client_token", sa.String(length=128), nullable=True), ) op.create_index( "uq_feed_posts_author_client_token", "feed_posts", ["author_person_id", "client_token"], unique=True, ) def downgrade() -> None: op.drop_index("uq_feed_posts_author_client_token", table_name="feed_posts") op.drop_column("feed_posts", "client_token")