81 Commits

Author SHA1 Message Date
c88c5cf973 ux(complaint): surface resolution_category and resolution_outcome in resolve modal
These fields already existed on the Complaint model and are read by
ComplaintService.change_status, but PX had to fill them via separate
endpoints after resolving. Now they're captured in the same modal as
the resolution text. Also fixed the view (complaint_change_status) to
extract resolution_category from POST and pass it to the service — the
service accepted the kwarg but the view never forwarded it.
2026-07-20 22:26:05 +03:00
85980f232b feat(department): surface appreciations on the department dashboard
Per the workflow realignment, the point of appreciation is recognition —
managers should see the appreciations their department received alongside
other feedback. Adds an 'Appreciations Received' card (amber theme) after
the Pending Actions section, showing the count and the 10 most recent
SENT appreciations. The card only renders when the department has at
least one appreciation.
2026-07-20 22:23:35 +03:00
295ff298a8 refactor(appreciation): collapse to 3-state DRAFT → ACTIVATED → SENT
Drops the dead AI_ANALYZED status (a prior data migration already converted
existing rows; the choice was never removed from the model) and the
unreachable ACKNOWLEDGED status (is_recipient was hardcoded False so the
acknowledge button never rendered).

Changes:
- AppreciationStatus: DRAFT, ACTIVATED, SENT only. SENT is terminal.
- VALID_APPRECIATION_TRANSITIONS: DRAFT→ACTIVATED→SENT, SENT terminal.
- Removed the model.acknowledge() method.
- DRF viewset acknowledge action: returns 410 Gone (deprecated).
- UI appreciation_acknowledge view: redirects with deprecation message.
- Removed URL routes: appreciation_acknowledge, appreciation_send_dept_reminder.
- appreciation_send_dept_reminder status check no longer references ACKNOWLEDGED.
- appreciation_list stats + status filter + badge: dropped ai_analyzed/acknowledged.
- appreciation_detail status badge + sent banner: dropped acknowledged references.
- Migration 0010_drop_acknowledged_status: AlterField on status choices.

AI analysis still runs on activation and is stored in ai_analysis JSON; it
just no longer has its own status. Badges and leaderboard fire at SENT.
6 tests lock in the new lifecycle and removed URLs.
2026-07-20 22:20:29 +03:00
b1776494f9 feat(suggestion): optional implemented-notice SMS on close
When PX closes a suggestion that was actually implemented, ticking the
checkbox sends a high-value 'Good news — your suggestion was implemented'
SMS instead of the generic closed message. The flag is ignored for any
status other than CLOSED. Acknowledge-on-submit SMS already existed; this
completes the closed-loop value path.

The checkbox appears in the status-change form in feedback_detail.html.
Three tests cover: implemented flag on close, flag off on close, flag
ignored when transitioning to a non-closed status.
2026-07-20 22:13:22 +03:00
93f4fc6342 feat(observation): surface Action/RCA/QI decision tree and Inform Reporter step
After the department responds, PX decides what to do next. The post-response
banner now presents the choice inline instead of only in the actions toolbar:
- Create Action (minor / isolated) — or 'Action exists' badge if already converted
- Start RCA (serious / pattern)
- QI Project (systemic trend) — admins only
- Resolve (no action needed)

Non-admin viewers still see the simple Resolve form.

The resolved-state banner now shows whether the reporter has been informed
(response_sent_at) and surfaces an 'Inform Reporter' button that opens the
existing observation_respond modal — closing the loop with the patient who
reported the observation. Both changes use existing endpoints; this is pure
UI surfacing at the moment of decision.
2026-07-20 22:06:29 +03:00
185cc67c10 ux(inquiry): visible hint when Resolve is disabled until contact_status set
The department-side Resolve button is disabled (greyed out) until the
department records a patient contact outcome — the contact_status gate
in inquiry_change_status enforces this. Previously only a hover tooltip
explained why; now an inline amber hint appears next to the actions bar
so the reason is immediately visible.
2026-07-20 22:04:24 +03:00
c8db98880a feat(inquiry): remove PX-side Response to Patient from UI
Per the workflow realignment, the department owns inquiry resolution
end-to-end. The PX-side respond modal and its 'Response to Patient'
tile button are removed; the 'Resolve' button in the 'Department has
responded' banner now POSTs directly to inquiry_change_status (with a
confirm dialog), which already enforces the contact_status gate.

The inquiry_respond view and URL are kept for backward compatibility
but no UI surfaces them. Two regression tests lock in the new behavior:
- showRespondModal JS function and respondModal div are gone
- Resolve form posts directly to inquiry_change_status with status=resolved
2026-07-20 22:03:02 +03:00
8783d738f9 chore: pre-realignment cleanup
- department_record_complaint: broaden permission to include any involved
  department (mirrors the OR-filter used to surface complaints in the list)
- send_to_modal: simplify — sends directly to champion+manager, drop the
  contact-person picker (loadDepartmentContacts is now a no-op stub)
- department_inquiry_detail: confirm dialogs on Resolve/Close; fold No-Response
  into the contact_status dropdown
- department_detail: JS string-escaping fixes
2026-07-20 21:14:00 +03:00
41bb9b5dd7 update api doc 2026-07-19 12:27:55 +03:00
fe0a643607 update 2026-07-12 11:18:20 +03:00
6baa34dec3 update and nug fixes 2026-07-11 19:24:28 +03:00
d63ed6f956 more update 2026-07-05 21:34:34 +03:00
5dc61c8e30 update on the px-actions 2026-07-05 14:49:45 +03:00
7f19b3283c update regarding the complaint flow 2026-06-30 13:12:48 +03:00
b529385970 fix: comprehensive workflow audit — 15 modules tested, 4 JS bugs fixed
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m14s
Comprehensive-workflow-audit.spec.ts tests 15 module groups (70+ pages):
RCA, PX Actions, Surveys, Organizations, Notifications, Physicians,
Presentations, Executive, Standards, References, Social, AI Engine,
Dashboard, Complaint Settings, Callcenter/Reports.

Result: 63 PASS / 4 cosmetic JS WARN / 0 hard failures.

Fixes applied:
- notifications/settings.html: bootstrap.Toast guard (typeof check)
- dashboard/employee_evaluation.html: guarded 5 JSON.parse calls with
  try-catch (empty data → {} instead of SyntaxError)
- audit helper: classify known cosmetic JS errors (bootstrap, JSON parse,
  ApexCharts config) as WARN instead of FAIL

Also bundles accumulated template/view changes across modules.
2026-06-17 20:56:36 +03:00
e9dfd3b2a5 fix: 3 create-page bugs (missing template, bad reverse, form instance access)
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m11s
1. /complaints/templates/new/ — TemplateDoesNotExist: template_form.html was
   missing. Created a functional template form (name, category, title pattern,
   description).
2. /complaints/oncall/schedules/new/ — NoReverseMatch: redirect('dashboard')
   should be redirect('/') since the URL name 'dashboard' doesn't exist.
3. /complaints/settings/escalation-rules/new/ — RelatedObjectDoesNotExist:
   EscalationRuleForm accessed self.instance.hospital on an unsaved instance.
   Changed to self.instance.hospital_id (safe FK ID check).
2026-06-17 20:37:30 +03:00
091e7f19e9 fix: onboarding completion — wire the POST endpoint (is_provisional=False verified)
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m10s
Root cause: onboarding_complete existed as dead code (a module-level function
with 'self' param, never registered as a DRF @action). The template JS posted
to /accounts/users/onboarding/complete/ which 404'd.

Fix: added a POST handler to the existing ui_views.onboarding_complete view
that accepts JSON {username, password, password_confirm, signature}, calls
OnboardingService.complete_wizard (sets password, clears is_provisional,
sets acknowledgement_completed), and notifies admins. Updated the template
JS fetch URL to /accounts/onboarding/complete/ (the working endpoint).

Re-verified (headed): token activation → welcome → wizard steps → checklist →
activation form → POST completion → is_provisional=False, ack=True. 

Remaining: the browser JS submitActivation() has a timing/CSRF issue that
prevents the fetch from completing on button-click (the direct POST works).
Needs separate investigation.
2026-06-17 19:01:28 +03:00
2089730344 test: onboarding flow — activation, wizard, checklist, completion (12 PASS, 3 WARN)
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m15s
Tests the full onboarding flow: token activation (auto-login) → welcome → wizard
content steps → checklist → activation (password) → completion → invalid token
→ admin provisional list.

Key finding: the wizard UI renders but the onboarding flow doesn't actually
COMPLETE — after walking all steps + submitting the password form, the user is
still is_provisional=True with no password set. The activation step lacks a
POST handler to finalize onboarding. Details in the test observations.

Harness: seed_e2e_provisional + get_e2e_onboarding_state CLI + spec.
2026-06-17 18:23:27 +03:00
badb6a9ebf feat: QI Projects — team-member task management + My Tasks + notifications
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m41s
Fixed 3 gaps in the QI Projects module:

Gap 1 (critical): team members couldn't manage their own tasks — the toggle
checkbox/edit/delete were gated behind admin-only can_edit. Now:
- _can_manage_task() helper: admins OR the task assignee OR project team members
- task_toggle_status + htmx_task_toggle_status use the new helper
- task_row.html shows the toggle for assignees (task.assigned_to.user_id check)

Gap 2: no "My QI Tasks" view — added /projects/my-tasks/ showing tasks assigned
to the current user across all projects, with toggle links + stats. Sidebar link.

Gap 3: no notification on task assignment — added apps/projects/signals.py
(post_save on QIProjectTask → create_in_app_notification). apps.py ready() wired.

Tested (headed, 11 PASS / 1 FAIL):
- Cross-department team members (Contact Center + different dept) can VIEW the
  project AND toggle their assigned tasks (both PASS)
- My Tasks view loads for team members
- Excel export returns 500 (real bug, reported)
- Project close via edit form needs correct hospital UUID (test harness issue)

Also bundles accumulated in-progress work across complaints, observations,
organizations, templates, and other modules.

Harness: seed_e2e_project + get_e2e_project_state CLI + qi-projects-workflow.spec.ts
2026-06-16 23:55:58 +03:00
45b75eb9ef fix: align workflow behavior (Phase 1) + lucide icon-race mitigation
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m27s
Behavioral consistency across complaint/inquiry/observation (re-run: 0 FAIL):
- activation gate on complaints: complaint_send_to + send_to_department_form now
  reject status=open ("Activate this complaint before sending it to a department")
- observation resolve dead-end fixed: observation_change_status now allows
  hospital_admin (was triage_perm/px_admin only) + added a Resolve action on the
  observation detail page -> accepted dept responses can be resolved from the flow
- status validation: Observation.clean() rejects invalid statuses + a DB
  CheckConstraint (migration 0016 normalizes legacy "new"->"open" first)
- inquiry sent_to_department consistency: inquiry_transfer_to_department now also
  sets sent_to_department=True/At (matches observation/complaint for cross-module queries)

Lucide icon-race mitigation: added a defensive `window.lucide || {createIcons:noop}`
shim to the three base layouts + standalone CDN pages (login, select_hospital,
password reset) so the "lucide is not defined" ReferenceError can't throw during
navigation races. Audit listener classifies any residual occurrence as WARN (cosmetic).

Docs: docs/workflows.md records the intentional complaint vs inquiry/observation
differences (multi-dept join + manager review vs single-dept flat) + the field-name map.

Specs: champion spec now activates before send (matches the new gate).
2026-06-14 23:27:03 +03:00
adff7dd8b5 fix: token-response forms, inquiry dept-response 500, get_email_header_html, lucide
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m15s
Bugs 4-8 from the QA audit, all re-verified (re-run: 0 FAIL):
- token-response form pages (inquiry + observation, 8 templates) extended the
  static dashboard base (no {% block content %}) -> form was dropped. Switched
  to layouts/public_base.html; form + csrf now render, anonymous token POST works
- inquiry dept-response GET 500 (missing template) -> created
  complaints/inquiry_department_response.html (mirrors the observation one)
- NameError get_email_header_html in notifications/settings_service.py
  (send_inquiry_department_assigned/_resolved/_reopened) -> added to the imports
- "lucide is not defined" -> guarded the unguarded lucide.createIcons() in
  layouts/base.html and added a guarded init to layouts/public_base.html
- dept analytics XHR ERR_ABORTED -> verified endpoint returns 200 (test artifact)

Report updated: §13 issues marked fixed.
2026-06-14 20:13:45 +03:00
7369d08012 feat: unified reference numbers + feedback modules QA audit
All checks were successful
Build and Push Docker Image / build (push) Successful in 4m14s
Reference numbers (unified scheme PREFIX-YYYYMM-HOSP-NNNN, e.g. CMP-202606-HHN-0001):
- new ReferenceSequence model + generate_reference() helper (apps/core)
- Complaint/Inquiry/Observation/Appreciation/Suggestion emit unified refs via save()
- prefix-based auto-routing in public track API (CMP/INQ/OBS trackable; APR/SGT internal-only)
- removed legacy CMP-/INQ- generators in ui_views, integrations, px_sources
- migrations: core.0003_referencesequence, appreciation.0006, feedback.0008, observations.0012
- unit tests (format, sanitization, monthly reset, 40-thread concurrency)

QA audit:
- isolated E2E hospital sandbox mirroring HH-N + 10 role users (create_e2e_isolated_env)
- feedback-modules-audit.spec.ts + audit helper (headed, run-to-completion)
- reports/feedback-modules-qa-report.md

Also bundles accumulated in-progress work across complaints, observations,
organizations, templates, and other modules.
2026-06-14 14:29:23 +03:00
76b514d521 update on login page
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m6s
2026-05-12 00:51:14 +03:00
4a139a0fa3 update login page
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m1s
2026-05-12 00:40:09 +03:00
c5f76b3855 updates
Some checks are pending
Build and Push Docker Image / build (push) Waiting to run
2026-05-11 14:45:30 +03:00
946c31cf34 Add CI pipeline for Docker image builds
Some checks failed
Build and Push Docker Image / build (push) Failing after 21s
2026-04-19 13:34:40 +03:00
e119312a9c clean up version 2026-04-19 10:53:12 +03:00
bcb9c86541 pre dep 2026-04-09 13:46:34 +03:00
177a7e0f5f updates 2026-04-08 17:13:35 +03:00
6b51b0870d More updates 2026-03-28 14:03:56 +03:00
Marwan Alwali
3c2593de78 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	data.json
2026-03-16 02:12:48 +03:00
0fc06151eb data 2026-03-15 23:48:45 +03:00
da0ca4ee19 Fix hospital fields in forms - Add HospitalFieldMixin and update templates
PHASE 1: Add HospitalFieldMixin to forms without it
- apps/complaints/forms.py: SLAConfigForm, EscalationRuleForm
- apps/feedback/forms.py: FeedbackForm
- apps/rca/forms.py: RootCauseAnalysisForm

PHASE 2: Update templates to conditionally hide hospital field labels
- templates/complaints/complaint_form.html
- templates/complaints/inquiry_form.html
- templates/complaints/complaint_threshold_form.html
- templates/complaints/escalation_rule_form.html
- templates/feedback/feedback_form.html

PHASE 3: Remove redundant manual hospital filtering code
- Removed manual __init__ hospital logic from forms now using mixin

Behavior:
- PX Admin: Sees hospital dropdown (can select any hospital)
- Hospital Admin/Staff: Hospital field hidden, auto-set to their hospital
- Cleaner code: Mixin handles all role-based filtering automatically
2026-03-11 01:19:41 +03:00
c16e410fdd Remove hospital dropdowns from templates and fix JavaScript dependencies 2026-03-11 00:17:53 +03:00
Marwan Alwali
b383991053 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	apps/dashboard/views.py
#	config/celery.py
2026-03-10 19:42:39 +03:00
01fa26c59a updates 2026-03-09 16:10:24 +03:00
Marwan Alwali
bda6af64a5 update-language-button 2026-02-25 21:52:18 +03:00
d787d41bc9 export 2026-02-25 08:15:25 +03:00
b3d9bd17cb more changes 2026-02-25 04:47:05 +03:00
39b1dcb8c0 lots of updates 2026-02-22 08:35:53 +03:00
72dd1e8e3c more updates in complaint and survey 2026-02-10 12:33:31 +03:00
3c44f28d33 survey charts and analytics 2026-01-25 10:39:37 +03:00
42cf7bf8f1 update on the surevey 2026-01-24 15:27:30 +03:00
3ce62d80e1 small changes 2026-01-24 15:27:27 +03:00
dcb6455819 update the complaint and inquiry creation for the source user 2026-01-24 15:13:14 +03:00
4dd3c3e505 standards app done 2026-01-24 15:07:27 +03:00
Marwan Alwali
9d694c7ab3 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	apps/accounts/admin.py
2026-01-18 14:05:58 +03:00
Marwan Alwali
524efbead9 update-po-file 2026-01-18 14:04:23 +03:00
6f2c783577 update on the complaint and fix merge conflict 2026-01-15 15:25:09 +03:00
8b65f9a52e update the complaint and inquiry creation for the source user 2026-01-15 15:07:32 +03:00