diff --git a/ai-patient-onboarding/docs/API_INTEGRATION_GUIDE.md b/ai-patient-onboarding/docs/API_INTEGRATION_GUIDE.md index aa17ac9..8e42486 100644 --- a/ai-patient-onboarding/docs/API_INTEGRATION_GUIDE.md +++ b/ai-patient-onboarding/docs/API_INTEGRATION_GUIDE.md @@ -1,4 +1,4 @@ -# AI Patient Onboarding API — Frontend Integration Guide +# AI Patient Onboarding API — Complete Frontend Integration Guide **Version**: `1.0.0` **Target Audience**: Frontend Engineers (React / React Native / Vue / Next.js / Mobile) @@ -13,7 +13,9 @@ ## 1. Executive System Overview -The **AI Patient Onboarding API** is an enterprise multi-modal clinical intake system designed for hospitals, clinics, and digital health platforms. It automates patient registration, symptom intake, medical history collection, document extraction, and specialty triage before a physician consultation. +The **AI Patient Onboarding API** is an enterprise multi-modal clinical intake system designed for hospitals, clinics, a + +nd digital health platforms. It automates patient registration, symptom intake, medical history collection, document extraction, and specialty triage before a physician consultation. ### Key Capabilities for Frontend Applications: 1. **Multi-Modal Onboarding**: @@ -60,21 +62,7 @@ The backend enforces production-safe `CORSMiddleware`. --- -## 4. Documentation Index - -To explore detailed specifications, refer to the following module guides: - -| Module Guide | Focus Area | Description | -| :--- | :--- | :--- | -| [`AUTHENTICATION.md`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/docs/AUTHENTICATION.md) | Security & Headers | Bearer tokens, `X-API-Key`, patient session isolation (IDOR protection). | -| [`ONBOARDING_API.md`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/docs/ONBOARDING_API.md) | Text & Document Intake | Full specification for text chat endpoints, document OCR, and session completion. | -| [`VOICE_ONBOARDING_API.md`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/docs/VOICE_ONBOARDING_API.md) | Voice & Speech APIs | Audio streaming, WebSpeech fallbacks, multilingual Sarvam AI voice turns. | -| [`ERROR_HANDLING.md`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/docs/ERROR_HANDLING.md) | Error Codes & SLAs | HTTP 401, 403, 413, 422, 429 status codes and SLA latency boundaries. | -| [`FRONTEND_EXAMPLES.md`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/docs/FRONTEND_EXAMPLES.md) | TypeScript & React | Copy-pasteable React hooks, MediaRecorder voice capture, and fetch client examples. | - ---- - -## 5. Master API Endpoint Directory +## 4. Master API Endpoint Directory | HTTP Method | Endpoint Path | Auth Required | Rate Limit | Purpose | | :--- | :--- | :--- | :--- | :--- | @@ -90,18 +78,387 @@ To explore detailed specifications, refer to the following module guides: --- -## 6. Response Time & Timing Metadata +## 5. Authentication & Patient Security -All interactive conversation endpoints append performance metadata to help frontend applications measure latency: +### Authentication Mechanisms: +#### Method A: HTTP Bearer Token (Standard) +```http +Authorization: Bearer +``` + +#### Method B: `X-API-Key` Custom Header +```http +X-API-Key: +``` + +### Supported Access Tokens: +1. **Service Secret API Key**: `skyheal_secure_api_key_2026` (configurable via `API_SECRET_KEY` in server environment). +2. **Patient Development Tokens**: `test_token_` (e.g. `test_token_PAT-10023`). Automatically establishes patient identity context. + +### Patient Isolation & IDOR Protection Rules: +1. When starting a session (`/v1/onboarding/start`), `patient.id` is bound as session owner (`session.patient_id`). +2. Subsequent requests verify caller's authenticated `patient_id` matches session owner. +3. Access attempts by other patients return **`HTTP 403 Forbidden`**. + +--- + +## 6. Text Onboarding API Specifications + +### 6.1. POST `/v1/onboarding/start` + +Starts a new text-based clinical onboarding intake session. + +#### Request Headers: +```http +Content-Type: application/json +Authorization: Bearer test_token_PAT-10023 +``` + +#### Request Body (`StartOnboardingRequest`): +```json +{ + "patient": { + "id": "PAT-10023", + "name": "Kavitha Ramesh", + "age": 35, + "gender": "female", + "phone": "+919876543210", + "abha_id": "91-1234-5678-9012", + "insurance_scheme": "PMJAY", + "dietary_habits": "Vegetarian" + }, + "category": { + "type": "general", + "code": "general_medicine", + "name": "General Medicine" + }, + "language": "en" +} +``` + +#### Field Descriptions: + +| Field | Type | Required | Validation Rules | Description | +| :--- | :--- | :--- | :--- | :--- | +| `patient.id` | string | **Yes** | Min length 1 | Unique patient identifier | +| `patient.name` | string | No | Optional | Full name of patient | +| `patient.age` | integer | No | $0 \le \text{age} \le 120$ | Patient age in years | +| `patient.gender` | string | No | Optional | Gender identity ("male", "female", "other") | +| `category.type` | string | **Yes** | `"general"` or `"speciality"` | Onboarding workflow type | +| `category.code` | string | **Yes** | Min length 1 | Specialty classification code | +| `category.name` | string | **Yes** | Min length 1 | Category display name | +| `language` | string | No | Default `"en"` | Preferred intake language | + +#### Successful Response (`200 OK` - `StartOnboardingResponse`): ```json { "success": true, "session_id": "ONB-8F12A9C4", + "patient_id": "PAT-10023", + "category": { + "type": "general", + "code": "general_medicine", + "name": "General Medicine" + }, + "language": "en", + "status": "in_progress", + "stage": "symptoms", + "message": "Hello Kavitha Ramesh! I am your clinical onboarding assistant. What symptoms are you experiencing today?" +} +``` + +--- + +### 6.2. POST `/v1/onboarding/{session_id}/message` + +Sends a patient chat response to the AI intake orchestrator. + +#### Request Body (`SendMessageRequest`): +```json +{ + "message": "I have had severe chest tightness and shortness of breath for 2 days." +} +``` + +#### Successful Response (`200 OK` - `SendMessageResponse`): +```json +{ + "success": true, + "session_id": "ONB-8F12A9C4", + "stage": "medical_history", + "message": "Thank you for sharing. Does the chest tightness radiate to your arm or jaw, and do you have any history of high blood pressure?", + "status": "in_progress", "response_time_ms": 1529.74, "response_time_sec": 1.53 } ``` -- `response_time_ms`: Backend processing duration in milliseconds (floating-point number). -- `response_time_sec`: Backend processing duration in seconds (rounded to 3 decimal places). +--- + +### 6.3. POST `/v1/onboarding/{session_id}/complete` + +Finalizes the intake session and outputs the structured clinical EHR payload. + +#### Request Body (`CompleteOnboardingRequest`): +```json +{ + "confirmed": true +} +``` + +#### Successful Response (`200 OK` - `CompleteOnboardingResponse`): +```json +{ + "success": true, + "session_id": "ONB-8F12A9C4", + "status": "completed", + "result": { + "patient_id": "PAT-10023", + "abha_id": "91-1234-5678-9012", + "phone": "+919876543210", + "insurance_scheme": "PMJAY", + "category": { + "type": "general", + "code": "general_medicine", + "name": "General Medicine" + }, + "chief_complaint": "Chest tightness and shortness of breath for 2 days", + "symptoms": [ + { + "name": "Chest tightness", + "duration": "2 days", + "severity": "severe", + "description": "Triggered during exertion" + } + ], + "medical_history": ["Prehypertension"], + "medications": ["Metformin 500mg"], + "allergies": ["Penicillin"], + "dietary_habits": "Vegetarian", + "additional_information": "Patient confirmed details.", + "language": "en", + "onboarding_completed": true + }, + "message": "Onboarding successfully completed and saved to patient record.", + "response_time_ms": 4075.41, + "response_time_sec": 4.08 +} +``` + +--- + +## 7. Voice Onboarding API Specifications + +### 7.1. POST `/v1/voice-onboarding/start` + +Starts a voice-first onboarding session with Sarvam AI multilingual speech engine. + +#### Supported Languages: +`en-IN` (Indian English), `ta-IN` (Tamil), `hi-IN` (Hindi), `te-IN` (Telugu), `kn-IN` (Kannada), `ml-IN` (Malayalam), `mr-IN` (Marathi). + +#### Request Body: +```json +{ + "patient": { + "id": "PAT-VOICE-1", + "name": "Ramesh G", + "age": 34, + "gender": "male" + }, + "category": { + "type": "general", + "code": "general_medicine", + "name": "General Medicine" + }, + "language": "ta-IN" +} +``` + +#### Successful Response (`200 OK`): +```json +{ + "success": true, + "session_id": "VOICE-D3CAEA5C", + "patient_id": "PAT-VOICE-1", + "category": { + "type": "general", + "code": "general_medicine", + "name": "General Medicine" + }, + "language": "ta-IN", + "status": "in_progress", + "stage": "greeting", + "greeting_text": "வணக்கம் Ramesh G, CureSelect மருத்துவமனைக்கு வரவேற்கிறோம். இன்று உங்களுக்கு என்ன சுகவீனம் உள்ளது?", + "audio_url": "/v1/voice-onboarding/audio/aud_a1b2c3d4e5f6", + "response_time_ms": 78.32, + "response_time_sec": 0.08 +} +``` + +--- + +### 7.2. POST `/v1/voice-onboarding/{session_id}/turn` + +Processes a conversational voice turn using audio recording or text fallback. + +#### Multipart Form Data: +- `audio`: Binary audio recording file (`WAV`, `WEBM`, `MP3`, `OGG` up to 10MB). +- `text_fallback`: String text transcript (used if WebSpeech STT processed client-side). + +#### Successful Response (`200 OK`): +```json +{ + "success": true, + "session_id": "VOICE-D3CAEA5C", + "patient_transcript": "எனக்குகடந்த 3 நாளா நெஞ்சு பாரமா இருக்குங்க.", + "ai_text": "நன்றி. இந்த நெஞ்சு பாரம் உடற்பயிற்சி செய்யும் போது அதிகமாகிறதா?", + "stage": "symptoms", + "completed": false, + "audio_url": "/v1/voice-onboarding/audio/aud_f9e8d7c6b5a4", + "audio_base64": null, + "suggested_specialty": { + "specialty": "Cardiology", + "reason": "Chest tightness reported" + }, + "response_time_ms": 1412.37, + "response_time_sec": 1.41 +} +``` + +--- + +### 7.3. GET `/v1/voice-onboarding/audio/{audio_id}` + +Streams generated TTS audio for browser or mobile playback. + +```javascript +const audio = new Audio(`${BASE_URL}/v1/voice-onboarding/audio/${audioId}`); +await audio.play(); +``` + +--- + +## 8. Medical Document Analysis API + +### POST `/v1/documents/{session_id}/upload` + +Uploads a medical report / prescription for vision extraction. + +- **Content-Type**: `multipart/form-data` +- **File Limit**: Max `10MB` (`10,485,760 bytes`). +- **Allowed Formats**: `image/jpeg`, `image/png`, `image/webp`, `application/pdf`. + +#### Successful Response (`200 OK`): +```json +{ + "success": true, + "session_id": "ONB-8F12A9C4", + "document_type": "lab_report", + "summary": "Report indicates elevated HbA1c (7.2%) and stage 1 hypertension (130/85 mmHg).", + "findings": [ + { + "test": "HbA1c", + "value": "7.2", + "unit": "%", + "interpretation": "Elevated" + } + ], + "medications_found": ["Metformin 500mg"], + "allergies_found": ["Penicillin"], + "message": "Medical document analyzed and integrated into onboarding session." +} +``` + +--- + +## 9. Error Handling & Status Codes + +| HTTP Status Code | Meaning | Cause & Resolution | +| :--- | :--- | :--- | +| `400 Bad Request` | Bad Request | Invalid category or unsupported file format. | +| `401 Unauthorized` | Unauthorized | Missing or invalid `Authorization: Bearer` or `X-API-Key` header. | +| `403 Forbidden` | Forbidden (IDOR) | Authenticated `patient_id` does not match session owner. | +| `404 Not Found` | Not Found | Session ID does not exist in backend database. | +| `413 Payload Too Large` | File Too Large | Uploaded document exceeds 10MB limit. | +| `422 Validation Error` | Pydantic Error | Request body violates schema rules (e.g. `age < 0`). | +| `429 Too Many Requests` | Rate Limited | Exceeded rate limit bucket (30 req/min). Check `Retry-After` header. | +| `500 Internal Error` | Server Error | Unhandled backend failure. | + +--- + +## 10. Frontend React & TypeScript Implementation Examples + +### React API Client (`src/api/onboardingClient.ts`) + +```typescript +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'; + +export interface PatientContext { + id: string; + name?: string; + age?: number; + gender?: string; + phone?: string; + abha_id?: string; +} + +export interface CategoryContext { + type: 'general' | 'speciality'; + code: string; + name: string; +} + +async function fetchApi(endpoint: string, options: RequestInit = {}, patientId: string): Promise { + const token = `test_token_${patientId}`; + const headers = new Headers(options.headers || {}); + headers.set('Authorization', `Bearer ${token}`); + if (!(options.body instanceof FormData)) { + headers.set('Content-Type', 'application/json'); + } + + const response = await fetch(`${API_BASE_URL}${endpoint}`, { ...options, headers }); + if (!response.ok) { + const errorBody = await response.json().catch(() => ({ detail: 'Network response error' })); + throw new Error(errorBody.detail || `HTTP Error ${response.status}`); + } + return response.json(); +} + +export async function startOnboarding(patient: PatientContext, category: CategoryContext, language: string = 'en') { + return fetchApi('/v1/onboarding/start', { + method: 'POST', + body: JSON.stringify({ patient, category, language }), + }, patient.id); +} + +export async function sendMessage(sessionId: string, patientId: string, message: string) { + return fetchApi(`/v1/onboarding/${sessionId}/message`, { + method: 'POST', + body: JSON.stringify({ message }), + }, patientId); +} + +export async function completeOnboarding(sessionId: string, patientId: string, confirmed: boolean = true) { + return fetchApi(`/v1/onboarding/${sessionId}/complete`, { + method: 'POST', + body: JSON.stringify({ confirmed }), + }, patientId); +} +``` + +--- + +## 11. Frontend Integration Checklist + +```text +[ ] Configure API_BASE_URL in environment (VITE_API_BASE_URL=http://localhost:8000) +[ ] Verify CORS preflight request from localhost:3000 / localhost:5173 +[ ] Attach Authorization: Bearer test_token_ header +[ ] Call POST /v1/onboarding/start and store session_id +[ ] Multi-turn chat message sending via POST /v1/onboarding/{session_id}/message +[ ] Handle 401 Unauthorized & 403 Forbidden errors +[ ] Upload medical documents via POST /v1/documents/{session_id}/upload (10MB max) +[ ] Call POST /v1/onboarding/{session_id}/complete to retrieve final PatientOnboardingResult +[ ] Test voice onboarding audio streaming via GET /v1/voice-onboarding/audio/{audio_id} +``` diff --git a/ai-patient-onboarding/docs/AUTHENTICATION.md b/ai-patient-onboarding/docs/AUTHENTICATION.md deleted file mode 100644 index 158c4a6..0000000 --- a/ai-patient-onboarding/docs/AUTHENTICATION.md +++ /dev/null @@ -1,79 +0,0 @@ -# Authentication & Patient Security Specification - -**Module**: API Security & Identity Management -**Implementation Source**: [`app/core/security.py`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/app/core/security.py) - ---- - -## 1. Authentication Mechanisms - -The API supports two authentication methods for frontend applications and client services: - -### Method A: HTTP Bearer Token (Standard) -Send the access token in the `Authorization` request header: -```http -Authorization: Bearer -``` - -### Method B: `X-API-Key` Custom Header -Send the API key in the custom `X-API-Key` header: -```http -X-API-Key: -``` - ---- - -## 2. Supported Access Tokens - -### 1. Service Secret API Key -For service-to-service integration or administrative access: -- **Default Key**: `skyheal_secure_api_key_2026` (configurable via `API_SECRET_KEY` in server environment). - -### 2. Patient Development / Testing Tokens -For patient-specific web or mobile client authentication: -- **Format**: `test_token_` -- **Example**: `test_token_PAT-10023` - -When `test_token_` is passed, the backend automatically establishes the patient context with `patient_id = ""`. - ---- - -## 3. Patient Isolation & IDOR Protection Rules - -The backend enforces strict **Broken Object Level Authorization (IDOR) Protection**: -1. When starting an onboarding session (`/v1/onboarding/start` or `/v1/voice-onboarding/start`), the `patient.id` provided in the JSON body is bound as the session owner (`session.patient_id`). -2. Subsequent requests to `/message`, `/turn`, `/upload`, or `/complete` verify that the caller's authenticated `patient_id` matches the session owner. -3. If Client B attempts to send a message to Client A's session, the server immediately returns **`HTTP 403 Forbidden`**: - ```json - { - "detail": "Forbidden: You do not have authorization to access or modify this patient onboarding session." - } - ``` - ---- - -## 4. Authentication Error Responses - -### Missing Credentials (HTTP 401) -Triggered when no `Authorization` or `X-API-Key` header is present: -```http -HTTP/1.1 401 Unauthorized -WWW-Authenticate: Bearer -Content-Type: application/json - -{ - "detail": "Authentication credentials required. Please provide X-API-Key or Bearer token." -} -``` - -### Invalid Token (HTTP 401) -Triggered when an invalid token string is provided: -```http -HTTP/1.1 401 Unauthorized -WWW-Authenticate: Bearer -Content-Type: application/json - -{ - "detail": "Invalid authentication token or API key." -} -``` diff --git a/ai-patient-onboarding/docs/ERROR_HANDLING.md b/ai-patient-onboarding/docs/ERROR_HANDLING.md deleted file mode 100644 index 32a8776..0000000 --- a/ai-patient-onboarding/docs/ERROR_HANDLING.md +++ /dev/null @@ -1,58 +0,0 @@ -# Error Handling & SLA Reference - -**Module**: API Error Contracts & Status Codes - ---- - -## 1. Standard Error Payload Format - -All HTTP error responses (`4xx` and `5xx`) follow FastAPI JSON error contracts: - -```json -{ - "detail": "Descriptive human-readable error message explaining why the request failed." -} -``` - -### Unhandled Internal Server Errors (HTTP 500) -For unhandled exceptions, the global exception handler masks Python tracebacks and returns a sanitized JSON payload: -```json -{ - "success": false, - "error": { - "code": "INTERNAL_SERVER_ERROR", - "message": "An unexpected internal server error occurred. Please contact system administration." - } -} -``` - ---- - -## 2. Master Error Status Code Guide - -| HTTP Status Code | Name | Cause | Frontend Action | -| :--- | :--- | :--- | :--- | -| `400 Bad Request` | Bad Request | Invalid category, unparseable JSON, or disallowed document format (e.g. `.exe`). | Validate input parameters before sending request. | -| `401 Unauthorized` | Unauthorized | Missing or invalid `Authorization: Bearer` or `X-API-Key` header. | Redirect to login or attach valid patient token `test_token_`. | -| `403 Forbidden` | Forbidden (IDOR) | Authenticated `patient_id` does not match session owner. | Ensure patient accesses only their own session. | -| `404 Not Found` | Not Found | Session ID does not exist in backend database or audio ID expired. | Start a fresh onboarding session via `/v1/onboarding/start`. | -| `413 Payload Too Large` | File Too Large | Uploaded medical document exceeds 10MB (`10,485,760 bytes`). | Compress or resize file before uploading. | -| `422 Validation Error` | Pydantic Error | Request body violates schema rules (e.g. `age < 0` or missing required field). | Display field validation message to user. | -| `429 Too Many Requests` | Rate Limited | Exceeded rate limit bucket (30 req/min for onboarding; 10 req/min for uploads). | Respect `Retry-After: ` response header and back off. | -| `500 Internal Error` | Server Error | Unhandled backend logic or database failure. | Show user retry alert and report issue. | - ---- - -## 3. Rate Limit Headers - -When `HTTP 429` is returned, inspect the response header: -```http -HTTP/1.1 429 Too Many Requests -Retry-After: 59 -Content-Type: application/json - -{ - "detail": "Rate limit exceeded (30 requests per 60s). Please try again later." -} -``` -`Retry-After` specifies the exact number of seconds the frontend should pause before retrying. diff --git a/ai-patient-onboarding/docs/FRONTEND_EXAMPLES.md b/ai-patient-onboarding/docs/FRONTEND_EXAMPLES.md deleted file mode 100644 index 06701f1..0000000 --- a/ai-patient-onboarding/docs/FRONTEND_EXAMPLES.md +++ /dev/null @@ -1,255 +0,0 @@ -# Frontend Developer Integration Examples (React & TypeScript) - -**Language**: TypeScript / JavaScript (React 18+) - ---- - -## 1. Complete API Client (`src/api/client.ts`) - -```typescript -const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'; - -export interface PatientContext { - id: string; - name?: string; - age?: number; - gender?: string; - phone?: string; - abha_id?: string; - insurance_scheme?: string; - dietary_habits?: string; -} - -export interface CategoryContext { - type: 'general' | 'speciality'; - code: string; - name: string; -} - -export interface StartOnboardingResponse { - success: boolean; - session_id: string; - patient_id: string; - category: CategoryContext; - language: string; - status: string; - stage: string; - message: string; -} - -export interface SendMessageResponse { - success: boolean; - session_id: string; - stage: string; - message: string; - status: string; - response_time_ms?: number; - response_time_sec?: number; -} - -export interface CompleteOnboardingResponse { - success: boolean; - session_id: string; - status: string; - result?: any; - message: string; - response_time_ms?: number; - response_time_sec?: number; -} - -/** - * Generic Fetch Wrapper with Authorization & Error Handling - */ -async function fetchApi(endpoint: string, options: RequestInit = {}, patientId: string): Promise { - const token = `test_token_${patientId}`; - const headers = new Headers(options.headers || {}); - headers.set('Authorization', `Bearer ${token}`); - if (!(options.body instanceof FormData)) { - headers.set('Content-Type', 'application/json'); - } - - const response = await fetch(`${API_BASE_URL}${endpoint}`, { - ...options, - headers, - }); - - if (!response.ok) { - const errorBody = await response.json().catch(() => ({ detail: 'Network response error' })); - throw new Error(errorBody.detail || `HTTP Error ${response.status}`); - } - - return response.json(); -} - -/** - * Start Text Onboarding Session - */ -export async function startOnboarding( - patient: PatientContext, - category: CategoryContext, - language: string = 'en' -): Promise { - return fetchApi( - '/v1/onboarding/start', - { - method: 'POST', - body: JSON.stringify({ patient, category, language }), - }, - patient.id - ); -} - -/** - * Send Intake Chat Message - */ -export async function sendMessage( - sessionId: string, - patientId: string, - message: string -): Promise { - return fetchApi( - `/v1/onboarding/${sessionId}/message`, - { - method: 'POST', - body: JSON.stringify({ message }), - }, - patientId - ); -} - -/** - * Upload Medical Document (Report / Prescription) - */ -export async function uploadDocument( - sessionId: string, - patientId: string, - file: File -): Promise { - const formData = new FormData(); - formData.append('file', file); - - return fetchApi( - `/v1/documents/${sessionId}/upload`, - { - method: 'POST', - body: formData, - }, - patientId - ); -} - -/** - * Finalize Session & Extract Structured EHR - */ -export async function completeOnboarding( - sessionId: string, - patientId: string, - confirmed: boolean = true -): Promise { - return fetchApi( - `/v1/onboarding/${sessionId}/complete`, - { - method: 'POST', - body: JSON.stringify({ confirmed }), - }, - patientId - ); -} -``` - ---- - -## 2. Voice Onboarding Hook (`src/hooks/useVoiceOnboarding.ts`) - -```typescript -import { useState, useRef } from 'react'; - -export function useVoiceOnboarding(patientId: string) { - const [sessionId, setSessionId] = useState(null); - const [isRecording, setIsRecording] = useState(false); - const [isPlayingAudio, setIsPlayingAudio] = useState(false); - const mediaRecorderRef = useRef(null); - const audioChunksRef = useRef([]); - - const startVoiceSession = async (patient: any, language: string = 'en-IN') => { - const res = await fetch('http://localhost:8000/v1/voice-onboarding/start', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer test_token_${patientId}`, - }, - body: JSON.stringify({ - patient, - category: { type: 'general', code: 'general_medicine', name: 'General Medicine' }, - language, - }), - }); - const data = await res.json(); - setSessionId(data.session_id); - if (data.audio_url) { - playAudioResponse(data.audio_url); - } - return data; - }; - - const playAudioResponse = (audioUrl: string) => { - setIsPlayingAudio(true); - const audio = new Audio(`http://localhost:8000${audioUrl}`); - audio.onended = () => setIsPlayingAudio(false); - audio.onerror = () => setIsPlayingAudio(false); - audio.play(); - }; - - const startRecording = async () => { - const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); - const mediaRecorder = new MediaRecorder(stream); - mediaRecorderRef.current = mediaRecorder; - audioChunksRef.current = []; - - mediaRecorder.ondataavailable = (event) => { - if (event.data.size > 0) audioChunksRef.current.push(event.data); - }; - - mediaRecorder.start(); - setIsRecording(true); - }; - - const stopRecordingAndSend = async () => { - if (!mediaRecorderRef.current || !sessionId) return; - - return new Promise((resolve) => { - mediaRecorderRef.current!.onstop = async () => { - setIsRecording(false); - const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/wav' }); - const formData = new FormData(); - formData.append('audio', audioBlob, 'speech.wav'); - - const res = await fetch(`http://localhost:8000/v1/voice-onboarding/${sessionId}/turn`, { - method: 'POST', - headers: { - 'Authorization': `Bearer test_token_${patientId}`, - }, - body: formData, - }); - - const turnData = await res.json(); - if (turnData.audio_url) { - playAudioResponse(turnData.audio_url); - } - resolve(turnData); - }; - - mediaRecorderRef.current!.stop(); - }); - }; - - return { - sessionId, - isRecording, - isPlayingAudio, - startVoiceSession, - startRecording, - stopRecordingAndSend, - }; -} -``` diff --git a/ai-patient-onboarding/docs/ONBOARDING_API.md b/ai-patient-onboarding/docs/ONBOARDING_API.md deleted file mode 100644 index f8f3fae..0000000 --- a/ai-patient-onboarding/docs/ONBOARDING_API.md +++ /dev/null @@ -1,194 +0,0 @@ -# Text Onboarding & Document API Reference - -**Implementation Sources**: [`app/api/onboarding.py`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/app/api/onboarding.py), [`app/api/documents.py`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/app/api/documents.py) - ---- - -## 1. POST `/v1/onboarding/start` - -Starts a new text-based clinical onboarding intake session. - -### Request Headers: -```http -Content-Type: application/json -Authorization: Bearer test_token_PAT-10023 -``` - -### Request Body (`StartOnboardingRequest`): -```json -{ - "patient": { - "id": "PAT-10023", - "name": "Kavitha Ramesh", - "age": 35, - "gender": "female", - "phone": "+919876543210", - "abha_id": "91-1234-5678-9012", - "insurance_scheme": "PMJAY", - "dietary_habits": "Vegetarian" - }, - "category": { - "type": "general", - "code": "general_medicine", - "name": "General Medicine" - }, - "language": "en" -} -``` - -### Field Descriptions: - -| Field | Type | Required | Validation Rules | Description | -| :--- | :--- | :--- | :--- | :--- | -| `patient.id` | string | **Yes** | Min length 1 | Unique patient identifier | -| `patient.name` | string | No | Optional | Full name of patient | -| `patient.age` | integer | No | $0 \le \text{age} \le 120$ | Patient age in years | -| `patient.gender` | string | No | Optional | Gender identity ("male", "female", "other") | -| `category.type` | string | **Yes** | `"general"` or `"speciality"` | Onboarding workflow type | -| `category.code` | string | **Yes** | Min length 1 | Specialty classification code | -| `category.name` | string | **Yes** | Min length 1 | Human-readable category display name | -| `language` | string | No | Default `"en"` | Preferred intake language | - -### Successful Response (`200 OK` - `StartOnboardingResponse`): -```json -{ - "success": true, - "session_id": "ONB-8F12A9C4", - "patient_id": "PAT-10023", - "category": { - "type": "general", - "code": "general_medicine", - "name": "General Medicine" - }, - "language": "en", - "status": "in_progress", - "stage": "symptoms", - "message": "Hello Kavitha Ramesh! I am your clinical onboarding assistant. What symptoms are you experiencing today?" -} -``` - ---- - -## 2. POST `/v1/onboarding/{session_id}/message` - -Sends a patient chat response to the AI intake orchestrator. - -### Request Headers: -```http -Content-Type: application/json -Authorization: Bearer test_token_PAT-10023 -``` - -### Request Body (`SendMessageRequest`): -```json -{ - "message": "I have had severe chest tightness and shortness of breath for 2 days." -} -``` - -### Successful Response (`200 OK` - `SendMessageResponse`): -```json -{ - "success": true, - "session_id": "ONB-8F12A9C4", - "stage": "medical_history", - "message": "Thank you for sharing. Does the chest tightness radiate to your arm or jaw, and do you have any history of high blood pressure?", - "status": "in_progress", - "response_time_ms": 1529.74, - "response_time_sec": 1.53 -} -``` - ---- - -## 3. POST `/v1/documents/{session_id}/upload` - -Uploads a medical document (lab report, prescription, discharge summary) for vision extraction. - -### Request Headers: -```http -Content-Type: multipart/form-data -Authorization: Bearer test_token_PAT-10023 -``` - -### Form Data Parameters: -- `file`: Binary file upload (**Allowed formats**: `image/jpeg`, `image/png`, `image/webp`, `application/pdf`). **Maximum size**: `10MB` (`10,485,760 bytes`). - -### Successful Response (`200 OK` - `DocumentExtractionResponse`): -```json -{ - "success": true, - "session_id": "ONB-8F12A9C4", - "document_type": "lab_report", - "summary": "Report indicates elevated HbA1c (7.2%) and stage 1 hypertension (130/85 mmHg).", - "findings": [ - { - "test": "HbA1c", - "value": "7.2", - "unit": "%", - "interpretation": "Elevated" - }, - { - "test": "Blood Pressure", - "value": "130/85", - "unit": "mmHg", - "interpretation": "Stage 1" - } - ], - "medications_found": ["Metformin 500mg"], - "allergies_found": ["Penicillin"], - "message": "Medical document analyzed and integrated into onboarding session." -} -``` - ---- - -## 4. POST `/v1/onboarding/{session_id}/complete` - -Finalizes the intake session and outputs the structured clinical EHR payload. - -### Request Body (`CompleteOnboardingRequest`): -```json -{ - "confirmed": true -} -``` - -### Successful Response (`200 OK` - `CompleteOnboardingResponse`): -```json -{ - "success": true, - "session_id": "ONB-8F12A9C4", - "status": "completed", - "result": { - "patient_id": "PAT-10023", - "abha_id": "91-1234-5678-9012", - "phone": "+919876543210", - "insurance_scheme": "PMJAY", - "category": { - "type": "general", - "code": "general_medicine", - "name": "General Medicine" - }, - "chief_complaint": "Chest tightness and shortness of breath for 2 days", - "symptoms": [ - { - "name": "Chest tightness", - "duration": "2 days", - "severity": "severe", - "description": "Triggered during exertion" - } - ], - "medical_history": ["Prehypertension"], - "medications": ["Metformin 500mg"], - "allergies": ["Penicillin"], - "dietary_habits": "Vegetarian", - "additional_information": "Patient confirmed details.", - "language": "en", - "onboarding_completed": true - }, - "message": "Onboarding successfully completed and saved to patient record.", - "response_time_ms": 4075.41, - "response_time_sec": 4.08 -} -``` diff --git a/ai-patient-onboarding/docs/VOICE_ONBOARDING_API.md b/ai-patient-onboarding/docs/VOICE_ONBOARDING_API.md deleted file mode 100644 index 219bb36..0000000 --- a/ai-patient-onboarding/docs/VOICE_ONBOARDING_API.md +++ /dev/null @@ -1,149 +0,0 @@ -# Voice Onboarding & Audio API Reference - -**Implementation Sources**: [`app/api/voice_onboarding.py`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/app/api/voice_onboarding.py), [`app/services/voice_service.py`](file:///c:/Users/Lenovo/New%20folder%20%282%29/ai-patient-onboarding/app/services/voice_service.py) - ---- - -## 1. POST `/v1/voice-onboarding/start` - -Starts a voice-first onboarding session with Sarvam AI multilingual speech engine. - -### Request Body (`StartVoiceOnboardingRequest`): -```json -{ - "patient": { - "id": "PAT-VOICE-1", - "name": "Ramesh G", - "age": 34, - "gender": "male" - }, - "category": { - "type": "general", - "code": "general_medicine", - "name": "General Medicine" - }, - "language": "ta-IN" -} -``` - -### Supported Language Codes: -- `en-IN` (Indian English) -- `ta-IN` (Tamil) -- `hi-IN` (Hindi) -- `te-IN` (Telugu) -- `kn-IN` (Kannada) -- `ml-IN` (Malayalam) -- `mr-IN` (Marathi) - -### Successful Response (`200 OK` - `StartVoiceOnboardingResponse`): -```json -{ - "success": true, - "session_id": "VOICE-D3CAEA5C", - "patient_id": "PAT-VOICE-1", - "category": { - "type": "general", - "code": "general_medicine", - "name": "General Medicine" - }, - "language": "ta-IN", - "status": "in_progress", - "stage": "greeting", - "greeting_text": "வணக்கம் Ramesh G, CureSelect மருத்துவமனைக்கு வரவேற்கிறோம். இன்று உங்களுக்கு என்ன சுகவீனம் உள்ளது?", - "audio_url": "/v1/voice-onboarding/audio/aud_a1b2c3d4e5f6", - "response_time_ms": 78.32, - "response_time_sec": 0.08 -} -``` - ---- - -## 2. POST `/v1/voice-onboarding/{session_id}/turn` - -Processes a conversational voice turn using audio recording or text fallback. - -### Request Headers: -```http -Content-Type: multipart/form-data -Authorization: Bearer test_token_PAT-VOICE-1 -``` - -### Multipart Form Data Parameters: -- `audio`: Binary audio recording file (`WAV`, `WEBM`, `MP3`, `OGG` up to 10MB). -- `text_fallback`: String text transcript (used if WebSpeech STT processed client-side or audio is unprovided). - -*Note: At least one of `audio` or `text_fallback` must be provided.* - -### Successful Response (`200 OK` - `VoiceTurnResponse`): -```json -{ - "success": true, - "session_id": "VOICE-D3CAEA5C", - "patient_transcript": "எனக்கு கடந்த 3 நாளா நெஞ்சு பாரமா இருக்குங்க.", - "ai_text": "நன்றி. இந்த நெஞ்சு பாரம் உடற்பயிற்சி செய்யும் போது அதிகமாகிறதா?", - "stage": "symptoms", - "completed": false, - "audio_url": "/v1/voice-onboarding/audio/aud_f9e8d7c6b5a4", - "audio_base64": null, - "suggested_specialty": { - "specialty": "Cardiology", - "reason": "Chest tightness reported" - }, - "response_time_ms": 1412.37, - "response_time_sec": 1.41 -} -``` - ---- - -## 3. GET `/v1/voice-onboarding/audio/{audio_id}` - -Streams generated TTS audio for browser or mobile playback. - -### Request Headers: -No authentication required for audio file streaming. - -### Response Headers: -```http -HTTP/1.1 200 OK -Content-Type: audio/wav (or audio/mpeg) -Accept-Ranges: bytes -Content-Length: 48290 -``` - -### Frontend Audio Playback snippet: -```javascript -const audio = new Audio(`${BASE_URL}/v1/voice-onboarding/audio/${audioId}`); -await audio.play(); -``` - ---- - -## 4. POST `/v1/voice-onboarding/{session_id}/complete` - -Finalizes a voice onboarding session. - -### Request Body: -```json -{ - "confirmed": true -} -``` - -### Successful Response (`200 OK`): -```json -{ - "success": true, - "session_id": "VOICE-D3CAEA5C", - "status": "completed", - "result": { - "patient_id": "PAT-VOICE-1", - "chief_complaint": "Chest tightness for 3 days", - "language": "ta-IN", - "onboarding_completed": true - }, - "message": "Voice onboarding successfully saved to patient record.", - "response_time_ms": 4121.79, - "response_time_sec": 4.12 -} -```