feat(engine): deterministic peat fire danger scoring and cluster inspection drawer (Issue 4) #14

Merged
yuris merged 1 commit from feat/issue-4-danger-scoring-drawer into main 2026-10-14 20:18:32 +00:00
Owner

Summary

Implements Issue 4: Deterministic peat fire danger scoring engine and cluster drawer.

  • Pure typed TypeScript domain module danger-score.ts implementing the 100-point deterministic formula:
    • Groundwater Table Depth (TMAT) [0-35 pts]
    • Historical Fire Recurrence [0-30 pts]
    • Peat Depth and Landform [0-20 pts]
    • Weather and Wind [0-15 pts]
  • Vitest unit test suite danger-score.test.ts with 22 tests passing across all boundary conditions and brackets (KRITIS, TINGGI, SEDANG, RENDAH).
  • Spatial clustering module spatial-clustering.ts grouping points within ~2.7 km (0.025 deg).
  • Interactive inspection drawer ClusterDetailDrawer with keyboard accessibility (Escape to close), administrative metadata, dominant peat depth, plain-language explanation, and horizontal telemetry progress bars (RiskFactorBreakdown).
  • Integrated drawer triggering on MapLibre cluster and single-point clicks with dynamic danger level tinting.

Closes #4

## Summary Implements Issue 4: Deterministic peat fire danger scoring engine and cluster drawer. - Pure typed TypeScript domain module `danger-score.ts` implementing the 100-point deterministic formula: - Groundwater Table Depth (TMAT) [0-35 pts] - Historical Fire Recurrence [0-30 pts] - Peat Depth and Landform [0-20 pts] - Weather and Wind [0-15 pts] - Vitest unit test suite `danger-score.test.ts` with 22 tests passing across all boundary conditions and brackets (KRITIS, TINGGI, SEDANG, RENDAH). - Spatial clustering module `spatial-clustering.ts` grouping points within ~2.7 km (0.025 deg). - Interactive inspection drawer `ClusterDetailDrawer` with keyboard accessibility (Escape to close), administrative metadata, dominant peat depth, plain-language explanation, and horizontal telemetry progress bars (`RiskFactorBreakdown`). - Integrated drawer triggering on MapLibre cluster and single-point clicks with dynamic danger level tinting. Closes #4
feat(engine): deterministic peat fire danger scoring and cluster inspection drawer (Issue 4)
All checks were successful
CI / Verify Quality & Build (pull_request) Successful in 1m42s
4be20d12b3
yuris-bot approved these changes 2026-10-14 20:16:51 +00:00
yuris-bot left a comment

Review: Issue 4 - Deterministic peat fire danger scoring engine and cluster drawer

Verdict: APPROVE


Five-Axis Review Summary

1. Correctness

  • 100-Point Scoring Algorithm: Fully verified according to specifications in src/lib/domain/danger-score.ts:
    • Groundwater Table Depth (TMAT) [0–35 pts]: < -40\text{ cm} \to 35, [-40, 0] \to \text{round}((|\text{TMAT}|/40)*35), > 0 \to 0, fallback 20.
    • Historical Fire Recurrence [0–30 pts]: 3+ \to 30, 1\text{–}2 \to 15, 0 \to 0.
    • Peat Depth and Landform [0–20 pts]: > 500\text{ cm} \to 20, 300\text{–}500 \to 17, 100\text{–}300 \to 12, < 100 \to 6, mineral \to 0.
    • Weather and Wind [0–15 pts]: > 20\text{ km/h} \land < 60\% \to 15, 10\text{–}20 \to 8, calm \to 2.
    • Classification Brackets: KRITIS (80–100), TINGGI (60–79), SEDANG (40–59), RENDAH (0–39).
  • Unit Testing: Vitest test suite (danger-score.test.ts) contains 22 tests passing across all boundary conditions, brackets, and interpolation formulas.
  • Cluster & Point Inspection: Clicking clusters or individual hotspot markers populates FireCluster state and opens the inspection drawer.

2. Readability & Simplicity

  • Domain logic is pure and free of side effects.
  • Clean separation between pure calculations (danger-score.ts), spatial clustering (spatial-clustering.ts), and display components (cluster-detail-drawer.tsx, risk-factor-breakdown.tsx).

3. Architecture

  • MapView uses ref forwarding (onSelectClusterRef) to prevent map lifecycle re-instantiation when drawer selection handlers update.
  • Pure domain models live in src/lib/domain/ with zero coupling to React or MapLibre.

4. Security & Hardening

  • Pure deterministic input validation.
  • All numbers clamped and bounded (0 \le \text{score} \le 100).

5. Accessibility & UX

  • ClusterDetailDrawer provides full keyboard accessibility (Escape key closes drawer).
  • Includes role="dialog", aria-modal="true", and explicit aria-label elements.
  • Clear visual hierarchy with color-coded badges and horizontal telemetry bars for each of the 4 risk factors.

Ponytail Audit

  • Dependencies: Only vitest added as devDependency for testing, fully aligned with test-driven development mandate.
  • Complexity: Zero extraneous abstractions.

Verification

  • pnpm test: All 22 Vitest unit tests passed (790ms).
  • vp check: Clean across 92 files (0 errors, 0 warnings).
  • next build: Standalone production build compiled successfully.
# Review: Issue 4 - Deterministic peat fire danger scoring engine and cluster drawer ### Verdict: **APPROVE** --- ### Five-Axis Review Summary #### 1. Correctness - **100-Point Scoring Algorithm**: Fully verified according to specifications in `src/lib/domain/danger-score.ts`: - Groundwater Table Depth (TMAT) [0–35 pts]: $< -40\text{ cm} \to 35$, $[-40, 0] \to \text{round}((|\text{TMAT}|/40)*35)$, $> 0 \to 0$, fallback $20$. - Historical Fire Recurrence [0–30 pts]: $3+ \to 30$, $1\text{–}2 \to 15$, $0 \to 0$. - Peat Depth and Landform [0–20 pts]: $> 500\text{ cm} \to 20$, $300\text{–}500 \to 17$, $100\text{–}300 \to 12$, $< 100 \to 6$, mineral $\to 0$. - Weather and Wind [0–15 pts]: $> 20\text{ km/h} \land < 60\% \to 15$, $10\text{–}20 \to 8$, calm $\to 2$. - Classification Brackets: KRITIS (80–100), TINGGI (60–79), SEDANG (40–59), RENDAH (0–39). - **Unit Testing**: Vitest test suite (`danger-score.test.ts`) contains 22 tests passing across all boundary conditions, brackets, and interpolation formulas. - **Cluster & Point Inspection**: Clicking clusters or individual hotspot markers populates `FireCluster` state and opens the inspection drawer. #### 2. Readability & Simplicity - Domain logic is pure and free of side effects. - Clean separation between pure calculations (`danger-score.ts`), spatial clustering (`spatial-clustering.ts`), and display components (`cluster-detail-drawer.tsx`, `risk-factor-breakdown.tsx`). #### 3. Architecture - `MapView` uses ref forwarding (`onSelectClusterRef`) to prevent map lifecycle re-instantiation when drawer selection handlers update. - Pure domain models live in `src/lib/domain/` with zero coupling to React or MapLibre. #### 4. Security & Hardening - Pure deterministic input validation. - All numbers clamped and bounded ($0 \le \text{score} \le 100$). #### 5. Accessibility & UX - `ClusterDetailDrawer` provides full keyboard accessibility (`Escape` key closes drawer). - Includes `role="dialog"`, `aria-modal="true"`, and explicit `aria-label` elements. - Clear visual hierarchy with color-coded badges and horizontal telemetry bars for each of the 4 risk factors. --- ### Ponytail Audit - **Dependencies**: Only `vitest` added as devDependency for testing, fully aligned with test-driven development mandate. - **Complexity**: Zero extraneous abstractions. --- ### Verification - `pnpm test`: All 22 Vitest unit tests passed (790ms). - `vp check`: Clean across 92 files (0 errors, 0 warnings). - `next build`: Standalone production build compiled successfully.
yuris merged commit 03950fa2db into main 2026-10-14 20:18:32 +00:00
Sign in to join this conversation.
No reviewers
No labels
backend
frontend
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
yuris/titik-gambut-next!14
No description provided.