state-hub/api/models/interface_change.py

54 lines
2 KiB
Python
Raw Permalink Normal View History

import uuid
from datetime import date, datetime
from sqlalchemy import Date, DateTime, ForeignKey, Index, String, Text
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from api.models.base import Base, TimestampMixin, new_uuid
class InterfaceChange(Base, TimestampMixin):
__tablename__ = "interface_changes"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True), primary_key=True, default=new_uuid
)
repo_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True), ForeignKey("managed_repos.id", ondelete="CASCADE"),
nullable=False, index=True,
)
interface_type: Mapped[str] = mapped_column(
String(40), nullable=False
) # rest_api | mcp_tool | cli | schema | capability
change_type: Mapped[str] = mapped_column(
String(40), nullable=False
) # breaking | additive | deprecation | removal
title: Mapped[str] = mapped_column(String(300), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False)
affected_paths: Mapped[list] = mapped_column(
JSONB, nullable=False, default=list, server_default="[]"
)
affected_repo_slugs: Mapped[list] = mapped_column(
JSONB, nullable=False, default=list, server_default="[]"
)
status: Mapped[str] = mapped_column(
String(20), nullable=False, default="draft", index=True
) # draft | published | resolved
planned_for: Mapped[date | None] = mapped_column(Date, nullable=True)
published_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
resolved_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
author: Mapped[str] = mapped_column(String(100), nullable=False, default="custodian")
repo: Mapped["ManagedRepo"] = relationship( # noqa: F821
"ManagedRepo", lazy="selectin"
)
__table_args__ = (
Index("ix_interface_changes_repo_status", "repo_id", "status"),
)