Files
TieMeasureFlow/server/models/access_log.py
Adriano d6508e0ae8 feat: FASE 1 - Backend Core (modelli, auth, API)
Implementazione completa del backend FastAPI:
- Modelli SQLAlchemy: User, Recipe, RecipeVersion, RecipeTask,
  RecipeSubtask, Measurement, AccessLog, SystemSetting, RecipeVersionAudit
- Schemas Pydantic v2 per tutti i CRUD + statistiche SPC
- Middleware: API Key auth (X-API-Key) con role checking + access logging
- Router: auth, users, recipes, tasks, measurements, files, settings
- Services: auth (bcrypt+secrets), recipe (copy-on-write versioning),
  measurement (auto pass/fail con UTL/UWL/LWL/LTL)
- Alembic env.py con import modelli attivi
- Fix architect review: no double-commit, recipe_id subquery filter,
  user_id in access logs, type annotations corrette

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 00:40:50 +01:00

33 lines
1.2 KiB
Python

"""Access log model for tracking user actions."""
from datetime import datetime
from typing import Optional
from sqlalchemy import BigInteger, DateTime, ForeignKey, Index, Integer, JSON, String, func
from sqlalchemy.orm import Mapped, mapped_column
from database import Base
class AccessLog(Base):
__tablename__ = "access_logs"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
user_id: Mapped[Optional[int]] = mapped_column(
Integer, ForeignKey("users.id"), nullable=True
)
action: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
details: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)
ip_address: Mapped[Optional[str]] = mapped_column(String(45), nullable=True)
user_agent: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
created_at: Mapped[datetime] = mapped_column(
DateTime, nullable=False, server_default=func.now()
)
__table_args__ = (
Index("ix_access_log_user_time", "user_id", "created_at"),
{"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"},
)
def __repr__(self) -> str:
return f"<AccessLog user={self.user_id} action={self.action}>"