From 0c1c730f9b95ac464214bf9499d46557e416a357 Mon Sep 17 00:00:00 2001 From: demo-bot Date: Sun, 9 Aug 2026 15:49:36 +0000 Subject: [PATCH] decomposer: generate deliverable files for Define the service contract and project architecture for the FastAPI endpoint monitoring service.; Implement the typed monitor CRUD API and concurrency-safe in-memory state according to the service design.; Implement secure on-demand endpoint checks with status updates, latency measurement, robust error handling, and redacted structured logs.; Add operational API endpoints and environment-driven runtime configuration to the monitoring service.; Create automated tests for the monitoring service.; Package the service with Docker and developer documentation.; Validate the complete project. --- app/models.py | 57 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/app/models.py b/app/models.py index 52e14d7..47bddcc 100644 --- a/app/models.py +++ b/app/models.py @@ -1,41 +1,56 @@ -from datetime import UTC, datetime +from datetime import datetime, timezone from enum import StrEnum -from uuid import UUID, uuid4 +from uuid import UUID from pydantic import AnyHttpUrl, BaseModel, ConfigDict, Field -class State(StrEnum): - UNKNOWN = "unknown" - UP = "up" - DOWN = "down" - ERROR = "error" +def utc_now() -> datetime: + return datetime.now(timezone.utc) + + +class HealthState(StrEnum): + unknown = "unknown" + up = "up" + down = "down" class MonitorCreate(BaseModel): - name: str = Field(min_length=1, max_length=100) + name: str = Field(min_length=1, max_length=120) url: AnyHttpUrl -class MonitorUpdate(BaseModel): - name: str | None = Field(default=None, min_length=1, max_length=100) - url: AnyHttpUrl | None = None +class MonitorUpdate(MonitorCreate): + pass class CurrentStatus(BaseModel): - state: State = State.UNKNOWN - checked_at: datetime | None = None - status_code: int | None = None - latency_ms: float | None = Field(default=None, ge=0) - error: str | None = None + state: HealthState + checked_at: datetime + latency_ms: float = Field(ge=0) + http_status: int | None = None + error_code: str | None = None + error_message: str | None = None class Monitor(BaseModel): - model_config = ConfigDict(from_attributes=True) + model_config = ConfigDict(frozen=True) - id: UUID = Field(default_factory=uuid4) + id: UUID name: str url: AnyHttpUrl - created_at: datetime = Field(default_factory=lambda: datetime.now(UTC)) - updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC)) - current_status: CurrentStatus = Field(default_factory=CurrentStatus) + created_at: datetime + updated_at: datetime + revision: int + current_status: CurrentStatus | None = None + + +class CheckResponse(BaseModel): + monitor_id: UUID + status: CurrentStatus + applied: bool + + +class ErrorDetail(BaseModel): + code: str + message: str