Investment Plans workspace
Open raw ↗

Comprehensive Specification Mining & Handoff Report: HAD Digital MVP

Agent: spec_miner_survey_1 Working Directory: c:\AI Projects\Kais Project\.agents\spec_miner_survey_1 Date: 2026-09-05 Mission: Exhaustive discovery and specification mining for HAD Digital MVP skeleton (Authentication, Patient Toxicity Reporting, Care Timeline, Local-First Architecture, Executable Packaging).


1. Observation

Authoritative specification documents, reference architectures, and codebase artifacts were inspected across c:\AI Projects\Kais Project:

  1. ORIGINAL_REQUEST.md (Lines 11–36):
    • "Build the foundational skeleton for the HAD Digital MVP: a standalone Windows executable (.exe) Python web application for home-hospitalization oncology patients and their care teams."
    • R1. Standalone Executable Packaging: Bundled via PyInstaller into a single Windows executable (.exe) containing Python web server (Flask or http.server) and embedded SQLite database, zero external dependencies on host machine.
    • R2. Foundational Core Features: Role-based authentication (Oncologist, Nurse, Patient), basic patient toxicity reporting form (saving to SQLite), basic care timeline displaying submitted reports.
    • R3. Local-First Frontend: Responsive HTML5/CSS3/vanilla JS frontend interacting with embedded backend.
    • Acceptance Criteria: Automatic packaging build script; programmatic verification script testing launch, auth, and zero-dependency server response; patient login & SQLite report submission; clinician login & timeline viewing.
  1. HAD_Digital_Specifications.docx (Cahier des Charges, Dr Kais Aldabbagh, Medical Oncology, Polyclinique St Côme):
    • Originated 1 September 2026 for French Hospitalisation à Domicile (HAD) oncology care.
    • Defines the centerpiece Toxicity Reader module: structured CTCAE v5.0 capture, automated grading, and tiered alerts (Routine, Urgent, Emergency).
    • Core clinical triage triad: Oncologist, HAD Coordinating Nurse, Patient/Caregiver, supported by Community Nurse, General Practitioner, Pharmacist, and Admin.
    • Safety rule: Decision-support tool, not autonomous diagnostic software; all automated grades $\ge 2$ flagged as "provisional" pending qualified clinician review.
  1. 02_Requirements/Role_Permissions.md (Lines 15–164):
    • 8 user roles: oncologist, had_nurse, community_nurse, gp, pharmacist, patient, caregiver, admin.
    • Access control across 9 permission categories: Patient Data, Toxicity Reports, CTCAE Grades, Alerts, Timeline, Treatment Plans, Messages, Export & Reports, System Administration.
    • Session policy: HAD_SESSION cookie with 24-hour max-age, 5-fail lockout (30 minutes).
  1. 02_Requirements/User_Stories.md (Lines 15–420):
    • 23 user stories across 12 Epics (22 HIGH priority in MVP scope, 1 escalation chain story deferred to Phase 2).
    • Traceable to FR-1 through FR-11 and CAP-12 through CAP-20.
  1. 02_Requirements/CTCAE_Term_Subset.md & MVP/data/ctcae_rules.json:
    • 5 core symptom domains: Gastrointestinal, Hematologic, Dermatologic, Neurologic, Constitutional.
    • 12 prioritized terms in MVP: Nausea, Vomiting, Diarrhea, Neutropenia, Anemia, Thrombocytopenia, Rash/Dermatitis, Alopecia, Peripheral Neuropathy, Fatigue, Fever, Febrile Neutropenia.
    • Rules map quantitative and qualitative inputs (e.g., severity_score, episodes_per_24h, stools_increase_per_day, anc_mm3, hemoglobin_gdl, platelets_mm3, temp_celsius, bsa_percent) to Grades 1–5.
  1. 02_Requirements/Escalation_Protocol.md & MVP/alert_engine.py:
    • Tier 1: Routine (Grade 1 $\rightarrow$ timeline only, 48h review window).
    • Tier 2: Urgent (Grade 2 $\rightarrow$ notification to HAD nurse within 30 min delay).
    • Tier 3: Emergency (Grade 3+ or high-risk Grade 2+ like fever >38.5°C with neutropenia $\rightarrow$ immediate notification to on-call oncologist within 5 min).
  1. 03_Architecture/API_Contract.md & MVP/app.py:
    • Pure Python standard library http.server backend (zero external runtime dependencies).
    • 19 REST API endpoints under /api.
    • Security headers: Content-Security-Policy, X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin, Cache-Control: no-store.
  1. 03_Architecture/Database_Schema.md & MVP/database.py:
    • SQLite with WAL (journal_mode=WAL), foreign key enforcement (foreign_keys=ON), 5000ms busy timeout.
    • 10 relational tables: users, patients, episodes, treatment_plans, toxicity_reports, toxicity_grades, alerts, messages, timeline_events, audit_log.
  1. MVP/static/ (index.html, app.css, app.js):
    • Responsive Single Page Application (vanilla JS, modern CSS3 variables, no npm or frontend build tool).
    • Role-customized navigation shell, patient reporting questionnaire, clinician observation form, care timeline, alert center, export modal, demo credentials.

2. Logic Chain

  1. Traceability to Original Request:
    • The user requested an MVP skeleton satisfying standalone Windows executable packaging (R1), core features (R2: role-based auth, toxicity reporting, care timeline), and a local-first frontend (R3).
    • The authoritative specification set in 02_Requirements and 03_Architecture expands R1–R3 into an explicit clinical coordination architecture designed for French Hospitalisation à Domicile (HAD).
  1. Architecture Decoupling and Portability:
    • By adopting Python's built-in http.server, sqlite3, and hashlib.scrypt, the system eliminates runtime dependencies on pip, npm, Docker, or external DBMS services.
    • Relative path resolution (Path(__file__).resolve().parent) ensures that data (data/had.db), rules (data/ctcae_rules.json), guidance (guidance/guidance.json), and logs (logs/) remain portable across host filesystems and USB drives.
  1. Clinical Safety & Regulatory Design:
    • The CTCAE grading engine enforces clinical safety by designating all automated grades $\ge 2$ as provisional = 1 until reviewed and confirmed by a clinician.
    • All critical actions (login, logout, report submission, grading, alerting, acknowledgment, data export) append immutable records to audit_log.
  1. Edge Case Handling:
    • Testing proved that missing input thresholds, unknown symptoms, out-of-range inputs, and unauthenticated/unauthorized API queries fail safely without throwing unhandled exceptions or corrupting SQLite state.
    • Account lockout occurs after 5 failed authentication attempts for 30 minutes.

3. Features Discovered

#CategoryFeatureDescriptionInputsOutputsError BehaviorDiscovered Via
1AuthUser LoginAuthenticates user credentials using hashlib.scrypt with per-user salt; establishes sessionJSON: {username, password}200 OK + Set-Cookie: HAD_SESSION=..., user object400 Bad Request if missing fields; 401 Unauthorized if invalid or lockedAPI_Contract.md, user_store.py:68
2AuthUser LogoutTerminates active session and clears session cookieHeader: Cookie: HAD_SESSION200 OK + expired session cookieSilent no-op if session does not existAPI_Contract.md, app.py:201
3AuthSession Verification (/api/whoami)Checks caller session identity and returns role/profileHeader: Cookie: HAD_SESSION200 OK: {authenticated: true, user: {...}}401 Unauthorized: {authenticated: false} if no sessionAPI_Contract.md, app.py:209
4AuthAccount LockoutLocks user account for 30 minutes after 5 consecutive failed password attemptsFailed login attempts on same usernameIncremented failed_attempts, locked_until timestamp401 Unauthorized on subsequent attempts until expiryuser_store.py:71, Database_Schema.md
5PatientList Patients (/api/patients)Retrieves patients filtered by calling user role and assignmentQuery params: id (optional); Caller role in session200 OK: {patients: [...]}401 Unauthorized if not logged inAPI_Contract.md, app.py:216
6PatientPatient Detail (/api/patients/{id})Retrieves patient demographics, active treatment plan, recent grades, and pending alertsURL path: patient_id200 OK: Full patient detail record401 Unauthorized; 404 Not Found if ID invalidAPI_Contract.md, app.py:233
7ToxicityPatient Self-Report (/api/reports)Submits symptom report covering CTCAE domains (GI, hematologic, dermatologic, neurologic, constitutional)JSON: patient_id, symptom_id, symptom_category, severity_score, notes, grading_inputs201 Created: {message, report_id, grading, alert}400 Bad Request if missing required fields; 401 if unauthenticatedAPI_Contract.md, app.py:253
8ToxicityClinician Observation EntryClinician submits home-visit clinical findings, vital signs, and observed toxicity signsJSON: patient_id, vital signs (temp, bp, hr, spo2, weight), symptoms, notes, type201 Created: Saved report and timeline event400 Bad Request if missing patient/symptom fieldsUser_Stories.md:US-2.1, app.js:247
9ToxicityList Reports (/api/reports)Lists past toxicity reports for a specified patientQuery param: patient_id200 OK: {reports: [...]}400 Bad Request if patient_id omitted; 401 if not logged inAPI_Contract.md, app.py:290
10CTCAEAutomated Grading EngineEvaluates symptom inputs against CTCAE v5.0 thresholds; assigns grades 1–5; marks grades $\ge 2$ provisionalsymptom_id, input dictionary (e.g. severity_score, anc_mm3)Dict: grade, criteria, intervention, provisional, matched_thresholdReturns grade: None + error string if symptom unknown or inputs out of rangectcae_engine.py:52, CTCAE_Term_Subset.md
11CTCAEList Grades (/api/grades)Retrieves graded toxicity assessments for a patientQuery param: patient_id200 OK: {grades: [...]}400 if patient_id missing; 401 if unauthenticatedAPI_Contract.md, app.py:303
12CTCAEList Symptoms (/api/symptoms)Enumerates all configured CTCAE symptom terms and categoriesNone200 OK: {symptoms: [{symptom_id, display_name, category}, ...]}200 with empty list if rules file missingAPI_Contract.md, app.py:453
13CTCAEConfirm Provisional GradePrescribing oncologist confirms or overrides provisional automated gradegrade_id, confirmed_by user IDUpdated provisional = 0, confirmed_by, confirmed_at in DBReturns False if grade ID does not existctcae_engine.py:185, Role_Permissions.md
14AlertsTiered Alert RoutingRoutes grades to Routine (timeline only), Urgent (HAD nurse notification), or Emergency (oncologist alert)Grade, symptom ID, patient ID, report IDAlert created in alerts, notification message sent, timeline updatedReturns None if Grade < 1 or > 5alert_engine.py:31, Escalation_Protocol.md
15AlertsList Alerts (/api/alerts)Retrieves alerts filtered by patient, status, or roleQuery params: patient_id, status200 OK: {alerts: [...]}401 Unauthorized if not logged inAPI_Contract.md, app.py:316
16AlertsAcknowledge Alert (/api/alerts/{id}/acknowledge)Clinician marks an alert acknowledged, stamping user and timestampURL path: alert_id200 OK: {message: "Alert acknowledged"}404 Not Found if alert ID invalid; 401 if unauthenticatedAPI_Contract.md, app.py:330
17TimelineCare Coordination Timeline (/api/timeline)Unified chronological stream of reports, observations, grades, alerts, and care notesQuery params: patient_id, episode_id, limit200 OK: {events: [...]} ordered by event_date DESC401 Unauthorized if not logged inAPI_Contract.md, app.py:341
18TreatmentTreatment Plan View (/api/treatment-plan)Displays protocol name, regimen, cycle count, drugs, schedule, and supportive careQuery param: patient_id200 OK: {treatment_plans: [...]}400 if patient_id missing; 401 if unauthenticatedAPI_Contract.md, app.py:359
19MessagesSend Message (/api/messages)Secure direct or role-directed messaging between care-team membersJSON: recipient_id, recipient_role, patient_id, subject, body, message_type201 Created: {message: "Message sent", message_id: ...}400 Bad Request if body empty; 401 if unauthenticatedAPI_Contract.md, app.py:372
20MessagesList Messages (/api/messages)Lists messages where caller is sender, recipient, or recipient roleQuery params: patient_id (optional), limit200 OK: {messages: [...]}401 Unauthorized if not logged inAPI_Contract.md, app.py:389
21ExportToxicity Summary Export (/api/export/summary)Compiles structured JSON summary with patient metadata, treatment plans, and symptom grade historyQuery params: patient_id, start, end200 OK: Full clinical summary JSON400 if patient_id missing; 404 if patient not foundAPI_Contract.md, app.py:406
22GuidancePatient Guidance (/api/guidance)Delivers French-language actionable guidance per symptom and grade (self-care vs contact team vs emergency)Query params: symptom_id, grade (optional)200 OK: Guidance object with title, patient message, actions, when_to_call400 if symptom_id missing; 404 if symptom or grade not foundAPI_Contract.md, app.py:456, guidance.json
23AuditImmutable Audit Log (/api/audit-log)Records timestamped user actions, resources, IPs, and details; accessible by AdminQuery params: limit, offset, action200 OK: {audit_log: [...]}403 Forbidden if caller is not admin; 401 if unauthenticatedAPI_Contract.md, app.py:439
24AIPluggable AI Assistant (/api/chat)Natural language assistant supporting stub (offline demo) or glm (online API)JSON: message, patient_id, history, symptoms200 OK: {response: "...", adapter: "..."}400 if message empty; 401 if unauthenticatedAPI_Contract.md, app.py:483, adapters/
25UI ShellMobile-First SPA NavigationClient-side vanilla JS router, role-customized nav bar, modal overlays, toast alertsBrowser user interactionsRendered views: Dashboard, Report, Observation, Timeline, Alerts, Treatment, Messages, Export, PatientsToast notification on error; auto-redirect to login on 401static/app.js, static/app.css
26DataDemo Data Auto-SeederSeeds realistic French patients (Jeanne Durand, Pierre Moreau, Marie-Claire Laurent), treatment plans, users for all rolesServer start when users table is emptyPre-populated database with 3 patients, 11 users, active plans, alertsSkips seeding if users already exist (idempotent)seed_demo.py, app.py:515
27PackagingPyInstaller .exe BuildPackages application into single binary or folder bundle with embedded Python runtime & SQLitePyInstaller CLI / Spec fileHAD Digital.exe in dist/Build error if missing static or data assetsHAD Digital.spec, README.md:259

4. Edge Cases

#FeatureInputObserved Behavior
1CTCAE GradingUnknown symptom ID (non_existent)Returns {grade: None, criteria: 'Unknown symptom: non_existent', provisional: True, error: "No rule found for symptom 'non_existent'"}. Does not crash.
2CTCAE GradingEmpty inputs dictionary {} for valid symptom (nausea)Returns {grade: None, criteria: 'No matching grade found for provided inputs', provisional: True, error: 'Inputs did not match any grade threshold'}.
3CTCAE GradingZero severity score ({'severity_score': 0}) where grade 1 starts at 1Returns grade: None (indicates symptom absent/grade 0). Safe no-grade outcome.
4CTCAE GradingOut-of-bounds high value ({'severity_score': 999}) where grade 5 caps at 11Returns grade: None with 'Inputs did not match any grade threshold'.
5CTCAE GradingString value for numeric threshold ({'severity_score': 'abc'})Caught by (ValueError, TypeError) in threshold loop; returns grade: None safely.
6AuthenticationNon-existent usernameReturns None from authenticate(); logs login_failed audit entry; returns 401 Unauthorized.
7Authentication5 consecutive wrong passwords for existing userIncrements failed_attempts to 5; sets locked_until to now + 30 minutes; denies subsequent attempts with 401 until time expires.
8AuthenticationLogin after lockout period expiresResets failed_attempts = 0 and locked_until = NULL; authenticates normally if password correct.
9Alert EngineGrade out of range (< 1 or > 5, e.g. Grade 0 or Grade 6)Returns None; creates no alert and no timeline event.
10Alert EngineGrade 1 toxicity reportReturns None (no alert created in alerts table); logs routine notification event to timeline_events.
11Static FilesPath traversal attempt (/static/../../etc/passwd or ..\config.json)Intercepted by resolved path check against static directory; returns 403 Forbidden (Path traversal blocked).
12API AuthRequest to protected endpoint without HAD_SESSION cookieReturns 401 Unauthorized ({"error": "Authentication required"}).
13RBAC Export / PatientsPatient user requests patient listServer returns only their own linked patient profile (user['patient_id']). Cannot view other patients.
14RBAC Admin APINon-admin user calls /api/audit-logReturns 403 Forbidden ({"error": "Admin access required"}).
15Database ConcurrencySimultaneous read/write operationsSQLite WAL mode handles multi-reader concurrency with thread-local connections and busy_timeout=5000.

5. Detailed User Roles & Permissions Matrix

The platform specifies 8 distinct roles (02_Requirements/Role_Permissions.md), centered around the Oncology Triage Triad (Oncologist, HAD Nurse, Patient):

  1. oncologist: Hospital oncologist / referring physician. Prescribes treatment protocols, defines toxicity thresholds and escalation protocols, confirms provisional CTCAE grades $\ge 2$, overrides automated grades, resolves alerts, reviews care timeline, generates clinical exports.
  1. had_nurse: HAD coordinating nurse. Daily central point of coordination and triage, receives urgent alerts, triages incoming reports, schedules home visits, reviews Grade 1 timeline events, acknowledges alerts, communicates with oncology team and community nurses.
  1. community_nurse: Community/liberal nurse. Conducts home visits, performs clinician observation entry (vital signs, skin/wound signs), administers supportive care, receives urgent alert notifications, views assigned patient timeline.
  1. gp: General practitioner (Médecin Traitant). Informed of patient episode progress, read-access to assigned patient timeline, treatment plans, and reports; first responder in designated emergencies.
  1. pharmacist: Hospital / HAD pharmacist. Reviews systemic therapy protocols, drug dosages, drug-drug interactions, and supportive care prescriptions.
  1. patient: Patient undergoing home hospitalization. Completes structured CTCAE symptom questionnaires on scheduled cadence and on demand, accesses physician-validated guidance, views own timeline and treatment plan, sends messages to care team.
  1. caregiver: Family member / designated support person. Reports symptoms alongside or on behalf of patient, consumes guidance, views patient timeline.
  1. admin: System administrator. Manages user accounts, configures system parameters, inspects full immutable audit trail and system diagnostics.

Matrix of Permissions Across Functional Categories

Functional DomainAction / PermissionOncologistHAD NurseCommunity NurseGPPharmacistPatientCaregiverAdmin
Patient DataView patient list✓✓✓✓✓✗✗✓
View patient details✓✓✓✓✓✓ (own)✓ (own)✓
Edit patient demographics✓✓✗✗✗✗✗✓
Toxicity ReportsSubmit patient self-report✗✗✗✗✗✓✓✗
Submit clinician observation✓✓✓✗✗✗✗✗
View all reports✓✓✓✓✓✗✗✓
View assigned patient reports✓✓✓✓✓✓ (own)✓ (own)✓
CTCAE GradesView grades✓✓✓✓✓✓ (own)✓ (own)✓
Confirm provisional grade ($\ge 2$)✓✗✗✗✗✗✗✗
Override automated grade✓✗✗✗✗✗✗✗
Clinical AlertsView all alerts✓✓✓✗✗✗✗✓
View assigned alerts✓✓✓✓✓✗✗✓
Acknowledge alerts✓✓✓✓✓✗✗✓
Escalate / Resolve alerts✓✓✗✗✗✗✗✓
Care TimelineView all timeline events✓✓✓✗✗✗✗✓
View assigned patient timeline✓✓✓✓✓✓ (own)✓ (own)✓
Add clinical notes to timeline✓✓✓✓✗✗✗✓
Treatment PlansView treatment plans✓✓✓✓✓✓ (own)✓ (own)✓
Create / Modify plans✓✗✗✗✗✗✗✗
MessagingSend direct messages✓✓✓✓✓✓✓✓
View messages✓✓✓✓✓✓ (own)✓ (own)✓
Exports & AuditExport toxicity summary✓✓✓✓✓✗✗✓
View audit log✗✗✗✗✗✗✗✓

6. Complete Data Model & Field Enumerations

Database: SQLite with Write-Ahead Logging (PRAGMA journal_mode=WAL), Foreign Key enforcement (PRAGMA foreign_keys=ON), and busy timeout (5000ms).

Table 1: users

Table 2: patients

Table 3: episodes

Table 4: treatment_plans

Table 5: toxicity_reports

Table 6: toxicity_grades

Table 7: alerts

Table 8: messages

Table 9: timeline_events

Table 10: audit_log (Immutable / Append-Only)


7. API Endpoints & Contract Requirements

Base URL: http://127.0.0.1:8080 (API root /api)

  1. POST /api/login:
    • Auth required: No.
    • Body: {"username": "<string>", "password": "<string>"}.
    • Response 200: {"message": "Login successful", "user": {"id": 1, "username": "admin", "role": "admin", "display_name": "..."}}.
    • Headers: Set-Cookie: HAD_SESSION=<uuid>; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400.
    • Response 400: {"error": "Username and password required"}.
    • Response 401: {"error": "Invalid credentials or account locked"}.
  1. POST /api/logout:
    • Auth required: Yes (session cookie).
    • Body: Empty {}.
    • Response 200: {"message": "Logged out"}.
    • Headers: Set-Cookie: HAD_SESSION=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0.
  1. GET /api/whoami:
    • Auth required: Optional.
    • Response 200 (authenticated): {"authenticated": true, "user": {"id": 1, "username": "...", "role": "...", "display_name": "..."}}.
    • Response 401 (unauthenticated): {"authenticated": false}.
  1. GET /api/patients:
    • Auth required: Yes.
    • Query params: id (optional).
    • Logic: Patients/caregivers receive only their assigned patient profile; clinicians/admins receive active patient roster.
    • Response 200: {"patients": [{"id": 1, "mrn": "MRN-2024-001", "first_name": "Jeanne", "last_name": "Durand", ...}]}.
  1. GET /api/patients/{id}:
    • Auth required: Yes.
    • Response 200: Full patient record + active_treatment_plan + recent_grades (last 10) + pending_alerts.
    • Response 404: {"error": "Patient not found"}.
  1. POST /api/reports:
    • Auth required: Yes (Patient, Caregiver, Clinician).
    • Body:
     {
       "patient_id": 1,
       "symptom_id": "nausea",
       "symptom_category": "gastrointestinal",
       "severity_score": 5,
       "lab_values": {},
       "notes": "Patient reports moderate nausea preventing solid food",
       "grading_inputs": {"severity_score": 5}
     }
  • Logic: Stores report in toxicity_reports; executes ctcae_engine.grade_and_save(); evaluates grade $\ge 2$ for alert creation via alert_engine; inserts timeline event; logs audit entry.
  • Response 201: {"message": "Report submitted and graded", "report_id": 42, "grading": {...}, "alert": {...}}.
    1. GET /api/reports:
      • Auth required: Yes.
      • Query params: patient_id (required).
      • Response 200: {"reports": [...]} ordered by report_date DESC.
    1. GET /api/grades:
      • Auth required: Yes.
      • Query params: patient_id (required).
      • Response 200: {"grades": [...]} ordered by created_at DESC.
    1. GET /api/symptoms:
      • Auth required: No / Publicly accessible.
      • Response 200: {"symptoms": [{"symptom_id": "nausea", "display_name": "Nausea", "category": "gastrointestinal"}, ...]}.
    1. GET /api/alerts:
      • Auth required: Yes.
      • Query params: patient_id (optional), status (optional).
      • Logic: Patient/caregiver filtered to own patient ID; clinicians see assigned or patient-specific alerts.
      • Response 200: {"alerts": [...]}.
    1. POST /api/alerts/{id}/acknowledge:
      • Auth required: Yes (Clinician, Admin).
      • Logic: Sets status = 'acknowledged', acknowledged_by = user.id, acknowledged_at = datetime('now').
      • Response 200: {"message": "Alert acknowledged"}.
      • Response 404: {"error": "Alert not found"}.
    1. GET /api/timeline:
      • Auth required: Yes.
      • Query params: patient_id (optional), episode_id (optional), limit (default 50).
      • Response 200: {"events": [...]}.
    1. GET /api/treatment-plan:
      • Auth required: Yes.
      • Query params: patient_id (required).
      • Response 200: {"treatment_plans": [...]}.
    1. POST /api/messages:
      • Auth required: Yes.
      • Body: {"recipient_id": 2, "recipient_role": "had_nurse", "patient_id": 1, "subject": "Question", "body": "...", "message_type": "direct"}.
      • Response 201: {"message": "Message sent", "message_id": 15}.
    1. GET /api/messages:
      • Auth required: Yes.
      • Query params: patient_id (optional), limit (default 50).
      • Logic: Returns messages where caller is sender, recipient, or belongs to recipient_role.
      • Response 200: {"messages": [...]}.
    1. GET /api/export/summary:
      • Auth required: Yes (Clinician, Admin).
      • Query params: patient_id (required), start (optional), end (optional).
      • Response 200:
          {
            "patient": {"mrn": "...", "name": "...", "date_of_birth": "...", "cancer_type": "..."},
            "treatment_plans": [...],
            "toxicity_summary": {
              "nausea": {
                "latest_grade": 2,
                "latest_criteria": "...",
                "provisional": true,
                "history": [{"grade": 2, "criteria": "...", "date": "..."}]
              }
            },
            "generated_at": "...",
            "generated_by": "..."
          }
    1. GET /api/guidance:
      • Auth required: Yes / Open.
      • Query params: symptom_id (required), grade (optional 1–4).
      • Response 200: French patient-facing guidance (title, patient_message, actions, when_to_call).
    1. GET /api/audit-log:
      • Auth required: Yes (role == 'admin').
      • Query params: limit (default 100), offset (default 0), action (optional).
      • Response 200: {"audit_log": [...]}.
      • Response 403: {"error": "Admin access required"} if not admin.
    1. POST /api/chat:
      • Auth required: Yes.
      • Body: {"message": "...", "patient_id": 1, "history": [], "symptoms": []}.
      • Response 200: {"response": "...", "adapter": "stub", ...}.

    8. Validation Rules & Business Constraints

    1. Authentication & Session Rules:
      • Password hashing must use standard library hashlib.scrypt with a minimum of 32-byte salt and $N=16384, r=8, p=1$.
      • Plaintext passwords must never be logged or stored.
      • Sessions are identified by high-entropy UUIDv4 tokens stored server-side in memory and transmitted via HttpOnly, SameSite=Strict cookie named HAD_SESSION.
      • Max session age is 86,400 seconds (24 hours).
      • Lockout rule: 5 consecutive failed authentications lock the user account for 30 minutes (locked_until).
    1. Clinical Safety & CTCAE Grading Constraints:
      • System is a clinical decision-support and triage aid, not an autonomous diagnostic tool.
      • All automated CTCAE grades $\ge 2$ must be stored with provisional = 1. Only a licensed oncologist may set provisional = 0 via formal grade confirmation.
      • Input thresholds must match CTCAE v5.0 definitions:
      • Nausea: Grade 1 (score 1–3), Grade 2 (score 4–6), Grade 3 (score 7–8), Grade 4 (score 9–10).
      • Vomiting: Grade 1 (1–2 episodes/24h), Grade 2 (3–5 episodes/24h), Grade 3 (6–9 episodes/24h), Grade 4 ($\ge 10$ episodes/24h).
      • Diarrhea: Grade 1 (<4 increase/day), Grade 2 (4–6 increase/day), Grade 3 ($\ge 7$ increase/day).
      • Fever: Grade 1 (38.0–39.0°C), Grade 2 (>39.0–40.0°C), Grade 3 (>40.0°C $\le 24$h), Grade 4 (>40.0°C $>24$h).
      • Neutropenia: Grade 1 (1000–1500/mm³), Grade 2 (500–999/mm³), Grade 3 (200–499/mm³), Grade 4 (<200/mm³).
      • Febrile Neutropenia: Automatically Grade 3 (ANC <1000/mm³ and temp $\ge 38.0$°C) or Grade 4 (ANC <500/mm³).
    1. Escalation & Alerting Constraints:
      • Grade 1 $\rightarrow$ Routine (logged in timeline_events only, no row inserted in alerts).
      • Grade 2 $\rightarrow$ Urgent (alerts.alert_type = 'urgent', severity = 'medium', assigned to HAD nurse with a target response delay of $\le 30$ minutes).
      • Grade 3+ $\rightarrow$ Emergency (alerts.alert_type = 'emergency', severity = 'high' or 'critical', assigned to on-call oncologist with target response time of $\le 5$ minutes).
      • High-risk symptoms (fever >38.5°C in neutropenic patient, acute bleeding with thrombocytopenia) trigger emergency alert tier even at Grade 2.
    1. Data Isolation & Security Constraints:
      • Patient and caregiver roles must never have access to other patients' data (WHERE patient_id = user.patient_id).
      • Static file server must strictly validate path resolution against static/ root to prevent directory traversal (.. attacks).
      • HTTP responses must send strict security headers: Content-Security-Policy: default-src 'self', X-Content-Type-Options: nosniff, X-Frame-Options: DENY.
      • All clinical modifications must produce an immutable audit log entry in audit_log.

    9. Acceptance Criteria & Traceability

    R1. Standalone Executable Packaging

    R2. Foundational Core Features

    R3. Local-First Frontend


    10. Packaging, Portability & Local-First Requirements

    1. PyInstaller Configuration:
      • Spec file: HAD Digital.spec.
      • Analysis data bundles: static;static, data;data, guidance;guidance, adapters;adapters.
      • Hidden imports: adapters, adapters.stub, adapters.glm, adapters.base.
      • Output mode: Standalone executable (--onedir folder bundle or --onefile single executable).
    1. Relative Path Discipline:
      • All runtime paths resolved relative to executable or app.py:
      • database_path: data/had.db
      • rules_path: data/ctcae_rules.json
      • guidance_path: guidance/guidance.json
      • log_path: logs/had_digital.log
      • Application can be moved to a USB drive or secondary Windows PC without breaking path references or requiring administrator permissions.
    1. Patching Strategy:
      • Drop-in file replacement: Overwriting HAD Digital.exe or static/ leaves data/had.db intact.
      • Database migrations: Forward-only, additive schema creation (CREATE TABLE IF NOT EXISTS, CREATE INDEX IF NOT EXISTS).

    11. Caveats

    1. SaMD Regulatory Qualification: The current MVP is designed for demonstration and pilot validation under clinical governance. Production deployment with real oncology patients requires formal EU MDR Software as a Medical Device (SaMD) qualification, CE marking, and HDS-certified cloud hosting.
    1. Offline Field Sync: The current web application runs locally on 127.0.0.1:8080. True disconnected field sync with a central server is scheduled for Phase 2.
    1. Notification Channels: Push notifications, SMS (Twilio), and automated telephony are modeled via in-app timeline messages in the MVP; telecom integrations are deferred to Phase 2.
    1. AI Engine Connector: Pluggable AI adapter (/api/chat) defaults to StubAdapter for offline zero-dependency demos; requires external network and GLM_API_KEY for online AI responses.

    12. Conclusion

    The specification mining has uncovered and documented 27 distinct functional features, 8 user roles, 10 database tables with 94 distinct columns, 19 REST API endpoints, and 23 user stories. The system architecture is completely self-contained, requiring pure Python standard library components and zero external packages at runtime. The existing MVP codebase in MVP/ accurately implements the foundational skeleton required by ORIGINAL_REQUEST.md, and all data structures, rules, and acceptance criteria have been fully verified and mapped.


    13. Verification Method

    To independently verify the mined specification and validate the system:

    1. Verify CTCAE Engine and Auth Logic:
       python -c "import sys; sys.path.insert(0, r'c:\AI Projects\Kais Project\MVP'); from ctcae_engine import get_ctcae_engine; from user_store import authenticate; engine = get_ctcae_engine(); print('Engine rules loaded:', len(engine.list_symptoms())); print('Grade test:', engine.grade_symptom('nausea', {'severity_score': 5})); print('Auth test:', authenticate('admin', 'admin123')['role'])"
    1. Verify Database Schema and Integrity:
       python -c "import sys; sys.path.insert(0, r'c:\AI Projects\Kais Project\MVP'); from database import get_db; db = get_db(); tables = [r[0] for r in db.fetchall(\"SELECT name FROM sqlite_master WHERE type='table'\")]; print('Tables count:', len(tables), tables)"
    1. Verify Executable / App Launch:
       python "c:\AI Projects\Kais Project\MVP\app.py" --port 8080
       # Then visit http://127.0.0.1:8080 in a web browser, log in as patient.durand / demo123, submit a toxicity report, log out, log in as dr.martin / demo123, and observe the report on the Care Timeline.
    1. Invalidation Conditions:
      • Invalidation occurs if any external package (e.g. flask, requests, sqlalchemy) is introduced to the runtime environment without user waiver.
      • Invalidation occurs if automated grades $\ge 2$ are stored without the provisional = 1 flag.
      • Invalidation occurs if patient users are permitted to query records of other patients.