mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
50 lines
2.3 KiB
Python
50 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import ClassVar, Optional
|
|
|
|
from sqlalchemy import Column
|
|
from sqlalchemy import Enum as SAEnum
|
|
from sqlmodel import Field, SQLModel
|
|
|
|
# Mirror of the FE-owned `creation_status` pgEnum (property.ts:
|
|
# propertyCreationStatusEnum = {LOADING, READY, ERROR}). A single SAEnum instance
|
|
# so test-schema create_all emits one CREATE TYPE; prod owns the type via Drizzle.
|
|
property_creation_status_sa_enum = SAEnum(
|
|
"LOADING", "READY", "ERROR", name="creation_status"
|
|
)
|
|
|
|
|
|
class PropertyRow(SQLModel, table=True):
|
|
"""Mirror of the FE-owned ``property`` table.
|
|
|
|
The schema and migrations for ``property`` are owned by the front-end Next.js
|
|
repo (``src/app/db/schema/property.ts``); this declares the identity columns
|
|
the modelling backend reads, plus the subset the ``bulk_upload_finaliser``
|
|
Lambda **inserts** at Finalise (ADR-0013). It is no longer read-only — the
|
|
finaliser is the one backend caller that inserts. Columns not declared here
|
|
are still owned by FE migrations and don't ripple into us.
|
|
"""
|
|
|
|
__tablename__: ClassVar[str] = "property" # pyright: ignore[reportIncompatibleVariableOverride]
|
|
|
|
# bigserial in the FE schema — DB-assigned on insert, so Optional/None on the
|
|
# way in and always populated on the way out.
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
portfolio_id: int
|
|
# Nullable in the FE schema. The finaliser writes `matched ?? user-inputted`,
|
|
# which is absent for fully-unmatched rows.
|
|
postcode: Optional[str] = Field(default=None)
|
|
address: Optional[str] = Field(default=None)
|
|
uprn: Optional[int] = Field(default=None)
|
|
landlord_property_id: Optional[str] = Field(default=None)
|
|
|
|
# Insertable columns the finaliser writes (ADR-0013). All nullable in the FE
|
|
# schema except `creation_status` (NOT NULL); the finaliser always sets it to
|
|
# 'READY', so a nullable mirror is safe — the real column enforces NOT NULL.
|
|
creation_status: Optional[str] = Field(
|
|
default=None,
|
|
sa_column=Column(property_creation_status_sa_enum, nullable=True),
|
|
)
|
|
user_inputted_address: Optional[str] = Field(default=None)
|
|
user_inputted_postcode: Optional[str] = Field(default=None)
|
|
lexiscore: Optional[float] = Field(default=None)
|