Files
AlphaPulse/backend/alembic/versions/20261101_d4e6f8012345_news_events.py
eezd f1d060d475
Development CI / check-and-build (push) Successful in 2m33s
GitHub Git mirror / mirror (push) Successful in 5s
Development CI / deploy-development (push) Failing after 7s
feat: organize news packages into verified event timelines
Add optional events, evidence-backed timelines, versioned package corrections and bounded historical reprocessing. Keep independent packages readable and isolate retries by failed stage. Configure reasoning effort per model stage and refresh default news Skill drafts without publishing.
2026-11-01 11:46:11 +08:00

56 lines
4.8 KiB
Python

"""Add event timelines, grouping history and explicit reprocessing jobs."""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import JSONB
revision = 'd4e6f8012345'
down_revision = 'c3d5e7f90123'
branch_labels = None
depends_on = None
def upgrade():
op.add_column('news_ai_summaries', sa.Column('review_config', JSONB))
op.add_column('news_ai_summaries', sa.Column('replacement_ids', JSONB, nullable=False, server_default='[]'))
op.add_column('news_ai_summary_articles', sa.Column('active', sa.Boolean, nullable=False, server_default=sa.true()))
op.add_column('news_ai_summary_articles', sa.Column('unit', JSONB, nullable=True))
op.create_table('news_ai_events', sa.Column('id', sa.BigInteger, primary_key=True), sa.Column('title', sa.Text, nullable=False),
sa.Column('state', sa.String(16), nullable=False), sa.Column('revision', sa.Integer, nullable=False), sa.Column('published_revision', sa.Integer, nullable=False),
sa.Column('result', JSONB), sa.Column('error', sa.Text), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('due_at', sa.DateTime(timezone=True), nullable=False), sa.Column('review_config', JSONB))
op.create_index('ix_news_ai_events_due_at', 'news_ai_events', ['due_at'])
op.create_table('news_ai_event_members', sa.Column('package_id', sa.BigInteger, sa.ForeignKey('news_ai_summaries.id'), primary_key=True),
sa.Column('event_id', sa.BigInteger, sa.ForeignKey('news_ai_events.id'), nullable=False), sa.Column('reason', sa.Text, nullable=False))
op.create_index('ix_news_ai_event_members_event_id', 'news_ai_event_members', ['event_id'])
op.create_table('news_ai_event_versions', sa.Column('id', sa.BigInteger, primary_key=True),
sa.Column('event_id', sa.BigInteger, sa.ForeignKey('news_ai_events.id'), nullable=False), sa.Column('revision', sa.Integer, nullable=False),
sa.Column('input', JSONB, nullable=False), sa.Column('result', JSONB), sa.Column('rules', JSONB, nullable=False),
sa.Column('state', sa.String(16), nullable=False), sa.Column('error', sa.Text), sa.Column('usage', JSONB),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()))
op.create_index('ix_news_ai_event_versions_event_id', 'news_ai_event_versions', ['event_id'])
op.create_table('news_ai_grouping_versions', sa.Column('id', sa.BigInteger, primary_key=True),
sa.Column('analysis_id', sa.BigInteger, sa.ForeignKey('news_ai_article_analyses.id'), nullable=False),
sa.Column('input', JSONB, nullable=False), sa.Column('result', JSONB), sa.Column('rules', JSONB),
sa.Column('state', sa.String(16), nullable=False), sa.Column('error', sa.Text),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()))
op.create_index('ix_news_ai_grouping_versions_analysis_id', 'news_ai_grouping_versions', ['analysis_id'])
op.execute('INSERT INTO news_ai_grouping_versions (analysis_id,input,result,rules,state,error) SELECT id,input,result,rules,state,error FROM news_ai_article_analyses')
op.create_table('news_ai_package_corrections', sa.Column('id', sa.BigInteger, primary_key=True),
sa.Column('fingerprint', sa.String(64), nullable=False, unique=True), sa.Column('input', JSONB, nullable=False),
sa.Column('result', JSONB, nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()))
op.create_table('news_ai_reprocess_jobs', sa.Column('id', sa.BigInteger, primary_key=True), sa.Column('state', sa.String(16), nullable=False),
sa.Column('settings', JSONB, nullable=False), sa.Column('items', JSONB, nullable=False), sa.Column('position', sa.Integer, nullable=False),
sa.Column('failures', JSONB, nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()))
op.create_index('ix_news_ai_reprocess_jobs_state', 'news_ai_reprocess_jobs', ['state'])
op.create_table('news_ai_event_links', sa.Column('package_id', sa.BigInteger, sa.ForeignKey('news_ai_summaries.id'), primary_key=True), sa.Column('event_id', sa.BigInteger, sa.ForeignKey('news_ai_events.id'), primary_key=True), sa.Column('reason', sa.Text, nullable=False), sa.Column('package_revision', sa.Integer, nullable=False))
op.execute('UPDATE risk_settings SET enabled=false')
def downgrade():
for table in ('news_ai_event_links', 'news_ai_reprocess_jobs', 'news_ai_package_corrections', 'news_ai_grouping_versions', 'news_ai_event_versions', 'news_ai_event_members', 'news_ai_events'):
op.drop_table(table)
op.drop_column('news_ai_summary_articles', 'unit')
op.drop_column('news_ai_summary_articles', 'active')
op.drop_column('news_ai_summaries', 'replacement_ids')
op.drop_column('news_ai_summaries', 'review_config')