feat(psa): add psa_ticket_id and psa_connection_id to sessions

Add columns to link sessions to PSA tickets and connections. Includes
migration 059, model relationship, and response schema fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-03-14 22:45:04 -04:00
parent 2a53f48d69
commit 5bcaf6a9d4
3 changed files with 69 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
"""Add psa_ticket_id and psa_connection_id to sessions.
Revision ID: 059
Revises: 058
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
revision = "059"
down_revision = "058"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.add_column("sessions", sa.Column("psa_ticket_id", sa.String(100), nullable=True))
op.add_column(
"sessions",
sa.Column(
"psa_connection_id",
postgresql.UUID(as_uuid=True),
sa.ForeignKey("psa_connections.id", ondelete="SET NULL"),
nullable=True,
),
)
def downgrade() -> None:
op.drop_column("sessions", "psa_connection_id")
op.drop_column("sessions", "psa_ticket_id")

View File

@@ -83,6 +83,15 @@ class Session(Base):
attachments: Mapped[list["Attachment"]] = relationship("Attachment", back_populates="session")
shares: Mapped[list["SessionShare"]] = relationship("SessionShare", back_populates="session", cascade="all, delete-orphan")
# PSA ticket link
psa_ticket_id: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
psa_connection_id: Mapped[Optional[uuid.UUID]] = mapped_column(
UUID(as_uuid=True),
ForeignKey("psa_connections.id", ondelete="SET NULL"),
nullable=True,
)
psa_connection = relationship("PsaConnection", foreign_keys=[psa_connection_id])
# Batch tracking (maintenance flows)
batch_id: Mapped[Optional[uuid.UUID]] = mapped_column(
UUID(as_uuid=True), nullable=True, index=True

View File

@@ -94,6 +94,10 @@ class SessionResponse(BaseModel):
batch_id: Optional[UUID] = None
target_label: Optional[str] = None
# PSA ticket link
psa_ticket_id: Optional[str] = None
psa_connection_id: Optional[UUID] = None
class Config:
from_attributes = True
@@ -140,3 +144,28 @@ class SaveAsTreeResponse(BaseModel):
tree_id: UUID
tree_name: str
message: str
# ── PSA ticket link ──────────────────────────────────────────────────
class TicketLinkRequest(BaseModel):
"""Link or unlink a PSA ticket to a session."""
psa_ticket_id: Optional[str] = None # null to unlink
class PSATicketResponse(BaseModel):
"""PSA ticket details returned when linking."""
id: str
summary: str
company_name: Optional[str] = None
board_name: Optional[str] = None
status_name: Optional[str] = None
priority_name: Optional[str] = None
class TicketLinkResponse(BaseModel):
"""Response after linking/unlinking a ticket."""
session_id: str
psa_ticket_id: Optional[str] = None
ticket: Optional[PSATicketResponse] = None