coming together

This commit is contained in:
HotSwapp
2025-08-13 18:53:35 -05:00
parent acc5155bf7
commit 5111079149
51 changed files with 14457 additions and 588 deletions

View File

@@ -46,4 +46,57 @@ class LoginAttempt(BaseModel):
failure_reason = Column(String(200), nullable=True) # Reason for failure
def __repr__(self):
return f"<LoginAttempt(username='{self.username}', success={bool(self.success)}, timestamp='{self.timestamp}')>"
return f"<LoginAttempt(username='{self.username}', success={bool(self.success)}, timestamp='{self.timestamp}')>"
class ImportAudit(BaseModel):
"""
Records each batch CSV upload run with metrics and outcome.
"""
__tablename__ = "import_audit"
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
started_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
finished_at = Column(DateTime, nullable=True, index=True)
status = Column(String(30), nullable=False, default="running", index=True) # running|success|completed_with_errors|failed
total_files = Column(Integer, nullable=False, default=0)
successful_files = Column(Integer, nullable=False, default=0)
failed_files = Column(Integer, nullable=False, default=0)
total_imported = Column(Integer, nullable=False, default=0)
total_errors = Column(Integer, nullable=False, default=0)
initiated_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
initiated_by_username = Column(String(100), nullable=True)
message = Column(String(255), nullable=True)
details = Column(JSON, nullable=True) # optional, compact summary payload
user = relationship("User")
files = relationship("ImportAuditFile", back_populates="audit", cascade="all, delete-orphan")
def __repr__(self):
return (
f"<ImportAudit(id={self.id}, status='{self.status}', files={self.successful_files}/{self.total_files}, "
f"imported={self.total_imported}, errors={self.total_errors})>"
)
class ImportAuditFile(BaseModel):
"""Per-file result for a given batch import run."""
__tablename__ = "import_audit_files"
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
audit_id = Column(Integer, ForeignKey("import_audit.id", ondelete="CASCADE"), nullable=False, index=True)
file_type = Column(String(64), nullable=False, index=True)
status = Column(String(30), nullable=False, index=True)
imported_count = Column(Integer, nullable=False, default=0)
errors = Column(Integer, nullable=False, default=0)
message = Column(String(255), nullable=True)
details = Column(JSON, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
audit = relationship("ImportAudit", back_populates="files")
def __repr__(self):
return f"<ImportAuditFile(audit_id={self.audit_id}, file='{self.file_type}', status='{self.status}', imported={self.imported_count}, errors={self.errors})>"