HH/dep.md
ismail 7369d08012
All checks were successful
Build and Push Docker Image / build (push) Successful in 4m14s
feat: unified reference numbers + feedback modules QA audit
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

588 lines
7.2 KiB
Markdown

# PX360 Organizational Structure Refactor (Final Architecture)
## Objective
Refactor the current Department Hierarchy implementation into a simpler and more maintainable model that:
* Uses a single source of truth for routing.
* Uses a single source of truth for reporting.
* Preserves legacy complaint mappings for historical records.
* Removes unnecessary hierarchy levels.
* Aligns with the latest organizational spreadsheet.
* Supports future department and section changes without impacting reporting.
---
# Key Business Findings
After reviewing:
* Legacy complaint hierarchy
* Existing reports
* Final organization spreadsheet
the following conclusions were reached.
## Legacy Structure
Historical complaints used:
Location
→ Main Section
→ Sub Section
Example:
Outpatient
→ Medical
→ Radiology
The old Sub Section was the actual operational unit receiving complaints.
---
## Current Organization Structure
The latest organization file contains:
* Main Section
* Department
* Section
Examples:
Medical
→ Pharmacy Department
→ Central Outpatient Pharmacy
Medical
→ Pharmacy Department
→ General
---
## Important Discovery
Area is not a valid hierarchy level.
Evidence:
* Frequently empty
* Often duplicates Department concepts
* Not used in reporting
* Not used in routing
* Not used in ownership
Therefore:
Area should not become a first-class model.
---
## Reporting Structure
All management reports are grouped by:
* Medical
* Non-Medical
* Nursing
* Support Services
These values come from:
Main Section
Therefore Main Section is actually the reporting category.
---
# Target Hierarchy
## Department Category
Represents:
* Medical
* Non-Medical
* Nursing
* Support Services
Model:
```python
class DepartmentCategory(models.TextChoices):
MEDICAL = "medical"
NON_MEDICAL = "non_medical"
NURSING = "nursing"
SUPPORT_SERVICES = "support_services"
```
This replaces the old concept of:
Main Section
---
## Department
Primary accountable organizational unit.
Model:
```python
class Department(models.Model):
category
name
code
champion
manager_1st
manager_2nd
manager_3rd
deputy_manager
supervisor
deputy_supervisor
is_active
```
Examples:
* Pharmacy Department
* Radiology Department
* Laboratory Department
* Emergency Department
Departments always have ownership.
Departments always have a Champion.
Departments are the fallback routing target.
---
## Section
Optional child unit under a Department.
Model:
```python
class Section(models.Model):
department = models.ForeignKey(
Department,
related_name="sections"
)
name
code
champion = models.ForeignKey(
Staff,
null=True,
blank=True
)
location_type
location_code
zone
floor
is_active
```
Examples:
* Central Outpatient Pharmacy
* ER Pharmacy
* Pediatric Pharmacy
Not every Department requires Sections.
Not every Section requires a Champion.
---
## Remove Sub-Section
Current model:
OrgSubSubSection
Findings:
* Mostly empty in source data.
* Not used in reports.
* Not used in routing.
* Not used in escalation.
Action:
Deprecate and remove.
---
# Complaint Model
## Target Structure
```python
class Complaint(models.Model):
department = models.ForeignKey(
Department
)
section = models.ForeignKey(
Section,
null=True,
blank=True
)
legacy_mapping = models.ForeignKey(
LegacyHierarchyMapping,
null=True,
blank=True
)
```
---
# Ownership Rules
Single ownership strategy.
```python
def get_owner():
if complaint.section and complaint.section.champion:
return complaint.section.champion
return complaint.department.champion
```
Rules:
1. Section Champion takes ownership when available.
2. Otherwise Department Champion owns the complaint.
This becomes the only routing rule in the system.
---
# Legacy Data Strategy
## Legacy Mapping Table
Keep:
```python
class LegacyHierarchyMapping(models.Model):
old_location
old_main_section
old_subsection
department
section
```
Purpose:
Legacy Complaint
→ Legacy Mapping
→ Department / Section
---
## Legacy Fields
The following fields become historical reference only:
* legacy_location
* legacy_main_section
* legacy_subsection
Rules:
* No reporting usage
* No routing usage
* No escalation usage
* No dashboard usage
May remain temporarily for audit purposes.
---
# Reporting Strategy
## Single Source of Truth
All reports must use:
```python
complaint.department
complaint.section
```
only.
Never use legacy hierarchy fields.
---
## Category Reports
Medical / Nursing / Support Services reports:
```python
Complaint.objects.values(
"department__category"
)
```
---
## Department Reports
```python
Complaint.objects.values(
"department__name"
)
```
---
## Section Reports
```python
Complaint.objects.values(
"section__name"
)
```
---
# Location Handling
Location is metadata.
It is not part of ownership hierarchy.
Examples:
* Outpatient Clinics
* Inpatient
* Emergency
* General Services
Used for:
* Display
* Filtering
* Analytics
Not used for routing ownership.
---
## Location Type
Retain:
* OP
* IP
* ER
* GENERAL
This becomes the preferred reporting dimension instead of string matching location names.
Example:
```python
class LocationType(models.TextChoices):
OP = "OP"
IP = "IP"
ER = "ER"
GENERAL = "GENERAL"
```
---
# Import Strategy
Department uniqueness:
```python
(category, department_name)
```
must create a single Department.
Never create duplicate Departments from repeated spreadsheet rows.
---
Sections:
```python
(department, section_name)
```
must be unique.
---
# Migration Plan
## Phase 1
Create:
* DepartmentCategory
* LocationType enums
Remove Area dependency.
---
## Phase 2
Rename:
OrgSubSection
to:
Section
Update:
* models
* serializers
* views
* APIs
* templates
* services
---
## Phase 3
Deprecate:
OrgSubSubSection
Backfill any valid data.
Remove references.
---
## Phase 4
Backfill all historical complaints.
Populate:
* department
* section
using LegacyHierarchyMapping.
Target:
100% coverage.
---
## Phase 5
Update routing services.
Replace all routing logic with:
```python
complaint.get_owner()
```
---
## Phase 6
Update:
* Dashboards
* KPI services
* Reports
* Exports
* Analytics
to use:
* Department
* Section
* Department Category
only.
---
## Phase 7
Update forms.
Replace:
Location
→ Main Section
→ Sub Section
with:
Category
→ Department
→ Section
Section optional.
---
## Phase 8
Mark legacy hierarchy fields as deprecated.
Prevent all new writes.
Keep read-only until final cleanup release.
---
# Success Criteria
✓ Department is the primary accountable entity.
✓ Section is optional.
✓ Reporting uses Department Category.
✓ Routing uses Department / Section only.
✓ Legacy hierarchy is used only for historical mapping.
✓ Area is removed from operational design.
✓ OrgSubSubSection is removed.
✓ OrgSubSection is renamed to Section.
✓ Dashboards no longer depend on legacy hierarchy.
✓ Complaint ownership has a single source of truth.