Talk to a patient. Take a history. Get scored. Repeat.
Medical students in Iran must pass a national clinical competency exam called آزمون صلاحیت بالینی before graduation. One major component is the OSCE — where students interact with standardized patients at timed stations.
This tool simulates that experience:
- 🤖 An AI plays the patient — in natural conversational Persian
- 📋 The student takes a history — just like the real exam
- ✅ Performance is automatically scored — against the official checklist from the exam textbook
| Feature | Status |
|---|---|
| 🎭 AI patient simulation | ✅ |
| 🏥 10 clinical stations | ✅ |
| 📊 Checklist-based scoring (20 pts) | ✅ |
| ⏱️ 10-minute countdown timer | ✅ |
| 📝 Per-item feedback in Persian | ✅ |
| 📱 Mobile-first UI | ✅ |
| 🌐 Persian RTL interface | ✅ |
| # | Station | Department | Type |
|---|---|---|---|
| 1 | 🫀 Chest Pain History | Cardiology | ضروری |
| 2 | 🧠 Suicide Risk Assessment | Psychiatry | ضروری |
| 3 | 💊 Headache History | Neurology | مفید |
| 4 | 😔 Depression History | Psychiatry | مفید |
| 5 | 🩺 Hematuria History | Urology | ضروری |
| 6 | 🤢 Nausea & Vomiting History | Internal Medicine | مفید |
| 7 | 🟡 Jaundice History | Internal Medicine | مفید |
| 8 | 🔬 Generalized Lymphadenopathy | Internal Medicine | مفید |
| 9 | ⚡ Mania History | Psychiatry | مفید |
| 10 | 🚨 Fever & Urinary Retention | Urology | ضروری |
All checklists verified at exactly 20 points each, based on the official صلاحیت بالینی textbook (Farvardin 1405).
| Layer | Tech |
|---|---|
| 🐍 Backend | Python 3.11 + FastAPI |
| 🎨 Frontend | HTML / CSS / JavaScript (Persian RTL) |
| 🤖 AI | OpenAI GPT-4o-mini |
| 📁 Cases | JSON files — no code changes needed to add stations |
osce-tutor/
├── 🐍 main.py — FastAPI backend (3 endpoints)
├── 📋 requirements.txt
├── 🚀 Procfile
├── 📁 cases/ — one JSON file per clinical station
│ ├── chest_pain.json
│ ├── suicide.json
│ ├── headache.json
│ ├── depression.json
│ ├── hematuria.json
│ ├── nausea_vomiting.json
│ ├── jaundice.json
│ ├── lymphadenopathy.json
│ ├── mania.json
│ └── urinary_retention.json
└── 📁 static/
└── index.html — full frontend, three screens
git clone https://github.com/NafisSam/osce-tutor.git
cd osce-tutor
pip install -r requirements.txtCreate a .env file:
OPENAI_KEY=your-key-here
Start the server:
uvicorn main:app --reloadOpen http://127.0.0.1:8000 🎉
Each station is a self-contained JSON file. No code changes needed — just drop a new file in cases/.
{
"id": "case_id",
"icon": "🫀",
"title": "شرح حال ...",
"department": "...",
"tags": ["ضروری"],
"station_number": "۱۱",
"patient_name": "... — ۴۵ ساله",
"duration_seconds": 600,
"difficulty": "ضروری",
"requires_final_action": false,
"patient_persona": "...",
"brief": "...",
"example_responses": "سلام → ...\nچی شده؟ → ...",
"checklist": [
{ "item": "...", "score": 1 }
]
}
⚠️ Checklist scores must sum to exactly 20.
| Method | Endpoint | Description |
|---|---|---|
| GET | /cases |
Case list (patient brief hidden from client) |
| POST | /chat |
{case_id, messages} → patient reply |
| POST | /score |
{case_id, conversation} → score + feedback |
📖 Interactive docs at /docs
Based on the official آزمون صلاحیت بالینی regulations:
| Metric | Value |
|---|---|
| 🎯 Points per station | 20 |
| ✅ Pass per station | ≥ 12 / 20 |
| 🏆 Pass overall | Average ≥ 14 / 20 |
| 📋 Stations per exam | 12–15 (8 ضروری + 4 مفید) |
Scoring is calculated server-side from the checklist JSON — not from the model's arithmetic — to prevent model math errors.
All clinical content, checklist items, scoring weights, and exam rules are based on:
📖 کتاب جامع آزمون صلاحیت بالینی — فروردین ۱۴۰۵
دکتر میلاد شمشیرکار — موسسه دکترهای خوب
Built by a final-year medical student learning to code while finishing clinical training. This was a first end-to-end project — from prompt engineering and API design to frontend development and clinical content authoring — completed in parallel with thesis work and hospital rotations.
Status: V1 complete. Built and documented. ✨
MIT License — free to use, modify, and distribute with attribution.