Files
checklist/backend/app/schemas.py

325 lines
7.3 KiB
Python

from pydantic import BaseModel, EmailStr, Field
from typing import Optional, List
from datetime import datetime
# User Schemas
class UserBase(BaseModel):
username: str
email: Optional[EmailStr] = None
full_name: Optional[str] = None
role: str = "mechanic"
class UserCreate(UserBase):
password: str
class UserUpdate(BaseModel):
username: Optional[str] = None
email: Optional[EmailStr] = None
full_name: Optional[str] = None
role: Optional[str] = None
class UserPasswordUpdate(BaseModel):
current_password: str
new_password: str
class AdminPasswordUpdate(BaseModel):
new_password: str
class UserLogin(BaseModel):
username: str
password: str
class User(UserBase):
id: int
is_active: bool
created_at: datetime
class Config:
from_attributes = True
class Token(BaseModel):
access_token: str
token_type: str
user: User
# API Token Schemas
class APITokenCreate(BaseModel):
description: Optional[str] = None
class APIToken(BaseModel):
id: int
description: Optional[str] = None
is_active: bool
last_used_at: Optional[datetime] = None
created_at: datetime
class Config:
from_attributes = True
class APITokenWithValue(APIToken):
token: str
# Checklist Schemas
class ChecklistBase(BaseModel):
name: str
description: Optional[str] = None
ai_mode: str = "off"
scoring_enabled: bool = True
logo_url: Optional[str] = None
class ChecklistCreate(ChecklistBase):
mechanic_ids: Optional[List[int]] = [] # IDs de mecánicos autorizados
class ChecklistUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
ai_mode: Optional[str] = None
scoring_enabled: Optional[bool] = None
logo_url: Optional[str] = None
is_active: Optional[bool] = None
mechanic_ids: Optional[List[int]] = None # IDs de mecánicos autorizados
class Checklist(ChecklistBase):
id: int
max_score: int
is_active: bool
created_by: int
created_at: datetime
allowed_mechanics: Optional[List[int]] = [] # IDs de mecánicos permitidos
class Config:
from_attributes = True
# Question Schemas
class QuestionBase(BaseModel):
section: Optional[str] = None
text: str
type: str
points: int = 1
options: Optional[dict] = None
order: int = 0
allow_photos: bool = True
max_photos: int = 3
requires_comment_on_fail: bool = False
send_notification: bool = False
parent_question_id: Optional[int] = None
show_if_answer: Optional[str] = None
ai_prompt: Optional[str] = None
class QuestionCreate(QuestionBase):
checklist_id: int
class QuestionUpdate(QuestionBase):
pass
class Question(QuestionBase):
id: int
checklist_id: int
created_at: datetime
class Config:
from_attributes = True
# Inspection Schemas
class InspectionBase(BaseModel):
or_number: Optional[str] = None
work_order_number: Optional[str] = None
vehicle_plate: str
vehicle_brand: Optional[str] = None
vehicle_model: Optional[str] = None
vehicle_km: Optional[int] = None
client_name: Optional[str] = None
class InspectionCreate(InspectionBase):
checklist_id: int
class InspectionUpdate(BaseModel):
vehicle_brand: Optional[str] = None
vehicle_model: Optional[str] = None
vehicle_km: Optional[int] = None
signature_data: Optional[str] = None
status: Optional[str] = None
class Inspection(InspectionBase):
id: int
checklist_id: int
mechanic_id: int
score: int
max_score: int
percentage: float
flagged_items_count: int
status: str
started_at: datetime
completed_at: Optional[datetime] = None
class Config:
from_attributes = True
# Answer Schemas
class AnswerBase(BaseModel):
answer_value: str
status: str = "ok"
comment: Optional[str] = None
is_flagged: bool = False
class AnswerCreate(AnswerBase):
inspection_id: int
question_id: int
class AnswerUpdate(AnswerBase):
pass
class Answer(AnswerBase):
id: int
inspection_id: int
question_id: int
points_earned: int
ai_analysis: Optional[dict] = None
created_at: datetime
class Config:
from_attributes = True
# MediaFile Schemas
class MediaFileBase(BaseModel):
caption: Optional[str] = None
order: int = 0
class MediaFileCreate(MediaFileBase):
file_type: str = "image"
class MediaFile(MediaFileBase):
id: int
answer_id: int
file_path: str
file_type: str
uploaded_at: datetime
class Config:
from_attributes = True
# Response Schemas
class ChecklistWithQuestions(Checklist):
questions: List[Question] = []
class AnswerWithMedia(Answer):
media_files: List[MediaFile] = []
question: Question
class InspectionDetail(Inspection):
checklist: ChecklistWithQuestions
mechanic: User
answers: List[AnswerWithMedia] = []
# AI Configuration Schemas
class AIConfigurationBase(BaseModel):
provider: str # openai, gemini
api_key: str
model_name: Optional[str] = None
class AIConfigurationCreate(AIConfigurationBase):
pass
class AIConfigurationUpdate(BaseModel):
provider: Optional[str] = None
api_key: Optional[str] = None
model_name: Optional[str] = None
is_active: Optional[bool] = None
class AIConfiguration(AIConfigurationBase):
id: int
is_active: bool
created_at: datetime
class Config:
from_attributes = True
class AIModelInfo(BaseModel):
id: str
name: str
provider: str
description: Optional[str] = None
# Reports Schemas
class InspectionStats(BaseModel):
total_inspections: int
completed_inspections: int
pending_inspections: int
completion_rate: float
avg_score: float
total_flagged_items: int
class MechanicRanking(BaseModel):
mechanic_id: int
mechanic_name: str
total_inspections: int
avg_score: float
completion_rate: float
class ChecklistStats(BaseModel):
checklist_id: int
checklist_name: str
total_inspections: int
avg_score: float
class DashboardData(BaseModel):
stats: InspectionStats
mechanic_ranking: List[MechanicRanking]
checklist_stats: List[ChecklistStats]
inspections_by_date: dict
pass_fail_ratio: dict
class InspectionListItem(BaseModel):
id: int
vehicle_plate: str
checklist_name: str
mechanic_name: str
status: str
score: Optional[int]
max_score: Optional[int]
flagged_items: int
started_at: Optional[datetime]
completed_at: Optional[datetime]
# Audit Log Schemas
class AuditLogBase(BaseModel):
action: str
entity_type: str
field_name: Optional[str] = None
old_value: Optional[str] = None
new_value: Optional[str] = None
comment: Optional[str] = None
class AuditLog(AuditLogBase):
id: int
inspection_id: int
answer_id: Optional[int] = None
user_id: int
user_name: Optional[str] = None
created_at: datetime
class Config:
from_attributes = True
class AnswerEdit(BaseModel):
answer_value: Optional[str] = None
status: Optional[str] = None
comment: Optional[str] = None
is_flagged: Optional[bool] = None
edit_comment: Optional[str] = None # Comentario del admin sobre por qué editó
max_score: Optional[int]
flagged_items: int
started_at: Optional[datetime]
completed_at: Optional[datetime]