Daily review 2026-06-21 - #56
Draft
NghaReformer wants to merge 1 commit into
Draft
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Daily Review — 2026-06-21
Reviewer: automated (claude-sonnet-4-6)
Branch scanned:
main(HEAD at review time)1. Bugs & Issues
Issue 1 — Emoji icons in all playground manifests
Severity: high
Files:
src/lib/playgrounds/amortization/manifest.ts:7src/lib/playgrounds/bank-reconciliation/manifest.ts:7src/lib/playgrounds/cvp/manifest.ts:7src/lib/playgrounds/interest/manifest.ts:7src/lib/playgrounds/journal-entry/manifest.ts:7src/lib/playgrounds/tvm/manifest.ts:7src/lib/data/playgrounds.ts:18,27,36,44,53,61,69CLAUDE.md rule: "No emoji icons." Every playground manifest sets
iconto an emoji literal ('📊','🏦','📒','🏧','📈','📐'). These render inPlaygroundCard.svelte:13,PlaygroundShell.svelte:110, and the playground detail header atsrc/routes/[lang]/playgrounds/[slug]/+page.svelte:80.Suggested fix: Replace emoji strings with short SVG icon identifiers (e.g., a slug like
"bar-chart") and render them through a shared<Icon name={pg.icon} />component backed by inline SVG sprites. UpdatePlaygroundManifest.icontype to a union of allowed icon slugs instead ofstring.Issue 2 — Hardcoded
#fffin component CSSSeverity: medium
Files:
src/routes/[lang]/learn/+page.svelte:202src/routes/[lang]/chart-of-accounts/+page.svelte:423,458src/lib/playgrounds/journal-entry/components/EntryHistory.svelte:400Each site sets
color: #ffffor button or chip text. This bypasses the theme token system and will be invisible if the design ever introduces a light-mode variant or increases button contrast.Suggested fix: Add a
--color-on-accentor--color-on-errortoken tosrc/lib/theme/tokens.tsand reference it via CSS custom property, e.g.color: var(--color-on-accent).Issue 3 — Hardcoded hex fallbacks in bank-reconciliation SVG/CSS
Severity: medium
Files:
src/lib/playgrounds/bank-reconciliation/components/ReconciliationFlow.svelte:137,144,207-208,270,275,278,281src/lib/playgrounds/bank-reconciliation/components/ScenarioWalkthrough.svelte:182-183,195,199,231,234,238-239,271,274SVG
stroke/fillattributes and CSS rules use the patternvar(--accent, #6ea8fe),var(--green, #22c55e), andvar(--orange, #f59e0b)with hardcoded fallback values. The fallback hex values duplicate what the theme already defines and will silently diverge if tokens change.Suggested fix: Remove the hex fallbacks. The root layout always injects theme CSS before these components mount, so the vars are always defined. If a fallback is truly needed for standalone rendering, define a
<style>block at the top of each file with scoped--accent,--green,--orangethat inherit from the theme.Issue 4 —
$effectused to initialize$statefrom a prop (GoalSeekPanel)Severity: medium
File:
src/lib/playgrounds/cvp/components/GoalSeekPanel.svelte:43–46$effect(() => { if (targetProfitInput === '') { targetProfitInput = fmtNumber(targetProfit || 20000, 0, locale); } });This effect runs once (when
targetProfitInputis empty string on mount), then never re-runs because the condition is never truthy again. If the parent changestargetProfitafter mount (e.g., the user loads a new scenario), the input does not update. Additionally, using$effectfor one-time initialization is an anti-pattern in Svelte 5.Suggested fix: Initialize the state directly at declaration time using the prop:
If the input must reset when
targetProfitchanges from the parent, use$derivedwith a reset gate or expose areset()function the parent can call.Issue 5 — Three redundant
$effectcalls each syncing one tween (VarianceScale)Severity: low
File:
src/lib/playgrounds/bank-reconciliation/components/VarianceScale.svelte:54–62Three separate
$effectblocks each set a singletweenedstore, creating three reactive subscriptions that fire separately even when all inputs change in the same tick.Suggested fix: Collapse into one
$effectblock.Issue 6 — Deprecated
buildGoogleFontsUrlstill publicly exportedSeverity: low
Files:
src/lib/theme/fonts.ts:66–73(declaration, marked@deprecated)src/lib/theme/index.ts:7(re-exports it)Marked deprecated but still exported from the theme barrel. No callers found in the source tree — dead code that exposes a Google Fonts CDN dependency through the public API.
Suggested fix: Delete
buildGoogleFontsUrlfromfonts.tsand remove it from theindex.tsre-export.Issue 7 —
PlaygroundManifest.icontyped asstringwith no enforcementSeverity: low
File:
src/lib/contracts/playground.ts:17The
icon: stringfield places no compile-time constraint on what gets stored, making CLAUDE.md's "No emoji icons" rule unenforceable at the type level.Suggested fix: Replace with a union type of allowed SVG icon slugs once Issue 1 is resolved.
2. New Playground Ideas
Existing coverage: journal-entry, TVM (annuities + investments), CVP (break-even, sensitivity, goal-seek), simple/compound interest, loan amortization, bank reconciliation, depreciation (static HTML).
Idea 1 — Financial Statement Builder (Constructeur d'états financiers)
Title (EN/FR): Financial Statement Builder / Constructeur d'états financiers SYSCOHADA
Target learner: Licence 3 / Master 1
Pedagogical objective: Students can post journal entries and calculate account balances but struggle to assemble the SYSCOHADA Bilan and Compte de résultat from a trial balance. This playground bridges the gap between the chart of accounts and published statements.
Core interaction: The learner receives a pre-populated trial balance of 12–18 accounts and drags rows into the correct line item of either the Bilan or Compte de résultat. Wrong placements are highlighted with the SYSCOHADA classification number that should have been used.
Minimum viable inputs / outputs: Trial balance rows (account code, debit/credit balance) → completed Bilan + Compte de résultat, Assets = Liabilities + Equity check, score.
Why it complements existing playgrounds: Journal Entry teaches debits/credits; Amortization teaches periodic expense recognition; this closes the loop by teaching how those entries aggregate into SYSCOHADA statutory reports.
Idea 2 — VAT & Withholding Tax Simulator (Simulateur TVA / taxes)
Title (EN/FR): VAT & Withholding Tax Simulator / Simulateur TVA et retenues à la source
Target learner: Licence 2 / Licence 3
Pedagogical objective: Students routinely mis-post recoverable VAT (4451) vs. collected VAT (4452) and confuse the net/gross/tax triangle. OHADA-zone VAT rates vary by country (18–20%) and withholding regimes add further complexity.
Core interaction: Given a purchase or sale invoice (amount HT, VAT rate, optional withholding), the learner computes VAT and net amounts, selects the correct SYSCOHADA accounts for each journal line, and verifies the tax payable balance. A live "tax triangle" diagram updates as they type.
Minimum viable inputs / outputs: Invoice amount (HT), VAT rate selector, transaction type, withholding toggle → journal entry, tax payable/recoverable balances, score. Country-specific presets (Côte d'Ivoire, Sénégal, Cameroun, Congo).
Why it complements existing playgrounds: Fills the most important OHADA-specific tax gap not addressed by any current playground.
Idea 3 — Payroll & Social Charges Calculator (Calculateur de paie)
Title (EN/FR): Payroll & Social Charges Calculator / Calculateur de paie et charges sociales
Target learner: Licence 3 / practicing professional (HR/accounting staff)
Pedagogical objective: African payroll computation is a frequent source of errors: CNPS contributions, IRPP brackets, and the employer/employee split differ by country and are often misapplied.
Core interaction: The learner enters gross salary and selects a country (Cameroun, Côte d'Ivoire, Sénégal, Gabon). The playground computes gross → employee deductions (CNPS, IRPP) → net pay, plus employer CNPS share and training levy, then generates the full payroll journal entry with SYSCOHADA accounts (641x, 431x, 444x).
Minimum viable inputs / outputs: Gross salary, country selector, number of dependents → net pay, deduction breakdown, employer cost, journal entry.
Why it complements existing playgrounds: No existing playground touches HR accounting or tax administration. Payroll is a daily task for OHADA-zone accountants with direct legal exposure.
Idea 4 — Foreign Currency Transaction Trainer (Transactions en devises)
Title (EN/FR): Foreign Currency Transaction Trainer / Transactions en devises étrangères
Target learner: Master 1 / Master 2 / practicing professional
Pedagogical objective: SYSCOHADA requires revaluation of monetary items at closing rate and recognition of unrealized exchange differences in accounts 476/477. Students confuse the three separate events: transaction-date recording, payment-date settlement, and year-end revaluation.
Core interaction: A three-stage timeline steps the learner through: (1) invoice date — record at spot rate; (2) payment date — record settlement and realized FX gain/loss (776/676); (3) year-end — revalue open receivable/payable at closing rate and post unrealized difference to 476/477. A rate slider makes it easy to see how a weakening CFA franc changes each entry.
Minimum viable inputs / outputs: Invoice amount (foreign currency), invoice/payment/year-end exchange rates, transaction type → three journal entries, running balance, net FX impact. Optional IFRS IAS 21 comparison mode.
Why it complements existing playgrounds: The only multi-currency mechanics topic in the curriculum; not addressed by any current playground.
Idea 5 — Cash Flow Statement Builder (Tableau des flux de trésorerie)
Title (EN/FR): Cash Flow Statement Builder / Tableau des flux de trésorerie — méthode indirecte
Target learner: Master 1 / Master 2
Pedagogical objective: Most students can produce a P&L but cannot derive operating cash flow using the indirect method — adjusting net income for non-cash items and working capital changes. A standard DSCG and OHADA audit exam topic.
Core interaction: Given net income, depreciation charge, and balance sheet deltas (receivables, payables, inventory), the learner classifies each item (Add-back, Deduction, Working Capital Change) by dragging it to the correct TFT row. Running cash-from-operations updates live. A toggle switches between SYSCOHADA TFT format and IAS 7.
Minimum viable inputs / outputs: Net income, depreciation, Δ receivables/payables/inventory, capex → completed indirect-method TFT (Operating + Investing + Financing), net change in cash, score.
Why it complements existing playgrounds: Completes the trio of SYSCOHADA primary financial statements alongside the Financial Statement Builder (Idea 1). No current playground addresses cash flow mechanics.
Report generated by automated daily review on 2026-06-21.
Generated by Claude Code