from __future__ import annotations import enum from sqlalchemy import Boolean, ForeignKey, Integer, JSON, String, Text from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base, TimestampMixin, UUIDMixin class ReportTemplate(Base, UUIDMixin, TimestampMixin): __tablename__ = "report_templates" template_key: Mapped[str] = mapped_column(String(120), unique=True, index=True) name: Mapped[str] = mapped_column(String(180)) version: Mapped[str] = mapped_column(String(40)) validation_type: Mapped[str] = mapped_column(String(120), index=True) reference_path: Mapped[str] = mapped_column(String(500)) active: Mapped[bool] = mapped_column(Boolean, default=True, index=True) class TextBlock(Base, UUIDMixin, TimestampMixin): __tablename__ = "text_blocks" template_id: Mapped[str] = mapped_column(ForeignKey("report_templates.id"), index=True) block_key: Mapped[str] = mapped_column(String(160), index=True) title: Mapped[str] = mapped_column(String(240)) content: Mapped[str] = mapped_column(Text) order_index: Mapped[int] = mapped_column(Integer, default=0) version: Mapped[str] = mapped_column(String(40), default="1.0") active: Mapped[bool] = mapped_column(Boolean, default=True, index=True) class ReportSection(Base, UUIDMixin, TimestampMixin): __tablename__ = "report_sections" template_id: Mapped[str] = mapped_column(ForeignKey("report_templates.id"), index=True) section_key: Mapped[str] = mapped_column(String(160), index=True) number: Mapped[str | None] = mapped_column(String(40)) title: Mapped[str] = mapped_column(String(240)) order_index: Mapped[int] = mapped_column(Integer, default=0) page_break_before: Mapped[bool] = mapped_column(Boolean, default=False) active: Mapped[bool] = mapped_column(Boolean, default=True, index=True) class ChecklistTemplate(Base, UUIDMixin, TimestampMixin): __tablename__ = "checklist_templates" template_id: Mapped[str] = mapped_column(ForeignKey("report_templates.id"), index=True) checklist_key: Mapped[str] = mapped_column(String(160), index=True) title: Mapped[str] = mapped_column(String(240)) columns: Mapped[list[str]] = mapped_column(JSON, default=list) items: Mapped[list[dict]] = mapped_column(JSON, default=list) order_index: Mapped[int] = mapped_column(Integer, default=0) active: Mapped[bool] = mapped_column(Boolean, default=True, index=True) class MeasurementImportStatus(str, enum.Enum): uploaded = "HOCHGELADEN" analyzing = "ANALYSE_LAEUFT" preview_ready = "VORSCHAU_BEREIT" confirmed = "BESTAETIGT" error = "FEHLER" attachment_only = "NUR_ANLAGE" class MeasurementImportType(str, enum.Enum): winlog_csv = "WINLOG_CSV" winlog_pdf = "WINLOG_PDF" winlog_attachment_only = "WINLOG_ATTACHMENT_ONLY" class MeasurementImport(Base, UUIDMixin, TimestampMixin): __tablename__ = "measurement_imports" validation_id: Mapped[str] = mapped_column(ForeignKey("validations.id"), index=True) import_type: Mapped[str] = mapped_column(String(60), index=True) original_filename: Mapped[str] = mapped_column(String(255)) storage_path: Mapped[str] = mapped_column(String(500)) sha256: Mapped[str] = mapped_column(String(64), index=True) parser_version: Mapped[str] = mapped_column(String(40)) status: Mapped[str] = mapped_column(String(60), index=True) class MeasurementImportValue(Base, UUIDMixin, TimestampMixin): __tablename__ = "measurement_import_values" import_id: Mapped[str] = mapped_column(ForeignKey("measurement_imports.id"), index=True) test_run: Mapped[str] = mapped_column(String(120), index=True) field_name: Mapped[str] = mapped_column(String(120), index=True) raw_value: Mapped[str | None] = mapped_column(Text) normalized_value: Mapped[str | None] = mapped_column(String(180)) unit: Mapped[str | None] = mapped_column(String(40)) source_page: Mapped[int | None] = mapped_column(Integer) source_text: Mapped[str | None] = mapped_column(Text) confidence: Mapped[int] = mapped_column(Integer, default=0) confirmed: Mapped[bool] = mapped_column(Boolean, default=False, index=True) corrected_value: Mapped[str | None] = mapped_column(String(180))