Skip to content

Daily review 2026-07-11 - #75

Draft
NghaReformer wants to merge 1 commit into
mainfrom
daily-review/2026-07-11
Draft

Daily review 2026-07-11#75
NghaReformer wants to merge 1 commit into
mainfrom
daily-review/2026-07-11

Conversation

@NghaReformer

Copy link
Copy Markdown
Owner

Daily Review — 2026-07-11

Scope: Full codebase scan (SvelteKit 2 / Svelte 5 runes, i18n, theme, accessibility, TS)
Reviewer: Automated senior review


1. Bugs & Issues

Critical

C-1 · scripts/generate-i18n-types.ts · npm run i18n:check broken in CI

Severity: Critical
File: package.json (script), scripts/generate-i18n-types.ts

tsx is listed in devDependencies but node_modules is absent in this environment, causing sh: tsx: not found when npm run i18n:check runs. The generated type file src/lib/i18n/generated.ts may be stale, silently allowing out-of-sync translation keys to type-check. A missing npm ci step in CI pipelines will surface this.

Fix: Ensure npm ci runs before any i18n:check step in CI/CD.


High

H-1 · src/lib/finance/dayCount.ts:7 · Missing return + exhaustiveness gap

Severity: High
File: src/lib/finance/dayCount.ts:7

yearFraction has a switch over DayCount without a default clause. TypeScript reports TS2366: Function lacks ending return statement. If an unexpected value is passed at runtime (e.g., a new convention added to the type without updating this function), the function returns undefined typed as number, propagating NaN silently into amortization and interest schedule calculations.

Fix: Add default: return assertNever(convention); (or default: return 0; with a log) after the switch.


H-2 · src/lib/components/feedback/FeedbackForm.svelte:7 · Server-boundary import type from $lib/server/

Severity: High
File: src/lib/components/feedback/FeedbackForm.svelte:7

import type { FeedbackType, FeedbackSeverity } from '$lib/server/db/types';

FeedbackForm.svelte is a client component that imports types from $lib/server/db/types. While import type is erased at runtime, SvelteKit's Vite plugin enforces the $lib/server/ boundary statically and can flag this during build. The shared types FeedbackType and FeedbackSeverity are pure string unions with no server-only dependencies.

Fix: Move FeedbackType and FeedbackSeverity to src/lib/shared/types.ts (or src/lib/contracts/feedback.ts) and import from there.


H-3 · src/lib/playgrounds/cvp/components/GoalSeekPanel.svelte:43-47 · $effect does not re-initialize on prop change

Severity: High
File: src/lib/playgrounds/cvp/components/GoalSeekPanel.svelte:43

$effect(() => {
    if (targetProfitInput === '') {
        targetProfitInput = fmtNumber(targetProfit || 20000, 0, locale);
    }
});

This effect tracks targetProfit and locale reactively, but only writes when targetProfitInput === ''. If the parent scenario changes targetProfit, the input field is never updated (it's already non-empty). The solver will run against stale data while displaying fresh scenario values.

Fix: Reset targetProfitInput whenever targetProfit changes, not only when empty. Track the previous targetProfit value and reset when it changes.


Medium

M-1 · Multiple files · Undefined CSS variables with hex fallbacks

Severity: Medium
Files: src/lib/playgrounds/amortization/components/{ScheduleTable,ChartPanel,InputsPanel}.svelte, src/lib/playgrounds/bank-reconciliation/components/LedgerPanel.svelte, src/lib/components/playground/KpiStrip.svelte

These files reference var(--orange, #f59e0b), var(--blue, #3b82f6), var(--red, #ef4444), var(--green, #22c55e) extensively. None of --orange, --blue, --red are emitted by src/lib/theme/css-generator.ts (the theme defines --accent, --green, --amber, --error). The hex fallback is the effective color — it bypasses the theme system.

Fix: Add semantic aliases --color-positive, --color-negative, --color-highlight to tokens.ts and the CSS generator. Replace bare hex fallbacks with these tokens.


M-2 · CategoryBreakdownDonut.svelte:30-40 + MatchingPairsOverlay.svelte:31-34 · Hardcoded hex chart palette

Severity: Medium

Nine hex literals hardcoded in JS objects for SVG chart colors. These are written directly to SVG fill attributes, making them impossible to theme.

Fix: Define --chart-series-{1..9} tokens in tokens.ts, expose via CSS, and read them via getComputedStyle.


M-3 · Multiple files · Bare #fff hardcoded as CSS color

Severity: Medium
Files: src/lib/playgrounds/journal-entry/components/EntryHistory.svelte:400, src/routes/[lang]/chart-of-accounts/+page.svelte:423,458, src/routes/[lang]/learn/+page.svelte:202

All three use color: #fff for text on accent/error backgrounds. Should be color: var(--bg) or a future --text-on-accent token.


M-4 · Multiple files · Emoji icons violate CLAUDE.md

Severity: Medium
Files: src/lib/data/playgrounds.ts, src/lib/playgrounds/cvp/manifest.ts, src/lib/components/playground/PlaygroundTabs.svelte

CLAUDE.md explicitly states "No emoji icons." The icon field and tab icons use '📊', '📐', '🏦', '📖', '🧮', '📋', '📒', '📈', '📉', '🏧'.

Fix: Replace with SVG icon names/components. Define a PlaygroundIcon type referencing an icon-set key.


M-5 · src/lib/components/WaitlistForm.svelte:55 · Inline style on honeypot field

Severity: Medium

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

CLAUDE.md forbids inline styles. Move to a scoped CSS class (.honeypot-trap or similar).


Low

L-1 · src/lib/playgrounds/tvm/components/WorkingsPanel.svelte:16 · Unused $derived

let translate = $derived($t); is assigned but never referenced — the template uses $t(...) directly. Delete this line.

L-2 · src/lib/theme/tokens.ts · No spacing tokens

ThemeTokens has no spacing scale. CLAUDE.md mandates spacing via theme tokens, but every component uses raw rem literals. Add spacing: { xs, sm, md, lg, xl } and emit --space-* from the CSS generator.

L-3 · src/lib/i18n/namespaces/common.fr.ts · Mixed quotes on coa.class.6 / coa.class.7

Double quotes on two keys, inconsistent with the rest of the file. No functional impact; run Prettier to normalize.


2. New Playground Ideas

Existing (not duplicated): TVM, CVP, Journal Entry, Amortization, Depreciation (static), Bank Reconciliation, Interest (Simple/Compound/Bond)


A — VAT Register & Returns / Grand livre TVA & Déclaration

Target: Licence 2–3, practicing professional
Gap: Students confuse TVA collectée vs. TVA déductible and miscalculate net TVA payable.
Interaction: Enter purchase/sale transactions → live TVA register → OHADA-style return form → journal entries (Accounts 4456/4457/445711). Toggle monthly vs. quarterly filing.
Complements: Journal Entry teaches mechanics; this adds tax-reporting context (SYSCOHADA class 4).


B — Payroll & Social Charges / Bulletin de paie & Charges sociales

Target: Licence 3, Master 1, HR/accounting professional
Gap: OHADA-zone payroll (CNPS, IRPP, allowances) varies by country; students can't reconcile gross-to-net.
Interaction: Enter gross salary, country (Cameroon/Côte d'Ivoire/Sénégal), grade → detailed payslip + journal entries (Accounts 641, 645, 431, 447) + total employer cost.
Complements: CVP shows labor as a fixed cost but not how it's computed.


C — Inventory Costing Methods / Valorisation des stocks

Target: Licence 1–2
Gap: FIFO vs. CUMP vs. LIFO differences only become concrete through real numbers.
Interaction: Enter movement table (buy/sell, qty, unit cost) → live stock card (fiche de stock) per selected method + side-by-side COGS/ending inventory comparison. LIFO shown for IFRS contrast only.
Complements: Depreciation handles fixed assets; this covers SYSCOHADA class 3.


D — Financial Ratio Analyzer / Analyse par ratios financiers

Target: Licence 3, Master
Gap: Students memorize formulas without building sensitivity intuition.
Interaction: Adjust simplified balance sheet (Actif/Passif) and IS following SYSCOHADA Tableau de Synthèse → 15 key ratios update live with color-coded bands + radar chart + "what-if" single-line-item sensitivity.
Complements: CVP covers managerial levers; this covers the external financial health picture (auditor/creditor view).


E — Provisions & Depreciation of Receivables / Provisions & Dépréciation des créances

Target: Licence 3, Master 1
Gap: Learners confuse provisions, asset depreciation, and accruals — all have different SYSCOHADA account trees.
Interaction: Scenario presented (doubtful receivable, lawsuit, warranty) → learner decides if a provision is required, estimates amount, records journal entry → graded feedback on account choice (39x/49x/59x for dépréciation; 19x for provisions) + BS impact preview.
Complements: Journal Entry teaches mechanics; this applies them to the most conceptually confusing SYSCOHADA exam domain.


Full report at reports/daily/2026-07-11.md


Generated by Claude Code

Automated codebase scan: 3 high-severity issues (missing return/exhaustiveness
in dayCount.ts, server-boundary import type in FeedbackForm, $effect stale-prop
bug in GoalSeekPanel), 5 medium issues (hex fallbacks for undefined CSS vars,
hardcoded chart palette, #fff literals, emoji icons, inline honeypot style),
2 low issues (dead derived, missing spacing tokens). Five new playground ideas
proposed (VAT Register, Payroll, Inventory Costing, Financial Ratios,
Provisions & Contingent Liabilities).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017x6b9APuC3M8YfZnjB36Bu
@vercel

vercel Bot commented Jul 11, 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 Jul 11, 2026 11:16pm

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