fix: Add data transformer to resolve metrics dashboard template mismatch
Root cause: Template expects flat structure (metrics.database.count) but monitoring module provides nested structure (metrics.by_type.database.count) with different field names (avg_duration_ms vs avg). Solution: Route Adapter Pattern - transformer function maps data structure at presentation layer. Changes: - Add transform_metrics_for_template() function to admin.py - Update metrics_dashboard() route to use transformer - Provide safe defaults for missing/empty metrics data - Handle all operation types: database, http, render Testing: All 32 admin route tests passing Documentation: - Updated implementation report with actual fix details - Created consolidated hotfix design documentation - Architectural review by architect (approved with minor concerns) Technical debt: Adapter layer should be replaced with proper data contracts in v1.2.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
197
docs/design/hotfix-v1.1.1-rc2-route-conflict.md
Normal file
197
docs/design/hotfix-v1.1.1-rc2-route-conflict.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Hotfix Design: v1.1.1-rc.2 Route Conflict Resolution
|
||||
|
||||
## Problem Summary
|
||||
Production deployment of v1.1.1-rc.1 causes 500 error at `/admin/dashboard` due to:
|
||||
1. Route naming conflict between two dashboard functions
|
||||
2. Missing `starpunk.monitoring` module causing ImportError
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Primary Issue: Route Conflict
|
||||
```python
|
||||
# Line 26: Original dashboard
|
||||
@bp.route("/") # Registered as "admin.dashboard"
|
||||
def dashboard(): # Function name creates endpoint "admin.dashboard"
|
||||
# Shows notes list
|
||||
|
||||
# Line 218: Metrics dashboard
|
||||
@bp.route("/dashboard") # CONFLICT: Also accessible at /admin/dashboard
|
||||
def metrics_dashboard(): # Function name creates endpoint "admin.metrics_dashboard"
|
||||
from starpunk.monitoring import get_metrics_stats # FAILS: Module doesn't exist
|
||||
```
|
||||
|
||||
### Secondary Issue: Missing Module
|
||||
The metrics dashboard attempts to import `starpunk.monitoring` which doesn't exist in production, causing immediate ImportError on route access.
|
||||
|
||||
## Solution Design
|
||||
|
||||
### Minimal Code Changes
|
||||
|
||||
#### 1. Route Path Change (admin.py)
|
||||
**Line 218 - Change route decorator:**
|
||||
```python
|
||||
# FROM:
|
||||
@bp.route("/dashboard")
|
||||
|
||||
# TO:
|
||||
@bp.route("/metrics-dashboard")
|
||||
```
|
||||
|
||||
This single character change resolves the route conflict while maintaining all other functionality.
|
||||
|
||||
#### 2. Defensive Import Pattern (admin.py)
|
||||
**Lines 239-250 - Add graceful degradation:**
|
||||
```python
|
||||
def metrics_dashboard():
|
||||
"""Metrics visualization dashboard (Phase 3)"""
|
||||
# Defensive imports with fallback
|
||||
try:
|
||||
from starpunk.database.pool import get_pool_stats
|
||||
from starpunk.monitoring import get_metrics_stats
|
||||
monitoring_available = True
|
||||
except ImportError:
|
||||
monitoring_available = False
|
||||
get_pool_stats = lambda: {"error": "Pool stats not available"}
|
||||
get_metrics_stats = lambda: {"error": "Monitoring not implemented"}
|
||||
|
||||
# Continue with safe execution...
|
||||
```
|
||||
|
||||
### URL Structure After Fix
|
||||
|
||||
| Path | Function | Purpose | Status |
|
||||
|------|----------|---------|--------|
|
||||
| `/admin/` | `dashboard()` | Notes list | Working |
|
||||
| `/admin/metrics-dashboard` | `metrics_dashboard()` | Metrics viz | Fixed |
|
||||
| `/admin/metrics` | `metrics()` | JSON API | Working |
|
||||
| `/admin/health` | `health_diagnostics()` | Health check | Working |
|
||||
|
||||
### Redirect Behavior
|
||||
|
||||
All existing redirects using `url_for("admin.dashboard")` will continue to work:
|
||||
- They resolve to the `dashboard()` function
|
||||
- Users land on the notes list at `/admin/`
|
||||
- No code changes needed in 8+ redirect locations
|
||||
|
||||
### Navigation Updates
|
||||
|
||||
The template at `/templates/admin/base.html` is already correct:
|
||||
```html
|
||||
<a href="{{ url_for('admin.dashboard') }}">Dashboard</a> <!-- Goes to /admin/ -->
|
||||
<a href="{{ url_for('admin.metrics_dashboard') }}">Metrics</a> <!-- Goes to /admin/metrics-dashboard -->
|
||||
```
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Step 1: Create Hotfix Branch
|
||||
```bash
|
||||
git checkout -b hotfix/v1.1.1-rc2-route-conflict
|
||||
```
|
||||
|
||||
### Step 2: Apply Code Changes
|
||||
1. Edit `/starpunk/routes/admin.py`:
|
||||
- Change line 218 route decorator
|
||||
- Add try/except around monitoring imports (lines 239-250)
|
||||
- Add try/except around pool stats import (line 284)
|
||||
|
||||
### Step 3: Local Testing
|
||||
```bash
|
||||
# Test without monitoring module (production scenario)
|
||||
uv run python -m pytest tests/test_admin_routes.py
|
||||
uv run flask run
|
||||
|
||||
# Verify:
|
||||
# 1. /admin/ shows notes
|
||||
# 2. /admin/metrics-dashboard doesn't 500
|
||||
# 3. All CRUD operations work
|
||||
```
|
||||
|
||||
### Step 4: Update Version
|
||||
Edit `/starpunk/__init__.py`:
|
||||
```python
|
||||
__version__ = "1.1.1-rc.2"
|
||||
```
|
||||
|
||||
### Step 5: Document in CHANGELOG
|
||||
Add to `/CHANGELOG.md`:
|
||||
```markdown
|
||||
## [1.1.1-rc.2] - 2025-11-25
|
||||
|
||||
### Fixed
|
||||
- Critical: Resolved route conflict causing 500 error on /admin/dashboard
|
||||
- Added defensive imports for missing monitoring module
|
||||
- Renamed metrics dashboard route to /admin/metrics-dashboard for clarity
|
||||
```
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Functional Tests
|
||||
- [ ] `/admin/` displays notes dashboard
|
||||
- [ ] `/admin/metrics-dashboard` loads without 500 error
|
||||
- [ ] Create note redirects to `/admin/`
|
||||
- [ ] Edit note redirects to `/admin/`
|
||||
- [ ] Delete note redirects to `/admin/`
|
||||
- [ ] Navigation links work correctly
|
||||
- [ ] `/admin/metrics` JSON endpoint works
|
||||
- [ ] `/admin/health` diagnostic endpoint works
|
||||
|
||||
### Error Handling Tests
|
||||
- [ ] Metrics dashboard shows graceful message when monitoring unavailable
|
||||
- [ ] No Python tracebacks exposed to users
|
||||
- [ ] Flash messages display appropriately
|
||||
|
||||
### Regression Tests
|
||||
- [ ] IndieAuth login flow works
|
||||
- [ ] Note CRUD operations unchanged
|
||||
- [ ] RSS feed generation works
|
||||
- [ ] Micropub endpoint functional
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues discovered after deployment:
|
||||
1. Revert to v1.1.1-rc.1
|
||||
2. Users directed to `/admin/` instead of `/admin/dashboard`
|
||||
3. Metrics dashboard temporarily disabled
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. **No 500 Errors**: All admin routes respond with 200/300 status codes
|
||||
2. **Backward Compatible**: Existing functionality unchanged
|
||||
3. **Clear Navigation**: Users can access both dashboards
|
||||
4. **Graceful Degradation**: Missing modules handled elegantly
|
||||
|
||||
## Long-term Recommendations
|
||||
|
||||
### For v1.2.0
|
||||
1. Implement `starpunk.monitoring` module properly
|
||||
2. Add comprehensive metrics collection
|
||||
3. Consider dashboard consolidation
|
||||
|
||||
### For v2.0.0
|
||||
1. Restructure admin area with sub-blueprints
|
||||
2. Implement consistent URL patterns
|
||||
3. Add dashboard customization options
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation |
|
||||
|------|------------|--------|------------|
|
||||
| Route still conflicts | Low | High | Tested locally first |
|
||||
| Template breaks | Low | Medium | Template already correct |
|
||||
| Monitoring import fails differently | Low | Low | Defensive imports added |
|
||||
| Performance impact | Very Low | Low | Minimal code change |
|
||||
|
||||
## Approval Requirements
|
||||
|
||||
This hotfix requires:
|
||||
1. Code review of changes
|
||||
2. Local testing confirmation
|
||||
3. Staging deployment (if available)
|
||||
4. Production deployment authorization
|
||||
|
||||
## Contact
|
||||
|
||||
- Architect: StarPunk Architect
|
||||
- Issue: Production 500 error on /admin/dashboard
|
||||
- Priority: CRITICAL
|
||||
- Timeline: Immediate deployment required
|
||||
Reference in New Issue
Block a user