"""Модели проектов и заявок.""" import uuid from datetime import datetime, timezone from sqlalchemy import Column, DateTime, Enum, Float, ForeignKey, Integer, String, Text, func from sqlalchemy.dialects.postgresql import UUID as PG_UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from app.core.database import Base class Project(Base): __tablename__ = "projects" id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) client_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("users.id"), nullable=False) title: Mapped[str] = mapped_column(String(255), nullable=False) description: Mapped[str] = mapped_column(Text, nullable=False) category: Mapped[str | None] = mapped_column(String(100)) required_skills: Mapped[list] = mapped_column("required_skills", postgresql.JSONB, default=list) skill_embeddings: Mapped[list | None] = mapped_column("skill_embeddings") # pgvector budget_min: Mapped[float | None] = mapped_column(Float(precision=10, scale=2)) budget_max: Mapped[float | None] = mapped_column(Float(precision=10, scale=2)) status: Mapped[str] = mapped_column(Enum("open", "in_progress", "completed", "cancelled"), default="open") deadline: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), onupdate=func.now()) # Relationships client = relationship("User", foreign_keys=[client_id]) proposals: Mapped[list["Proposal"]] = relationship(back_populates="project") class Proposal(Base): __tablename__ = "proposals" id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) project_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("projects.id"), nullable=False) freelancer_id: Mapped[uuid.UUID] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("users.id"), nullable=False) cover_letter: Mapped[str | None] = mapped_column(Text) proposed_price: Mapped[float | None] = mapped_column(Float(precision=10, scale=2)) estimated_days: Mapped[int | None] = mapped_column(Integer) status: Mapped[str] = mapped_column(Enum("pending", "accepted", "rejected"), default="pending") created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) project: Mapped["Project"] = relationship(back_populates="proposals")