Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion backend/app/models/event_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ class EventChain(Base):
__tablename__ = "event_chains"

event_id = Column(String, primary_key=True) # UUID string
session_id = Column(String(36), ForeignKey("sessions.session_id_str"), nullable=False, index=True)
session_id = Column(Integer, ForeignKey("sessions.id"), nullable=False, index=True)
session_id_str = Column(String(36), nullable=False)
Comment on lines +8 to +9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

session_id and session_id_str can silently diverge — no DB-level consistency enforcement.

There is no ForeignKey, CheckConstraint, or ORM-level validation ensuring that session_id_str matches sessions.session_id_str for the referenced sessions.id. Any code path that sets these two fields independently can produce inconsistent rows with no error raised.

Consider one of these approaches:

  1. Add a ForeignKey("sessions.session_id_str") to session_id_str (requires a unique constraint on sessions.session_id_str, which already exists).
  2. Enforce the invariant in application code at the service layer and document clearly that session_id_str is a denormalized copy of sessions.session_id_str.
  3. Derive session_id_str via a DB-level Computed column or a @validates ORM event rather than storing it as a raw, unconstrained field.

As per coding guidelines, "Use explicit code rather than implicit; avoid hidden behavior or side effects."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/app/models/event_chain.py` around lines 8 - 9, The session_id_str
column can diverge from sessions.session_id_str because there's no DB-level
constraint; update the EventChain model to enforce consistency by adding a
foreign key on session_id_str referencing sessions.session_id_str
(sessions.session_id_str is already unique) instead of leaving it unconstrained;
modify the Column declaration for session_id_str to include
ForeignKey("sessions.session_id_str"), regenerate the migration to add the FK,
and run the migration so the database enforces the invariant (alternatively, if
you prefer not to add an FK, implement a Computed column or a `@validates` hook on
EventChain.session_id/session_id_str and document the denormalization).

sequence_number = Column(Integer, nullable=False)
timestamp_wall = Column(DateTime, nullable=False)
timestamp_monotonic = Column(Float, nullable=True)
Expand Down
5 changes: 4 additions & 1 deletion backend/app/models/session.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.database import Base

from sqlalchemy.sql import expression

class Session(Base):
__tablename__ = "sessions"

Expand All @@ -20,3 +22,4 @@ class Session(Base):
# Relationships
user = relationship("User", back_populates="sessions")
events = relationship("Event", back_populates="session", cascade="all, delete-orphan")
is_replay = Column(Boolean, default=False, nullable=False, server_default=expression.false())
Loading