GrantForge Bot
Deploy sha-565ad85979610064f6d1c18ab3b6404357d61073 — source build (no GHCR)
ce8f04a
Raw
History Blame Contribute Delete
1.96 kB
"""Audit persistence models — tenant audit log and project collaborators."""
from __future__ import annotations
import datetime
import uuid
from sqlalchemy import Column, DateTime, ForeignKey, JSON, String, UniqueConstraint
from sqlalchemy.orm import backref, relationship
from core.subscription.db import Base
class TenantAuditLog(Base):
"""Per-tenant audit trail (collaborator changes, exports, gap audits)."""
__tablename__ = "tenant_audit_logs"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
tenant_user_id = Column(String, index=True, nullable=False)
project_id = Column(String, ForeignKey("projects.id", ondelete="SET NULL"), index=True, nullable=True)
action = Column(String, nullable=False, index=True)
actor_user_id = Column(String, nullable=True)
target_user_id = Column(String, nullable=True)
details = Column(JSON, nullable=True)
created_at = Column(
DateTime,
default=lambda: datetime.datetime.now(datetime.timezone.utc),
index=True,
)
class ProjectCollaborator(Base):
"""Współpracownik projektu (tenant-scoped)."""
__tablename__ = "project_collaborators"
__table_args__ = (
UniqueConstraint("project_id", "collaborator_user_id", name="uq_project_collaborator"),
)
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(
String,
ForeignKey("projects.id", ondelete="CASCADE"),
index=True,
nullable=False,
)
owner_user_id = Column(String, index=True, nullable=False)
collaborator_user_id = Column(String, index=True, nullable=False)
role = Column(String, default="editor")
created_at = Column(
DateTime,
default=lambda: datetime.datetime.now(datetime.timezone.utc),
)
project = relationship(
"Project",
backref=backref("collaborators", cascade="all, delete-orphan"),
)