Ship Sprint 0 CAD foundations so findings, KiCad hierarchy, BOM match, eval, and optional PCB ingest have a stable contract.

Extend Finding with rule_id/net/pins, flatten multi-sheet .kicad_sch, flag MPN mismatches, score simple_project, and parse .kicad_pcb without running layout DRC.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-10 21:54:37 +02:00
co-authored by Cursor
parent d31c04ba86
commit e4fd6c3849
29 changed files with 1995 additions and 46 deletions
+11
View File
@@ -5,6 +5,7 @@ Each project lives at users/{user_id}/projects/{id}/ with:
uploads/bom.csv — uploaded BOM
uploads/netlist.asc — uploaded netlist
uploads/datasheets/*.pdf — uploaded datasheets
uploads/pcb.kicad_pcb — optional KiCad board (layout checks)
extracted/ — IC extraction output
patterns/ — passive patterns
models/ — cached component specs
@@ -82,6 +83,7 @@ class ProjectMeta(BaseModel):
updated: str = ""
has_bom: bool = False
has_netlist: bool = False
has_pcb: bool = False
# "pads" | "edif" | None — None for legacy projects (pre-EDIF-support).
# Legacy reads fall back to looking for netlist.asc on disk.
netlist_format: str | None = None
@@ -658,6 +660,15 @@ def save_netlist(
return key
def save_pcb(
storage: StorageBackend, user_id: str, project_id: str, data: bytes
) -> str:
key = f"{_project_prefix(user_id, project_id)}/uploads/pcb.kicad_pcb"
storage.write_bytes(key, data)
update_project(storage, user_id, project_id, has_pcb=True)
return key
def save_datasheet(
storage: StorageBackend, user_id: str, project_id: str, mpn: str, data: bytes
) -> str: