Files
checklist/backend/app/models.py
2025-11-18 13:09:42 -03:00

147 lines
5.8 KiB
Python

from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Text, JSON, Float
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.core.database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String(50), unique=True, index=True, nullable=False)
email = Column(String(100), unique=True, index=True)
password_hash = Column(String(255), nullable=False)
role = Column(String(20), nullable=False) # admin, mechanic
full_name = Column(String(100))
is_active = Column(Boolean, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
checklists_created = relationship("Checklist", back_populates="creator")
inspections = relationship("Inspection", back_populates="mechanic")
class Checklist(Base):
__tablename__ = "checklists"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(200), nullable=False)
description = Column(Text)
ai_mode = Column(String(20), default="off") # off, assisted, copilot
scoring_enabled = Column(Boolean, default=True)
max_score = Column(Integer, default=0)
logo_url = Column(String(500))
is_active = Column(Boolean, default=True)
created_by = Column(Integer, ForeignKey("users.id"))
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
creator = relationship("User", back_populates="checklists_created")
questions = relationship("Question", back_populates="checklist", cascade="all, delete-orphan")
inspections = relationship("Inspection", back_populates="checklist")
class Question(Base):
__tablename__ = "questions"
id = Column(Integer, primary_key=True, index=True)
checklist_id = Column(Integer, ForeignKey("checklists.id"), nullable=False)
section = Column(String(100)) # Sistema eléctrico, Frenos, etc
text = Column(Text, nullable=False)
type = Column(String(30), nullable=False) # pass_fail, good_bad, text, etc
points = Column(Integer, default=1)
options = Column(JSON) # Para multiple choice
order = Column(Integer, default=0)
allow_photos = Column(Boolean, default=True)
max_photos = Column(Integer, default=3)
requires_comment_on_fail = Column(Boolean, default=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
checklist = relationship("Checklist", back_populates="questions")
answers = relationship("Answer", back_populates="question")
class Inspection(Base):
__tablename__ = "inspections"
id = Column(Integer, primary_key=True, index=True)
checklist_id = Column(Integer, ForeignKey("checklists.id"), nullable=False)
mechanic_id = Column(Integer, ForeignKey("users.id"), nullable=False)
# Datos de la OR
or_number = Column(String(50))
work_order_number = Column(String(50))
# Datos del vehículo
vehicle_plate = Column(String(20), nullable=False, index=True)
vehicle_brand = Column(String(50))
vehicle_model = Column(String(100))
vehicle_km = Column(Integer)
client_name = Column(String(200))
# Scoring
score = Column(Integer, default=0)
max_score = Column(Integer, default=0)
percentage = Column(Float, default=0.0)
flagged_items_count = Column(Integer, default=0)
# Estado
status = Column(String(20), default="draft") # draft, completed
# Firma
signature_data = Column(Text) # Base64 de la firma
signed_at = Column(DateTime(timezone=True))
# Timestamps
started_at = Column(DateTime(timezone=True), server_default=func.now())
completed_at = Column(DateTime(timezone=True))
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
checklist = relationship("Checklist", back_populates="inspections")
mechanic = relationship("User", back_populates="inspections")
answers = relationship("Answer", back_populates="inspection", cascade="all, delete-orphan")
class Answer(Base):
__tablename__ = "answers"
id = Column(Integer, primary_key=True, index=True)
inspection_id = Column(Integer, ForeignKey("inspections.id"), nullable=False)
question_id = Column(Integer, ForeignKey("questions.id"), nullable=False)
answer_value = Column(Text) # La respuesta del mecánico
status = Column(String(20), default="ok") # ok, warning, critical, info
points_earned = Column(Integer, default=0)
comment = Column(Text) # Comentarios adicionales
ai_analysis = Column(JSON) # Análisis de IA si aplica
is_flagged = Column(Boolean, default=False) # Si requiere atención
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
inspection = relationship("Inspection", back_populates="answers")
question = relationship("Question", back_populates="answers")
media_files = relationship("MediaFile", back_populates="answer", cascade="all, delete-orphan")
class MediaFile(Base):
__tablename__ = "media_files"
id = Column(Integer, primary_key=True, index=True)
answer_id = Column(Integer, ForeignKey("answers.id"), nullable=False)
file_path = Column(String(500), nullable=False)
file_type = Column(String(20), default="image") # image, video
caption = Column(Text)
order = Column(Integer, default=0)
uploaded_at = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
answer = relationship("Answer", back_populates="media_files")