# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What This Is NestJS backend for the PalmOilAI system. Provides server-side YOLOv8 ONNX inference, SQLite history persistence, WebSocket gateways for real-time vision streaming and chat proxying, and a process surveillance monitor for n8n and Ollama. Detection classes: `Ripe`, `Unripe`, `Underripe`, `Overripe`, `Abnormal`, `Empty_Bunch` (MPOB standard). ## Commands ```bash npm install npm run start:dev # Watch mode dev server (port 3000) npm run start # Single-run dev server npm run start:prod # Production (from dist/) npm run build # Compile → dist/ npm run lint # ESLint with auto-fix npm run test # Jest unit tests npm run test:watch # Jest watch mode npm run test:cov # Coverage report npm run test:e2e # End-to-end tests jest --testPathPattern=palm-oil # Run a single test file ``` Set `PORT` env var to override the default port 3000. Set `N8N_WEBHOOK_URL` in `.env` for chat proxy and agent readiness probing. ## Architecture ### Modules **`PalmOilModule`** (`src/palm-oil/`) — Core feature module: - `ScannerProvider` — ONNX inference pipeline: `sharp` resizes to 640×640, strips alpha, transposes HWC→CHW, normalizes to `[0.0, 1.0]`, feeds `[1, 3, 640, 640]` tensor to `onnxruntime-node`. Output is `[1, N, 6]` (`x1, y1, x2, y2, confidence, class_index`), filtered at 0.25 confidence by default. - `PalmOilService` — Orchestrates inference + SQLite persistence. `analyzeImage()` is the main entry point; it fully awaits the `historyRepository.save()` before returning (intentional blocking — guarantees DB write before socket emit). - `VisionGateway` — WebSocket gateway on `/vision` namespace. Handles `vision:analyze` (Base64 image → ONNX inference → `vision:result`) and `chat:send` (proxies to n8n webhook → `chat:result`). Receives raw, uncompressed Base64 strings only — no binary frames, no WebRTC. - `HistoryEntity` — TypeORM entity; fields: `archive_id`, `filename`, `total_count`, `industrial_summary` (JSON), `detections` (JSON), `inference_ms`, `processing_ms`, `created_at`. - `mpob-standards.ts` — Source of truth for class names, grade colors, and health alert flag list (`Abnormal`, `Empty_Bunch`). **`SurveillanceModule`** (`src/surveillance/`) — Process monitoring module: - `SurveillanceService` — Boots on `OnModuleInit`. Discovers PIDs for n8n (Node.js process containing "n8n" in cmd, port 5678 must be accepting TCP connections) and Ollama (`ollama_llama_server` or `ollama`). Polls every 500ms via `pidusage`. Probes `N8N_WEBHOOK_URL` every 10s to determine agent readiness. PIDs are evicted if the process dies or n8n's port goes silent. - `SurveillanceGateway` — WebSocket gateway on `/monitor` namespace. Broadcasts `monitor:data` (CPU/memory metrics) on every 500ms tick and `monitor:status` (n8n webhook ready/not ready) when status changes. Pushes an immediate snapshot on client connect. ### Database SQLite file `palm_history.db` in the project root. Managed by TypeORM with `synchronize: true` (auto-creates tables — dev only). No external DB setup required. ### Required File `best.onnx` must be placed in the **project root directory** (not `src/`). This is the YOLOv8 ONNX model loaded by `ScannerProvider` at inference time. ### WebSocket Event Contracts | Namespace | Client → Server | Server → Client | |---|---|---| | `/vision` | `vision:analyze` `{ frame: string, sourceLabel?: string }` | `vision:result`, `vision:error` | | `/vision` | `chat:send` `{ message: string }` | `chat:result`, `chat:error` | | `/monitor` | `monitor:subscribe` | `monitor:data` (MonitorPayload[]), `monitor:status` |