Files
OCR/backend/app/models/audit_log.py
egg fd98018ddd refactor: complete V1 to V2 migration and remove legacy architecture
Remove all V1 architecture components and promote V2 to primary:
- Delete all paddle_ocr_* table models (export, ocr, translation, user)
- Delete legacy routers (auth, export, ocr, translation)
- Delete legacy schemas and services
- Promote user_v2.py to user.py as primary user model
- Update all imports and dependencies to use V2 models only
- Update main.py version to 2.0.0

Database changes:
- Fix SQLAlchemy reserved word: rename audit_log.metadata to extra_data
- Add migration to drop all paddle_ocr_* tables
- Update alembic env to only import V2 models

Frontend fixes:
- Fix Select component exports in TaskHistoryPage.tsx
- Update to use simplified Select API with options prop
- Fix AxiosInstance TypeScript import syntax

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 21:27:39 +08:00

96 lines
3.0 KiB
Python

"""
Tool_OCR - Audit Log Model
Security audit logging for authentication and task operations
"""
from sqlalchemy import Column, Integer, String, DateTime, Text, ForeignKey
from sqlalchemy.orm import relationship
from datetime import datetime
from app.core.database import Base
class AuditLog(Base):
"""
Audit log model for security tracking
Records all important events including:
- Authentication events (login, logout, failures)
- Task operations (create, update, delete)
- Admin operations
"""
__tablename__ = "tool_ocr_audit_logs"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
user_id = Column(
Integer,
ForeignKey("tool_ocr_users.id", ondelete="SET NULL"),
nullable=True,
index=True,
comment="User who performed the action (NULL for system events)"
)
event_type = Column(
String(50),
nullable=False,
index=True,
comment="Event type: auth_login, auth_logout, auth_failed, task_create, etc."
)
event_category = Column(
String(20),
nullable=False,
index=True,
comment="Category: authentication, task, admin, system"
)
description = Column(
Text,
nullable=False,
comment="Human-readable event description"
)
ip_address = Column(String(45), nullable=True, comment="Client IP address (IPv4/IPv6)")
user_agent = Column(String(500), nullable=True, comment="Client user agent")
resource_type = Column(
String(50),
nullable=True,
comment="Type of resource affected (task, user, session)"
)
resource_id = Column(
String(255),
nullable=True,
index=True,
comment="ID of affected resource"
)
success = Column(
Integer,
default=1,
nullable=False,
comment="1 for success, 0 for failure"
)
error_message = Column(Text, nullable=True, comment="Error details if failed")
extra_data = Column(Text, nullable=True, comment="Additional JSON metadata")
created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
# Relationships
user = relationship("User", back_populates="audit_logs")
def __repr__(self):
return f"<AuditLog(id={self.id}, type='{self.event_type}', user_id={self.user_id})>"
def to_dict(self):
"""Convert audit log to dictionary"""
return {
"id": self.id,
"user_id": self.user_id,
"event_type": self.event_type,
"event_category": self.event_category,
"description": self.description,
"ip_address": self.ip_address,
"user_agent": self.user_agent,
"resource_type": self.resource_type,
"resource_id": self.resource_id,
"success": bool(self.success),
"error_message": self.error_message,
"extra_data": self.extra_data,
"created_at": self.created_at.isoformat() if self.created_at else None
}