Skip to content

Daily review 2026-06-26 - #61

Draft
NghaReformer wants to merge 1 commit into
mainfrom
daily-review/2026-06-26
Draft

Daily review 2026-06-26#61
NghaReformer wants to merge 1 commit into
mainfrom
daily-review/2026-06-26

Conversation

@NghaReformer

Copy link
Copy Markdown
Owner

Daily Review — 2026-06-26

Automated daily review · Branch: daily-review/2026-06-26


1. Bugs & Issues

HIGH — Missing --orange CSS variable in theme tokens

File: src/lib/theme/tokens.ts + 20+ component files
The theme token set defines amber (→ --amber), but over 20 components reference var(--orange, #f59e0b). The CSS generator never emits --orange, so every usage always falls through to the hardcoded fallback #f59e0b. A theme change to amber has no effect on these components.
Affected files (sample): KpiStrip.svelte:76, amortization/ChartPanel.svelte:436, bank-reconciliation/VarianceScale.svelte:230, ReconciliationFlow.svelte:278.
Fix: Add orange to ThemeTokens.colors in tokens.ts, regenerate CSS; or replace all var(--orange, …) usages with var(--amber).


HIGH — Hardcoded hex colors in CATEGORY_COLORS and COLOR maps

Files:

  • bank-reconciliation/CategoryBreakdownDonut.svelte:30–40 — 9 hardcoded hex values
  • bank-reconciliation/MatchingPairsOverlay.svelte:30–35 — 4 hardcoded hex values

These bypass the theme system entirely. CategoryBreakdownDonut also uses an inline style="background: {seg.color}" at line 120.
Fix: Move colour sets to tokens.ts (or a dataColors sub-object), emit as CSS custom properties. Replace style="background: {seg.color}" with style="--swatch: {seg.color}" and .legend-swatch { background: var(--swatch) }.


HIGH — Hardcoded English string "items" in donut SVG

File: src/lib/playgrounds/bank-reconciliation/components/CategoryBreakdownDonut.svelte:105

<text class="donut-center-label" x="80" y="96">items</text>

Raw English literal never routed through i18n. French users see English text.
Fix: Add centerLabel prop; pass $t('br.donut.items') at the call site; add EN/FR keys; run npm run i18n:check.


HIGH — NumberField formats with hardcoded 'en-US' locale

File: src/lib/components/playground/NumberField.svelte:30

return v.toLocaleString('en-US', { maximumFractionDigits: 2 });

French-locale users see 1,234.56 instead of 1 234,56. NumberField is used in every playground.
Fix: Import formatNumber from $lib/format, pass $locale$, replace the raw toLocaleString call.


HIGH — Empty aria-labelledby target on direction radio group

File: src/lib/playgrounds/bank-reconciliation/components/TransactionJournal.svelte:183–184

<span class="field-label" id="br-journal-direction">&nbsp;</span>
<div class="direction-toggle" role="radiogroup" aria-labelledby="br-journal-direction">

The referenced element contains only &nbsp;, so screen readers announce a blank label for the inflow/outflow toggle.
Fix: Remove aria-labelledby; add aria-label={directionLabel} directly on the radiogroup div with an i18n'd prop.


MEDIUM — Emoji icons in playground data (banned by CLAUDE.md)

File: src/lib/data/playgrounds.ts:18,27,36,44,53,61,69
All 7 playground entries use emoji in the icon field (📐 📊 📒 🏦 📉 🏧 📈). CLAUDE.md explicitly prohibits emoji icons. These render in PlaygroundCard and the playground header.
Also: src/routes/[lang]/+page.svelte:13–16 — feature section uses Unicode dingbats ❖ ⭐ ⚖ ♡ as icons.
Fix: Replace emoji with inline SVG icons or a named icon key resolved by an <Icon> component.


MEDIUM — Stale/mismatched fallback hex values in CSS var() calls

Files:

  • bank-reconciliation/ReconciliationFlow.svelte:137var(--accent, #6ea8fe) but theme accent is #7c7fff
  • bank-reconciliation/ReconciliationStatement.svelte:275,292,293var(--green, #16a34a) but theme green is #34d399
  • bank-reconciliation/VarianceScale.svelte:122,126var(--accent, #6ea8fe) same mismatch

Produces wrong colours in pre-hydration flash, print, and no-JS environments.
Fix: Update fallbacks to match current defaultTheme values in tokens.ts.


MEDIUM — Inline style for honeypot field (banned by CLAUDE.md)

File: src/lib/components/WaitlistForm.svelte:55

<div style="position:absolute;left:-9999px;opacity:0;height:0;overflow:hidden;" aria-hidden="true">

Fix: Replace with a .honeypot CSS class in the component <style> block.


MEDIUM — SVG <defs> IDs are document-global and will conflict if component rendered twice

Files: bank-reconciliation/VarianceScale.svelte:120,125,129 (IDs brBeam, brPivot, brGlow) and bank-reconciliation/MatchingPairsOverlay.svelte:92 (ID brMatchGlow).
Duplicate IDs cause the first definition to apply to all later instances silently.
Fix: Generate a per-instance prefix (crypto.randomUUID().slice(0, 8) in $state) and interpolate it into each id= and url(#…) reference.


LOW — new Date() in module scope causes SSR/hydration year mismatch

File: src/lib/components/Footer.svelte:6

let year = new Date().getFullYear();

Runs at SSR time. Cross-year deploys or differing server timezones produce a hydration mismatch warning.
Fix: Compute server-side in +layout.ts and pass as a prop, or use $effect for client-only initialisation.


LOW — Interest playground default dates computed at module parse time

File: src/lib/playgrounds/interest/Playground.svelte:27–30
startDate/endDate defaults call new Date() at component definition time. A long-lived SPA session retains the original startup dates until a full page reload.
Fix: Move into a factory function called at $state initialisation.


Summary: 0 Svelte 4 syntax violations · 0 server-boundary leaks · 0 circular imports · 0 TypeScript errors. Primary themes: (1) --orange token gap breaks 20+ components' theme-system connection; (2) scattered hardcoded hex in data-colour maps; (3) one EN-only string in the bank-reconciliation donut; (4) locale bug in NumberField.


2. New Playground Ideas

Verified existing playgrounds (none of these duplicate them): tvm, cvp, journal-entry, amortization, depreciation, bank-reconciliation, interest.


1. Financial Ratio Dashboard / Tableau de Bord des Ratios Financiers

Target: Licence 3, Master 1, practicing accountants
Pedagogical objective: Students compute individual ratios in isolation but rarely see how SYSCOHADA's FR/BFR/TN triangle governs solvency as a system. This playground fixes that mental model.
Core interaction: Learner inputs a simplified SYSCOHADA balance sheet and income statement. The playground computes FR, BFR, TN plus 8–10 standard ratios; all animate as inputs change. A traffic-light panel highlights ratios outside industry norms. What-if slider: "increase trade receivables 10% — how does BFR move?"
MVP inputs/outputs: Balance sheet line items, revenue, EBITDA, interest charges → FR/BFR/TN waterfall; ratio panel with thresholds; one-sentence contextual insight per outlier ratio.
Complements existing: Upstream of Bank Reconciliation (both address cash/liquidity); downstream of Journal Entry (which generates the balance sheet inputs).


2. Inventory Valuation: FIFO vs CMP / Évaluation des Stocks FIFO vs CMP

Target: Licence 2
Pedagogical objective: SYSCOHADA mandates FIFO or CMP (LIFO is prohibited). Students consistently mis-calculate the running CMP after a new purchase lot. This playground makes the recalculation transparent at every step.
Core interaction: Learner adds purchase and issue transactions chronologically. Two parallel stock cards (FIFO / CMP) update live. Each row highlights which lot was consumed under FIFO and shows the CMP formula step-by-step. A summary compares COGS and ending inventory under each method.
MVP inputs/outputs: Opening stock, purchase lots (qty × unit price), issue quantities → dual FIFO/CMP stock cards; COGS comparison; ending inventory; gross-margin impact.
Complements existing: Feeds directly into Journal Entry — the ending inventory figure is a 31xx debit entry in SYSCOHADA.


3. Foreign Currency Transactions / Opérations en Devises SYSCOHADA

Target: Licence 3, Master, import/export professionals
Pedagogical objective: SYSCOHADA accounts 176, 476, 477 follow recognition rules that differ from IFRS. Students book exchange differences in the wrong period or direction, especially the year-end adjusting entry versus the settlement entry.
Core interaction: Learner records a foreign-currency invoice. The playground advances the timeline (transaction date → year-end → settlement date); the learner enters the rate at each point and the system auto-generates the three journal entries for accounts 47x with a sign-convention explanation at each step.
MVP inputs/outputs: Functional currency (XAF/XOF/GNF…), foreign currency (EUR/USD), amounts at three rates → three SYSCOHADA journal entries; net exchange gain/loss; provision vs. actual comparison.
Complements existing: Extends Journal Entry into multi-period scenarios; introduces accounts not covered by Depreciation or Amortization.


4. Payroll & Social Charges / Bulletin de Paie et Charges Sociales

Target: Licence 2–3, HR/accounting professionals
Pedagogical objective: Students can compute net pay but cannot reconstruct the composite journal entry (debit 661/645, credit 421/431/432/433). Different OHADA states use different social-charge rates (CNPS Cameroon vs. CNSS Côte d'Ivoire); the playground exposes this variability explicitly.
Core interaction: Learner enters gross salary and selects a country-specific regime (configurable rate table). A live payslip appears alongside the exact SYSCOHADA journal entry for the pay period. A second tab shows employer total labour cost vs. employee net.
MVP inputs/outputs: Gross salary, employee category, country preset (Cameroon / Côte d'Ivoire / Senegal / generic) → annotated payslip; 66x/421/43x journal entry; employer total-cost breakdown.
Complements existing: Bridges Journal Entry mechanics with an OHADA-specific workflow absent from all existing playgrounds.


5. Cash Flow Statement Builder (Indirect Method) / Tableau des Flux de Trésorerie — Méthode Indirecte

Target: Master 1–2, CPA/DSCG candidates, professionals
Pedagogical objective: SYSCOHADA mandates the indirect method. Students who can read a P&L cannot reconcile net income to operating cash flow — particularly when non-cash items (depreciation, provisions) and working-capital changes (Δ clients, Δ fournisseurs, Δ stocks) interact. Sign-convention errors are the most common exam mistake.
Core interaction: Learner receives a simplified income statement and two-period balance sheet. They drag-and-drop line items into the correct TFT section (operating/investing/financing) and choose the adjustment sign. A running total updates live and a "balance check" confirms the statement ties to opening/closing cash. Wrong placements trigger a one-sentence SYSCOHADA rule explanation.
MVP inputs/outputs: Net income, depreciation, WC account changes, capex, financing flows → three-section TFT; cash reconciliation; per-item feedback on sign errors.
Complements existing: Sits above Journal Entry and Bank Reconciliation in the learning journey — it consumes the outputs of those playgrounds as source data.


Report generated by automated daily review · 2026-06-26


Generated by Claude Code

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ohadalearn Ready Ready Preview, Comment Jun 26, 2026 11:10pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants