matching-tool / backend /app /schemas.py
KronosDP's picture
let there be light
57303cc unverified
Raw
History Blame Contribute Delete
3.54 kB
"""
schemas.py — Pydantic v2 request/response schemas.
"""
import json
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field, field_validator
# ---------------------------------------------------------------------------
# Client
# ---------------------------------------------------------------------------
class ClientCreate(BaseModel):
name: str
archetype: str = Field(..., pattern="^(consulting|startup)$")
expectations: str = ""
min_communication: int = Field(3, ge=1, le=5)
min_adaptability: int = Field(3, ge=1, le=5)
min_collaboration: int = Field(3, ge=1, le=5)
min_problem_solving: int = Field(3, ge=1, le=5)
min_leadership: int = Field(3, ge=1, le=5)
class ClientResponse(BaseModel):
model_config = {"from_attributes": True}
id: int
name: str
archetype: str
expectations: str
min_communication: int
min_adaptability: int
min_collaboration: int
min_problem_solving: int
min_leadership: int
created_at: datetime
# ---------------------------------------------------------------------------
# Candidate
# ---------------------------------------------------------------------------
class CandidateCreate(BaseModel):
name: str
email: str = ""
recruiter_notes: str = ""
client_id: int
class ScoreResponse(BaseModel):
model_config = {"from_attributes": True}
id: int
candidate_id: int
communication: int
adaptability: int
collaboration: int
problem_solving: int
leadership: int
overall_match: float
mismatches: list[str] = []
@field_validator("mismatches", mode="before")
@classmethod
def parse_mismatches(cls, v):
if isinstance(v, str):
return json.loads(v)
return v
class FeedbackResponse(BaseModel):
model_config = {"from_attributes": True}
id: int
candidate_id: int
outcome: str
primary_reason: str
client_notes: str
created_at: datetime
class CandidateResponse(BaseModel):
model_config = {"from_attributes": True}
id: int
name: str
email: str
recruiter_notes: str
client_id: int
created_at: datetime
score: Optional[ScoreResponse] = None
feedback: Optional[FeedbackResponse] = None
# ---------------------------------------------------------------------------
# Score
# ---------------------------------------------------------------------------
class ScoreCreate(BaseModel):
communication: int = Field(..., ge=1, le=5)
adaptability: int = Field(..., ge=1, le=5)
collaboration: int = Field(..., ge=1, le=5)
problem_solving: int = Field(..., ge=1, le=5)
leadership: int = Field(..., ge=1, le=5)
# ---------------------------------------------------------------------------
# Feedback
# ---------------------------------------------------------------------------
class FeedbackCreate(BaseModel):
outcome: str = Field(..., pattern="^(accepted|rejected)$")
primary_reason: str = Field(
...,
pattern="^(communication_soft_skills|technical_capability|alignment_cultural_vibe|candidate_declined)$",
)
client_notes: str = ""
# ---------------------------------------------------------------------------
# Stats
# ---------------------------------------------------------------------------
class StatsResponse(BaseModel):
total_candidates: int
total_with_feedback: int
accepted_count: int
rejected_count: int
acceptance_rate: float
feedback_compliance_rate: float