feat(ai-onboarding): enhance conversation flow, prompt rules & update Postman environment port to 8001

This commit is contained in:
2026-09-01 15:22:40 +05:30
parent 1d794ca425
commit c23d979338
31 changed files with 4686 additions and 749 deletions
@@ -260,7 +260,8 @@ async def voice_turn(
user_message=patient_transcript,
)
# 6. Update Structured Clinical State
# 6. Update Structured Clinical State using shared intelligent merge
from app.ai.orchestrator import merge_state_updates
current_state = json.loads(state.state_json)
updates = ai_response.get("state_updates", {})
if hasattr(updates, "model_dump"):
@@ -268,16 +269,12 @@ async def voice_turn(
elif not isinstance(updates, dict):
updates = {}
for k, v in updates.items():
if v is not None:
if isinstance(v, list) and len(v) == 0:
continue
current_state[k] = v
merged_state = merge_state_updates(current_state, updates)
onboarding_service.update_state(
db=db,
state=state,
data=current_state,
data=merged_state,
)
# 7. Update session stage, status & auto-assigned specialty
@@ -376,98 +373,106 @@ async def complete_voice_onboarding(
db: Session = Depends(get_db),
):
start_time = time.time()
onboarding_service = OnboardingService()
completion_service = CompletionService()
result_service = ResultExtractionService()
submission_service = PatientSubmissionService()
try:
onboarding_service = OnboardingService()
completion_service = CompletionService()
result_service = ResultExtractionService()
submission_service = PatientSubmissionService()
session = onboarding_service.get_session(db, session_id)
if not session:
raise HTTPException(
status_code=404,
detail="Voice onboarding session not found",
session = onboarding_service.get_session(db, session_id)
if not session:
raise HTTPException(
status_code=404,
detail="Voice onboarding session not found",
)
# 1b. Verify Session Ownership (IDOR Prevention)
verify_session_ownership(session.patient_id, auth, detail="Forbidden: You do not have authorization to complete this voice session.")
state = onboarding_service.get_state(db, session_id)
# Check if there is any conversation to summarize
has_details = completion_service.is_complete(session, state)
messages = (
db.query(OnboardingMessage)
.filter(OnboardingMessage.session_id == session_id)
.order_by(OnboardingMessage.created_at.asc())
.all()
)
conversation_history = [
{"role": m.role, "message": m.message, "stage": m.stage}
for m in messages
]
result = await result_service.extract_result(
session=session,
state=state,
conversation_history=conversation_history,
)
# 1b. Verify Session Ownership (IDOR Prevention)
verify_session_ownership(session.patient_id, auth, detail="Forbidden: You do not have authorization to complete this voice session.")
elapsed = time.time() - start_time
resp_ms = round(elapsed * 1000, 2)
resp_sec = round(elapsed, 3)
state = onboarding_service.get_state(db, session_id)
if isinstance(result, dict):
result["onboarding_completed"] = True
# Check if there is any conversation to summarize
has_details = completion_service.is_complete(session, state)
if session.status == "completed":
return CompleteOnboardingResponse(
success=True,
session_id=session_id,
status="completed",
result=result,
message="Voice onboarding session is already completed.",
response_time_ms=resp_ms,
response_time_sec=resp_sec,
)
messages = (
db.query(OnboardingMessage)
.filter(OnboardingMessage.session_id == session_id)
.order_by(OnboardingMessage.created_at.asc())
.all()
)
conversation_history = [
{"role": m.role, "message": m.message, "stage": m.stage}
for m in messages
]
if not request.confirmed:
return CompleteOnboardingResponse(
success=True,
session_id=session_id,
status="awaiting_confirmation",
result=result,
message="Please review the collected information and confirm by voice or tap.",
response_time_ms=resp_ms,
response_time_sec=resp_sec,
)
result = await result_service.extract_result(
session=session,
state=state,
conversation_history=conversation_history,
)
submission = await submission_service.submit(result)
elapsed = time.time() - start_time
resp_ms = round(elapsed * 1000, 2)
resp_sec = round(elapsed, 3)
if submission.get("success"):
session.status = "completed"
session.stage = "confirmation"
db.commit()
if isinstance(result, dict):
result["onboarding_completed"] = True
return CompleteOnboardingResponse(
success=True,
session_id=session_id,
status="completed",
result=result,
message="Voice onboarding successfully saved to patient record.",
response_time_ms=resp_ms,
response_time_sec=resp_sec,
)
if session.status == "completed":
return CompleteOnboardingResponse(
success=True,
session_id=session_id,
status="completed",
result=result,
message="Voice onboarding session is already completed.",
response_time_ms=resp_ms,
response_time_sec=resp_sec,
)
if not request.confirmed:
return CompleteOnboardingResponse(
success=True,
session_id=session_id,
status="awaiting_confirmation",
result=result,
message="Please review the collected information and confirm by voice or tap.",
response_time_ms=resp_ms,
response_time_sec=resp_sec,
)
submission = await submission_service.submit(result)
if submission.get("success"):
session.status = "completed"
session.stage = "confirmation"
session.status = "submission_pending_retry"
db.commit()
return CompleteOnboardingResponse(
success=True,
success=False,
session_id=session_id,
status="completed",
status="submission_pending_retry",
result=result,
message="Voice onboarding successfully saved to patient record.",
message="Patient API submission failed. Session preserved for retry.",
response_time_ms=resp_ms,
response_time_sec=resp_sec,
)
session.status = "submission_pending_retry"
db.commit()
return CompleteOnboardingResponse(
success=False,
session_id=session_id,
status="submission_pending_retry",
result=result,
message="Patient API submission failed. Session preserved for retry.",
response_time_ms=resp_ms,
response_time_sec=resp_sec,
)
except HTTPException:
raise
except Exception as err:
import traceback
print(f"[CompleteVoiceOnboarding Error]: {err}")
traceback.print_exc()
raise HTTPException(status_code=500, detail=str(err))