from datetime import datetime from typing import Any, Dict, List, Optional from pydantic import BaseModel, Field class CustomerBase(BaseModel): name: str = Field(..., description="Customer name") contact_info: Optional[str] = Field(None, description="Contact information") class CustomerCreate(CustomerBase): pass class CustomerUpdate(BaseModel): name: Optional[str] = None contact_info: Optional[str] = None class CustomerRead(CustomerBase): id: int created_at: datetime class Config: from_attributes = True class ProjectRead(BaseModel): id: int customer_id: int raw_requirement: str ai_solution_md: Optional[str] = None status: str created_at: datetime class Config: from_attributes = True class ProjectUpdate(BaseModel): ai_solution_md: Optional[str] = None status: Optional[str] = None class RequirementAnalyzeRequest(BaseModel): customer_id: int = Field(..., description="Related customer id") raw_text: str = Field(..., description="Raw requirement text from chat or WeChat") class RequirementAnalyzeResponse(BaseModel): project_id: int ai_solution_md: str ai_solution_json: Dict[str, Any] class QuoteGenerateResponse(BaseModel): quote_id: int project_id: int total_amount: float excel_path: str pdf_path: str class ContractGenerateRequest(BaseModel): delivery_date: str = Field(..., description="Delivery date, e.g. 2026-03-31") extra_placeholders: Dict[str, str] = Field( default_factory=dict, description="Additional placeholder mappings for the contract template", ) class ContractGenerateResponse(BaseModel): project_id: int contract_path: str class FinanceSyncResult(BaseModel): id: int month: str type: str file_name: str file_path: str class FinanceSyncResponse(BaseModel): items: List[FinanceSyncResult]