decomposer: generate deliverable files for Implement the task REST API service with FastAPI, including standard CRUD endpoints, HTTP status semantics, request and response models, and structured error handling.; Add a PostgreSQL persistence layer for the task service using SQLAlchemy models, session management, database initialization or migrations, and durable task storage integrated with the existing API contract.; Define and integrate Pydantic request and response schemas for task fields, status values, identifiers, timestamps, and validation errors across the existing FastAPI service and persistence contract.; Add automated pytest coverage for the task API, including CRUD behavior, request and response validation failures, HTTP status semantics, and persistence interactions using isolated test data.; Containerize the FastAPI task service and PostgreSQL persistence service with Docker Compose, including environment-based configuration, health checks, networking, startup dependencies, and persistent database storage.; Create project documentation and operational guidance covering local setup, Docker Compose configuration, environment variables, API endpoints, validation and error responses, testing commands, persistence behavior, and relevant best-practice notes.

This commit is contained in:
2026-08-19 11:37:10 +00:00
parent 878957c05a
commit 324ddc19db
18 changed files with 550 additions and 5 deletions

64
app/schemas.py Normal file
View File

@@ -0,0 +1,64 @@
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field, field_validator
from .models import TaskStatus
class TaskBase(BaseModel):
title: str = Field(min_length=1, max_length=200)
description: str | None = Field(default=None, max_length=5000)
status: TaskStatus = TaskStatus.pending
due_at: datetime | None = None
@field_validator("title")
@classmethod
def title_not_blank(cls, value: str) -> str:
value = value.strip()
if not value:
raise ValueError("title must not be blank")
return value
class TaskCreate(TaskBase):
pass
class TaskUpdate(BaseModel):
title: str | None = Field(default=None, min_length=1, max_length=200)
description: str | None = Field(default=None, max_length=5000)
status: TaskStatus | None = None
due_at: datetime | None = None
@field_validator("title")
@classmethod
def title_not_blank(cls, value: str | None) -> str | None:
if value is not None:
value = value.strip()
if not value:
raise ValueError("title must not be blank")
return value
class TaskRead(TaskBase):
id: UUID
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class ErrorDetail(BaseModel):
loc: list[str | int] = []
msg: str
type: str | None = None
class ErrorBody(BaseModel):
code: str
message: str
details: list[ErrorDetail] = []
class ErrorResponse(BaseModel):
error: ErrorBody