# backend/models.py from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, UniqueConstraint from sqlalchemy.orm import relationship, declarative_base import datetime Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(150), unique=True, nullable=False) password_hash = Column(String(255), nullable=False) role = Column(String(50), nullable=False, default='viewer') # 'admin' | 'editor' | 'viewer' class Auditory(Base): __tablename__ = 'auditories' id = Column(Integer, primary_key=True) audnazvanie = Column(String) oboruds = relationship("Oboruds", back_populates="auditory") class EquipmentType(Base): __tablename__ = 'equipment_types' id = Column(Integer, primary_key=True) name = Column(String, unique=True, nullable=False) oboruds = relationship("Oboruds", back_populates="type") class Owner(Base): __tablename__ = 'owners' id = Column(Integer, primary_key=True) name = Column(String, unique=True, nullable=False) oboruds = relationship("Oboruds", back_populates="owner") class Oboruds(Base): __tablename__ = 'oboruds' id = Column(Integer, primary_key=True) invNumber = Column(Integer) nazvanie = Column(String(500)) raspologenie = Column(String(200)) numberppasu = Column(String(100)) kolichestvo = Column(Integer) aud_id = Column(Integer, ForeignKey("auditories.id")) auditory = relationship("Auditory", back_populates="oboruds") type_id = Column(Integer, ForeignKey("equipment_types.id")) type = relationship("EquipmentType", back_populates="oboruds") owner_id = Column(Integer, ForeignKey("owners.id")) owner = relationship("Owner", back_populates="oboruds") components = relationship("Component", back_populates="oborud") consumables = relationship("Consumable", back_populates="oborud") class Component(Base): __tablename__ = 'components' id = Column(Integer, primary_key=True) name = Column(String, nullable=False) description = Column(String) oborud_id = Column(Integer, ForeignKey("oboruds.id")) oborud = relationship("Oboruds", back_populates="components") class Consumable(Base): __tablename__ = 'consumables' id = Column(Integer, primary_key=True) name = Column(String, nullable=False) description = Column(String) oborud_id = Column(Integer, ForeignKey("oboruds.id")) oborud = relationship("Oboruds", back_populates="consumables") class Zametki(Base): __tablename__ = 'zametki' id = Column(Integer, primary_key=True) txtzam = Column(String(10000)) created_date = Column(DateTime, default=datetime.datetime.utcnow) rmdt = Column(DateTime) class InspectionSession(Base): __tablename__ = 'inspection_sessions' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False) started_at = Column(DateTime, nullable=False) completed_at = Column(DateTime, nullable=True) aud_id = Column(Integer, ForeignKey("auditories.id"), nullable=True) # null = всё подряд # Relationships user = relationship("User") auditory = relationship("Auditory") records = relationship("InspectionRecord", back_populates="session") unknown_barcodes = relationship("UnknownBarcode", back_populates="session") class InspectionRecord(Base): __tablename__ = 'inspection_records' id = Column(Integer, primary_key=True) session_id = Column(Integer, ForeignKey("inspection_sessions.id"), nullable=False) oborud_id = Column(Integer, ForeignKey("oboruds.id"), nullable=False) checked_at = Column(DateTime, nullable=False) # обновляется при повторном сканировании # Relationships session = relationship("InspectionSession", back_populates="records") oborud = relationship("Oboruds") # Уникальное ограничение: одна запись на оборудование в рамках сессии __table_args__ = (UniqueConstraint('session_id', 'oborud_id', name='_session_oborud_uc'),) class UnknownBarcode(Base): __tablename__ = 'unknown_barcodes' id = Column(Integer, primary_key=True) session_id = Column(Integer, ForeignKey("inspection_sessions.id"), nullable=False) barcode = Column(String(100), nullable=False) scanned_at = Column(DateTime, nullable=False) # Relationships session = relationship("InspectionSession", back_populates="unknown_barcodes")