feat: add new folder
This commit is contained in:
171
gig-poc/apps/api/app/domain/schemas.py
Normal file
171
gig-poc/apps/api/app/domain/schemas.py
Normal file
@@ -0,0 +1,171 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
|
||||
|
||||
class SalaryType(str, Enum):
|
||||
daily = "daily"
|
||||
hourly = "hourly"
|
||||
monthly = "monthly"
|
||||
task = "task"
|
||||
|
||||
|
||||
class SourceType(str, Enum):
|
||||
job_to_worker = "job_to_worker"
|
||||
worker_to_job = "worker_to_job"
|
||||
|
||||
|
||||
class Salary(BaseModel):
|
||||
type: SalaryType = SalaryType.daily
|
||||
amount: float = 0
|
||||
currency: str = "CNY"
|
||||
|
||||
|
||||
class SkillScore(BaseModel):
|
||||
name: str
|
||||
score: float = Field(ge=0, le=1)
|
||||
|
||||
|
||||
class JobCard(BaseModel):
|
||||
job_id: str
|
||||
title: str
|
||||
category: str
|
||||
description: str
|
||||
skills: list[str] = Field(default_factory=list)
|
||||
city: str
|
||||
region: str
|
||||
location_detail: str
|
||||
start_time: datetime
|
||||
duration_hours: float = Field(gt=0)
|
||||
headcount: int = Field(gt=0)
|
||||
salary: Salary
|
||||
work_mode: str
|
||||
tags: list[str] = Field(default_factory=list)
|
||||
confidence: float = Field(ge=0, le=1)
|
||||
|
||||
|
||||
class WorkerCard(BaseModel):
|
||||
worker_id: str
|
||||
name: str
|
||||
description: str
|
||||
skills: list[SkillScore] = Field(default_factory=list)
|
||||
cities: list[str] = Field(default_factory=list)
|
||||
regions: list[str] = Field(default_factory=list)
|
||||
availability: list[str] = Field(default_factory=list)
|
||||
experience_tags: list[str] = Field(default_factory=list)
|
||||
reliability_score: float = Field(ge=0, le=1)
|
||||
profile_completion: float = Field(ge=0, le=1)
|
||||
confidence: float = Field(ge=0, le=1)
|
||||
|
||||
|
||||
class MatchBreakdown(BaseModel):
|
||||
skill_score: float = Field(ge=0, le=1)
|
||||
region_score: float = Field(ge=0, le=1)
|
||||
time_score: float = Field(ge=0, le=1)
|
||||
experience_score: float = Field(ge=0, le=1)
|
||||
reliability_score: float = Field(ge=0, le=1)
|
||||
|
||||
|
||||
class MatchResult(BaseModel):
|
||||
match_id: str
|
||||
source_type: SourceType
|
||||
source_id: str
|
||||
target_id: str
|
||||
match_score: float = Field(ge=0, le=1)
|
||||
breakdown: MatchBreakdown
|
||||
reasons: list[str] = Field(default_factory=list, min_length=3)
|
||||
|
||||
|
||||
class ExtractTextRequest(BaseModel):
|
||||
text: str = Field(min_length=5)
|
||||
|
||||
|
||||
class IngestJobRequest(BaseModel):
|
||||
job: JobCard
|
||||
|
||||
|
||||
class IngestWorkerRequest(BaseModel):
|
||||
worker: WorkerCard
|
||||
|
||||
|
||||
class MatchWorkersRequest(BaseModel):
|
||||
job_id: str | None = None
|
||||
job: JobCard | None = None
|
||||
top_n: int = Field(default=10, ge=1, le=50)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_source(self) -> "MatchWorkersRequest":
|
||||
if not self.job_id and not self.job:
|
||||
raise ValueError("job_id 或 job 至少需要提供一个")
|
||||
return self
|
||||
|
||||
|
||||
class MatchJobsRequest(BaseModel):
|
||||
worker_id: str | None = None
|
||||
worker: WorkerCard | None = None
|
||||
top_n: int = Field(default=10, ge=1, le=50)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_source(self) -> "MatchJobsRequest":
|
||||
if not self.worker_id and not self.worker:
|
||||
raise ValueError("worker_id 或 worker 至少需要提供一个")
|
||||
return self
|
||||
|
||||
|
||||
class ExtractResponse(BaseModel):
|
||||
success: bool
|
||||
data: JobCard | WorkerCard | None = None
|
||||
errors: list[str] = Field(default_factory=list)
|
||||
missing_fields: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class BootstrapResponse(BaseModel):
|
||||
jobs: int
|
||||
workers: int
|
||||
skills: int
|
||||
categories: int
|
||||
regions: int
|
||||
|
||||
|
||||
class HealthStatus(BaseModel):
|
||||
service: str
|
||||
database: str
|
||||
rag: str
|
||||
timestamp: datetime
|
||||
|
||||
|
||||
class ListResponse(BaseModel):
|
||||
items: list[dict]
|
||||
total: int
|
||||
|
||||
|
||||
class MatchResponse(BaseModel):
|
||||
items: list[MatchResult]
|
||||
|
||||
|
||||
class ExplainResponse(BaseModel):
|
||||
match: MatchResult
|
||||
|
||||
|
||||
class PromptOutput(BaseModel):
|
||||
content: dict
|
||||
raw_text: str
|
||||
|
||||
|
||||
class QueryFilters(BaseModel):
|
||||
entity_type: str
|
||||
city: str | None = None
|
||||
region: str | None = None
|
||||
categories: list[str] = Field(default_factory=list)
|
||||
tags: list[str] = Field(default_factory=list)
|
||||
skills: list[str] = Field(default_factory=list)
|
||||
|
||||
@field_validator("entity_type")
|
||||
@classmethod
|
||||
def validate_entity_type(cls, value: str) -> str:
|
||||
if value not in {"job", "worker"}:
|
||||
raise ValueError("entity_type must be job or worker")
|
||||
return value
|
||||
Reference in New Issue
Block a user