feat: upgrade tree deletion to soft delete with deleted_at timestamp

Adds deleted_at and deleted_by columns to trees table for proper soft
delete tracking. Supports future 30-day restore window functionality.
The delete endpoint now sets both is_active=False (backward compat) and
deleted_at/deleted_by. Migration backfills existing is_active=False rows.

Fixed ambiguous FK relationship between User/Tree models by adding
explicit foreign_keys to both sides of the author relationship.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-05 23:33:05 -05:00
parent 3a5ac0f201
commit 33368688b2
4 changed files with 54 additions and 3 deletions

View File

@@ -50,6 +50,16 @@ class Tree(Base):
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
is_public: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
is_default: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
deleted_at: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True),
nullable=True,
index=True
)
deleted_by: Mapped[Optional[uuid.UUID]] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id"),
nullable=True
)
version: Mapped[int] = mapped_column(Integer, default=1)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
@@ -63,7 +73,7 @@ class Tree(Base):
usage_count: Mapped[int] = mapped_column(Integer, default=0)
# Relationships
author: Mapped[Optional["User"]] = relationship("User", back_populates="trees")
author: Mapped[Optional["User"]] = relationship("User", foreign_keys=[author_id], back_populates="trees")
team: Mapped[Optional["Team"]] = relationship("Team", back_populates="trees")
sessions: Mapped[list["Session"]] = relationship("Session", back_populates="tree")