74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
import uuid
|
|
from sqlalchemy import Column, String, Integer, Enum, DateTime, ForeignKey, UniqueConstraint
|
|
from sqlalchemy.orm import relationship, synonym
|
|
from sqlalchemy.sql import func
|
|
from app.core.database import Base
|
|
import enum
|
|
|
|
|
|
class DependencyType(str, enum.Enum):
|
|
"""
|
|
Task dependency types for Gantt chart.
|
|
|
|
FS (Finish-to-Start): Predecessor must finish before successor starts (most common)
|
|
SS (Start-to-Start): Predecessor must start before successor starts
|
|
FF (Finish-to-Finish): Predecessor must finish before successor finishes
|
|
SF (Start-to-Finish): Predecessor must start before successor finishes (rare)
|
|
"""
|
|
FS = "FS" # Finish-to-Start
|
|
SS = "SS" # Start-to-Start
|
|
FF = "FF" # Finish-to-Finish
|
|
SF = "SF" # Start-to-Finish
|
|
|
|
|
|
class TaskDependency(Base):
|
|
"""
|
|
Represents a dependency relationship between two tasks.
|
|
|
|
The predecessor task affects when the successor task can be scheduled,
|
|
based on the dependency_type. This is used for Gantt chart visualization
|
|
and date validation.
|
|
"""
|
|
__tablename__ = "pjctrl_task_dependencies"
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint('predecessor_id', 'successor_id', name='uq_predecessor_successor'),
|
|
)
|
|
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
predecessor_id = Column(
|
|
String(36),
|
|
ForeignKey("pjctrl_tasks.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
index=True
|
|
)
|
|
successor_id = Column(
|
|
String(36),
|
|
ForeignKey("pjctrl_tasks.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
index=True
|
|
)
|
|
dependency_type = Column(
|
|
Enum("FS", "SS", "FF", "SF", name="dependency_type_enum"),
|
|
default="FS",
|
|
nullable=False
|
|
)
|
|
lag_days = Column(Integer, default=0, nullable=False)
|
|
created_at = Column(DateTime, server_default=func.now(), nullable=False)
|
|
|
|
# Relationships
|
|
predecessor = relationship(
|
|
"Task",
|
|
foreign_keys=[predecessor_id],
|
|
back_populates="successors"
|
|
)
|
|
successor = relationship(
|
|
"Task",
|
|
foreign_keys=[successor_id],
|
|
back_populates="predecessors"
|
|
)
|
|
|
|
# Backward-compatible aliases for legacy field names
|
|
task_id = synonym("successor_id")
|
|
depends_on_task_id = synonym("predecessor_id")
|