forma-3d-review-api / src /api /schemas.py
lomit's picture
Sync from forma-3d-review@b6d4687f5d0f2e5303758c97095ea7e38e740723
182efca verified
"""Pydantic request/response models for the CAD review API."""
from __future__ import annotations
from pydantic import BaseModel, Field
# --- Request models ---
class DistanceRequest(BaseModel):
"""Request to measure distance between two parts."""
part_a_id: str
part_b_id: str
# --- Response models ---
class UploadResponse(BaseModel):
job_id: str
status: str
exterior_filename: str
interior_filename: str
class SampleFileResponse(BaseModel):
filename: str
size: int
class SamplePairResponse(BaseModel):
id: str
name: str
exterior: SampleFileResponse
interior: SampleFileResponse
class StepProgress(BaseModel):
step: str
status: str # pending, running, completed
progress_pct: int = 0
class JobStatus(BaseModel):
job_id: str
status: str # pending, running, completed, failed
steps: list[StepProgress] = []
error: str | None = None
# Rebuild to resolve forward reference
JobStatus.model_rebuild()
class AssemblyNodeResponse(BaseModel):
id: str
name: str
is_assembly: bool
is_leaf: bool
classification: str = "unknown"
num_faces: int = 0
num_solids: int = 0
bounding_box: dict | None = None
children: list[AssemblyNodeResponse] = []
AssemblyNodeResponse.model_rebuild()
class GroupInfoResponse(BaseModel):
name: str # "exterior" or "interior"
part_count: int
part_ids: list[str]
part_names: list[str]
class AssemblyTreeResponse(BaseModel):
root: AssemblyNodeResponse
groups: list[GroupInfoResponse] = []
class ProximityPairResponse(BaseModel):
part_a_id: str
part_a_name: str
part_b_id: str
part_b_name: str
min_distance_mm: float
point_a: list[float]
point_b: list[float]
status: str # collision, near, ok
class ProximityResponse(BaseModel):
pairs: list[ProximityPairResponse]
collision_count: int
near_count: int
class DistanceMeasurementResponse(BaseModel):
distance_mm: float
point_a: list[float]
point_b: list[float]
class ComplianceResultResponse(BaseModel):
rule_id: str
rule_name: str
passed: bool
severity: str
measured_value: float | None = None
threshold_value: float | None = None
unit: str = "mm"
message: str = ""
affected_parts: list[str] = []
class ComplianceRuleResponse(BaseModel):
id: str
name: str
description: str
type: str
severity: str
class ComplianceResponse(BaseModel):
results: list[ComplianceResultResponse]
pass_count: int
fail_count: int
class SSEEvent(BaseModel):
step: str
status: str
progress_pct: int = 0
overall_status: str | None = None
error: str | None = None