"""Log entry schemas.""" from datetime import datetime from typing import Any, Dict, List, Optional from pydantic import BaseModel, Field class LogEntry(BaseModel): """A single log entry pushed by a project.""" timestamp: Optional[datetime] = None level: str = Field(default="info", pattern="^(debug|info|warning|error|critical)$") logger: str = Field(default="root", max_length=128) message: str = Field(..., min_length=1, max_length=65536) module: Optional[str] = Field(default=None, max_length=256) function: Optional[str] = Field(default=None, max_length=128) line_no: Optional[int] = None trace_id: Optional[str] = Field(default=None, max_length=64) exception: Optional[str] = None extra: Dict[str, Any] = Field(default_factory=dict) class LogBatchRequest(BaseModel): """Batch of log entries pushed in a single request.""" project: str = Field(..., min_length=1, max_length=128) entries: List[LogEntry] = Field(..., min_length=1, max_length=5000) class LogQueryParams(BaseModel): """Parameters for log search / query.""" project: Optional[str] = None level: Optional[str] = Field( default=None, pattern="^(debug|info|warning|error|critical)$" ) query: Optional[str] = Field(default=None, max_length=1024) trace_id: Optional[str] = Field(default=None, max_length=64) start_time: Optional[datetime] = None end_time: Optional[datetime] = None page: int = Field(default=1, ge=1) page_size: int = Field(default=50, ge=1, le=1000) sort_by: str = Field(default="timestamp", max_length=32) sort_order: str = Field(default="desc", pattern="^(asc|desc)$") class LogSearchResult(BaseModel): """Search result wrapper.""" total: int page: int page_size: int hits: List[Dict[str, Any]] class LogStatsResult(BaseModel): """Aggregated log statistics.""" project: Optional[str] = None time_buckets: List[Dict[str, Any]] level_counts: Dict[str, int] top_loggers: List[Dict[str, Any]] total: int