This project is a high-fidelity Healthcare Professional (HCP) Customer Relationship Management (CRM) module focused on the "Log Interaction" screen, built as a professional hiring assignment submission.
It provides a dual-input CRM interface where representatives can log, view, and edit visits manually through a Structured Form (left pane) or conversationally through an AI Assistant Chat Interface (right pane). The form and chat share state in real-time (via Redux Toolkit). When the assistant executes tools, it updates the database and synchronizes the form dynamically.
- Frontend: React + Vite + TypeScript, Redux Toolkit, Axios, Lucide Icons
- Styling: Modern Vanilla CSS, Google Inter Font, Responsive split grid layout
- Backend: Python 3.12+ with FastAPI, SQLAlchemy ORM
- Agent Framework: LangGraph Python, LangChain Core
- LLM Integration: Groq Cloud API (Configurable via environment variables)
- Database: PostgreSQL (SQLAlchemy models and transactions)
- Testing: PyTest for transactional databases (using in-memory SQLite for isolation)
Below is a map of the repository's primary source files. Click any link to open the file directly:
- main.py — Main FastAPI routes and application entry point.
- models.py — SQLAlchemy ORM schema declarations (e.g. HCP, Interaction).
- database.py — PostgreSQL engine and session providers.
- crud.py — Database transactional operations (e.g. log_interaction_transactional).
- schemas.py — Pydantic request/response validation schemas.
- graph.py — LangGraph state chart definition and agent runner execute_agent.
- tools.py — Concrete LangGraph tool configurations and implementations.
- prompts.py — System and Generator instructions for the LLM.
- seed.py — Script to initialize the PostgreSQL database and seed sample HCPs, stock levels, and historical interactions.
- test_backend.py — PyTest suite that executes transactional tests against SQLite memory space.
- App.tsx — Main dashboard template and pane layout.
- InteractionForm.tsx — Structured manual log/edit panel.
- ChatPanel.tsx — Conversational AI interface and tool invocation tracer.
- HCPContextPanel.tsx — Profile card panel detailing specialty, clinic, preferences, and histories.
- InventoryPanel.tsx — Live inventory tracker reflecting stock deductions dynamically.
- interactionSlice.ts — Redux State slice managing active interaction, forms, chat history, and metadata.
The AI assistant is built as a bounded deterministic graph using LangGraph to ensure maximum reliability and speed:
graph TD
Start([User Query]) --> Router{LLM Router Node}
Router -->|log_interaction| Log[Log Interaction Tool Node]
Router -->|edit_interaction| Edit[Edit Interaction Tool Node]
Router -->|get_hcp_context| Context[Get HCP Context Tool Node]
Router -->|search_interactions| Search[Search Interactions Tool Node]
Router -->|suggest_follow_up| Suggest[Suggest Follow-up Tool Node]
Router -->|manage_samples_and_materials| Inventory[Inventory Tool Node]
Router -->|direct_response| Generator[Response Generator Node]
Log --> Generator
Edit --> Generator
Context --> Generator
Search --> Generator
Suggest --> Generator
Inventory --> Generator
Generator --> End([Final Response + Form Sync JSON])
- Router Node: Analyzes intent and parses user input using the Groq LLM. If database mutations or queries are requested, it binds and calls the corresponding tool. If no tools are required, it routes to a direct response generator node.
- Transactional Tool Nodes: Catch execution states, run SQLAlchemy mutations, update inventory stock, and return structured output payloads.
- Response Generator Node: Formulates a user-friendly conversational summary of what the agent performed.
If the Groq API key is missing or the API call fails, the backend automatically falls back to an offline rule-based parser engine that runs the exact same transactional tools against the database. This guarantees a 100% crash-proof demo even when offline or without an active API key.
The backend agent defines six discrete tools in tools.py:
- log_interaction_tool: Extracts HCP name, products discussed, brochures shared, sentiment, and sample packs to save a new record. Transactionally rolls back on stock check failures.
- edit_interaction_tool: Modifies whitelisted fields (
topics_discussed,observed_sentiment,outcomes,follow_up_actions) on the active interaction. - get_hcp_context_tool: Retrieves specialty, clinic details, last 3 interactions, preferred products, and pending follow-ups for a doctor.
- search_interactions_tool: Searches meeting logs by keyword or doctor name.
- suggest_follow_up_tool: Analyzes meeting topics and generates actionable next steps (e.g. follow-up emails, advisory nominations).
- manage_samples_and_materials_tool: Lists active inventory stock levels.
- Node.js (v18+)
- Python (v3.12+)
- PostgreSQL running locally
- Open a terminal and copy the
.envconfiguration template:cp backend/.env.example backend/.env
- Configure your environment credentials in
backend/.env. Note that on this machine, PostgreSQL is configured on port9571with the password (the defaultDATABASE_URLis set accordingly). - Activate the virtual environment and initialize the database (creates tables, drops old, and seeds records):
# Create virtualenv and install requirements (if not done) uv venv backend/.venv uv pip install -r backend/requirements.txt # Run the seed script backend/.venv/Scripts/python.exe backend/seed.py
Start the FastAPI server on port 8000:
cd backend
.venv/Scripts/uvicorn app.main:app --reloadYou can verify the Swagger UI at http://localhost:8000/docs and the health check at http://localhost:8000/api/health.
Start the React Vite server:
cd frontend
npm install
npm run devOpen your browser at http://localhost:5173/ to interact with the dashboard.
We have created focused backend tests utilizing a temporary, isolated SQLite in-memory database to verify mutations without corrupting your active PostgreSQL instance.
To run the test suite:
cd backend
.venv/Scripts/pytest tests/test_backend.pyTests assert:
- Successful transactional interaction logging.
- Whitelisted interactive editing.
- Sample stock deduction.
- Reversion and prevention of negative sample stock.
To demonstrate the high-fidelity features of the application, follow these scenarios:
- Action: Click on the Log Meeting chip under the chat window (or type: "Met Dr. Sarah Jenkins today. We discussed OncoBoost 50mg. She was positive. Shared OncoBoost Phase III Trial Report and gave 3 samples. Follow up in two weeks.")
- Visual Sync: Notice the left-side form automatically fills with Dr. Sarah Jenkins, OncoBoost 50mg, OncoBoost Report, 3 samples, and the follow-up text. The sample inventory panel dynamically decreases the stock of OncoBoost from 50 to 47.
- Tracer: Expand the
⚙️ log_interactionbadge in the chat window to view the parsed JSON arguments.
- Action: Click on Change Sentiment (or type: "Actually, change the sentiment to neutral and follow up next Thursday.")
- Visual Sync: The sentiment radio button instantly shifts to Neutral, and the follow-up textarea updates.
- Tracer: Expand the
⚙️ edit_interactionbadge in the chat window to verify that only whitelisted fields were modified.
- Action: Click on Check Profile or Check Stocks to query history or print stock lists without mutating tables.
- Visual Sync: Renders the context profile card for the target HCP or returns the current stock inventory values.