96 lines
4.0 KiB
Python
96 lines
4.0 KiB
Python
|
|
# app/models.py
|
||
|
|
from sqlalchemy import Column, Integer, String, Float, DateTime, Text, ForeignKey, JSON, Boolean
|
||
|
|
from sqlalchemy.orm import relationship
|
||
|
|
from datetime import datetime
|
||
|
|
from app.database import Base
|
||
|
|
|
||
|
|
|
||
|
|
class Project(Base):
|
||
|
|
"""Проект — один загруженный PDF."""
|
||
|
|
__tablename__ = "projects"
|
||
|
|
|
||
|
|
id = Column(Integer, primary_key=True, index=True)
|
||
|
|
name = Column(String, index=True)
|
||
|
|
pdf_filename = Column(String, nullable=False)
|
||
|
|
status = Column(String, default="uploaded") # uploaded / processing / completed / error
|
||
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
||
|
|
completed_at = Column(DateTime, nullable=True)
|
||
|
|
error_message = Column(Text, nullable=True)
|
||
|
|
|
||
|
|
# Пути к файлам
|
||
|
|
output_folder = Column(String, nullable=True)
|
||
|
|
|
||
|
|
pages = relationship("Page", back_populates="project", cascade="all, delete-orphan")
|
||
|
|
issues = relationship("Issue", back_populates="project", cascade="all, delete-orphan")
|
||
|
|
|
||
|
|
|
||
|
|
class Page(Base):
|
||
|
|
"""Страница PDF."""
|
||
|
|
__tablename__ = "pages"
|
||
|
|
|
||
|
|
id = Column(Integer, primary_key=True, index=True)
|
||
|
|
project_id = Column(Integer, ForeignKey("projects.id"))
|
||
|
|
page_number = Column(Integer, nullable=False)
|
||
|
|
png_path = Column(String, nullable=True)
|
||
|
|
dzi_path = Column(String, nullable=True)
|
||
|
|
ocr_data = Column(JSON, nullable=True) # full_ocr_results для этой страницы
|
||
|
|
vlm_description = Column(Text, nullable=True)
|
||
|
|
width = Column(Integer, nullable=True)
|
||
|
|
height = Column(Integer, nullable=True)
|
||
|
|
|
||
|
|
project = relationship("Project", back_populates="pages")
|
||
|
|
issues = relationship("Issue", back_populates="page")
|
||
|
|
|
||
|
|
|
||
|
|
class Issue(Base):
|
||
|
|
"""Замечание QC — одна проблема на чертеже."""
|
||
|
|
__tablename__ = "issues"
|
||
|
|
|
||
|
|
id = Column(Integer, primary_key=True, index=True)
|
||
|
|
project_id = Column(Integer, ForeignKey("projects.id"))
|
||
|
|
page_id = Column(Integer, ForeignKey("pages.id"))
|
||
|
|
|
||
|
|
issue_type = Column(String, nullable=False) # DIMENSION_OVERLAP, LOW_CONFIDENCE, etc.
|
||
|
|
severity = Column(String, nullable=False) # error / warning / info
|
||
|
|
message = Column(Text, nullable=False)
|
||
|
|
|
||
|
|
# Координаты bbox на PNG (в пикселях)
|
||
|
|
bbox_x1 = Column(Float, nullable=True)
|
||
|
|
bbox_y1 = Column(Float, nullable=True)
|
||
|
|
bbox_x2 = Column(Float, nullable=True)
|
||
|
|
bbox_y2 = Column(Float, nullable=True)
|
||
|
|
|
||
|
|
# Дополнительные данные
|
||
|
|
dimension_text = Column(String, nullable=True) # Текст размера (если применимо)
|
||
|
|
confidence = Column(Float, nullable=True) # OCR confidence
|
||
|
|
extra_data = Column(JSON, nullable=True) # Всё остальное
|
||
|
|
source = Column(String, nullable=True) # "rules" или "vlm"
|
||
|
|
|
||
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
||
|
|
|
||
|
|
project = relationship("Project", back_populates="issues")
|
||
|
|
page = relationship("Page", back_populates="issues")
|
||
|
|
feedback = relationship("Feedback", back_populates="issue", uselist=False)
|
||
|
|
|
||
|
|
|
||
|
|
class Feedback(Base):
|
||
|
|
"""Feedback проектировщика — правда ли это замечание."""
|
||
|
|
__tablename__ = "feedback"
|
||
|
|
|
||
|
|
id = Column(Integer, primary_key=True, index=True)
|
||
|
|
issue_id = Column(Integer, ForeignKey("issues.id"), unique=True)
|
||
|
|
|
||
|
|
# True = реальная проблема, False = ложное срабатывание, None = не размечено
|
||
|
|
is_true_positive = Column(Boolean, nullable=True)
|
||
|
|
|
||
|
|
# Почему (опционально)
|
||
|
|
comment = Column(Text, nullable=True)
|
||
|
|
|
||
|
|
# Что сделал проектировщик
|
||
|
|
action_taken = Column(String, nullable=True) # fixed / ignored / not_sure
|
||
|
|
|
||
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
||
|
|
user_id = Column(String, nullable=True) # Для многопользовательского режима
|
||
|
|
|
||
|
|
issue = relationship("Issue", back_populates="feedback")
|