generated from coulomb/repo-seed
New entity types (DB tables, API routers, Pydantic schemas, Alembic migration a3f1c2d4e5b6): - extension_points: ep_id, domain, title, ep_type, status, priority, location, description, topic_id, workstream_id - technical_debt: td_id, domain, title, debt_type, severity, status, location, description, topic_id, workstream_id MCP server: 6 new tools — register_extension_point, list_extension_points, update_ep_status, register_technical_debt, list_technical_debt, update_td_status (each write emits a progress_event) Dashboard: two new pages (extensions.md, techdept.md) with KPI sidebar, charts, urgent-items section, and filterable card lists. Both added to nav in observablehq.config.js. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
73 lines
3.5 KiB
Python
73 lines
3.5 KiB
Python
"""add extension_points and technical_debt tables
|
|
|
|
Revision ID: a3f1c2d4e5b6
|
|
Revises: 0b547c153153
|
|
Create Date: 2026-02-27 00:00:00.000000
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
revision: str = "a3f1c2d4e5b6"
|
|
down_revision: Union[str, None] = "0b547c153153"
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
epstatus = postgresql.ENUM(
|
|
"open", "in_progress", "addressed", "deferred", "wont_fix",
|
|
name="epstatus", create_type=True,
|
|
)
|
|
tdstatus = postgresql.ENUM(
|
|
"open", "in_progress", "resolved", "deferred", "wont_fix",
|
|
name="tdstatus", create_type=True,
|
|
)
|
|
|
|
op.create_table(
|
|
"extension_points",
|
|
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
|
sa.Column("ep_id", sa.String(30), nullable=True, unique=True),
|
|
sa.Column("domain", sa.String(50), nullable=False),
|
|
sa.Column("title", sa.String(255), nullable=False),
|
|
sa.Column("description", sa.Text, nullable=True),
|
|
sa.Column("location", sa.String(500), nullable=True),
|
|
sa.Column("ep_type", sa.String(50), nullable=False, server_default="other"),
|
|
sa.Column("status", epstatus, nullable=False, server_default="open"),
|
|
sa.Column("priority", sa.String(20), nullable=False, server_default="medium"),
|
|
sa.Column("topic_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("topics.id", ondelete="SET NULL"), nullable=True),
|
|
sa.Column("workstream_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("workstreams.id", ondelete="SET NULL"), nullable=True),
|
|
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
|
|
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
|
|
)
|
|
op.create_index("ix_extension_points_ep_id", "extension_points", ["ep_id"])
|
|
op.create_index("ix_extension_points_domain", "extension_points", ["domain"])
|
|
|
|
op.create_table(
|
|
"technical_debt",
|
|
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
|
sa.Column("td_id", sa.String(30), nullable=True, unique=True),
|
|
sa.Column("domain", sa.String(50), nullable=False),
|
|
sa.Column("title", sa.String(255), nullable=False),
|
|
sa.Column("description", sa.Text, nullable=True),
|
|
sa.Column("location", sa.String(500), nullable=True),
|
|
sa.Column("debt_type", sa.String(50), nullable=False, server_default="other"),
|
|
sa.Column("severity", sa.String(20), nullable=False, server_default="medium"),
|
|
sa.Column("status", tdstatus, nullable=False, server_default="open"),
|
|
sa.Column("topic_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("topics.id", ondelete="SET NULL"), nullable=True),
|
|
sa.Column("workstream_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("workstreams.id", ondelete="SET NULL"), nullable=True),
|
|
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
|
|
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
|
|
)
|
|
op.create_index("ix_technical_debt_td_id", "technical_debt", ["td_id"])
|
|
op.create_index("ix_technical_debt_domain", "technical_debt", ["domain"])
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_table("technical_debt")
|
|
op.drop_table("extension_points")
|
|
op.execute("DROP TYPE IF EXISTS tdstatus")
|
|
op.execute("DROP TYPE IF EXISTS epstatus")
|