diff --git a/CLAUDE.md b/CLAUDE.md index 1c937b0297..2ff2ed4baf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,6 +32,37 @@ uv run ruff format . # Format Python code uv run mypy . # Type check Python code ``` +### Database Migration (api/) + +The project uses **Flask-Migrate** (Alembic) for database schema management: + +```bash +cd api +# Apply pending migrations to database +uv run flask db upgrade + +# Generate new migration from model changes +uv run flask db migrate -m "description_of_changes" + +# Check current migration status +uv run flask db current + +# View migration history +uv run flask db history + +# Downgrade to previous migration (if needed) +uv run flask db downgrade +``` + +**Migration File Naming Pattern**: `YYYY_MM_DD_HHMM-{revision_id}_{description}.py` + +**Key Migration Guidelines**: +- Always review auto-generated migrations before applying +- Use descriptive migration messages +- Test migrations on staging before production +- Migrations are in `api/migrations/versions/` +- Migration templates use `script.py.mako` + ### Docker Development ```bash diff --git a/api/migrations/versions/2025_07_03_1704-ad34c0f30fcc_add_null_organization_indexes.py b/api/migrations/versions/2025_07_03_1704-ad34c0f30fcc_add_null_organization_indexes.py new file mode 100644 index 0000000000..638660ce98 --- /dev/null +++ b/api/migrations/versions/2025_07_03_1704-ad34c0f30fcc_add_null_organization_indexes.py @@ -0,0 +1,55 @@ +"""add_null_organization_indexes + +Revision ID: ad34c0f30fcc +Revises: 81cd7d2f1cf0 +Create Date: 2025-07-03 17:04:27.080113 + +""" +from alembic import op +import models as models +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'ad34c0f30fcc' +down_revision = '81cd7d2f1cf0' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_files', schema=None) as batch_op: + batch_op.alter_column('user_id', + existing_type=sa.UUID(), + nullable=False) + + with op.batch_alter_table('tool_published_apps', schema=None) as batch_op: + batch_op.drop_column('size') + batch_op.drop_column('mimetype') + batch_op.drop_column('name') + batch_op.drop_column('file_key') + batch_op.drop_column('original_url') + batch_op.drop_column('conversation_id') + batch_op.drop_column('tenant_id') + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_published_apps', schema=None) as batch_op: + batch_op.add_column(sa.Column('tenant_id', sa.UUID(), autoincrement=False, nullable=False)) + batch_op.add_column(sa.Column('conversation_id', sa.UUID(), autoincrement=False, nullable=True)) + batch_op.add_column(sa.Column('original_url', sa.VARCHAR(length=2048), autoincrement=False, nullable=True)) + batch_op.add_column(sa.Column('file_key', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + batch_op.add_column(sa.Column('name', sa.VARCHAR(), autoincrement=False, nullable=False)) + batch_op.add_column(sa.Column('mimetype', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + batch_op.add_column(sa.Column('size', sa.INTEGER(), autoincrement=False, nullable=False)) + + with op.batch_alter_table('tool_files', schema=None) as batch_op: + batch_op.alter_column('user_id', + existing_type=sa.UUID(), + nullable=True) + + # ### end Alembic commands ###