Files
denya-onecare/app/models/category.py
T
root 2407f294f4 feat: Sprint A Wahab review batch — categories, property hierarchy, priority grouping
Items 1-5, 9, 11 from denya-wahab-feedback-s2:
- Category.show_in_form (alert-only flag): Gas Leak hidden from issue picker
  but kept urgent for SLA/alert and reporting; emergency quick path on the
  new-issue form creates urgent tickets via include_hidden categories.
- Seed: Aluminum/Glass, Carpentry, Mould & Damp (Medium default) maintenance
  categories; Lost Property renamed Missing Item (+ sub).
- One alembic migration: add show_in_form (backfill True, Gas Leak False) +
  data rename Lost Property -> Missing Item.
- Property -> Building -> Apartment cascade with searchable apartment combobox
  on the new-issue form and ticket list filters; /api/tickets/units gains
  building filter + /units/grouped variant; /api/tickets gains additive
  building/unit_id filters. apartment_mapping.json committed (deterministic).
- Group-by-priority toggle on /tickets (four sections + unknown bucket,
  age-sortable, composes with filters, URL deep links), FM dashboard active
  tickets, and CS dashboard priority card click-through.
- Tests: 13 new (category visibility, seed idempotency/sync, unit grouping,
  ticket building/unit filters).
2026-08-02 09:30:29 +00:00

45 lines
1.5 KiB
Python

"""Ticket category model with self-referencing parent for sub-categories."""
from __future__ import annotations
from sqlalchemy import Boolean, ForeignKey, Integer, String, true
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.database import Base
class Category(Base):
__tablename__ = "categories"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
type: Mapped[str] = mapped_column(
String(20),
nullable=False,
comment="maintenance, cs, emergency",
)
name: Mapped[str] = mapped_column(String(100), nullable=False)
parent_id: Mapped[int | None] = mapped_column(
Integer,
ForeignKey("categories.id"),
nullable=True,
)
sla_urgency: Mapped[str | None] = mapped_column(
String(10),
nullable=True,
comment="urgent, high, medium, low",
)
show_in_form: Mapped[bool] = mapped_column(
Boolean,
nullable=False,
default=True,
server_default=true(),
comment="Visible in the new-issue category picker (False = alert-only, e.g. Gas Leak)",
)
# self-referencing relationship
children: Mapped[list[Category]] = relationship("Category", back_populates="parent", cascade="all, delete-orphan")
parent: Mapped[Category | None] = relationship("Category", back_populates="children", remote_side="Category.id")
def __repr__(self) -> str:
return f"<Category {self.type}:{self.name}>"