Files
leocrm/app/models/session.py
T
Agent Zero 6555655ecf
Check Cross-Plugin Imports / check (push) Has been cancelled
fix: sync all models with production DB schema
- Add OwnedMixin to 29 model files (78 tables that had owner_id in DB but not in model)
- Add search/embedding columns to 9 model files (18 columns: search_tsv, embedding, indexed_at, content_text, content_tsv, body_tsv, company_id, deleted_at)
- Fix import syntax errors in calendar/models.py, mail/models.py, notification.py, contact.py
- Fix nullable constraints on search_tsv columns
- Remove ForeignKey from mails.company_id (companies table not always loaded in test context)
- All 36 tests pass (24 Phase J + 12 Phase K)
- Models now match production DB schema
2026-08-21 11:20:15 +02:00

39 lines
1.3 KiB
Python

"""Session model — PostgreSQL audit trail for sessions.
⚠️ Session-Tabelle dient als audit trail. Redis ist der Runtime-Session-Store.
Dies ist ein bewusstes Dual-System.
⚠️ Sessions sind nicht an IP/Device gebunden (Design-Entscheidung).
Bei Bedarf IP-Binding hinzufügen.
"""
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, String, func
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
from app.models.owned_mixin import OwnedMixin
class Session(Base, TenantMixin, OwnedMixin):
"""Immutable session audit record. Runtime session lookup uses Redis."""
__tablename__ = "sessions"
id: Mapped[uuid.UUID] = mapped_column(
PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4
)
user_id: Mapped[uuid.UUID] = mapped_column(
PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
)
csrf_token: Mapped[str] = mapped_column(String(255), nullable=False)
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, index=True)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)