b3c3e2a3b2
- backend/app: FastAPI API wrapping the CAD skill modules - upload -> job -> poll -> model / BOM / artifacts -> geometry query - SQLite via SQLModel (Model, Job, BomRow, QueryLog) - ThreadPoolExecutor worker, serialized, with live stage updates - docker-compose.yml: dev server (mounts source, --reload) on :8000 - api-test.sh: end-to-end live validation script - requirements.txt: add fastapi, uvicorn, python-multipart, sqlmodel - external_diagram.py: port active-area detection OCC.Core -> OCP - .gitignore, PHASE1.md Validated live: MR16 round-trip passes (28 BOM rows, 12 artifacts, bounding-box query, xlsx download; active-area detection working). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
65 lines
2.3 KiB
Python
65 lines
2.3 KiB
Python
"""SQLModel tables: Model, Job, BomRow, QueryLog."""
|
|
from datetime import datetime, timezone
|
|
from typing import Optional
|
|
|
|
from sqlmodel import Field, SQLModel
|
|
|
|
|
|
def utcnow() -> datetime:
|
|
return datetime.now(timezone.utc)
|
|
|
|
|
|
class Model(SQLModel, table=True):
|
|
"""One uploaded STEP file and its extracted metadata."""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
name: str
|
|
original_filename: str
|
|
stem: str
|
|
backend: Optional[str] = None # "build123d" | "freecad"
|
|
face_count: Optional[int] = None
|
|
part_count: Optional[int] = None
|
|
bbox_x_mm: Optional[float] = None
|
|
bbox_y_mm: Optional[float] = None
|
|
bbox_z_mm: Optional[float] = None
|
|
has_chinese: bool = False
|
|
created_at: datetime = Field(default_factory=utcnow)
|
|
|
|
|
|
class Job(SQLModel, table=True):
|
|
"""A processing run for a model. Status: pending|running|done|error."""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
model_id: int = Field(foreign_key="model.id", index=True)
|
|
status: str = Field(default="pending", index=True)
|
|
stage: Optional[str] = None # current pipeline stage
|
|
error: Optional[str] = None
|
|
artifacts: Optional[str] = None # JSON list of relative filenames
|
|
options: Optional[str] = None # JSON of the request options
|
|
created_at: datetime = Field(default_factory=utcnow)
|
|
started_at: Optional[datetime] = None
|
|
finished_at: Optional[datetime] = None
|
|
|
|
|
|
class BomRow(SQLModel, table=True):
|
|
"""One BOM line for a model."""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
model_id: int = Field(foreign_key="model.id", index=True)
|
|
part_number: Optional[str] = None
|
|
part_name_original: Optional[str] = None
|
|
part_name_english: Optional[str] = None
|
|
quantity: Optional[int] = None
|
|
level: Optional[int] = None
|
|
parent: Optional[str] = None
|
|
bbox_x_mm: Optional[float] = None
|
|
bbox_y_mm: Optional[float] = None
|
|
bbox_z_mm: Optional[float] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
class QueryLog(SQLModel, table=True):
|
|
"""A natural-language geometry query and its result."""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
model_id: int = Field(foreign_key="model.id", index=True)
|
|
query: str
|
|
result: Optional[str] = None
|
|
created_at: datetime = Field(default_factory=utcnow)
|