63d065011b
- Updated timestamps and AST hashes in manifest.json for various backend and frontend files to reflect recent changes. - Added new files related to MCC categories and optional hold reasons in the manifest. - Modified the README in the infra directory to correct the linting tool from 'mypy' to 'ty' for type checking in the backend project.
142 lines
5.0 KiB
Python
142 lines
5.0 KiB
Python
import uuid
|
|
|
|
from sqlalchemy import (
|
|
Boolean,
|
|
ForeignKey,
|
|
ForeignKeyConstraint,
|
|
Integer,
|
|
String,
|
|
UniqueConstraint,
|
|
Uuid,
|
|
)
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base import Base, PkMixin, TimestampMixin
|
|
|
|
|
|
class IncomeSource(Base, PkMixin, TimestampMixin):
|
|
__tablename__ = "income_sources"
|
|
__table_args__ = (
|
|
UniqueConstraint("space_id", "name", name="uq_income_sources_space_name"),
|
|
UniqueConstraint("space_id", "id", name="uq_income_sources_space_id"),
|
|
)
|
|
|
|
space_id: Mapped[uuid.UUID] = mapped_column(
|
|
Uuid, ForeignKey("financial_spaces.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
name: Mapped[str] = mapped_column(String(200), nullable=False)
|
|
archived: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
|
|
|
|
class Payee(Base, PkMixin, TimestampMixin):
|
|
__tablename__ = "payees"
|
|
__table_args__ = (
|
|
UniqueConstraint("space_id", "name", name="uq_payees_space_name"),
|
|
UniqueConstraint("space_id", "id", name="uq_payees_space_id"),
|
|
)
|
|
|
|
space_id: Mapped[uuid.UUID] = mapped_column(
|
|
Uuid, ForeignKey("financial_spaces.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
name: Mapped[str] = mapped_column(String(200), nullable=False)
|
|
archived: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
|
|
|
|
class PayeeAlias(Base, PkMixin, TimestampMixin):
|
|
__tablename__ = "payee_aliases"
|
|
__table_args__ = (
|
|
UniqueConstraint("space_id", "alias", name="uq_payee_aliases_space_alias"),
|
|
ForeignKeyConstraint(
|
|
["space_id", "payee_id"],
|
|
["payees.space_id", "payees.id"],
|
|
ondelete="CASCADE",
|
|
name="fk_payee_aliases_payee_tenant",
|
|
),
|
|
)
|
|
|
|
space_id: Mapped[uuid.UUID] = mapped_column(
|
|
Uuid, ForeignKey("financial_spaces.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
payee_id: Mapped[uuid.UUID] = mapped_column(Uuid, nullable=False, index=True)
|
|
alias: Mapped[str] = mapped_column(String(300), nullable=False)
|
|
|
|
|
|
class CategorizationRule(Base, PkMixin, TimestampMixin):
|
|
"""Confirmed payee rule: auto-applies category to matching future operations."""
|
|
|
|
__tablename__ = "categorization_rules"
|
|
__table_args__ = (
|
|
UniqueConstraint("space_id", "payee_id", name="uq_rules_space_payee"),
|
|
ForeignKeyConstraint(
|
|
["space_id", "payee_id"],
|
|
["payees.space_id", "payees.id"],
|
|
ondelete="CASCADE",
|
|
name="fk_rules_payee_tenant",
|
|
),
|
|
ForeignKeyConstraint(
|
|
["space_id", "category_id"],
|
|
["categories.space_id", "categories.id"],
|
|
name="fk_rules_category_tenant",
|
|
),
|
|
)
|
|
|
|
space_id: Mapped[uuid.UUID] = mapped_column(
|
|
Uuid, ForeignKey("financial_spaces.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
payee_id: Mapped[uuid.UUID] = mapped_column(Uuid, nullable=False)
|
|
category_id: Mapped[uuid.UUID] = mapped_column(Uuid, nullable=False)
|
|
created_by_user_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
Uuid, ForeignKey("users.id", ondelete="SET NULL"), nullable=True
|
|
)
|
|
|
|
|
|
class MccCode(Base):
|
|
"""Global versioned MCC dictionary (not space-scoped, outside RLS)."""
|
|
|
|
__tablename__ = "mcc_codes"
|
|
|
|
code: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
title: Mapped[str] = mapped_column(String(300), nullable=False)
|
|
dictionary_version: Mapped[int] = mapped_column(nullable=False, default=1)
|
|
|
|
|
|
class CategoryMcc(Base, PkMixin):
|
|
"""Space-scoped MCC codes of a category: many codes per category, but every
|
|
code maps to at most one category inside the space."""
|
|
|
|
__tablename__ = "category_mcc_codes"
|
|
__table_args__ = (
|
|
UniqueConstraint("space_id", "mcc_code", name="uq_category_mcc_space_code"),
|
|
ForeignKeyConstraint(
|
|
["space_id", "category_id"],
|
|
["categories.space_id", "categories.id"],
|
|
ondelete="CASCADE",
|
|
name="fk_category_mcc_category_tenant",
|
|
),
|
|
ForeignKeyConstraint(
|
|
["mcc_code"],
|
|
["mcc_codes.code"],
|
|
ondelete="RESTRICT",
|
|
name="fk_category_mcc_dictionary",
|
|
),
|
|
)
|
|
|
|
space_id: Mapped[uuid.UUID] = mapped_column(
|
|
Uuid, ForeignKey("financial_spaces.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
category_id: Mapped[uuid.UUID] = mapped_column(Uuid, nullable=False, index=True)
|
|
mcc_code: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
|
|
|
class BankCategoryMapping(Base, PkMixin):
|
|
"""Maps a bank's raw category string to an MCC for suggestion purposes."""
|
|
|
|
__tablename__ = "bank_category_mappings"
|
|
__table_args__ = (
|
|
UniqueConstraint("bank_code", "bank_category", name="uq_bank_mappings_bank_category"),
|
|
)
|
|
|
|
bank_code: Mapped[str] = mapped_column(String(32), nullable=False, index=True)
|
|
bank_category: Mapped[str] = mapped_column(String(200), nullable=False)
|
|
mcc_code: Mapped[int | None] = mapped_column(Integer, nullable=True)
|