HH/org_hir_plan.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

602 lines
6.6 KiB
Markdown

# PX360 Organization Hierarchy Refactor Plan
## Objective
Simplify the current Department Hierarchy implementation and establish a single source of truth for complaint routing, reporting, escalation, and ownership.
The current implementation successfully migrated data but carries excessive legacy concepts into the active business model.
The goal is to:
* Use the new organizational structure as the only operational hierarchy.
* Preserve legacy complaint information only for audit/reference purposes.
* Eliminate dependency on legacy hierarchy fields for reporting.
* Simplify routing and ownership logic.
* Align the system with how the hospital currently operates.
---
# Business Understanding
## Legacy Structure
Old complaints were created using:
```text
Location
└── Main Section
└── Sub Section
```
Example:
```text
Outpatient
└── Medical
└── Radiology
```
In practice:
```text
Legacy SubSection
```
was the actual operational unit receiving complaints.
---
## New Structure
The new organization file defines:
```text
Location
└── Area
└── Department
└── Section
```
Example:
```text
Outpatient
└── Medical
└── Pharmacy
├── ER Pharmacy
├── OPD Pharmacy
└── Pediatric Pharmacy
```
---
## Complaint Ownership Rules
A complaint may be owned by:
* A Department
* A Section
Departments always have a Champion.
Sections may optionally have a Champion.
Routing rules:
```text
Section Champion
Department Champion
```
If a Section has no Champion, responsibility falls back to the Department Champion.
---
# Target Data Model
## Area
```python
class Area(models.Model):
hospital
name
name_en
name_ar
code
status
```
Represents:
```text
Medical
Non-Medical
Nursing
Support Services
```
---
## Department
```python
class Department(models.Model):
area = ForeignKey(Area)
name
code
champion
manager
manager_1st
manager_2nd
manager_3rd
deputy_manager
supervisor
deputy_supervisor
```
Examples:
```text
Pharmacy
Radiology
Laboratory
Emergency Department
```
---
## Section
Rename:
```python
OrgSubSection
```
to:
```python
Section
```
Model:
```python
class Section(models.Model):
department = ForeignKey(Department)
name
code
champion = FK(Staff, null=True)
status
```
Examples:
```text
ER Pharmacy
OPD Pharmacy
Pediatric Pharmacy
```
---
## Remove Sub-Section Layer
Current:
```python
OrgSubSubSection
```
Business review determined:
* Mostly empty
* Not used for reporting
* Not used for routing
* Not used for ownership
Action:
```text
Deprecate and remove
```
after data validation.
---
# Complaint Model
## Target Structure
```python
class Complaint(models.Model):
department = FK(Department)
section = FK(
Section,
null=True,
blank=True
)
legacy_mapping = FK(
LegacyHierarchyMapping,
null=True,
blank=True
)
```
---
## Ownership Resolution
Implement:
```python
Complaint.get_owner()
```
Logic:
```python
if complaint.section and complaint.section.champion:
return complaint.section.champion
return complaint.department.champion
```
This becomes the single ownership rule used everywhere.
---
# Legacy Data Strategy
## Important Rule
Legacy hierarchy is no longer part of the operational model.
Legacy hierarchy exists only to explain historical complaints.
---
## Keep Mapping Table
Retain:
```python
LegacyHierarchyMapping
```
Refactor to:
```python
class LegacyHierarchyMapping(models.Model):
old_location
old_main_section
old_subsection
department
section
```
Purpose:
```text
Legacy Complaint
Legacy Mapping
Department / Section
```
---
## Remove Operational Usage Of
```python
legacy_location
legacy_main_section
legacy_subsection
```
from:
* Reporting
* Routing
* Dashboards
* KPIs
* Escalation
* Filters
They may remain temporarily for audit/reference only.
---
# Reporting Refactor
## New Reporting Rule
All reports must use:
```python
complaint.department
complaint.section
```
only.
Never use:
```python
legacy_location
legacy_main_section
legacy_subsection
```
for any new report.
---
## Report Grouping
Department-level:
```python
values("department__name")
```
Section-level:
```python
values("section__name")
```
Area-level:
```python
values("department__area__name")
```
---
## Dashboard Refactor
Replace:
```python
location__name_en
main_section
legacy_main_section
```
with:
```python
department
department__area
section
```
---
# Routing Refactor
## Send To Department
Current behavior should become:
```python
owner = complaint.get_owner()
```
No custom routing logic should duplicate ownership checks.
---
## Escalation
Escalation should work against:
```python
Department
Section
```
only.
Legacy hierarchy must never influence escalation.
---
# Forms Refactor
Replace all remaining legacy hierarchy forms.
Current:
```text
Location
Main Section
Sub Section
```
New:
```text
Area
Department
Section
```
Fields:
```python
area
department
section
```
Section optional.
---
# Naming Cleanup
Rename:
```python
OrgSubSection
```
```python
Section
```
Rename related:
```python
org_subsections
```
```python
sections
```
Update:
* serializers
* views
* APIs
* templates
* services
---
# Migration Steps
## Phase 1
Create:
```python
Area
```
model.
Populate from Department records.
---
## Phase 2
Rename:
```python
OrgSubSection
```
to:
```python
Section
```
Update all references.
---
## Phase 3
Backfill:
```python
complaint.department
complaint.section
```
for all historical complaints.
Target:
```text
100%
```
coverage.
---
## Phase 4
Update:
* dashboards
* exports
* KPI services
* analytics
to use new hierarchy only.
---
## Phase 5
Update:
* complaint forms
* inquiry forms
* observation forms
* government ticket forms
to use:
```text
Area → Department → Section
```
---
## Phase 6
Mark legacy hierarchy fields as deprecated.
No new writes allowed.
---
# Success Criteria
The implementation is complete when:
✓ All complaints have Department assigned.
✓ Reporting uses only Department/Section hierarchy.
✓ Routing uses only Department/Section ownership.
✓ Dashboards use only Department/Section hierarchy.
✓ Legacy hierarchy is retained only for historical reference.
✓ OrgSubSubSection is removed.
✓ OrgSubSection is renamed to Section.
✓ Area is a first-class model.
✓ There is only one source of truth for complaint ownership.