"""assistant_messages.sources — keep an answer's citations with the answer Revision ID: 518 Revises: 517 The answer card renders the mirrored Feishu docs the reply drew on, and the employee taps 👍/👎 on that card. Handling the tap has to return a new card (Feishu replaces the old one with whatever the callback answers), and the new card was rebuilt from ``content`` alone — so **rating an answer deleted its sources**. The links were never stored: they lived only in the turn that sent the card. Stored as JSON rather than a child table: it is a short, ordered, read-together list (at most three ``{title, url}`` pairs — ``answer_card.MAX_DOC_LINKS``) that nothing ever queries by, which is what JSON is for. Nullable with no backfill: rows written before this column existed genuinely have no recorded sources, and inventing an empty list for them would claim we know they had none. """ from alembic import op import sqlalchemy as sa revision = "518" down_revision = "517" branch_labels = None depends_on = None def upgrade() -> None: op.add_column( "assistant_messages", sa.Column("sources", sa.JSON(), nullable=True), ) def downgrade() -> None: op.drop_column("assistant_messages", "sources")