HH/apps/observations/urls.py
ismail badb6a9ebf
All checks were successful
Build and Push Docker Image / build (push) Successful in 2m41s
feat: QI Projects — team-member task management + My Tasks + notifications
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

98 lines
5.1 KiB
Python

"""
Observations URL configuration.
Public routes (no login required):
- /observations/new/ - Submit new observation
- /observations/submitted/<tracking_code>/ - Success page
- /observations/track/ - Track observation by code
Internal routes (login required):
- /observations/ - List observations
- /observations/<id>/ - Observation detail
- /observations/<id>/triage/ - Triage observation
- /observations/<id>/status/ - Change status
- /observations/<id>/note/ - Add note
- /observations/<id>/convert-to-action/ - Convert to PX Action
- /observations/categories/ - Category management
"""
from django.urls import path
from . import views
app_name = "observations"
urlpatterns = [
# ==========================================================================
# PUBLIC ROUTES (No Login Required)
# ==========================================================================
# Submit new observation
path("new/", views.observation_create_public, name="observation_create_public"),
# Success page after submission
path("submitted/<str:tracking_code>/", views.observation_submitted, name="observation_submitted"),
# Track observation by code
path("track/", views.observation_track, name="observation_track"),
# Token-based department response (no login required)
path("<uuid:pk>/respond/<str:token>/", views.observation_respond_with_token, name="observation_respond_with_token"),
# ==========================================================================
# INTERNAL ROUTES (Login Required)
# ==========================================================================
# Create new observation (authenticated)
path("create/", views.observation_create, name="observation_create"),
# List observations
path("", views.observation_list, name="observation_list"),
# Observation detail
path("<uuid:pk>/", views.observation_detail, name="observation_detail"),
# Triage observation
path("<uuid:pk>/triage/", views.observation_triage, name="observation_triage"),
# Change status
path("<uuid:pk>/status/", views.observation_change_status, name="observation_change_status"),
# Assign/Reassign
path("<uuid:pk>/assign/", views.observation_assign, name="observation_assign"),
# Activate
path("<uuid:pk>/activate/", views.observation_activate, name="observation_activate"),
# Reopen
path("<uuid:pk>/reopen/", views.observation_reopen, name="observation_reopen"),
# Add note
path("<uuid:pk>/note/", views.observation_add_note, name="observation_add_note"),
# Respond (patient-facing response)
path("<uuid:pk>/respond/", views.observation_respond, name="observation_respond"),
path("<uuid:pk>/update-satisfaction/", views.observation_update_satisfaction, name="observation_update_satisfaction"),
path("<uuid:pk>/generate-ai-response/", views.observation_generate_ai_response, name="observation_generate_ai_response"),
# Send to Department
path("<uuid:pk>/send-to-department/", views.observation_send_to_department, name="observation_send_to_department"),
# Escalate observation
path("<uuid:pk>/escalate/", views.observation_escalate, name="observation_escalate"),
# Unified Send To (Person or Department)
path("<uuid:pk>/send-to/", views.observation_send_to, name="observation_send_to"),
# Department Response
path("<uuid:pk>/department-response/", views.observation_department_response, name="observation_department_response"),
# Review Department Response
path("<uuid:pk>/review-dept-response/", views.observation_review_dept_response, name="observation_review_dept_response"),
# Send Department Response Reminder
path("<uuid:pk>/send-dept-response-reminder/", views.observation_send_dept_response_reminder, name="observation_send_dept_response_reminder"),
# Convert to PX Action
path("<uuid:pk>/convert-to-action/", views.observation_convert_to_action, name="observation_convert_to_action"),
# ==========================================================================
# CATEGORY MANAGEMENT
# ==========================================================================
# List categories
path("categories/", views.category_list, name="category_list"),
# Create category
path("categories/create/", views.category_create, name="category_create"),
# Edit category
path("categories/<uuid:pk>/edit/", views.category_edit, name="category_edit"),
# Delete category
path("categories/<uuid:pk>/delete/", views.category_delete, name="category_delete"),
# ==========================================================================
# AJAX/API HELPERS
# ==========================================================================
# Get users by department
path("api/users-by-department/", views.get_users_by_department, name="get_users_by_department"),
# ==========================================================================
# SOFT DELETE & RESTORE
# ==========================================================================
path("<uuid:pk>/delete/", views.observation_soft_delete, name="observation_soft_delete"),
path("<uuid:pk>/restore/", views.observation_restore, name="observation_restore"),
]