An asynchronous, multi-tenant diagnostic microservice that turns raw manufacturing fault telemetry into AI-generated Root Cause Analysis reports — combining structured machine history (PostgreSQL) with retrieval-augmented technical documentation search (ChromaDB) and LLM synthesis (Gemini 3.5 Flash).
- Ingestion & Decoupling — a factory machine's error is POSTed to
the API, which writes it to Postgres, returns an immediate
202 Acceptedwith a tracking ticket, and hands off to a background task. - Context-Aware Investigation — the background worker pulls the machine's fault history from Postgres and performs a metadata-scoped vector search against technical manuals in ChromaDB.
- AI Synthesis — the combined context (structured history + unstructured docs) is sent to Gemini 3.5 Flash, which generates a multi-step preliminary RCA report, written back to the database.
flowchart TD
A["Factory Equipment / Client"] -->|"HTTP POST payload + tenant_id"| B["FastAPI Gateway"]
B -->|"Immediate HTTP 202"| A
B -->|"BackgroundTask"| C["Background Worker"]
C -->|"SQL History"| D[("PostgreSQL")]
C -->|"RAG Query"| E[("ChromaDB")]
D --> F["Gemini 3.5 Flash"]
E --> F
F --> G["Update Postgres — status: Completed"]
| Layer | Technology |
|---|---|
| API | FastAPI (async), Python 3.12 |
| Relational DB | PostgreSQL 16 (Docker) |
| Vector DB | ChromaDB (embedded, in-process, local persistent storage) |
| LLM | Google Gemini 3.5 Flash (Google AI Studio) |
| Multi-tenancy | Every SQL and vector query is scoped by tenant_id |
The seeded demo data spans two manufacturing system categories, backed by two independent technical manuals in the RAG knowledge base:
- Injection molding — hydraulic/barrel temperature exceedance faults
- CNC calibration — axis positional drift faults
This demonstrates that the architecture generalizes across fault domains rather than being hardcoded to a single machine type.
git clone <your-repo-url>
cd TraceFlow
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# fill in POSTGRES_PASSWORD and GEMINI_API_KEY in .env
docker-compose up -d
python src/scripts/seed_manuals.py
PYTHONPATH=src uvicorn app.main:app --reload --port 8000Populate the database with realistic demo incidents (runs against the live API and the real RAG/LLM pipeline — not mock data):
python src/scripts/seed_demo_incidents.pyAPI docs available at http://localhost:8000/docs.
POST /api/v1/incidents
{
"tenant_id": "tenant_toyota_aichi",
"machine_id": "MOLD_IM_402",
"error_code": "TEMP_EXCEED_E045",
"description": "Hydraulic clamp temperature spiked to 92C during continuous injection cycle.",
"system_category": "injection_molding"
}Immediate response (202 Accepted):
{
"ticket_id": "c877846f-0676-4432-94b8-ba438fa1e509",
"status": "Queued",
"message": "Incident logged successfully. Asynchronous root cause analysis initiated."
}GET /api/v1/incidents/{ticket_id}?tenant_id=tenant_toyota_aichi
Once the background pipeline completes, the same ticket returns:
{
"ticket_id": "c877846f-0676-4432-94b8-ba438fa1e509",
"tenant_id": "tenant_toyota_aichi",
"machine_id": "MOLD_IM_402",
"error_code": "TEMP_EXCEED_E045",
"system_category": "injection_molding",
"status": "Completed",
"created_at": "2026-07-12T00:00:00Z",
"rca_report": "# Preliminary Root Cause Analysis (RCA)\n\n**To:** Maintenance Supervisor / Reliability Team\n**From:** Junior Reliability Engineer\n**Subject:** Preliminary RCA — Recurring Hydraulic Temperature Exceedance\n\n... (full markdown report continues with Observations, Documentation Match, and Action Items sections)"
}A second, structurally identical example from the CNC category (ticket
1e0eaae4-391e-4f07-bed2-d5992073d9ab) confirms the same pipeline
correctly retrieves CNC-specific manual context rather than defaulting
to the injection molding manual.
TraceFlow/
├── docs/ # local AI-context files, gitignored
├── manuals/ # source docs for RAG ingestion
├── src/
│ └── app/
│ ├── main.py
│ ├── api/ # endpoints.py, schemas.py
│ ├── core/ # config.py
│ ├── db/ # models.py, session.py
│ └── services/ # rag_service.py, llm_service.py, pipeline_service.py
├── scripts/ # seed_manuals.py, seed_demo_incidents.py
├── tests/
├── docker-compose.yml
├── requirements.txt
└── Dockerfile
A minimal React + Vite frontend lives in /frontend. It's a thin
demonstration client for the API above — no new endpoints, no backend
changes.
What it does:
- Submit a new incident via a form (tenant, machine, system category, error code, description)
- Show the immediate
Queuedresponse - Poll the status endpoint every 2s until the analysis completes
- Render the generated RCA markdown report
Run it:
cd frontend
npm install
npm run devThen open http://localhost:5173 (make sure the backend is running on :8000 first).
Note on CORS: the frontend talks to the backend through Vite's dev-server
proxy (/api → http://localhost:8000), configured in vite.config.js.
This means the browser only ever calls the Vite origin — no CORSMiddleware
or other change was needed on the FastAPI side.