Files
step-parse/backend/app/models.py
T
Jason Stedwell b3c3e2a3b2 Phase 1: FastAPI backend with async job model
- 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>
2026-06-17 16:38:26 -05:00

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)