diff --git a/features/doc-service/CLAUDE.md b/features/doc-service/CLAUDE.md index 03bd28d..3dc60a3 100644 --- a/features/doc-service/CLAUDE.md +++ b/features/doc-service/CLAUDE.md @@ -117,6 +117,7 @@ Unique constraint: `(document_id, group_id)` | `0004` | `add_document_shares` | | `0005` | `add_share_can_delete` | | `0006` | `add_category_scope` | +| `0007` | `capitalize_system_category_names` | --- diff --git a/features/doc-service/alembic/versions/0007_capitalize_system_category_names.py b/features/doc-service/alembic/versions/0007_capitalize_system_category_names.py new file mode 100644 index 0000000..ce07fee --- /dev/null +++ b/features/doc-service/alembic/versions/0007_capitalize_system_category_names.py @@ -0,0 +1,44 @@ +"""capitalize existing system category names to PascalCase-with-dashes + +Revision ID: 0007 +Revises: 0006 +Create Date: 2026-04-18 + +Converts names like "invoices" → "Invoices", "vendor-invoices" → "Vendor-Invoices" +for all categories with scope='system' (watch-ingested). +""" +from typing import Sequence, Union + +import re + +from alembic import op +import sqlalchemy as sa +from sqlalchemy import text + + +revision: str = "0007" +down_revision: Union[str, None] = "0006" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def _to_pascal(name: str) -> str: + return "-".join(p.capitalize() for p in re.split(r"[-_\s]+", name) if p) + + +def upgrade() -> None: + conn = op.get_bind() + rows = conn.execute( + text("SELECT id, name FROM document_categories WHERE scope = 'system'") + ).fetchall() + for row in rows: + new_name = _to_pascal(row.name) + if new_name != row.name: + conn.execute( + text("UPDATE document_categories SET name = :name WHERE id = :id"), + {"name": new_name[:128], "id": row.id}, + ) + + +def downgrade() -> None: + pass # names before migration are unknown; downgrade is a no-op