Product
id, name, customer_ref, active
Technical concept
A modular monolith that runs on a Windows CPU, offline, next to the line. It writes nothing to the PLC in V1 and never auto-passes an image it cannot trust.
System context
FACTORY NETWORK — NO PLC WRITES IN V1
01
USB / industrial camera
Fixed mount, controlled light
02
Capture & quality check
Exposure, focus, brightness band
03
Registration / alignment
Fixture fiducials, pose correction
04
Recipe-based feature checks
OpenCV baseline · later anomaly-detection research track
05
Decision engine
PASS / FAIL / REVIEW
06
Evidence store
Local images + SHA-256 hashes · SQLite → PostgreSQL
07
Operator dashboard (React)
Human review, append-only
08
Reports / CSV
Evaluation & audit exports
Flow reads left→right, top→bottom
Stack
| Frontend | React + TypeScript + Vite |
|---|---|
| Backend | Python FastAPI, versioned under /api/v1 |
| Database | SQLite (dev) → PostgreSQL |
| Vision | OpenCV + NumPy; later PyTorch / anomaly methods (e.g. PatchCore-style) as research |
| Runtime | Windows, CPU-only, offline |
id, name, customer_ref, active
id, product_id, version, checks[] (JSON), created_by, created_at
id, source_type SYNTHETIC | LAB_PHOTO | CUSTOMER_AUTHORISED, sha256, provenance, captured_at
immutable · image_id, recipe/model version, decision, evidence, timestamp
append-only · result_id, reviewer, decision, comment, timestamp
actor, action, entity, payload hash, timestamp
Recipe
{
"id": "housing-A",
"version": "1.2.0",
"product": "Synthetic plastic housing (demo)",
"review_margin": 0.15,
"checks": [
{
"id": "top_clip",
"description": "Teal retaining clip seated in upper socket",
"roi": {
"x0": 184,
"y0": 139,
"x1": 306,
"y1": 177
},
"hsv": {
"hRanges": [
[
160,
190
]
],
"sMin": 0.27,
"vMin": 0.24
},
"mode": "present",
"threshold": 0.4
},
{
"id": "lower_clip",
"description": "Teal retaining clip seated in lower socket",
"roi": {
"x0": 184,
"y0": 249,
"x1": 306,
"y1": 288
},
"hsv": {
"hRanges": [
[
160,
190
]
],
"sMin": 0.27,
"vMin": 0.24
},
"mode": "present",
"threshold": 0.37
}
]
}API
def decide_inspection(capture_quality, registration, feature_checks, policy):
if not capture_quality.ok or not registration.ok:
return Decision.REVIEW, [class="s">'Image unsuitable for reliable inspection']
if any(check.status == class="s">'FAIL' for check in feature_checks):
return Decision.FAIL, failed_check_reasons(feature_checks)
if any(check.status in (class="s">'UNKNOWN', class="s">'UNCERTAIN') for check in feature_checks):
return Decision.REVIEW, uncertain_check_reasons(feature_checks)
if not feature_checks:
return Decision.REVIEW, [class="s">'No enabled checks in recipe']
return Decision.PASS, [class="s">'All configured visible feature checks passed']Engineering rules
Plan
Security & privacy
Avoid capturing people; document any personal data processing.
Images belong to the customer; usage defined in a data-rights agreement.
Evidence stored on-premises with SHA-256 integrity hashes.
Configurable retention with verifiable deletion.
Operator, quality manager, administrator — least privilege.