CI / skip-ci-check (pull_request) Successful in 29s
CI / python-lint (pull_request) Successful in 31s
CI / docker-ci (pull_request) Successful in 32s
CI / secret-scan (pull_request) Successful in 37s
CI / e2e (pull_request) Successful in 4m32s
CI / viewer-unit (pull_request) Successful in 4m42s
CI / admin-unit (pull_request) Successful in 5m6s
Capture optional contact fields on identify/approve, add Select All and Approve Next 10 on User Identified Faces, and email admins when the pending queue grows (ADMIN_NOTIFY_EMAIL via existing noreply SMTP).
90 lines
2.2 KiB
Python
90 lines
2.2 KiB
Python
"""People schemas for web API (Phase 3)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import date
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
class PersonResponse(BaseModel):
|
|
"""Person DTO returned from API."""
|
|
|
|
model_config = ConfigDict(from_attributes=True, protected_namespaces=())
|
|
|
|
id: int
|
|
first_name: str
|
|
last_name: str
|
|
middle_name: Optional[str] = None
|
|
maiden_name: Optional[str] = None
|
|
date_of_birth: Optional[date] = None
|
|
email: Optional[str] = None
|
|
phone: Optional[str] = None
|
|
|
|
|
|
class PersonCreateRequest(BaseModel):
|
|
"""Request payload to create a new person."""
|
|
|
|
model_config = ConfigDict(protected_namespaces=())
|
|
|
|
first_name: str = Field(..., min_length=1)
|
|
last_name: str = Field(..., min_length=1)
|
|
middle_name: Optional[str] = None
|
|
maiden_name: Optional[str] = None
|
|
date_of_birth: Optional[date] = None
|
|
email: Optional[str] = None
|
|
phone: Optional[str] = None
|
|
|
|
|
|
class PeopleListResponse(BaseModel):
|
|
"""List of people for selection dropdowns."""
|
|
|
|
model_config = ConfigDict(protected_namespaces=())
|
|
|
|
items: list[PersonResponse]
|
|
total: int
|
|
|
|
|
|
class PersonUpdateRequest(BaseModel):
|
|
"""Request payload to update a person."""
|
|
|
|
model_config = ConfigDict(protected_namespaces=())
|
|
|
|
first_name: str = Field(..., min_length=1)
|
|
last_name: str = Field(..., min_length=1)
|
|
middle_name: Optional[str] = None
|
|
maiden_name: Optional[str] = None
|
|
date_of_birth: Optional[date] = None
|
|
email: Optional[str] = None
|
|
phone: Optional[str] = None
|
|
|
|
|
|
class PersonWithFacesResponse(BaseModel):
|
|
"""Person with face count for modify identified workflow."""
|
|
|
|
model_config = ConfigDict(from_attributes=True, protected_namespaces=())
|
|
|
|
id: int
|
|
first_name: str
|
|
last_name: str
|
|
middle_name: Optional[str] = None
|
|
maiden_name: Optional[str] = None
|
|
date_of_birth: Optional[date] = None
|
|
email: Optional[str] = None
|
|
phone: Optional[str] = None
|
|
face_count: int
|
|
video_count: int
|
|
|
|
|
|
class PeopleWithFacesListResponse(BaseModel):
|
|
"""List of people with face counts."""
|
|
|
|
model_config = ConfigDict(protected_namespaces=())
|
|
|
|
items: list[PersonWithFacesResponse]
|
|
total: int
|
|
|
|
|
|
|