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.
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
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).