An AI-powered quality-management copilot that turns free-text complaints, emails, and PDF reports into structured, risk-assessed pharmaceutical QMS records.
QMS Copilot helps quality teams in pharmaceutical manufacturing (API & FDF) log customer complaints conversationally, extract complaint data from documents, assess risk automatically, and commit clean records to a ledger with a full audit trail—all from one full-stack web application.
Logging a customer complaint in a pharmaceutical QMS usually means reading a long email or PDF, re-typing product and batch details into a form, and manually judging severity and next actions. QMS Copilot brings those steps together in one workflow: describe the complaint in plain language (or drop in the document), and the AI fills the form, reasons about risk, and keeps everything editable through conversation. The form is never filled manually—every field flows through the AI assistant.
- Conversational complaint logging — describe a complaint in natural language and the agent extracts product, strength, batch, quantities, dates, category, and description into the form.
- AI risk assessment — the agent reasons like a QA reviewer to suggest severity, next action (e.g. "Route to QA Investigation & Issue Replacement"), and an initial GMP-oriented risk rationale.
- Natural-language editing — corrections like "sorry, the batch number is BMX24602 and the affected quantity is 48 capsules" update only the mentioned fields and preserve everything else.
- Document extraction — upload or drag-drop a complaint PDF or email; the agent extracts the record and remains editable by chat afterwards.
- Deterministic source detection — the complaint source (Manual Complaint, Email, Phone, PDF Document) is derived from how the complaint arrived, never guessed by the LLM.
- AI analysis suite — one click runs a completeness checker, duplicate-complaint detection against the ledger, root-cause recommendations, CAPA (corrective/preventive) suggestions, an executive summary, and an AI risk classification.
- Append-only audit trail — every AI action and ledger commit writes a who/what/when row (21 CFR Part 11-style structure), visible in a collapsible timeline panel.
- Resilient AI integration — strict JSON-only prompting with defensive parsing, plus an automatic fallback chain across live Groq models when a configured model is decommissioned.
| Area | Technologies |
|---|---|
| Frontend | React 18, Redux Toolkit, Vite, Google Inter font |
| Backend | Python, FastAPI, SQLAlchemy, Pydantic |
| AI agent | LangGraph (router + tool graphs), Groq llama-3.3-70b-versatile with automatic model fallback |
| Documents | pypdf text extraction, ReportLab-generated sample documents |
| Data | PostgreSQL (docker-compose provided); SQLite fallback for zero-setup development |
flowchart LR
B["Browser (React + Redux)"] --> F["FastAPI"]
F --> A["LangGraph agent"]
A -->|"router → log / edit"| G["Groq LLM"]
A -->|"extract"| G
A -->|"completeness → duplicates → analysis"| G
F --> P[("PostgreSQL")]
A typed chat message enters the chat graph, where a router node decides between the log and edit tools (an empty form short-circuits to log without an LLM call). Uploaded documents enter the extract graph. The analysis graph runs two deterministic checks (completeness, duplicates) and feeds their findings into a single LLM analysis call. Every tool returns strict JSON that is validated, merged over the current form server-side (so edits never wipe untouched fields), and pushed into Redux, where changed fields flash green.
| Conversational complaint logging | AI analysis suite |
|---|---|
| Complaint logged through the copilot chat, with the form and risk assessment populated | AI analysis output showing completeness, duplicate detection, root causes, and CAPA suggestions |
Append-only audit trail timeline after a ledger commit
- Python 3.10 or later
- Node.js 18 or later
- A free Groq API key from console.groq.com/keys
- Optional: Docker Desktop for the PostgreSQL database (SQLite fallback available)
git clone https://github.com/KrishnaSharma6650/QMS-Copilot.git cd QMS-Copilot docker compose up -d # PostgreSQL 16 on :5432 (skip to use SQLite)
Backend (terminal 1):
cd backend python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt cp .env.example .env # add your GROQ_API_KEY uvicorn app.main:app --reload --port 8000
Frontend (terminal 2):
cd frontend
npm install
npm run devOpen http://localhost:5173. The Vite dev server proxies /api to the backend on port 8000. Verify the backend at http://localhost:8000/api/health and explore the API at http://localhost:8000/docs.
- Type:
Apollo Pharmacy reported discolored capsules in Amoxicillin Capsules 500 mg. Batch number AMX240602. Manufacturing date March 2026. Expiry date February 2028. Please log this complaint— the form and risk assessment populate. - Type:
sorry, the batch number is BMX24602 and the affected quantity is 48 capsules— only those two fields update. - Attach
sample_docs/sample_complaint_zenith.pdfand press send — the document is extracted into the form. - Click 🧠 Run AI Analysis — completeness, duplicates, root causes, CAPA, summary, and risk classification appear.
- Click Commit to QMS Ledger — the record persists with an auto-generated
CC-YYYY-NNNNNnumber, and the audit trail shows the full timeline.
All supported configuration is documented in backend/.env.example. Never commit a real .env file.
| Variable | Required | Purpose |
|---|---|---|
GROQ_API_KEY |
Yes | Enables all AI features (extraction, editing, risk assessment, analysis). |
GROQ_MODEL |
No | Groq model to use; defaults to llama-3.3-70b-versatile with automatic fallback to other live models. |
DATABASE_URL |
No | SQLAlchemy URL; defaults to the docker-compose PostgreSQL, with a SQLite fallback line provided. |
FRONTEND_ORIGIN |
No | CORS origin for the dev frontend (default http://localhost:5173). |
| Endpoint | Purpose |
|---|---|
POST /api/chat |
Log or edit a complaint from a natural-language message |
POST /api/extract |
Extract a complaint from an uploaded PDF/email |
POST /api/analyze |
Completeness, duplicates, root causes, CAPA, summary, risk classification |
POST /api/commit |
Persist the complaint to the QMS ledger |
GET /api/complaints |
List committed complaints |
GET /api/audit |
Append-only audit trail, newest first |
GET /api/health |
Config and model status check |
QMS-Copilot/
├── backend/
│ └── app/
│ ├── main.py # FastAPI endpoints
│ ├── agent.py # LangGraph graphs (chat router, extract, analysis)
│ ├── tools.py # Log / edit / extract tools
│ ├── analysis_tools.py # Completeness, duplicates, LLM analysis
│ ├── prompts.py # System prompts + shared field schema
│ ├── llm.py # Groq client, JSON parsing, model fallback
│ ├── source.py # Deterministic complaint-source detection
│ ├── models.py # Complaint + append-only AuditEvent tables
│ ├── crud.py # Ledger persistence + audit logging
│ └── schemas.py # Pydantic contracts shared by AI, API, UI
├── frontend/
│ └── src/
│ ├── components/ # Complaint form, copilot chat, analysis, audit
│ ├── store/ # Redux slices (complaint, chat, audit)
│ └── services/ # API client
├── sample_docs/ # Realistic sample complaint PDF + email
├── docker-compose.yml # PostgreSQL 16
└── backend/.env.example # Safe configuration template
.env, virtual environments, local databases, and dependencies are excluded through.gitignore.- Real API keys must never be committed; configure them through environment variables.
- The audit trail is append-only with server-set timestamps; the actor is
"system"until authentication is added, and the schema is structurally ready to bind events to authenticated users. - Sample complaint documents use fictional companies and data.
- Never lose data — the edit tool merges LLM output over the current form server-side, and the Redux reducer ignores empty values: two layers of protection against a model dropping fields.
- Deterministic where it matters — routing shortcuts, complaint-source detection, completeness checking, and duplicate detection are all rule-based; the LLM is reserved for judgment tasks.
- JSON robustness — LLMs occasionally wrap output in code fences; the parser strips fences and locates the outermost
{...}block. - Production-grade OCR is intentionally out of scope;
pypdfcovers text-based PDFs.
- Authentication with unique users, role-based access control, and e-signatures bound to audit events (21 CFR Part 11).
- A complaints list view with search and status workflow (open → investigation → CAPA → closed).
- OCR support for scanned complaint documents.
- Automated tests and CI checks.
- Containerised deployment with HTTPS.
- Krishna Sharma — architecture, full-stack development, AI agent design, and documentation.
Released under the MIT License.