File size: 2,139 Bytes
de1e3fc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""Declarative base + shared mixins/enums.

Every table uses an integer surrogate PK and carries ``created_at``/``updated_at`` (spec §7).
Statuses/types are Python enums stored as strings.
"""
from __future__ import annotations

import enum
from datetime import datetime, timezone

from sqlalchemy import DateTime, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column


class Base(DeclarativeBase):
    pass


def _utcnow() -> datetime:
    return datetime.now(timezone.utc)


class TimestampMixin:
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=_utcnow, server_default=func.now()
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        default=_utcnow,
        onupdate=_utcnow,
        server_default=func.now(),
    )


# ---- Enums (stored as their string values) ----


class UserRole(str, enum.Enum):
    owner = "owner"
    finder = "finder"
    admin = "admin"


class KnownDogStatus(str, enum.Enum):
    home = "home"
    lost = "lost"
    reunited = "reunited"


class UnknownDogStatus(str, enum.Enum):
    pending = "pending"      # finder has the dog in their own custody
    at_shelter = "at_shelter"  # dropped at a shelter/vet
    claimed = "claimed"      # matched & resolved
    reunited = "reunited"


class DogSize(str, enum.Enum):
    small = "small"
    medium = "medium"
    large = "large"


class CaseType(str, enum.Enum):
    lost = "lost"
    found = "found"


class CaseStatus(str, enum.Enum):
    open = "open"
    matched = "matched"
    resolved = "resolved"
    closed = "closed"


class SubjectType(str, enum.Enum):
    known = "known"
    unknown = "unknown"


class MatchStatus(str, enum.Enum):
    pending = "pending"
    confirmed = "confirmed"
    rejected = "rejected"


class NotificationChannel(str, enum.Enum):
    email = "email"
    sms = "sms"


class NotificationStatus(str, enum.Enum):
    queued = "queued"
    sent = "sent"
    failed = "failed"


class DatasetType(str, enum.Enum):
    test_known = "test_known"
    test_found = "test_found"
    known = "known"
    unknown = "unknown"