"""Add workflow_definitions, workflow_runs, workflow_node_results tables. Revision ID: 037 Revises: 036 """ import sqlalchemy as sa from alembic import op from sqlalchemy.dialects.postgresql import UUID, JSONB revision = '037' down_revision = '036' branch_labels = None depends_on = None def upgrade(): op.create_table('workflow_definitions', sa.Column('id', UUID(as_uuid=True), primary_key=True, server_default=sa.text('gen_random_uuid()')), sa.Column('name', sa.String(200), nullable=False), sa.Column('output_type_id', UUID(as_uuid=True), sa.ForeignKey('output_types.id', ondelete='SET NULL'), nullable=True), sa.Column('config', JSONB, nullable=False, server_default='{}'), sa.Column('is_active', sa.Boolean, nullable=False, server_default='true'), sa.Column('created_at', sa.DateTime, nullable=False, server_default=sa.text('NOW()')), ) op.create_table('workflow_runs', sa.Column('id', UUID(as_uuid=True), primary_key=True, server_default=sa.text('gen_random_uuid()')), sa.Column('workflow_def_id', UUID(as_uuid=True), sa.ForeignKey('workflow_definitions.id', ondelete='SET NULL'), nullable=True), sa.Column('order_line_id', UUID(as_uuid=True), sa.ForeignKey('order_lines.id', ondelete='CASCADE'), nullable=True), sa.Column('celery_task_id', sa.String(500), nullable=True), sa.Column('status', sa.String(50), nullable=False, server_default='pending'), sa.Column('started_at', sa.DateTime, nullable=True), sa.Column('completed_at', sa.DateTime, nullable=True), sa.Column('error_message', sa.Text, nullable=True), sa.Column('created_at', sa.DateTime, nullable=False, server_default=sa.text('NOW()')), ) op.create_index('ix_workflow_runs_order_line', 'workflow_runs', ['order_line_id']) op.create_index('ix_workflow_runs_status', 'workflow_runs', ['status']) op.create_table('workflow_node_results', sa.Column('id', UUID(as_uuid=True), primary_key=True, server_default=sa.text('gen_random_uuid()')), sa.Column('run_id', UUID(as_uuid=True), sa.ForeignKey('workflow_runs.id', ondelete='CASCADE'), nullable=False), sa.Column('node_name', sa.String(200), nullable=False), sa.Column('status', sa.String(50), nullable=False, server_default='pending'), sa.Column('output', JSONB, nullable=True), sa.Column('log', sa.Text, nullable=True), sa.Column('duration_s', sa.Float, nullable=True), sa.Column('created_at', sa.DateTime, nullable=False, server_default=sa.text('NOW()')), ) op.create_index('ix_workflow_node_results_run', 'workflow_node_results', ['run_id']) # Seed standard workflow definitions op.execute(""" INSERT INTO workflow_definitions (name, config, is_active) VALUES ('Still-Render', '{"type": "still", "params": {"render_engine": "cycles", "samples": 256, "resolution": [2048, 2048]}}', true), ('Turntable-Animation', '{"type": "turntable", "params": {"render_engine": "cycles", "samples": 64, "fps": 24, "duration_s": 5}}', true), ('Multi-Angle', '{"type": "multi_angle", "params": {"render_engine": "cycles", "samples": 128, "angles": [0, 45, 90, 135, 180]}}', true) """) def downgrade(): op.drop_table('workflow_node_results') op.drop_table('workflow_runs') op.drop_table('workflow_definitions')