From 55fd42b696e2ae13adf5845e4aa72c2d6576e8f7 Mon Sep 17 00:00:00 2001 From: mytec Date: Fri, 30 Jan 2026 16:19:25 +0200 Subject: [PATCH] @mytec: iter10.1 start --- RFCP-Iteration10.1-Critical-Bugfixes.md | 456 ++++++++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 RFCP-Iteration10.1-Critical-Bugfixes.md diff --git a/RFCP-Iteration10.1-Critical-Bugfixes.md b/RFCP-Iteration10.1-Critical-Bugfixes.md new file mode 100644 index 0000000..cb624ad --- /dev/null +++ b/RFCP-Iteration10.1-Critical-Bugfixes.md @@ -0,0 +1,456 @@ +# RFCP - Iteration 10.1: Critical Bugfixes + +**Status:** Ready for Claude Code Implementation +**Priority:** P0 CRITICAL +**Time:** 30-60 minutes + +--- + +## 🐛 Three Critical Issues Found + +After Iteration 10 deployment, three critical bugs remain: + +1. ❌ **Stack overflow crash at 50m resolution** - **ROOT CAUSE FOUND: Spread operator on large arrays** +2. ❌ **No confirmation on Delete key** - keyboard shortcut bypasses dialog +3. ❌ **Cyan/green coverage zone** - синьо-зелене коло на карті (visible on screenshot) + +--- + +## 🔍 Bug Analysis + +### Bug 1: Stack Overflow at 50m Resolution ⚡ ROOT CAUSE IDENTIFIED + +**User Report:** "крашує на білий екран саме при розрахунку, натискання на кнопку" + +**Stack Trace Analysis:** +```javascript +const M = b.map(ht => ht.rsrp) // Maps to RSRP array +const B = Math.min(...M) // ❌ CRASHES HERE! +const A = Math.max(...M) // ❌ AND HERE! +const C = M.reduce((ht, Nt) => ht + Nt, 0) / z +``` + +**ROOT CAUSE: Spread Operator Argument Limit** + +JavaScript has a hard limit of ~65,000-125,000 function arguments (varies by engine): +- 50m resolution, 10km radius = ~158,000 points +- `Math.min(...array)` tries to pass 158,000 arguments +- **Exceeds engine limit → RangeError: Maximum call stack size exceeded** + +**Why Previous Fix Didn't Work:** + +Iteration 10 added `MAX_GRID_POINTS` cap and replaced `results.flat()`, but the **spread operator in Math.min/max was still there**! + +```typescript +// ❌ This is still in the code: +const minRsrp = Math.min(...rsrpValues) // CRASHES with 150k+ items +const maxRsrp = Math.max(...rsrpValues) // CRASHES with 150k+ items +``` + +**Solution: Replace Spread with Reduce** + +```typescript +// ❌ BAD (crashes on large arrays) +const minRsrp = Math.min(...rsrpValues) +const maxRsrp = Math.max(...rsrpValues) + +// ✅ GOOD (works with ANY size array) +const minRsrp = rsrpValues.reduce((min, val) => Math.min(min, val), rsrpValues[0]) +const maxRsrp = rsrpValues.reduce((max, val) => Math.max(max, val), rsrpValues[0]) + +// ✅ EVEN BETTER (slightly faster for large arrays) +const minRsrp = rsrpValues.reduce((min, val) => val < min ? val : min, rsrpValues[0]) +const maxRsrp = rsrpValues.reduce((max, val) => val > max ? val : max, rsrpValues[0]) +``` + +**Files to Fix:** + +Search for ALL instances of: +```bash +grep -rn "Math.min\(\.\.\..*\)" src/ +grep -rn "Math.max\(\.\.\..*\)" src/ +``` + +Most likely locations: +- `src/store/coverage.ts` - coverage statistics calculation +- `src/lib/calculator.ts` - coverage calculations +- `src/components/panels/CoverageStats.tsx` - stats display + +**Performance Comparison:** +- `Math.min(...array)`: ✅ Fast BUT ❌ Crashes >65k elements +- `reduce()`: ✅ Always works, ✅ Only ~2x slower +- For 200k elements: ~30ms (still imperceptible to user) + +--- + +### Bug 2: No Confirmation on Delete Key + +**User Report:** "нема підтвердження видалення сайту коли видаляєш кнопкою del" + +**Current Behavior:** +- Delete button in UI → Shows confirmation dialog ✅ +- Keyboard shortcut (Delete key) → Deletes immediately ❌ + +**Root Cause:** + +Keyboard handler calls `deleteSite()` directly, bypassing the confirmation wrapper. + +**Likely code pattern:** +```typescript +// Somewhere in App.tsx or SitesPanel.tsx +useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Delete' && selectedSiteId) { + deleteSite(selectedSiteId); // ❌ No confirmation! + } + }; + + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); +}, [selectedSiteId, deleteSite]); +``` + +**Solution:** + +Find the existing delete button's onClick handler and reuse it: + +```typescript +// Example: In SitesPanel.tsx or similar + +// Existing delete button logic (already has confirmation) +const handleDeleteClick = useCallback(() => { + if (!selectedSite) return; + + if (!window.confirm(`Delete site "${selectedSite.name}"?`)) { + return; + } + + const deletedSite = { ...selectedSite }; + deleteSite(selectedSiteId); + + // Show undo toast + toast.success('Site deleted', { + duration: 10000, + action: { + label: 'Undo', + onClick: () => addSite(deletedSite), + }, + }); +}, [selectedSite, selectedSiteId, deleteSite, addSite]); + +// Update keyboard handler to use SAME function +useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Delete' && selectedSiteId) { + e.preventDefault(); + handleDeleteClick(); // ✅ Reuses confirmation logic! + } + }; + + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); +}, [selectedSiteId, handleDeleteClick]); +``` + +**Search for:** +```bash +grep -rn "key.*Delete\|Delete.*key" src/ +grep -rn "handleKeyDown\|onKeyDown" src/ +``` + +**Files to check:** +- `src/App.tsx` - main keyboard handlers +- `src/components/panels/SitesPanel.tsx` - site list with delete button +- `src/components/map/Map.tsx` - map-level keyboard handlers + +--- + +### Bug 3: Cyan/Green Coverage Zone + +**User Report:** "колір зони синьо - зелений :)" (visible on screenshot) + +**Visual Evidence:** +- Синьо-зелене (cyan) коло видно навколо сайту +- Це НЕ частина RSRP gradient (який orange → red → dark red) +- Виглядає як dashed circle або зона + +**Most Likely Source: Leaflet Circle Component** + +```typescript +// Probably in src/components/map/SiteMarker.tsx or Map.tsx + +``` + +**Investigation Steps:** + +```bash +# 1. Find all Circle components +grep -rn " */} +``` + +**Option B: Change color to orange** (if circle is useful) +```typescript + +``` + +**Option C: Make it toggleable** +```typescript +// Add to coverage settings store +const [showCalculationBounds, setShowCalculationBounds] = useState(false); + +// In settings panel: + + +// In map: +{showCalculationBounds && ( + +)} +``` + +**Recommended:** Start with Option A (remove), can add back later if needed. + +--- + +## 📋 Implementation Checklist for Claude Code + +### Phase 1: Fix Spread Operator Crash (P0 - HIGHEST PRIORITY) + +**Task 1.1: Find all Math.min/max with spread operators** +```bash +cd /opt/rfcp/frontend +grep -rn "Math.min(\.\.\." src/ +grep -rn "Math.max(\.\.\." src/ +``` + +**Task 1.2: Replace ALL instances** + +Find patterns like: +```typescript +Math.min(...array) +Math.max(...array) +``` + +Replace with: +```typescript +array.reduce((min, val) => val < min ? val : min, array[0]) +array.reduce((max, val) => val > max ? val : max, array[0]) +``` + +**Task 1.3: Add safety checks** +```typescript +// Before using reduce, ensure array is not empty: +if (array.length === 0) { + return { minRsrp: 0, maxRsrp: 0, avgRsrp: 0 }; +} +``` + +**Expected files to modify:** +- `src/store/coverage.ts` - most likely location +- `src/lib/calculator.ts` - possible location +- `src/components/panels/CoverageStats.tsx` - stats display + +--- + +### Phase 2: Fix Delete Key Confirmation (P0) + +**Task 2.1: Find keyboard event handler** +```bash +grep -rn "key.*Delete\|Delete.*key" src/ +grep -rn "e.key === 'Delete'" src/ +``` + +**Task 2.2: Find existing delete button confirmation** +```bash +grep -rn "window.confirm.*[Dd]elete" src/ +grep -rn "handleDelete" src/ +``` + +**Task 2.3: Make keyboard handler use same confirmation logic** + +Pattern to find: +```typescript +if (e.key === 'Delete' && selectedSiteId) { + deleteSite(selectedSiteId); // ❌ No confirmation +} +``` + +Replace with: +```typescript +if (e.key === 'Delete' && selectedSiteId) { + e.preventDefault(); + handleDeleteClick(); // ✅ Uses existing confirmation +} +``` + +--- + +### Phase 3: Fix Cyan/Green Circle (P1) + +**Task 3.1: Find Circle component with cyan color** +```bash +grep -rn "-80 dBm): `#ff6b35` (orange) +- Good (-80 to -95): `#ff4444` (red) +- Fair (-95 to -105): `#cc0000` (dark red) +- Poor (<-105): `#8b0000` (very dark red) + +**Acceptable Colors for Circles (not in gradient):** +- Orange: `#ff9800` +- Purple: `#9c27b0` +- Black: `#000000` + +**NOT acceptable (conflicts with gradient):** +- Red shades +- Orange shades +- Cyan/blue: `#00bcd4` ❌ (this is the bug!) + +--- + +## 🎯 Success = All Three Bugs Fixed + Tested + +**Estimated time:** 30-60 minutes + +**Deploy when:** All tests pass + no TypeScript errors +