"""Add project templates table Revision ID: 016 Revises: 015 Create Date: 2026-01-10 Adds project_templates table for storing reusable project configurations with predefined task statuses and custom fields. """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = '016' down_revision: Union[str, None] = '015' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # Create pjctrl_project_templates table op.create_table( 'pjctrl_project_templates', sa.Column('id', sa.String(36), primary_key=True), sa.Column('name', sa.String(200), nullable=False), sa.Column('description', sa.Text, nullable=True), sa.Column('owner_id', sa.String(36), sa.ForeignKey('pjctrl_users.id'), nullable=False), sa.Column('is_public', sa.Boolean, default=False, nullable=False), sa.Column('is_active', sa.Boolean, default=True, nullable=False), sa.Column('task_statuses', sa.JSON, nullable=True), sa.Column('custom_fields', sa.JSON, nullable=True), sa.Column('default_security_level', sa.String(20), default='department', nullable=True), sa.Column('created_at', sa.DateTime, server_default=sa.func.now(), nullable=False), sa.Column('updated_at', sa.DateTime, server_default=sa.func.now(), onupdate=sa.func.now(), nullable=False), ) # Create indexes op.create_index('ix_pjctrl_project_templates_owner_id', 'pjctrl_project_templates', ['owner_id']) op.create_index('ix_pjctrl_project_templates_is_public', 'pjctrl_project_templates', ['is_public']) op.create_index('ix_pjctrl_project_templates_is_active', 'pjctrl_project_templates', ['is_active']) def downgrade() -> None: op.drop_index('ix_pjctrl_project_templates_is_active', table_name='pjctrl_project_templates') op.drop_index('ix_pjctrl_project_templates_is_public', table_name='pjctrl_project_templates') op.drop_index('ix_pjctrl_project_templates_owner_id', table_name='pjctrl_project_templates') op.drop_table('pjctrl_project_templates')