feat(iter-11): ship-wheel spinner, progressive hints, risk scorecard & YoY growth levels - #25
Merged
Conversation
…& YoY growth levels UI/UX: - Replace loading shimmer bar with rotating SVG ship-wheel helm (8 spokes, rim knobs, 3 s/rev spinWheel animation) — implements the rotation-list spinner item - Progressive hint disclosure: splitHint() chunks each level's hint into ≤3 parts; a Request-hint button replaces auto-display; each click reveals one more chunk with earlier chunks fading to 70% opacity; hintChunkIdx resets on level change Game Design: - Level 70 (Expert/4): Loan Book Risk Scorecard — weighted-average rate via SUM(x*w)/SUM(w), scalar CROSS JOIN CTE for grand total, portfolio_pct, and running cumulative_exposure window function; 3-row A/B/C result - Level 71 (Expert/4): Loan Portfolio YoY Disbursement Growth — STRFTIME year grouping, LAG for prev year, CASE WHEN NULL for first-year NULL handling; 7 rows DB & Code: - LevelUpModal hint map extended for levels 70-71; nextHintKey sentinel updated to 71 - MAX_LEVEL auto-derives to 71; 395 tests pass (20 more than iter-10) - No new tables, seed rows, or indexes — both levels use existing loans table
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
martinl5
marked this pull request as ready for review
June 26, 2026 14:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[UI/UX Improvements]
Ship-wheel loading spinner (
GameProvider.tsx):SPOKE_ANGLES.map()(hub r=5.5, spoke tips at r=21, knob circles r=2.8 at r=24, outer rim r=24).@keyframes spinWheel; no external asset dependency.aria-hidden="true"since adjacent text describes the loading state.Progressive hint disclosure (
SQLPanel.tsx):splitHint()helper splits each level's hint at.boundaries into ≤ 3 progressive chunks (longer hints are grouped into thirds).💡 Request hintbutton appears in place of the full hint text.Show more hint (N step(s) remaining)after the first reveal.hintChunkIdxstate resets to 0 on every level change.[Game Design Tweaks]
Level 70 (Expert, difficulty 4) — "Loan Book Risk Scorecard — Weighted Rate & Running Exposure":
Four senior-DS patterns in a single challenge:
ROUND(SUM(principal_amount * interest_rate) / SUM(principal_amount), 2)— correct way to aggregate differing rates by volume (wrong: AVG(interest_rate)).totalCTE feeds the grand total into the final SELECT viaCROSS JOIN— the idiomatic pattern when you need a scalar aggregate alongside window functions.ROUND(100.0 * g.total_principal / t.grand_total, 1).SUM(g.total_principal) OVER (ORDER BY g.risk_grade ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW).Result: 3 rows (A: $1.88M, 86.5%, cumulative $1.88M | B: $245K, 11.3%, cumulative $2.13M | C: $48K, 2.2%, cumulative $2.17M). Pattern mirrors Basel III RWA dashboards at GIC, JPMorgan, DBS.
Level 71 (Expert, difficulty 4) — "Loan Portfolio Year-over-Year Disbursement Growth":
yearly:GROUP BY STRFTIME('%Y', start_date)→ loan_count, total_disbursed (all statuses — disbursement is a historical fact).with_lag:LAG(total_disbursed) OVER (ORDER BY loan_year) AS prev_disbursed.CASE WHEN prev_disbursed IS NULL THEN NULL ELSE ROUND(100.0*(total_disbursed - prev_disbursed)/prev_disbursed, 1) END AS yoy_growth_pct.LAG → CASE WHEN NULLpattern is the canonical SQL idiom for period-over-period growth used in investor reports and loan-book analytics.[Database & Code Optimizations]
LevelUpModalEPOCH_NEXT_HINTmap extended for levels 70 and 71;nextHintKeysentinel array extended to[…, 69, 70, 71]; fallback updated?? 69→?? 71.MAX_LEVELinprogression.tsauto-derives fromlevels[levels.length - 1].id= 71 — no other touch points needed.loanstable.evolution_log.mdupdated with full iteration-11 entry.Test Results
npm ci✅ ·tsc --noEmit✅ ·eslint✅ ·vitest run✅ (395/395)Generated by Claude Code