empathy-framework 4.6.6__py3-none-any.whl → 4.7.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- empathy_framework-4.7.1.dist-info/METADATA +690 -0
- empathy_framework-4.7.1.dist-info/RECORD +379 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -2
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
- empathy_llm_toolkit/agent_factory/__init__.py +6 -6
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
- empathy_llm_toolkit/agents_md/__init__.py +22 -0
- empathy_llm_toolkit/agents_md/loader.py +218 -0
- empathy_llm_toolkit/agents_md/parser.py +271 -0
- empathy_llm_toolkit/agents_md/registry.py +307 -0
- empathy_llm_toolkit/commands/__init__.py +51 -0
- empathy_llm_toolkit/commands/context.py +375 -0
- empathy_llm_toolkit/commands/loader.py +301 -0
- empathy_llm_toolkit/commands/models.py +231 -0
- empathy_llm_toolkit/commands/parser.py +371 -0
- empathy_llm_toolkit/commands/registry.py +429 -0
- empathy_llm_toolkit/config/__init__.py +8 -8
- empathy_llm_toolkit/config/unified.py +3 -7
- empathy_llm_toolkit/context/__init__.py +22 -0
- empathy_llm_toolkit/context/compaction.py +455 -0
- empathy_llm_toolkit/context/manager.py +434 -0
- empathy_llm_toolkit/hooks/__init__.py +24 -0
- empathy_llm_toolkit/hooks/config.py +306 -0
- empathy_llm_toolkit/hooks/executor.py +289 -0
- empathy_llm_toolkit/hooks/registry.py +302 -0
- empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
- empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
- empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
- empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
- empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
- empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
- empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
- empathy_llm_toolkit/learning/__init__.py +30 -0
- empathy_llm_toolkit/learning/evaluator.py +438 -0
- empathy_llm_toolkit/learning/extractor.py +514 -0
- empathy_llm_toolkit/learning/storage.py +560 -0
- empathy_llm_toolkit/providers.py +4 -11
- empathy_llm_toolkit/security/__init__.py +17 -17
- empathy_llm_toolkit/utils/tokens.py +2 -5
- empathy_os/__init__.py +202 -70
- empathy_os/cache_monitor.py +5 -3
- empathy_os/cli/__init__.py +11 -55
- empathy_os/cli/__main__.py +29 -15
- empathy_os/cli/commands/inspection.py +21 -12
- empathy_os/cli/commands/memory.py +4 -12
- empathy_os/cli/commands/profiling.py +198 -0
- empathy_os/cli/commands/utilities.py +27 -7
- empathy_os/cli.py +28 -57
- empathy_os/cli_unified.py +525 -1164
- empathy_os/cost_tracker.py +9 -3
- empathy_os/dashboard/server.py +200 -2
- empathy_os/hot_reload/__init__.py +7 -7
- empathy_os/hot_reload/config.py +6 -7
- empathy_os/hot_reload/integration.py +35 -35
- empathy_os/hot_reload/reloader.py +57 -57
- empathy_os/hot_reload/watcher.py +28 -28
- empathy_os/hot_reload/websocket.py +2 -2
- empathy_os/memory/__init__.py +11 -4
- empathy_os/memory/claude_memory.py +1 -1
- empathy_os/memory/cross_session.py +8 -12
- empathy_os/memory/edges.py +6 -6
- empathy_os/memory/file_session.py +770 -0
- empathy_os/memory/graph.py +30 -30
- empathy_os/memory/nodes.py +6 -6
- empathy_os/memory/short_term.py +15 -9
- empathy_os/memory/unified.py +606 -140
- empathy_os/meta_workflows/agent_creator.py +3 -9
- empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
- empathy_os/meta_workflows/form_engine.py +6 -18
- empathy_os/meta_workflows/intent_detector.py +64 -24
- empathy_os/meta_workflows/models.py +3 -1
- empathy_os/meta_workflows/pattern_learner.py +13 -31
- empathy_os/meta_workflows/plan_generator.py +55 -47
- empathy_os/meta_workflows/session_context.py +2 -3
- empathy_os/meta_workflows/workflow.py +20 -51
- empathy_os/models/cli.py +2 -2
- empathy_os/models/tasks.py +1 -2
- empathy_os/models/telemetry.py +4 -1
- empathy_os/models/token_estimator.py +3 -1
- empathy_os/monitoring/alerts.py +938 -9
- empathy_os/monitoring/alerts_cli.py +346 -183
- empathy_os/orchestration/execution_strategies.py +12 -29
- empathy_os/orchestration/pattern_learner.py +20 -26
- empathy_os/orchestration/real_tools.py +6 -15
- empathy_os/platform_utils.py +2 -1
- empathy_os/plugins/__init__.py +2 -2
- empathy_os/plugins/base.py +64 -64
- empathy_os/plugins/registry.py +32 -32
- empathy_os/project_index/index.py +49 -15
- empathy_os/project_index/models.py +1 -2
- empathy_os/project_index/reports.py +1 -1
- empathy_os/project_index/scanner.py +1 -0
- empathy_os/redis_memory.py +10 -7
- empathy_os/resilience/__init__.py +1 -1
- empathy_os/resilience/health.py +10 -10
- empathy_os/routing/__init__.py +7 -7
- empathy_os/routing/chain_executor.py +37 -37
- empathy_os/routing/classifier.py +36 -36
- empathy_os/routing/smart_router.py +40 -40
- empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
- empathy_os/scaffolding/__init__.py +8 -8
- empathy_os/scaffolding/__main__.py +1 -1
- empathy_os/scaffolding/cli.py +28 -28
- empathy_os/socratic/__init__.py +3 -19
- empathy_os/socratic/ab_testing.py +25 -36
- empathy_os/socratic/blueprint.py +38 -38
- empathy_os/socratic/cli.py +34 -20
- empathy_os/socratic/collaboration.py +30 -28
- empathy_os/socratic/domain_templates.py +9 -1
- empathy_os/socratic/embeddings.py +17 -13
- empathy_os/socratic/engine.py +135 -70
- empathy_os/socratic/explainer.py +70 -60
- empathy_os/socratic/feedback.py +24 -19
- empathy_os/socratic/forms.py +15 -10
- empathy_os/socratic/generator.py +51 -35
- empathy_os/socratic/llm_analyzer.py +25 -23
- empathy_os/socratic/mcp_server.py +99 -159
- empathy_os/socratic/session.py +19 -13
- empathy_os/socratic/storage.py +98 -67
- empathy_os/socratic/success.py +38 -27
- empathy_os/socratic/visual_editor.py +51 -39
- empathy_os/socratic/web_ui.py +99 -66
- empathy_os/telemetry/cli.py +3 -1
- empathy_os/telemetry/usage_tracker.py +1 -3
- empathy_os/test_generator/__init__.py +3 -3
- empathy_os/test_generator/cli.py +28 -28
- empathy_os/test_generator/generator.py +64 -66
- empathy_os/test_generator/risk_analyzer.py +11 -11
- empathy_os/vscode_bridge 2.py +173 -0
- empathy_os/vscode_bridge.py +173 -0
- empathy_os/workflows/__init__.py +212 -120
- empathy_os/workflows/batch_processing.py +8 -24
- empathy_os/workflows/bug_predict.py +1 -1
- empathy_os/workflows/code_review.py +20 -5
- empathy_os/workflows/code_review_pipeline.py +13 -8
- empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
- empathy_os/workflows/manage_documentation.py +1 -0
- empathy_os/workflows/orchestrated_health_check.py +6 -11
- empathy_os/workflows/orchestrated_release_prep.py +3 -3
- empathy_os/workflows/pr_review.py +18 -10
- empathy_os/workflows/progressive/README 2.md +454 -0
- empathy_os/workflows/progressive/__init__ 2.py +92 -0
- empathy_os/workflows/progressive/__init__.py +2 -12
- empathy_os/workflows/progressive/cli 2.py +242 -0
- empathy_os/workflows/progressive/cli.py +14 -37
- empathy_os/workflows/progressive/core 2.py +488 -0
- empathy_os/workflows/progressive/core.py +12 -12
- empathy_os/workflows/progressive/orchestrator 2.py +701 -0
- empathy_os/workflows/progressive/orchestrator.py +166 -144
- empathy_os/workflows/progressive/reports 2.py +528 -0
- empathy_os/workflows/progressive/reports.py +22 -31
- empathy_os/workflows/progressive/telemetry 2.py +280 -0
- empathy_os/workflows/progressive/telemetry.py +8 -14
- empathy_os/workflows/progressive/test_gen 2.py +514 -0
- empathy_os/workflows/progressive/test_gen.py +29 -48
- empathy_os/workflows/progressive/workflow 2.py +628 -0
- empathy_os/workflows/progressive/workflow.py +31 -70
- empathy_os/workflows/release_prep.py +21 -6
- empathy_os/workflows/release_prep_crew.py +1 -0
- empathy_os/workflows/secure_release.py +13 -6
- empathy_os/workflows/security_audit.py +8 -3
- empathy_os/workflows/test_coverage_boost_crew.py +3 -2
- empathy_os/workflows/test_maintenance_crew.py +1 -0
- empathy_os/workflows/test_runner.py +16 -12
- empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
- empathy_software_plugin/cli.py +0 -122
- patterns/README.md +119 -0
- patterns/__init__.py +95 -0
- patterns/behavior.py +298 -0
- patterns/code_review_memory.json +441 -0
- patterns/core.py +97 -0
- patterns/debugging.json +3763 -0
- patterns/empathy.py +268 -0
- patterns/health_check_memory.json +505 -0
- patterns/input.py +161 -0
- patterns/memory_graph.json +8 -0
- patterns/refactoring_memory.json +1113 -0
- patterns/registry.py +663 -0
- patterns/security_memory.json +8 -0
- patterns/structural.py +415 -0
- patterns/validation.py +194 -0
- coach_wizards/__init__.py +0 -45
- coach_wizards/accessibility_wizard.py +0 -91
- coach_wizards/api_wizard.py +0 -91
- coach_wizards/base_wizard.py +0 -209
- coach_wizards/cicd_wizard.py +0 -91
- coach_wizards/code_reviewer_README.md +0 -60
- coach_wizards/code_reviewer_wizard.py +0 -180
- coach_wizards/compliance_wizard.py +0 -91
- coach_wizards/database_wizard.py +0 -91
- coach_wizards/debugging_wizard.py +0 -91
- coach_wizards/documentation_wizard.py +0 -91
- coach_wizards/generate_wizards.py +0 -347
- coach_wizards/localization_wizard.py +0 -173
- coach_wizards/migration_wizard.py +0 -91
- coach_wizards/monitoring_wizard.py +0 -91
- coach_wizards/observability_wizard.py +0 -91
- coach_wizards/performance_wizard.py +0 -91
- coach_wizards/prompt_engineering_wizard.py +0 -661
- coach_wizards/refactoring_wizard.py +0 -91
- coach_wizards/scaling_wizard.py +0 -90
- coach_wizards/security_wizard.py +0 -92
- coach_wizards/testing_wizard.py +0 -91
- empathy_framework-4.6.6.dist-info/METADATA +0 -1597
- empathy_framework-4.6.6.dist-info/RECORD +0 -410
- empathy_llm_toolkit/wizards/__init__.py +0 -43
- empathy_llm_toolkit/wizards/base_wizard.py +0 -364
- empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
- empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
- empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
- empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
- empathy_os/wizard_factory_cli.py +0 -170
- empathy_software_plugin/wizards/__init__.py +0 -42
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
- empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
- empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
- empathy_software_plugin/wizards/base_wizard.py +0 -288
- empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
- empathy_software_plugin/wizards/code_review_wizard.py +0 -604
- empathy_software_plugin/wizards/debugging/__init__.py +0 -50
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
- empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
- empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
- empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
- empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
- empathy_software_plugin/wizards/debugging/verification.py +0 -369
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
- empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
- empathy_software_plugin/wizards/performance/__init__.py +0 -9
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
- empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
- empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
- empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
- empathy_software_plugin/wizards/security/__init__.py +0 -32
- empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
- empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
- empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
- empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
- empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
- empathy_software_plugin/wizards/testing/__init__.py +0 -27
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
- empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
- empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
- empathy_software_plugin/wizards/testing_wizard.py +0 -274
- wizards/__init__.py +0 -82
- wizards/admission_assessment_wizard.py +0 -644
- wizards/care_plan.py +0 -321
- wizards/clinical_assessment.py +0 -769
- wizards/discharge_planning.py +0 -77
- wizards/discharge_summary_wizard.py +0 -468
- wizards/dosage_calculation.py +0 -497
- wizards/incident_report_wizard.py +0 -454
- wizards/medication_reconciliation.py +0 -85
- wizards/nursing_assessment.py +0 -171
- wizards/patient_education.py +0 -654
- wizards/quality_improvement.py +0 -705
- wizards/sbar_report.py +0 -324
- wizards/sbar_wizard.py +0 -608
- wizards/shift_handoff_wizard.py +0 -535
- wizards/soap_note_wizard.py +0 -679
- wizards/treatment_plan.py +0 -15
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/WHEEL +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,644 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Admission Assessment Wizard Router - AI Nurse Florence
|
|
3
|
-
Following Wizard Pattern Implementation from SOAP and Shift Handoff wizards
|
|
4
|
-
|
|
5
|
-
Structured patient admission workflow for comprehensive initial assessment.
|
|
6
|
-
Based on evidence-based nursing admission assessment standards.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import logging
|
|
10
|
-
from datetime import datetime
|
|
11
|
-
from typing import Any
|
|
12
|
-
from uuid import uuid4
|
|
13
|
-
|
|
14
|
-
from fastapi import APIRouter, HTTPException, status
|
|
15
|
-
from src.services import get_service
|
|
16
|
-
from src.utils.api_responses import create_success_response
|
|
17
|
-
from src.utils.config import get_settings
|
|
18
|
-
|
|
19
|
-
logger = logging.getLogger(__name__)
|
|
20
|
-
|
|
21
|
-
# Conditional translation import
|
|
22
|
-
try:
|
|
23
|
-
from src.services.translation_service import translate_text
|
|
24
|
-
|
|
25
|
-
_has_translation = True
|
|
26
|
-
except ImportError:
|
|
27
|
-
_has_translation = False
|
|
28
|
-
|
|
29
|
-
async def translate_text(
|
|
30
|
-
text: str,
|
|
31
|
-
target_language: str,
|
|
32
|
-
source_language: str = "en",
|
|
33
|
-
context: str = "medical",
|
|
34
|
-
):
|
|
35
|
-
return {"translated_text": text, "success": False}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# Settings following coding instructions
|
|
39
|
-
settings = get_settings()
|
|
40
|
-
|
|
41
|
-
router = APIRouter(
|
|
42
|
-
prefix="/wizards/admission-assessment",
|
|
43
|
-
tags=["clinical-wizards"],
|
|
44
|
-
responses={
|
|
45
|
-
404: {"description": "Wizard session not found"},
|
|
46
|
-
422: {"description": "Invalid wizard step data"},
|
|
47
|
-
500: {"description": "Wizard processing error"},
|
|
48
|
-
},
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
# Session storage (Redis in production, memory for development)
|
|
52
|
-
try:
|
|
53
|
-
from src.utils.redis_cache import get_redis_client
|
|
54
|
-
|
|
55
|
-
_has_redis = True
|
|
56
|
-
except ImportError:
|
|
57
|
-
_has_redis = False
|
|
58
|
-
|
|
59
|
-
_wizard_sessions: dict[str, dict[str, Any]] = {}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# Admission assessment wizard steps
|
|
63
|
-
ADMISSION_ASSESSMENT_STEPS = {
|
|
64
|
-
1: {
|
|
65
|
-
"step": 1,
|
|
66
|
-
"title": "Patient Demographics & Chief Complaint",
|
|
67
|
-
"prompt": "Gather patient identification and reason for admission",
|
|
68
|
-
"fields": [
|
|
69
|
-
"patient_name",
|
|
70
|
-
"date_of_birth",
|
|
71
|
-
"gender",
|
|
72
|
-
"admission_date",
|
|
73
|
-
"chief_complaint",
|
|
74
|
-
"referring_provider",
|
|
75
|
-
],
|
|
76
|
-
"help_text": "Start with basic patient information and primary reason for admission",
|
|
77
|
-
},
|
|
78
|
-
2: {
|
|
79
|
-
"step": 2,
|
|
80
|
-
"title": "Medical History & Medications",
|
|
81
|
-
"prompt": "Document past medical history and current medications",
|
|
82
|
-
"fields": [
|
|
83
|
-
"past_medical_history",
|
|
84
|
-
"past_surgical_history",
|
|
85
|
-
"current_medications",
|
|
86
|
-
"allergies",
|
|
87
|
-
"immunization_status",
|
|
88
|
-
"family_history",
|
|
89
|
-
],
|
|
90
|
-
"help_text": "Include chronic conditions, previous surgeries, all medications, allergies, and relevant family history",
|
|
91
|
-
},
|
|
92
|
-
3: {
|
|
93
|
-
"step": 3,
|
|
94
|
-
"title": "Review of Systems",
|
|
95
|
-
"prompt": "Conduct comprehensive systems review",
|
|
96
|
-
"fields": [
|
|
97
|
-
"cardiovascular",
|
|
98
|
-
"respiratory",
|
|
99
|
-
"gastrointestinal",
|
|
100
|
-
"genitourinary",
|
|
101
|
-
"neurological",
|
|
102
|
-
"musculoskeletal",
|
|
103
|
-
"integumentary",
|
|
104
|
-
"psychosocial",
|
|
105
|
-
],
|
|
106
|
-
"help_text": "Document findings for each body system. Note any abnormalities or patient concerns.",
|
|
107
|
-
},
|
|
108
|
-
4: {
|
|
109
|
-
"step": 4,
|
|
110
|
-
"title": "Physical Assessment & Vital Signs",
|
|
111
|
-
"prompt": "Record initial physical examination and vital signs",
|
|
112
|
-
"fields": [
|
|
113
|
-
"vital_signs",
|
|
114
|
-
"height_weight",
|
|
115
|
-
"general_appearance",
|
|
116
|
-
"physical_exam_findings",
|
|
117
|
-
"pain_assessment",
|
|
118
|
-
"fall_risk_score",
|
|
119
|
-
],
|
|
120
|
-
"help_text": "Include complete vital signs, measurements, general appearance, and initial physical findings",
|
|
121
|
-
},
|
|
122
|
-
5: {
|
|
123
|
-
"step": 5,
|
|
124
|
-
"title": "Psychosocial & Discharge Planning",
|
|
125
|
-
"prompt": "Assess psychosocial factors and begin discharge planning",
|
|
126
|
-
"fields": [
|
|
127
|
-
"living_situation",
|
|
128
|
-
"support_system",
|
|
129
|
-
"advance_directives",
|
|
130
|
-
"code_status",
|
|
131
|
-
"barriers_to_care",
|
|
132
|
-
"discharge_planning_needs",
|
|
133
|
-
],
|
|
134
|
-
"help_text": "Document living situation, support systems, advance care planning, and anticipated discharge needs",
|
|
135
|
-
},
|
|
136
|
-
6: {
|
|
137
|
-
"step": 6,
|
|
138
|
-
"title": "Initial Care Plan & Orders",
|
|
139
|
-
"prompt": "Establish initial nursing care plan and verify orders",
|
|
140
|
-
"fields": [
|
|
141
|
-
"nursing_diagnoses",
|
|
142
|
-
"care_priorities",
|
|
143
|
-
"patient_goals",
|
|
144
|
-
"pending_orders",
|
|
145
|
-
"patient_education_needs",
|
|
146
|
-
"follow_up_required",
|
|
147
|
-
],
|
|
148
|
-
"help_text": "Identify nursing diagnoses, set priorities, establish patient-centered goals, and note education needs",
|
|
149
|
-
},
|
|
150
|
-
7: {
|
|
151
|
-
"step": 7,
|
|
152
|
-
"title": "Review & Finalize",
|
|
153
|
-
"prompt": "Review your admission assessment and finalize the document",
|
|
154
|
-
"fields": ["review_complete", "user_approved"],
|
|
155
|
-
"help_text": "Review all sections of the admission assessment. Click 'Generate Preview' to see the formatted assessment. You can go back to edit any section before finalizing.",
|
|
156
|
-
"is_review_step": True,
|
|
157
|
-
},
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
# Educational banner for all admission assessment outputs
|
|
162
|
-
EDU_BANNER = """
|
|
163
|
-
⚕️ EDUCATIONAL TOOL NOTICE ⚕️
|
|
164
|
-
This admission assessment wizard is an educational tool for healthcare professionals.
|
|
165
|
-
All clinical assessments should be reviewed and validated by qualified providers.
|
|
166
|
-
Never rely solely on automated tools for clinical decision-making or documentation.
|
|
167
|
-
"""
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
async def _store_wizard_session(wizard_id: str, session_data: dict[str, Any]) -> bool:
|
|
171
|
-
"""Store wizard session in Redis (preferred) or memory (fallback)"""
|
|
172
|
-
try:
|
|
173
|
-
if _has_redis:
|
|
174
|
-
redis_client = await get_redis_client()
|
|
175
|
-
if redis_client:
|
|
176
|
-
import json
|
|
177
|
-
|
|
178
|
-
cache_key = f"wizard:admission_assessment:{wizard_id}"
|
|
179
|
-
await redis_client.setex(
|
|
180
|
-
cache_key, 7200, json.dumps(session_data) # 2 hour TTL - FIXED: use JSON
|
|
181
|
-
)
|
|
182
|
-
logger.info(f"Stored admission assessment wizard session {wizard_id} in Redis")
|
|
183
|
-
return True
|
|
184
|
-
except Exception as e:
|
|
185
|
-
logger.warning(f"Failed to store session in Redis: {e}, using memory fallback")
|
|
186
|
-
|
|
187
|
-
# Memory fallback
|
|
188
|
-
_wizard_sessions[wizard_id] = session_data
|
|
189
|
-
logger.info(f"Stored admission assessment wizard session {wizard_id} in memory")
|
|
190
|
-
return True
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
async def _get_wizard_session(wizard_id: str) -> dict[str, Any] | None:
|
|
194
|
-
"""Retrieve wizard session from Redis (preferred) or memory (fallback)"""
|
|
195
|
-
try:
|
|
196
|
-
if _has_redis:
|
|
197
|
-
redis_client = await get_redis_client()
|
|
198
|
-
if redis_client:
|
|
199
|
-
import json
|
|
200
|
-
|
|
201
|
-
cache_key = f"wizard:admission_assessment:{wizard_id}"
|
|
202
|
-
session_str = await redis_client.get(cache_key)
|
|
203
|
-
if session_str:
|
|
204
|
-
# SECURITY FIX: Use json.loads() instead of ast.literal_eval()
|
|
205
|
-
return json.loads(session_str)
|
|
206
|
-
except Exception as e:
|
|
207
|
-
logger.warning(f"Failed to retrieve session from Redis: {e}, checking memory")
|
|
208
|
-
|
|
209
|
-
# Memory fallback
|
|
210
|
-
return _wizard_sessions.get(wizard_id)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
def _get_step_data(step: int) -> dict[str, Any]:
|
|
214
|
-
"""Get step configuration data"""
|
|
215
|
-
if step not in ADMISSION_ASSESSMENT_STEPS:
|
|
216
|
-
raise HTTPException(
|
|
217
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
|
218
|
-
detail=f"Invalid step number: {step}",
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
step_config = ADMISSION_ASSESSMENT_STEPS[step]
|
|
222
|
-
return {
|
|
223
|
-
"step": step,
|
|
224
|
-
"title": step_config["title"],
|
|
225
|
-
"prompt": step_config["prompt"],
|
|
226
|
-
"fields": step_config["fields"],
|
|
227
|
-
"help_text": step_config["help_text"],
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
def _generate_admission_assessment_report(collected_data: dict[str, Any]) -> dict[str, Any]:
|
|
232
|
-
"""Generate final admission assessment report from collected data"""
|
|
233
|
-
|
|
234
|
-
# Generate formatted narrative
|
|
235
|
-
narrative = f"""
|
|
236
|
-
ADMISSION ASSESSMENT
|
|
237
|
-
Date: {collected_data.get('admission_date', datetime.now().strftime('%Y-%m-%d %H:%M'))}
|
|
238
|
-
|
|
239
|
-
PATIENT DEMOGRAPHICS
|
|
240
|
-
Name: {collected_data.get('patient_name', 'Not documented')}
|
|
241
|
-
Date of Birth: {collected_data.get('date_of_birth', 'Not documented')}
|
|
242
|
-
Gender: {collected_data.get('gender', 'Not documented')}
|
|
243
|
-
Chief Complaint: {collected_data.get('chief_complaint', 'Not documented')}
|
|
244
|
-
Referring Provider: {collected_data.get('referring_provider', 'Not documented')}
|
|
245
|
-
|
|
246
|
-
MEDICAL HISTORY
|
|
247
|
-
Past Medical History: {collected_data.get('past_medical_history', 'Not documented')}
|
|
248
|
-
Past Surgical History: {collected_data.get('past_surgical_history', 'Not documented')}
|
|
249
|
-
Current Medications: {collected_data.get('current_medications', 'Not documented')}
|
|
250
|
-
Allergies: {collected_data.get('allergies', 'NKDA')}
|
|
251
|
-
Immunizations: {collected_data.get('immunization_status', 'Not documented')}
|
|
252
|
-
Family History: {collected_data.get('family_history', 'Not documented')}
|
|
253
|
-
|
|
254
|
-
REVIEW OF SYSTEMS
|
|
255
|
-
Cardiovascular: {collected_data.get('cardiovascular', 'Not documented')}
|
|
256
|
-
Respiratory: {collected_data.get('respiratory', 'Not documented')}
|
|
257
|
-
Gastrointestinal: {collected_data.get('gastrointestinal', 'Not documented')}
|
|
258
|
-
Genitourinary: {collected_data.get('genitourinary', 'Not documented')}
|
|
259
|
-
Neurological: {collected_data.get('neurological', 'Not documented')}
|
|
260
|
-
Musculoskeletal: {collected_data.get('musculoskeletal', 'Not documented')}
|
|
261
|
-
Integumentary: {collected_data.get('integumentary', 'Not documented')}
|
|
262
|
-
Psychosocial: {collected_data.get('psychosocial', 'Not documented')}
|
|
263
|
-
|
|
264
|
-
PHYSICAL ASSESSMENT
|
|
265
|
-
Vital Signs: {collected_data.get('vital_signs', 'Not documented')}
|
|
266
|
-
Height/Weight: {collected_data.get('height_weight', 'Not documented')}
|
|
267
|
-
General Appearance: {collected_data.get('general_appearance', 'Not documented')}
|
|
268
|
-
Physical Exam: {collected_data.get('physical_exam_findings', 'Not documented')}
|
|
269
|
-
Pain Assessment: {collected_data.get('pain_assessment', 'Not documented')}
|
|
270
|
-
Fall Risk Score: {collected_data.get('fall_risk_score', 'Not assessed')}
|
|
271
|
-
|
|
272
|
-
PSYCHOSOCIAL & DISCHARGE PLANNING
|
|
273
|
-
Living Situation: {collected_data.get('living_situation', 'Not documented')}
|
|
274
|
-
Support System: {collected_data.get('support_system', 'Not documented')}
|
|
275
|
-
Advance Directives: {collected_data.get('advance_directives', 'Not documented')}
|
|
276
|
-
Code Status: {collected_data.get('code_status', 'Not documented')}
|
|
277
|
-
Barriers to Care: {collected_data.get('barriers_to_care', 'None identified')}
|
|
278
|
-
Discharge Planning Needs: {collected_data.get('discharge_planning_needs', 'Not documented')}
|
|
279
|
-
|
|
280
|
-
INITIAL CARE PLAN
|
|
281
|
-
Nursing Diagnoses: {collected_data.get('nursing_diagnoses', 'Not documented')}
|
|
282
|
-
Care Priorities: {collected_data.get('care_priorities', 'Not documented')}
|
|
283
|
-
Patient Goals: {collected_data.get('patient_goals', 'Not documented')}
|
|
284
|
-
Pending Orders: {collected_data.get('pending_orders', 'None noted')}
|
|
285
|
-
Patient Education Needs: {collected_data.get('patient_education_needs', 'Not documented')}
|
|
286
|
-
Follow-up Required: {collected_data.get('follow_up_required', 'Not documented')}
|
|
287
|
-
|
|
288
|
-
Completed by: [Nurse Name]
|
|
289
|
-
Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M')}
|
|
290
|
-
"""
|
|
291
|
-
|
|
292
|
-
return {
|
|
293
|
-
"admission_assessment": collected_data,
|
|
294
|
-
"narrative": narrative.strip(),
|
|
295
|
-
"metadata": {
|
|
296
|
-
"generated_at": datetime.now().isoformat(),
|
|
297
|
-
"admission_date": collected_data.get(
|
|
298
|
-
"admission_date", datetime.now().strftime("%Y-%m-%d %H:%M")
|
|
299
|
-
),
|
|
300
|
-
"wizard_type": "admission_assessment",
|
|
301
|
-
},
|
|
302
|
-
"banner": EDU_BANNER,
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
@router.post("/start", summary="Start Admission Assessment Wizard")
|
|
307
|
-
async def start_admission_assessment_wizard():
|
|
308
|
-
"""
|
|
309
|
-
Initialize a new admission assessment documentation wizard session.
|
|
310
|
-
|
|
311
|
-
Admission assessment is the comprehensive initial evaluation performed
|
|
312
|
-
when a patient is admitted to a healthcare facility.
|
|
313
|
-
|
|
314
|
-
Returns a wizard session ID and first step configuration.
|
|
315
|
-
"""
|
|
316
|
-
try:
|
|
317
|
-
wizard_id = str(uuid4())
|
|
318
|
-
|
|
319
|
-
session_data = {
|
|
320
|
-
"wizard_id": wizard_id,
|
|
321
|
-
"wizard_type": "admission_assessment",
|
|
322
|
-
"current_step": 1,
|
|
323
|
-
"total_steps": 7,
|
|
324
|
-
"collected_data": {},
|
|
325
|
-
"created_at": datetime.now().isoformat(),
|
|
326
|
-
"updated_at": datetime.now().isoformat(),
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
# Store session
|
|
330
|
-
await _store_wizard_session(wizard_id, session_data)
|
|
331
|
-
|
|
332
|
-
# Get first step data
|
|
333
|
-
step_data = _get_step_data(1)
|
|
334
|
-
|
|
335
|
-
response_data = {
|
|
336
|
-
"wizard_session": session_data,
|
|
337
|
-
"current_step": step_data,
|
|
338
|
-
"progress": {"current": 1, "total": 6, "percentage": 17},
|
|
339
|
-
"banner": EDU_BANNER,
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return create_success_response(
|
|
343
|
-
data=response_data,
|
|
344
|
-
message="Admission assessment wizard started successfully",
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
except Exception as e:
|
|
348
|
-
logger.error(f"Failed to start admission assessment wizard: {e}")
|
|
349
|
-
raise HTTPException(
|
|
350
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
351
|
-
detail=f"Failed to start admission assessment wizard: {str(e)}",
|
|
352
|
-
)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
@router.post("/{wizard_id}/step", summary="Submit admission assessment wizard step")
|
|
356
|
-
async def submit_admission_assessment_step(wizard_id: str, step_data: dict[str, Any]):
|
|
357
|
-
"""
|
|
358
|
-
Submit data for current step and advance to next step.
|
|
359
|
-
|
|
360
|
-
The wizard will validate the data, store it, and either:
|
|
361
|
-
- Return the next step configuration (if more steps remain)
|
|
362
|
-
- Return the complete admission assessment report (if all steps completed)
|
|
363
|
-
"""
|
|
364
|
-
try:
|
|
365
|
-
# Retrieve session
|
|
366
|
-
session = await _get_wizard_session(wizard_id)
|
|
367
|
-
if not session:
|
|
368
|
-
raise HTTPException(
|
|
369
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
|
370
|
-
detail=f"Wizard session {wizard_id} not found",
|
|
371
|
-
)
|
|
372
|
-
|
|
373
|
-
current_step = session["current_step"]
|
|
374
|
-
total_steps = session["total_steps"]
|
|
375
|
-
|
|
376
|
-
# Validate step number
|
|
377
|
-
submitted_step = step_data.get("step", current_step)
|
|
378
|
-
if submitted_step != current_step:
|
|
379
|
-
raise HTTPException(
|
|
380
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
381
|
-
detail=f"Expected step {current_step}, got step {submitted_step}",
|
|
382
|
-
)
|
|
383
|
-
|
|
384
|
-
# Store submitted data
|
|
385
|
-
session["collected_data"].update(step_data.get("data", {}))
|
|
386
|
-
session["updated_at"] = datetime.now().isoformat()
|
|
387
|
-
|
|
388
|
-
# Advance to next step (but don't auto-complete, even on final step)
|
|
389
|
-
if current_step < total_steps:
|
|
390
|
-
next_step = current_step + 1
|
|
391
|
-
session["current_step"] = next_step
|
|
392
|
-
else:
|
|
393
|
-
# On review step - stay on same step, don't auto-complete
|
|
394
|
-
next_step = current_step
|
|
395
|
-
|
|
396
|
-
await _store_wizard_session(wizard_id, session)
|
|
397
|
-
|
|
398
|
-
# Get next step configuration
|
|
399
|
-
next_step_data = _get_step_data(next_step)
|
|
400
|
-
|
|
401
|
-
response_data = {
|
|
402
|
-
"wizard_session": session,
|
|
403
|
-
"current_step": next_step_data,
|
|
404
|
-
"progress": {
|
|
405
|
-
"current": next_step,
|
|
406
|
-
"total": total_steps,
|
|
407
|
-
"percentage": int((next_step / total_steps) * 100),
|
|
408
|
-
},
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
return create_success_response(
|
|
412
|
-
data=response_data,
|
|
413
|
-
message=f"Step {current_step} completed, moved to step {next_step}",
|
|
414
|
-
)
|
|
415
|
-
|
|
416
|
-
except HTTPException:
|
|
417
|
-
raise
|
|
418
|
-
except Exception as e:
|
|
419
|
-
logger.error(f"Failed to process admission assessment wizard step: {e}")
|
|
420
|
-
raise HTTPException(
|
|
421
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
422
|
-
detail=f"Failed to process wizard step: {str(e)}",
|
|
423
|
-
)
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
@router.post("/{wizard_id}/enhance", summary="Enhance admission assessment text with AI")
|
|
427
|
-
async def enhance_admission_assessment_text(wizard_id: str, text_data: dict[str, Any]):
|
|
428
|
-
"""
|
|
429
|
-
Enhance user-provided text with AI to improve clinical documentation quality.
|
|
430
|
-
|
|
431
|
-
Uses the chat service to refine language, add clinical terminology,
|
|
432
|
-
and improve clarity while preserving the original meaning.
|
|
433
|
-
"""
|
|
434
|
-
try:
|
|
435
|
-
# Verify wizard session exists
|
|
436
|
-
session = await _get_wizard_session(wizard_id)
|
|
437
|
-
if not session:
|
|
438
|
-
raise HTTPException(
|
|
439
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
|
440
|
-
detail=f"Wizard session {wizard_id} not found",
|
|
441
|
-
)
|
|
442
|
-
|
|
443
|
-
original_text = text_data.get("text", "")
|
|
444
|
-
field_name = text_data.get("field", "text")
|
|
445
|
-
|
|
446
|
-
if not original_text:
|
|
447
|
-
raise HTTPException(
|
|
448
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
449
|
-
detail="No text provided for enhancement",
|
|
450
|
-
)
|
|
451
|
-
|
|
452
|
-
# Get chat service
|
|
453
|
-
chat_service = get_service("chat")
|
|
454
|
-
|
|
455
|
-
# Create enhancement prompt
|
|
456
|
-
enhancement_prompt = f"""
|
|
457
|
-
You are assisting with admission assessment documentation. Please enhance the following text
|
|
458
|
-
to be more professional and clinically appropriate while preserving the original meaning:
|
|
459
|
-
|
|
460
|
-
Field: {field_name}
|
|
461
|
-
Original text: {original_text}
|
|
462
|
-
|
|
463
|
-
Please provide an enhanced version that:
|
|
464
|
-
- Uses appropriate clinical terminology
|
|
465
|
-
- Is clear and concise
|
|
466
|
-
- Maintains professional tone
|
|
467
|
-
- Preserves all key information
|
|
468
|
-
- Follows nursing admission assessment documentation standards
|
|
469
|
-
|
|
470
|
-
Enhanced text:"""
|
|
471
|
-
|
|
472
|
-
# Call chat service for enhancement
|
|
473
|
-
chat_response = await chat_service.chat(
|
|
474
|
-
message=enhancement_prompt,
|
|
475
|
-
conversation_id=f"admission_enhance_{wizard_id}",
|
|
476
|
-
context={"wizard_id": wizard_id, "field": field_name},
|
|
477
|
-
)
|
|
478
|
-
|
|
479
|
-
enhanced_text = chat_response.get("response", original_text)
|
|
480
|
-
|
|
481
|
-
response_data = {
|
|
482
|
-
"original_text": original_text,
|
|
483
|
-
"enhanced_text": enhanced_text,
|
|
484
|
-
"field": field_name,
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
return create_success_response(data=response_data, message="Text enhanced successfully")
|
|
488
|
-
|
|
489
|
-
except HTTPException:
|
|
490
|
-
raise
|
|
491
|
-
except Exception as e:
|
|
492
|
-
logger.error(f"Failed to enhance admission assessment text: {e}")
|
|
493
|
-
raise HTTPException(
|
|
494
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
495
|
-
detail=f"Failed to enhance text: {str(e)}",
|
|
496
|
-
)
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
@router.post("/{wizard_id}/preview", summary="Preview admission assessment report")
|
|
500
|
-
async def preview_admission_assessment_report(wizard_id: str):
|
|
501
|
-
"""
|
|
502
|
-
Generate preview of admission assessment report without finalizing.
|
|
503
|
-
|
|
504
|
-
This endpoint allows users to see the formatted admission assessment before
|
|
505
|
-
finalizing it. The report is NOT marked as complete. Users can
|
|
506
|
-
still go back and edit data after previewing.
|
|
507
|
-
"""
|
|
508
|
-
try:
|
|
509
|
-
session = await _get_wizard_session(wizard_id)
|
|
510
|
-
if not session:
|
|
511
|
-
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Session not found")
|
|
512
|
-
|
|
513
|
-
# Verify user is on review step
|
|
514
|
-
if session["current_step"] != session["total_steps"]:
|
|
515
|
-
raise HTTPException(
|
|
516
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
|
517
|
-
detail=f"Not on review step. Complete steps 1-{session['total_steps']-1} first.",
|
|
518
|
-
)
|
|
519
|
-
|
|
520
|
-
# Generate preview report (does NOT mark as complete)
|
|
521
|
-
preview_report = _generate_admission_assessment_report(session["collected_data"])
|
|
522
|
-
|
|
523
|
-
# Store preview in session
|
|
524
|
-
session["preview_report"] = preview_report
|
|
525
|
-
session["preview_generated_at"] = datetime.now().isoformat()
|
|
526
|
-
await _store_wizard_session(wizard_id, session)
|
|
527
|
-
|
|
528
|
-
response_data = {
|
|
529
|
-
"preview": preview_report,
|
|
530
|
-
"wizard_session": session,
|
|
531
|
-
"message": "Review the admission assessment above. Click 'Finalize Report' to save, or go back to edit any section.",
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
return create_success_response(data=response_data, message="Preview generated successfully")
|
|
535
|
-
|
|
536
|
-
except HTTPException:
|
|
537
|
-
raise
|
|
538
|
-
except Exception as e:
|
|
539
|
-
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
@router.post("/{wizard_id}/save", summary="Finalize admission assessment report")
|
|
543
|
-
async def save_admission_assessment_report(wizard_id: str, approval_data: dict[str, Any]):
|
|
544
|
-
"""
|
|
545
|
-
Finalize and save the admission assessment report after user review and approval.
|
|
546
|
-
|
|
547
|
-
Requires that the user has:
|
|
548
|
-
1. Generated a preview first (/preview endpoint)
|
|
549
|
-
2. Explicitly approved the report (user_approved: true)
|
|
550
|
-
|
|
551
|
-
Only after calling this endpoint is the report marked as complete.
|
|
552
|
-
"""
|
|
553
|
-
try:
|
|
554
|
-
session = await _get_wizard_session(wizard_id)
|
|
555
|
-
if not session:
|
|
556
|
-
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Session not found")
|
|
557
|
-
|
|
558
|
-
# Verify preview was generated
|
|
559
|
-
if "preview_report" not in session:
|
|
560
|
-
raise HTTPException(
|
|
561
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
|
562
|
-
detail="Must generate preview before saving. Call /preview endpoint first.",
|
|
563
|
-
)
|
|
564
|
-
|
|
565
|
-
# Verify user explicitly approved
|
|
566
|
-
if not approval_data.get("user_approved", False):
|
|
567
|
-
raise HTTPException(
|
|
568
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
|
569
|
-
detail="User approval required. Set 'user_approved': true in request body.",
|
|
570
|
-
)
|
|
571
|
-
|
|
572
|
-
# NOW we mark as complete
|
|
573
|
-
session["completed"] = True
|
|
574
|
-
session["completed_at"] = datetime.now().isoformat()
|
|
575
|
-
session["final_report"] = session["preview_report"]
|
|
576
|
-
session["user_approved"] = True
|
|
577
|
-
|
|
578
|
-
await _store_wizard_session(wizard_id, session)
|
|
579
|
-
|
|
580
|
-
response_data = {
|
|
581
|
-
"wizard_session": session,
|
|
582
|
-
"report": session["final_report"],
|
|
583
|
-
"completed": True,
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
return create_success_response(
|
|
587
|
-
data=response_data, message="Admission assessment finalized successfully"
|
|
588
|
-
)
|
|
589
|
-
|
|
590
|
-
except HTTPException:
|
|
591
|
-
raise
|
|
592
|
-
except Exception as e:
|
|
593
|
-
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
@router.get("/{wizard_id}/report", summary="Get admission assessment report")
|
|
597
|
-
async def get_admission_assessment_report(wizard_id: str):
|
|
598
|
-
"""
|
|
599
|
-
Retrieve the completed admission assessment report.
|
|
600
|
-
|
|
601
|
-
Only available after all wizard steps have been completed.
|
|
602
|
-
Returns the structured assessment data and formatted narrative.
|
|
603
|
-
"""
|
|
604
|
-
try:
|
|
605
|
-
# Retrieve session
|
|
606
|
-
session = await _get_wizard_session(wizard_id)
|
|
607
|
-
if not session:
|
|
608
|
-
raise HTTPException(
|
|
609
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
|
610
|
-
detail=f"Wizard session {wizard_id} not found",
|
|
611
|
-
)
|
|
612
|
-
|
|
613
|
-
# Check if completed
|
|
614
|
-
if not session.get("completed", False):
|
|
615
|
-
raise HTTPException(
|
|
616
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
617
|
-
detail="Admission assessment wizard not yet completed. Complete all steps first.",
|
|
618
|
-
)
|
|
619
|
-
|
|
620
|
-
# Generate report
|
|
621
|
-
report = _generate_admission_assessment_report(session["collected_data"])
|
|
622
|
-
|
|
623
|
-
response_data = {
|
|
624
|
-
"wizard_session": session,
|
|
625
|
-
"report": report,
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
return create_success_response(
|
|
629
|
-
data=response_data,
|
|
630
|
-
message="Admission assessment report retrieved successfully",
|
|
631
|
-
)
|
|
632
|
-
|
|
633
|
-
except HTTPException:
|
|
634
|
-
raise
|
|
635
|
-
except Exception as e:
|
|
636
|
-
logger.error(f"Failed to retrieve admission assessment report: {e}")
|
|
637
|
-
raise HTTPException(
|
|
638
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
639
|
-
detail=f"Failed to retrieve report: {str(e)}",
|
|
640
|
-
)
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
# Export router
|
|
644
|
-
__all__ = ["router"]
|