Spaces:
Running
Running
| from datetime import date, datetime | |
| from sqlalchemy import ( | |
| Boolean, | |
| Column, | |
| Date, | |
| DateTime, | |
| Float, | |
| ForeignKey, | |
| Integer, | |
| String, | |
| Table, | |
| Text, | |
| UniqueConstraint, | |
| ) | |
| from sqlalchemy.orm import Mapped, mapped_column, relationship | |
| from database import Base | |
| person_tags = Table( | |
| "person_tags", | |
| Base.metadata, | |
| Column("person_id", ForeignKey("people.id", ondelete="CASCADE"), primary_key=True), | |
| Column("tag_id", ForeignKey("tags.id", ondelete="CASCADE"), primary_key=True), | |
| ) | |
| project_tags = Table( | |
| "project_tags", | |
| Base.metadata, | |
| Column("project_id", ForeignKey("projects.id", ondelete="CASCADE"), primary_key=True), | |
| Column("tag_id", ForeignKey("tags.id", ondelete="CASCADE"), primary_key=True), | |
| ) | |
| class User(Base): | |
| __tablename__ = "users" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| username: Mapped[str] = mapped_column(String, unique=True, nullable=False, index=True) | |
| password_hash: Mapped[str] = mapped_column(String, nullable=False) | |
| role: Mapped[str] = mapped_column(String, default="viewer", nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| class Role(Base): | |
| __tablename__ = "roles" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| name: Mapped[str] = mapped_column(String, unique=True, nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| people: Mapped[list["Person"]] = relationship(back_populates="role") | |
| class Team(Base): | |
| __tablename__ = "teams" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| name: Mapped[str] = mapped_column(String, unique=True, nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| people: Mapped[list["Person"]] = relationship(back_populates="team") | |
| class Tag(Base): | |
| __tablename__ = "tags" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| name: Mapped[str] = mapped_column(String, unique=True, nullable=False) | |
| color: Mapped[str] = mapped_column(String, default="#7c3aed", nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| class PersonSkill(Base): | |
| __tablename__ = "person_skills" | |
| __table_args__ = (UniqueConstraint("person_id", "skill_id", name="uq_person_skill"),) | |
| person_id: Mapped[int] = mapped_column(ForeignKey("people.id"), primary_key=True) | |
| skill_id: Mapped[int] = mapped_column(ForeignKey("skills.id"), primary_key=True) | |
| proficiency: Mapped[str] = mapped_column(String, default="intermediate", nullable=False) | |
| person: Mapped["Person"] = relationship(back_populates="person_skills") | |
| skill: Mapped["Skill"] = relationship(back_populates="person_skills") | |
| class Person(Base): | |
| __tablename__ = "people" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| name: Mapped[str] = mapped_column(String, nullable=False) | |
| email: Mapped[str] = mapped_column(String, unique=True, nullable=False, index=True) | |
| role_id: Mapped[int] = mapped_column(ForeignKey("roles.id"), nullable=False, index=True) | |
| team_id: Mapped[int | None] = mapped_column(ForeignKey("teams.id"), index=True) | |
| weekly_capacity_hrs: Mapped[float] = mapped_column(Float, default=40.0, nullable=False) | |
| start_date: Mapped[date | None] = mapped_column(Date) | |
| end_date: Mapped[date | None] = mapped_column(Date) | |
| is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) | |
| avatar_color: Mapped[str] = mapped_column(String, default="#2563eb", nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| role: Mapped[Role] = relationship(back_populates="people", lazy="selectin") | |
| team: Mapped[Team | None] = relationship(back_populates="people", lazy="selectin") | |
| tags: Mapped[list[Tag]] = relationship(secondary=person_tags, lazy="selectin") | |
| person_skills: Mapped[list[PersonSkill]] = relationship(back_populates="person", cascade="all, delete-orphan") | |
| allocations: Mapped[list["Allocation"]] = relationship(back_populates="person") | |
| leaves: Mapped[list["Leave"]] = relationship(back_populates="person") | |
| owned_projects: Mapped[list["Project"]] = relationship(back_populates="owner") | |
| class Skill(Base): | |
| __tablename__ = "skills" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| name: Mapped[str] = mapped_column(String, unique=True, nullable=False) | |
| category: Mapped[str | None] = mapped_column(String) | |
| person_skills: Mapped[list[PersonSkill]] = relationship(back_populates="skill") | |
| class Project(Base): | |
| __tablename__ = "projects" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| name: Mapped[str] = mapped_column(String, nullable=False) | |
| description: Mapped[str | None] = mapped_column(Text) | |
| status: Mapped[str] = mapped_column(String, default="planning", nullable=False) | |
| type: Mapped[str] = mapped_column(String, default="other", nullable=False) | |
| start_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| end_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| is_tentative: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False) | |
| is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) | |
| color: Mapped[str] = mapped_column(String, default="#0ea5e9", nullable=False) | |
| owner_id: Mapped[int | None] = mapped_column(ForeignKey("people.id")) | |
| team_id: Mapped[int | None] = mapped_column(ForeignKey("teams.id")) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| owner: Mapped[Person | None] = relationship(back_populates="owned_projects") | |
| team: Mapped["Team | None"] = relationship() | |
| milestones: Mapped[list["Milestone"]] = relationship(back_populates="project", cascade="all, delete-orphan") | |
| phases: Mapped[list["ProjectPhase"]] = relationship(back_populates="project", cascade="all, delete-orphan") | |
| allocations: Mapped[list["Allocation"]] = relationship(back_populates="project") | |
| tags: Mapped[list[Tag]] = relationship(secondary=project_tags, lazy="selectin") | |
| class ProjectPhase(Base): | |
| __tablename__ = "project_phases" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| project_id: Mapped[int] = mapped_column(ForeignKey("projects.id"), nullable=False) | |
| name: Mapped[str] = mapped_column(String, nullable=False) | |
| start_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| end_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| color: Mapped[str] = mapped_column(String, default="#14b8a6", nullable=False) | |
| project: Mapped[Project] = relationship(back_populates="phases") | |
| class Milestone(Base): | |
| __tablename__ = "milestones" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| project_id: Mapped[int] = mapped_column(ForeignKey("projects.id"), nullable=False) | |
| name: Mapped[str] = mapped_column(String, nullable=False) | |
| due_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| is_completed: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False) | |
| project: Mapped[Project] = relationship(back_populates="milestones") | |
| class Allocation(Base): | |
| __tablename__ = "allocations" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| person_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=False) | |
| project_id: Mapped[int] = mapped_column(ForeignKey("projects.id"), nullable=False) | |
| start_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| end_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| allocation_pct: Mapped[float] = mapped_column(Float, nullable=False) | |
| note: Mapped[str | None] = mapped_column(Text) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| person: Mapped[Person] = relationship(back_populates="allocations") | |
| project: Mapped[Project] = relationship(back_populates="allocations") | |
| class Leave(Base): | |
| __tablename__ = "leaves" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) | |
| person_id: Mapped[int | None] = mapped_column(ForeignKey("people.id")) | |
| leave_type: Mapped[str] = mapped_column(String, nullable=False) | |
| start_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| end_date: Mapped[date] = mapped_column(Date, nullable=False) | |
| note: Mapped[str | None] = mapped_column(Text) | |
| approved: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) | |
| person: Mapped[Person | None] = relationship(back_populates="leaves") | |