"""baseline schema Revision ID: c6af106a04da Revises: Create Date: 2026-07-15 08:21:07.450350 This is the initial baseline. It creates the current schema on a fresh database, and safely ADOPTS an existing database (one whose tables were created by the old `Base.metadata.create_all()` before Alembic was introduced): if the schema is already present it records this revision without recreating anything. That means `alembic upgrade head` is safe to run on both new and existing deployments — no manual `alembic stamp` step required. """ from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision = 'c6af106a04da' down_revision = None branch_labels = None depends_on = None def upgrade() -> None: bind = op.get_bind() if sa.inspect(bind).has_table("projects"): # Existing pre-Alembic database — adopt it as the baseline as-is. return # ### commands auto generated by Alembic - please adjust! ### op.create_table('comments', sa.Column('id', sa.String(length=40), nullable=False), sa.Column('source', sa.String(length=40), nullable=False), sa.Column('sop_id', sa.String(length=40), nullable=True), sa.Column('wp_id', sa.String(length=40), nullable=True), sa.Column('step', sa.Integer(), nullable=True), sa.Column('author', sa.String(length=200), nullable=False), sa.Column('text', sa.Text(), nullable=False), sa.Column('page', sa.String(length=200), nullable=False), sa.Column('extra', sa.JSON(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_comments_sop_id'), 'comments', ['sop_id'], unique=False) op.create_index(op.f('ix_comments_source'), 'comments', ['source'], unique=False) op.create_index(op.f('ix_comments_wp_id'), 'comments', ['wp_id'], unique=False) op.create_table('projects', sa.Column('id', sa.String(length=40), nullable=False), sa.Column('name', sa.String(length=300), nullable=False), sa.Column('number', sa.String(length=100), nullable=False), sa.Column('client', sa.String(length=300), nullable=False), sa.Column('division', sa.String(length=200), nullable=False), sa.Column('site', sa.String(length=300), nullable=False), sa.Column('sample', sa.Boolean(), nullable=False), sa.Column('data', sa.JSON(), nullable=False), sa.Column('created_by', sa.String(length=200), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_projects_number'), 'projects', ['number'], unique=False) op.create_table('users', sa.Column('id', sa.String(length=40), nullable=False), sa.Column('username', sa.String(length=120), nullable=False), sa.Column('email', sa.String(length=200), nullable=False), sa.Column('full_name', sa.String(length=200), nullable=False), sa.Column('password_hash', sa.String(length=200), nullable=False), sa.Column('role', sa.String(length=20), nullable=False), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.Column('last_login_at', sa.DateTime(timezone=True), nullable=True), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True) op.create_table('project_members', sa.Column('id', sa.String(length=40), nullable=False), sa.Column('user_id', sa.String(length=40), nullable=False), sa.Column('project_id', sa.String(length=40), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('user_id', 'project_id', name='uq_project_member') ) op.create_index(op.f('ix_project_members_project_id'), 'project_members', ['project_id'], unique=False) op.create_index(op.f('ix_project_members_user_id'), 'project_members', ['user_id'], unique=False) op.create_table('sops', sa.Column('id', sa.String(length=40), nullable=False), sa.Column('project_id', sa.String(length=40), nullable=True), sa.Column('name', sa.String(length=300), nullable=False), sa.Column('number', sa.String(length=100), nullable=False), sa.Column('complete', sa.Boolean(), nullable=False), sa.Column('data', sa.JSON(), nullable=False), sa.Column('created_by', sa.String(length=200), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_sops_project_id'), 'sops', ['project_id'], unique=False) op.create_table('work_packages', sa.Column('id', sa.String(length=40), nullable=False), sa.Column('project_id', sa.String(length=40), nullable=True), sa.Column('sop_id', sa.String(length=40), nullable=True), sa.Column('parent_id', sa.String(length=40), nullable=True), sa.Column('number', sa.String(length=120), nullable=False), sa.Column('subject', sa.String(length=400), nullable=False), sa.Column('type', sa.String(length=120), nullable=False), sa.Column('status', sa.String(length=40), nullable=False), sa.Column('issued_at', sa.DateTime(timezone=True), nullable=True), sa.Column('data', sa.JSON(), nullable=False), sa.Column('created_by', sa.String(length=200), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['sop_id'], ['sops.id'], ondelete='SET NULL'), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_work_packages_parent_id'), 'work_packages', ['parent_id'], unique=False) op.create_index(op.f('ix_work_packages_project_id'), 'work_packages', ['project_id'], unique=False) op.create_index(op.f('ix_work_packages_sop_id'), 'work_packages', ['sop_id'], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.drop_index(op.f('ix_work_packages_sop_id'), table_name='work_packages') op.drop_index(op.f('ix_work_packages_project_id'), table_name='work_packages') op.drop_index(op.f('ix_work_packages_parent_id'), table_name='work_packages') op.drop_table('work_packages') op.drop_index(op.f('ix_sops_project_id'), table_name='sops') op.drop_table('sops') op.drop_index(op.f('ix_project_members_user_id'), table_name='project_members') op.drop_index(op.f('ix_project_members_project_id'), table_name='project_members') op.drop_table('project_members') op.drop_index(op.f('ix_users_username'), table_name='users') op.drop_table('users') op.drop_index(op.f('ix_projects_number'), table_name='projects') op.drop_table('projects') op.drop_index(op.f('ix_comments_wp_id'), table_name='comments') op.drop_index(op.f('ix_comments_source'), table_name='comments') op.drop_index(op.f('ix_comments_sop_id'), table_name='comments') op.drop_table('comments') # ### end Alembic commands ###