|
8 | 8 | Create Date: 2026-02-09 |
9 | 9 |
|
10 | 10 | """ |
11 | | -from typing import Sequence, Union |
12 | 11 |
|
13 | | -from alembic import op |
| 12 | +from collections.abc import Sequence |
| 13 | + |
14 | 14 | import sqlalchemy as sa |
15 | 15 | from sqlalchemy.dialects import postgresql |
16 | 16 |
|
| 17 | +from alembic import op |
| 18 | + |
17 | 19 | # revision identifiers, used by Alembic. |
18 | | -revision: str = 'add_case_notes_001' |
19 | | -down_revision: Union[str, None] = 'e4b2c1a37f90' |
20 | | -branch_labels: Union[str, Sequence[str], None] = None |
21 | | -depends_on: Union[str, Sequence[str], None] = None |
| 20 | +revision: str = "add_case_notes_001" |
| 21 | +down_revision: str | None = "e4b2c1a37f90" |
| 22 | +branch_labels: str | Sequence[str] | None = None |
| 23 | +depends_on: str | Sequence[str] | None = None |
22 | 24 |
|
23 | 25 |
|
24 | 26 | def upgrade() -> None: |
25 | 27 | # Create enum for note type |
26 | | - note_type_enum = postgresql.ENUM('TEXT', 'AUDIO', name='notetype', create_type=False) |
| 28 | + note_type_enum = postgresql.ENUM( |
| 29 | + "TEXT", "AUDIO", name="notetype", create_type=False |
| 30 | + ) |
27 | 31 | note_type_enum.create(op.get_bind(), checkfirst=True) |
28 | 32 |
|
29 | 33 | op.create_table( |
30 | | - 'case_notes', |
31 | | - sa.Column('id', postgresql.UUID(as_uuid=True), primary_key=True, server_default=sa.text('gen_random_uuid()')), |
32 | | - sa.Column('case_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('cases.id', ondelete='CASCADE'), nullable=False), |
33 | | - sa.Column('user_id', sa.String(255), nullable=False), |
34 | | - sa.Column('type', postgresql.ENUM('TEXT', 'AUDIO', name='notetype', create_type=False), nullable=False), |
35 | | - sa.Column('content', sa.Text(), nullable=True), # For text notes |
36 | | - sa.Column('audio_storage_path', sa.String(500), nullable=True), # For audio notes |
37 | | - sa.Column('audio_duration_seconds', sa.Integer(), nullable=True), |
38 | | - sa.Column('audio_mime_type', sa.String(100), nullable=True), |
39 | | - sa.Column('title', sa.String(255), nullable=True), # AI-generated |
40 | | - sa.Column('subtitle', sa.Text(), nullable=True), # AI-generated |
41 | | - sa.Column('is_exported', sa.Boolean(), server_default='false', nullable=False), |
42 | | - sa.Column('exported_file_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('case_files.id', ondelete='SET NULL'), nullable=True), |
43 | | - sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), |
44 | | - sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), |
| 34 | + "case_notes", |
| 35 | + sa.Column( |
| 36 | + "id", |
| 37 | + postgresql.UUID(as_uuid=True), |
| 38 | + primary_key=True, |
| 39 | + server_default=sa.text("gen_random_uuid()"), |
| 40 | + ), |
| 41 | + sa.Column( |
| 42 | + "case_id", |
| 43 | + postgresql.UUID(as_uuid=True), |
| 44 | + sa.ForeignKey("cases.id", ondelete="CASCADE"), |
| 45 | + nullable=False, |
| 46 | + ), |
| 47 | + sa.Column("user_id", sa.String(255), nullable=False), |
| 48 | + sa.Column( |
| 49 | + "type", |
| 50 | + postgresql.ENUM("TEXT", "AUDIO", name="notetype", create_type=False), |
| 51 | + nullable=False, |
| 52 | + ), |
| 53 | + sa.Column("content", sa.Text(), nullable=True), # For text notes |
| 54 | + sa.Column( |
| 55 | + "audio_storage_path", sa.String(500), nullable=True |
| 56 | + ), # For audio notes |
| 57 | + sa.Column("audio_duration_seconds", sa.Integer(), nullable=True), |
| 58 | + sa.Column("audio_mime_type", sa.String(100), nullable=True), |
| 59 | + sa.Column("title", sa.String(255), nullable=True), # AI-generated |
| 60 | + sa.Column("subtitle", sa.Text(), nullable=True), # AI-generated |
| 61 | + sa.Column("is_exported", sa.Boolean(), server_default="false", nullable=False), |
| 62 | + sa.Column( |
| 63 | + "exported_file_id", |
| 64 | + postgresql.UUID(as_uuid=True), |
| 65 | + sa.ForeignKey("case_files.id", ondelete="SET NULL"), |
| 66 | + nullable=True, |
| 67 | + ), |
| 68 | + sa.Column( |
| 69 | + "created_at", |
| 70 | + sa.DateTime(timezone=True), |
| 71 | + server_default=sa.text("now()"), |
| 72 | + nullable=False, |
| 73 | + ), |
| 74 | + sa.Column( |
| 75 | + "updated_at", |
| 76 | + sa.DateTime(timezone=True), |
| 77 | + server_default=sa.text("now()"), |
| 78 | + nullable=False, |
| 79 | + ), |
45 | 80 | ) |
46 | 81 |
|
47 | 82 | # Create indexes for efficient querying |
48 | | - op.create_index('idx_case_notes_case_id', 'case_notes', ['case_id']) |
49 | | - op.create_index('idx_case_notes_user_id', 'case_notes', ['user_id']) |
50 | | - op.create_index('idx_case_notes_created_at', 'case_notes', ['created_at']) |
| 83 | + op.create_index("idx_case_notes_case_id", "case_notes", ["case_id"]) |
| 84 | + op.create_index("idx_case_notes_user_id", "case_notes", ["user_id"]) |
| 85 | + op.create_index("idx_case_notes_created_at", "case_notes", ["created_at"]) |
51 | 86 |
|
52 | 87 |
|
53 | 88 | def downgrade() -> None: |
54 | | - op.drop_index('idx_case_notes_created_at') |
55 | | - op.drop_index('idx_case_notes_user_id') |
56 | | - op.drop_index('idx_case_notes_case_id') |
57 | | - op.drop_table('case_notes') |
58 | | - |
| 89 | + op.drop_index("idx_case_notes_created_at") |
| 90 | + op.drop_index("idx_case_notes_user_id") |
| 91 | + op.drop_index("idx_case_notes_case_id") |
| 92 | + op.drop_table("case_notes") |
| 93 | + |
59 | 94 | # Drop the enum type |
60 | | - note_type_enum = postgresql.ENUM('TEXT', 'AUDIO', name='notetype') |
| 95 | + note_type_enum = postgresql.ENUM("TEXT", "AUDIO", name="notetype") |
61 | 96 | note_type_enum.drop(op.get_bind(), checkfirst=True) |
0 commit comments