2026-06-12 23:24:17 +02:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
# Location
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LocationRecord(BaseModel):
|
|
|
|
|
person: str
|
|
|
|
|
datetime: str
|
|
|
|
|
latitude: float
|
|
|
|
|
longitude: float
|
|
|
|
|
altitude: float | None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LocationsResponse(BaseModel):
|
|
|
|
|
items: list[LocationRecord]
|
|
|
|
|
limit: int
|
|
|
|
|
offset: int
|
|
|
|
|
|
|
|
|
|
|
2026-06-12 23:33:08 +02:00
|
|
|
class LocationUpdateRequest(BaseModel):
|
|
|
|
|
"""PATCH body for a location record — all fields optional; PK fields excluded."""
|
|
|
|
|
|
|
|
|
|
latitude: float | None = None
|
|
|
|
|
longitude: float | None = None
|
|
|
|
|
altitude: float | None = None
|
|
|
|
|
|
|
|
|
|
|
2026-06-12 23:24:17 +02:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
# Poo
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PooRecord(BaseModel):
|
|
|
|
|
timestamp: str
|
|
|
|
|
status: str
|
|
|
|
|
latitude: float
|
|
|
|
|
longitude: float
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PooResponse(BaseModel):
|
|
|
|
|
items: list[PooRecord]
|
|
|
|
|
limit: int
|
|
|
|
|
offset: int
|
|
|
|
|
|
|
|
|
|
|
2026-06-12 23:33:08 +02:00
|
|
|
class PooUpdateRequest(BaseModel):
|
|
|
|
|
"""PATCH body for a poo record — all fields optional; PK field excluded."""
|
|
|
|
|
|
|
|
|
|
status: str | None = None
|
|
|
|
|
latitude: float | None = None
|
|
|
|
|
longitude: float | None = None
|
|
|
|
|
|
|
|
|
|
|
2026-06-12 23:24:17 +02:00
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
# Public IP
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PublicIPStateSchema(BaseModel):
|
|
|
|
|
id: int
|
|
|
|
|
current_ipv4: str
|
|
|
|
|
previous_ipv4: str | None
|
|
|
|
|
first_seen_at: datetime
|
|
|
|
|
last_checked_at: datetime
|
|
|
|
|
last_changed_at: datetime | None
|
|
|
|
|
last_check_status: str
|
|
|
|
|
last_check_error: str | None
|
|
|
|
|
last_provider: str | None
|
|
|
|
|
|
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PublicIPHistorySchema(BaseModel):
|
|
|
|
|
id: int
|
|
|
|
|
ipv4: str
|
|
|
|
|
observed_at: datetime
|
|
|
|
|
change_type: str
|
|
|
|
|
provider: str | None
|
|
|
|
|
|
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PublicIPResponse(BaseModel):
|
|
|
|
|
state: PublicIPStateSchema | None
|
|
|
|
|
history: list[PublicIPHistorySchema]
|