Files
Airtep/gig-poc/apps/api/app/domain/models.py
2026-03-30 20:49:40 +08:00

87 lines
4.0 KiB
Python

from datetime import datetime
from uuid import uuid4
from sqlalchemy import DateTime, Float, ForeignKey, Integer, String, Text, func
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.db.base import Base
class Job(Base):
__tablename__ = "jobs"
id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: f"job_{uuid4().hex[:12]}")
title: Mapped[str] = mapped_column(String(255))
category: Mapped[str] = mapped_column(String(128))
description: Mapped[str] = mapped_column(Text)
city: Mapped[str] = mapped_column(String(64))
region: Mapped[str] = mapped_column(String(64))
location_detail: Mapped[str] = mapped_column(String(255))
start_time: Mapped[datetime] = mapped_column(DateTime(timezone=True))
duration_hours: Mapped[float] = mapped_column(Float)
headcount: Mapped[int] = mapped_column(Integer)
salary_type: Mapped[str] = mapped_column(String(32))
salary_amount: Mapped[float] = mapped_column(Float)
salary_currency: Mapped[str] = mapped_column(String(16), default="CNY")
work_mode: Mapped[str] = mapped_column(String(64))
tags_json: Mapped[list[str]] = mapped_column(JSONB, default=list)
confidence: Mapped[float] = mapped_column(Float)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
skills: Mapped[list["JobSkill"]] = relationship(back_populates="job", cascade="all, delete-orphan")
class JobSkill(Base):
__tablename__ = "job_skills"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
job_id: Mapped[str] = mapped_column(ForeignKey("jobs.id", ondelete="CASCADE"), index=True)
skill_name: Mapped[str] = mapped_column(String(128), index=True)
weight: Mapped[float] = mapped_column(Float, default=1.0)
is_required: Mapped[bool] = mapped_column(default=True)
job: Mapped[Job] = relationship(back_populates="skills")
class Worker(Base):
__tablename__ = "workers"
id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: f"worker_{uuid4().hex[:12]}")
name: Mapped[str] = mapped_column(String(128))
description: Mapped[str] = mapped_column(Text)
cities_json: Mapped[list[str]] = mapped_column(JSONB, default=list)
regions_json: Mapped[list[str]] = mapped_column(JSONB, default=list)
availability_json: Mapped[list[str]] = mapped_column(JSONB, default=list)
experience_tags_json: Mapped[list[str]] = mapped_column(JSONB, default=list)
reliability_score: Mapped[float] = mapped_column(Float, default=0.7)
profile_completion: Mapped[float] = mapped_column(Float, default=0.6)
confidence: Mapped[float] = mapped_column(Float, default=0.8)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
skills: Mapped[list["WorkerSkill"]] = relationship(back_populates="worker", cascade="all, delete-orphan")
class WorkerSkill(Base):
__tablename__ = "worker_skills"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
worker_id: Mapped[str] = mapped_column(ForeignKey("workers.id", ondelete="CASCADE"), index=True)
skill_name: Mapped[str] = mapped_column(String(128), index=True)
score: Mapped[float] = mapped_column(Float, default=0.7)
worker: Mapped[Worker] = relationship(back_populates="skills")
class MatchRecord(Base):
__tablename__ = "matches"
id: Mapped[str] = mapped_column(String(64), primary_key=True, default=lambda: f"match_{uuid4().hex[:12]}")
source_type: Mapped[str] = mapped_column(String(32), index=True)
source_id: Mapped[str] = mapped_column(String(64), index=True)
target_id: Mapped[str] = mapped_column(String(64), index=True)
match_score: Mapped[float] = mapped_column(Float)
breakdown_json: Mapped[dict] = mapped_column(JSONB)
reasons_json: Mapped[list[str]] = mapped_column(JSONB)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())