Files
HighCostDrugsDemo/IMPLEMENTATION_PLAN.md
T
Andrew Charlwood 14f970d37b feat: implement chart data preparation (Task 4.1)
- Add prepare_chart_data() method for hierarchical chart data
- Build Trust → Directory → Drug hierarchy from filtered SQLite data
- Calculate patient counts and costs at each hierarchy level
- Compute color values (proportions) for visualization
- Generate dynamic chart title based on filter state
- Call prepare_chart_data() from apply_filters() for reactivity
- Mark Task 3.4 complete (KPIs implemented in apply_filters)
2026-02-04 18:41:37 +00:00

207 lines
8.4 KiB
Markdown

# Implementation Plan - HCD Analysis UI Redesign
## Project Overview
Complete frontend redesign of the Patient Pathway Analysis tool. Replace the current multi-page sidebar layout with a modern, single-page dashboard featuring:
- Instant reactive filtering with debounce
- Interactive Plotly icicle chart that updates in real-time
- NHS-inspired but bold, modern visual design
- KPI metrics that respond to filter changes
**Design Reference:** See `DESIGN_SYSTEM.md` for color palette, typography, spacing, and component specs.
**Source Code:** The existing `pathways_app/pathways_app.py` contains the current implementation. Create a new `pathways_app/app_v2.py` for the redesign, leaving the original intact until verification.
## Quality Checks
Run after each task:
```bash
# Syntax check
python -m py_compile pathways_app/app_v2.py
# Import verification
python -c "from pathways_app.app_v2 import app"
# Reflex compilation test
cd pathways_app && timeout 60 python -m reflex run 2>&1 | head -30
# If compilation shows errors, fix before marking task complete
```
## Phase 1: Foundation
### 1.1 Design Tokens Module
- [x] Create `pathways_app/styles.py` with design token classes:
- `Colors` class with all palette colors as constants
- `Typography` class with font sizes, weights
- `Spacing` class with spacing scale
- `Shadows` class with shadow values
- `Radii` class with border radius values
- [x] Create helper functions for common style patterns (e.g., `card_style()`, `button_primary_style()`)
- [x] Verify imports work: `from pathways_app.styles import Colors, Spacing`
### 1.2 App Skeleton
- [x] Create `pathways_app/app_v2.py` with basic Reflex app structure
- [x] Define new `AppState` class with minimal state (placeholder for now)
- [x] Create single-page layout structure matching DESIGN_SYSTEM.md
- [x] Verify `reflex run` compiles and shows blank page with correct structure
- [x] Configure Reflex theme with design system colors
## Phase 2: Layout Components
### 2.1 Top Navigation Bar
- [x] Create `top_bar()` component:
- Logo (use existing NHS person logo from assets)
- App title "HCD Analysis"
- Chart type tabs/pills (Icicle active, placeholders for future charts)
- Data freshness indicator (right side): "12,450 records (2d ago)"
- [x] Style with Heritage Blue accents, clean typography
- [x] Fixed height: 64px
- [x] Verify renders correctly
### 2.2 Filter Section
- [x] Create `filter_section()` component with card styling
- [x] Add date range pickers:
- "Initiated" range with enable/disable checkbox (default: disabled)
- "Last Seen" range with enable/disable checkbox (default: enabled, last 6 months)
- "To" date defaults to latest date in dataset (placeholder — actual data integration in Phase 3)
- [x] Add searchable multi-select dropdowns:
- Drugs dropdown with search, select all, count display
- Indications dropdown with search, select all, count display
- Directorates dropdown with search, select all, count display
- [ ] Implement debounced filter change handlers (300ms) — deferred to Phase 3.3
- [x] Style according to design system
### 2.3 KPI Row
- [x] Create `kpi_card()` component:
- Large mono number (32-48px)
- Label below (caption style)
- Subtle background tint
- [x] Create `kpi_row()` component with responsive grid
- [x] Initially show: Unique Patients count
- [x] Leave space for future metrics (Drugs count, Total cost, Match rate)
- [x] KPIs should be reactive to filter state
### 2.4 Chart Container
- [x] Create `chart_section()` component
- [x] Full-width card with appropriate padding
- [x] Placeholder for Plotly chart (integrate in Phase 4)
- [x] Loading state with skeleton/spinner
- [x] Error state with friendly message
## Phase 3: State Management
### 3.1 Core State Variables
- [x] Define filter state variables in `AppState`:
- `initiated_filter_enabled: bool = False`
- `initiated_from_date: str = ""` (ISO date string)
- `initiated_to_date: str = ""`
- `last_seen_filter_enabled: bool = True`
- `last_seen_from_date: str` (default: 6 months ago, computed at class definition)
- `last_seen_to_date: str` (default: today, updated on data load)
- `selected_drugs: list[str] = []` (empty = all)
- `selected_indications: list[str] = []` (empty = all)
- `selected_directorates: list[str] = []` (empty = all)
- [x] Define data state variables:
- `data_loaded: bool = False`
- `total_records: int = 0`
- `last_updated: str = ""` (ISO timestamp)
- `raw_data: list[dict[str, Any]] = []` (list of dicts, Reflex-friendly)
- `latest_date_in_data: str = ""` (for "to" date defaults)
- [x] Define UI state variables:
- `chart_loading: bool = False`
- `error_message: str = ""`
- `current_chart: str = "icicle"`
### 3.2 Data Loading
- [x] Create `load_data()` method that reads from SQLite
- [x] Populate available options for dropdowns (drugs, indications, directorates)
- [x] Detect latest date in dataset for "to" date defaults
- [x] Calculate total records and last updated timestamp
- [x] Call on app initialization
### 3.3 Filter Logic
- [x] Create `apply_filters()` computed method that filters the data based on current state
- [x] Handle initiated date filter (when enabled)
- [x] Handle last seen date filter (when enabled)
- [x] Handle drug/indication/directorate multi-select filters
- [x] Return filtered DataFrame
### 3.4 KPI Calculations
- [x] Create computed properties for KPI values:
- `unique_patients: int` — COUNT(DISTINCT patient_id) from filtered data
- `total_drugs: int` — COUNT(DISTINCT drug_name_std) from filtered data
- `total_cost: float` — SUM(price_actual) from filtered data
- (Blocked: indication_match_rate requires Snowflake GP data)
- [x] Ensure KPIs update reactively when filters change
- Note: KPIs implemented in apply_filters() method, called by all filter event handlers
## Phase 4: Interactive Chart
### 4.1 Chart Data Preparation
- [x] Create `prepare_chart_data()` method that transforms filtered data for Plotly icicle
- [x] Reuse/adapt logic from existing `pathway_analyzer.py` (simplified hierarchy: Trust → Directory → Drug)
- [x] Return data structure compatible with `go.Icicle()` (list of dicts with parents, ids, labels, value, cost, colour)
- [x] Generate chart_title based on current filter state
- [x] Call prepare_chart_data() from apply_filters() for reactive updates
### 4.2 Reactive Plotly Integration
- [ ] Create `generate_icicle_chart()` computed property that returns Plotly figure
- [ ] Configure chart colors using design system palette
- [ ] Configure chart interactivity (zoom, pan, click, hover)
- [ ] Set responsive sizing
### 4.3 Chart Component
- [ ] Integrate `rx.plotly()` component in chart_section
- [ ] Pass reactive figure from state
- [ ] Handle loading states (show skeleton while computing)
- [ ] Handle empty data state (friendly message)
- [ ] Verify chart updates when filters change
## Phase 5: Polish & Verification
### 5.1 Visual Polish
- [ ] Review all components against DESIGN_SYSTEM.md
- [ ] Ensure consistent spacing throughout
- [ ] Ensure consistent typography throughout
- [ ] Add hover states and transitions to interactive elements
- [ ] Test responsive behavior (resize browser)
### 5.2 Performance Optimization
- [ ] Profile filter + chart update cycle
- [ ] Ensure debounce is working correctly (not triggering on every keystroke)
- [ ] Optimize any slow computed properties
- [ ] Verify smooth 60fps interactions
### 5.3 Error Handling
- [ ] Handle no data loaded state gracefully
- [ ] Handle filter resulting in zero records
- [ ] Handle any data loading errors
- [ ] User-friendly error messages
### 5.4 Final Verification
- [ ] Load real data from SQLite
- [ ] Test all filter combinations
- [ ] Verify KPIs update correctly
- [ ] Verify chart updates correctly
- [ ] Compare key metrics with original app to ensure correctness
- [ ] Test with large dataset for performance
### 5.5 Cleanup
- [ ] Remove or comment out old `pathways_app.py` code paths
- [ ] Update any imports/references to use new app
- [ ] Update README with new run instructions
- [ ] Document any breaking changes
## Completion Criteria
All tasks marked `[x]` AND:
- [ ] App compiles without errors (`reflex run` succeeds)
- [ ] All filters work with instant (debounced) updates
- [ ] KPIs display correct numbers matching filter state
- [ ] Icicle chart renders and updates reactively
- [ ] Visual design matches DESIGN_SYSTEM.md
- [ ] No console errors during normal operation
- [ ] Verified with real patient data from SQLite