- Add TranslationLog model to track translation API usage per task - Integrate Dify API actual price (total_price) into translation stats - Display translation statistics in admin dashboard with per-task costs - Remove unused Export and Settings pages to simplify frontend - Add GET /api/v2/admin/translation-stats endpoint 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
51 lines
1.9 KiB
Python
51 lines
1.9 KiB
Python
"""
|
|
Tool_OCR - User Model v2.0
|
|
External API authentication with simplified schema
|
|
"""
|
|
|
|
from sqlalchemy import Column, Integer, String, DateTime, Boolean
|
|
from sqlalchemy.orm import relationship
|
|
from datetime import datetime
|
|
|
|
from app.core.database import Base
|
|
|
|
|
|
class User(Base):
|
|
"""
|
|
User model for external API authentication
|
|
|
|
Uses email as primary identifier from Azure AD.
|
|
No password storage - authentication via external API only.
|
|
"""
|
|
|
|
__tablename__ = "tool_ocr_users"
|
|
|
|
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
|
email = Column(String(255), unique=True, nullable=False, index=True,
|
|
comment="Primary identifier from Azure AD")
|
|
display_name = Column(String(255), nullable=True,
|
|
comment="Display name from API response")
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
last_login = Column(DateTime, nullable=True)
|
|
is_active = Column(Boolean, default=True, nullable=False, index=True)
|
|
|
|
# Relationships
|
|
tasks = relationship("Task", back_populates="user", cascade="all, delete-orphan")
|
|
sessions = relationship("Session", back_populates="user", cascade="all, delete-orphan")
|
|
audit_logs = relationship("AuditLog", back_populates="user")
|
|
translation_logs = relationship("TranslationLog", back_populates="user", cascade="all, delete-orphan")
|
|
|
|
def __repr__(self):
|
|
return f"<User(id={self.id}, email='{self.email}', display_name='{self.display_name}')>"
|
|
|
|
def to_dict(self):
|
|
"""Convert user to dictionary"""
|
|
return {
|
|
"id": self.id,
|
|
"email": self.email,
|
|
"display_name": self.display_name,
|
|
"created_at": self.created_at.isoformat() if self.created_at else None,
|
|
"last_login": self.last_login.isoformat() if self.last_login else None,
|
|
"is_active": self.is_active
|
|
}
|