"""Initial schema Revision ID: 001 Revises: Create Date: 2025-01-24 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql revision: str = '001' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # Sources table op.create_table( 'sources', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(255), nullable=False), sa.Column('platform', sa.String(50), nullable=False), sa.Column('url', sa.Text(), nullable=False), sa.Column('enabled', sa.Boolean(), default=True), sa.Column('priority', sa.Integer(), default=0), sa.Column('check_interval', sa.Integer(), default=28800), sa.Column('last_check', sa.DateTime(), nullable=True), sa.Column('last_success', sa.DateTime(), nullable=True), sa.Column('error_count', sa.Integer(), default=0), sa.Column('metadata', postgresql.JSONB(), default={}), sa.Column('created_at', sa.DateTime(), server_default=sa.func.now()), sa.Column('updated_at', sa.DateTime(), server_default=sa.func.now(), onupdate=sa.func.now()), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('platform', 'url', name='uq_source_platform_url') ) op.create_index('ix_sources_platform', 'sources', ['platform']) # Downloads table op.create_table( 'downloads', sa.Column('id', sa.Integer(), nullable=False), sa.Column('source_id', sa.Integer(), nullable=True), sa.Column('url', sa.Text(), nullable=False), sa.Column('status', sa.String(20), default='pending'), sa.Column('error_type', sa.String(50), nullable=True), sa.Column('error_message', sa.Text(), nullable=True), sa.Column('file_count', sa.Integer(), default=0), sa.Column('total_size', sa.BigInteger(), nullable=True), sa.Column('started_at', sa.DateTime(), nullable=True), sa.Column('completed_at', sa.DateTime(), nullable=True), sa.Column('metadata', postgresql.JSONB(), default={}), sa.Column('created_at', sa.DateTime(), server_default=sa.func.now()), sa.Column('updated_at', sa.DateTime(), server_default=sa.func.now(), onupdate=sa.func.now()), sa.PrimaryKeyConstraint('id'), sa.ForeignKeyConstraint(['source_id'], ['sources.id'], ondelete='SET NULL') ) op.create_index('ix_downloads_status', 'downloads', ['status']) op.create_index('ix_downloads_source_id', 'downloads', ['source_id']) # Content items table op.create_table( 'content_items', sa.Column('id', sa.Integer(), nullable=False), sa.Column('source_id', sa.Integer(), nullable=False), sa.Column('download_id', sa.Integer(), nullable=True), sa.Column('external_id', sa.String(255), nullable=True), sa.Column('title', sa.String(500), nullable=True), sa.Column('content_type', sa.String(50), default='other'), sa.Column('file_path', sa.String(500), nullable=True), sa.Column('file_size', sa.BigInteger(), nullable=True), sa.Column('thumbnail_path', sa.String(500), nullable=True), sa.Column('published_at', sa.DateTime(), nullable=True), sa.Column('discovered_at', sa.DateTime(), server_default=sa.func.now()), sa.Column('metadata', postgresql.JSONB(), default={}), sa.PrimaryKeyConstraint('id'), sa.ForeignKeyConstraint(['source_id'], ['sources.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['download_id'], ['downloads.id'], ondelete='SET NULL'), sa.UniqueConstraint('source_id', 'external_id', name='uq_content_source_external') ) op.create_index('ix_content_items_source_id', 'content_items', ['source_id']) op.create_index('ix_content_items_discovered_at', 'content_items', ['discovered_at']) # Credentials table op.create_table( 'credentials', sa.Column('id', sa.Integer(), nullable=False), sa.Column('platform', sa.String(50), nullable=False), sa.Column('credential_type', sa.String(20), nullable=False), sa.Column('data', sa.LargeBinary(), nullable=False), sa.Column('expires_at', sa.DateTime(), nullable=True), sa.Column('last_verified', sa.DateTime(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.func.now()), sa.Column('updated_at', sa.DateTime(), server_default=sa.func.now(), onupdate=sa.func.now()), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('platform', name='uq_credential_platform') ) op.create_index('ix_credentials_platform', 'credentials', ['platform']) # Settings table op.create_table( 'settings', sa.Column('key', sa.String(100), nullable=False), sa.Column('value', postgresql.JSONB(), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.func.now(), onupdate=sa.func.now()), sa.PrimaryKeyConstraint('key') ) # Insert default settings op.execute(""" INSERT INTO settings (key, value) VALUES ('download.parallel_limit', '3'), ('download.rate_limit', '3.0'), ('download.retry_count', '3'), ('download.schedule_interval', '28800'), ('notification.enabled', 'false'), ('notification.webhook_url', 'null') """) def downgrade() -> None: op.drop_table('settings') op.drop_table('credentials') op.drop_table('content_items') op.drop_table('downloads') op.drop_table('sources')