- Added `bot_username` to settings for dynamic retrieval of the bot's username. - Implemented `_resolve_bot_username` function to fetch the bot's username if not set, improving user experience in group chats. - Updated `DutyWithUser` schema to include optional `phone` and `username` fields for enhanced duty information. - Enhanced API responses to include contact details for users, ensuring better communication. - Introduced a new current duty view in the web app, displaying active duty information along with contact options. - Updated CSS styles for better presentation of contact information in duty cards. - Added unit tests to verify the inclusion of contact details in API responses and the functionality of the current duty view.
77 lines
1.8 KiB
Python
77 lines
1.8 KiB
Python
"""Pydantic schemas for API request/response and validation."""
|
|
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
|
|
|
# Allowed duty event types; API maps unknown DB values to "duty".
|
|
DUTY_EVENT_TYPES = ("duty", "unavailable", "vacation")
|
|
|
|
|
|
class UserBase(BaseModel):
|
|
"""Base user fields (full_name, username, first/last name)."""
|
|
|
|
full_name: str
|
|
username: str | None = None
|
|
first_name: str | None = None
|
|
last_name: str | None = None
|
|
|
|
|
|
class UserCreate(UserBase):
|
|
"""User creation payload including Telegram user id."""
|
|
|
|
telegram_user_id: int
|
|
|
|
|
|
class UserInDb(UserBase):
|
|
"""User as stored in DB (includes id and telegram_user_id)."""
|
|
|
|
id: int
|
|
telegram_user_id: int
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class DutyBase(BaseModel):
|
|
"""Duty fields: user_id, start_at, end_at (UTC ISO 8601 with Z)."""
|
|
|
|
user_id: int
|
|
start_at: str # UTC, ISO 8601 with Z
|
|
end_at: str # UTC, ISO 8601 with Z
|
|
|
|
|
|
class DutyCreate(DutyBase):
|
|
"""Duty creation payload."""
|
|
|
|
pass
|
|
|
|
|
|
class DutyInDb(DutyBase):
|
|
"""Duty as stored in DB (includes id)."""
|
|
|
|
id: int
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class DutyWithUser(DutyInDb):
|
|
"""Duty with full_name, event_type, and optional contact fields for calendar display.
|
|
|
|
event_type: only these values are returned; unknown DB values are mapped to "duty" in the API.
|
|
phone and username are exposed only to authenticated Mini App users (role-gated).
|
|
"""
|
|
|
|
full_name: str
|
|
event_type: Literal["duty", "unavailable", "vacation"] = "duty"
|
|
phone: str | None = None
|
|
username: str | None = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class CalendarEvent(BaseModel):
|
|
"""External calendar event (e.g. holiday) for a single day."""
|
|
|
|
date: str # YYYY-MM-DD
|
|
summary: str
|