Skip to content

Daily review 2026-06-19 - #54

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

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

Conversation

@NghaReformer

Copy link
Copy Markdown
Owner

OhadaLearn Daily Review — 2026-06-19

Scope: Full codebase scan — Svelte 5 compliance, theme tokens, i18n, a11y, server isolation, dead code, async safety.
Verdict: No critical or high-severity issues. Four medium issues, four low issues. Codebase is production-healthy.


1. Bugs & Issues

MEDIUM — Hardcoded hex inside SVG data URI (accent color decoupled from token)

File: src/lib/components/playground/PlaygroundSettings.svelte:94
Rule: No hardcoded hex outside src/lib/theme/tokens.ts.
The dropdown chevron is rendered as an inline SVG background-image data URI with stroke='%237c7fff' (#7c7fff). CSS custom properties (var(--accent)) cannot be interpolated inside url() data URIs, so this color is permanently hardcoded. If --accent changes in tokens, the chevron silently shows the wrong color.
Suggested fix: Replace the data-URI approach with a CSS mask pattern, or extract the SVG to static/icons/chevron-down.svg and reference it via background-image + filter tint.


MEDIUM — In-memory rate limiter ineffective on serverless (Vercel)

Files: src/routes/api/waitlist/+server.ts:6 · src/routes/api/feedback/+server.ts:8
Each endpoint declares a module-level rateLimitMap. On Vercel, each invocation may spin up a new cold-start function; the map is reset every time, making the per-minute cap illusory under concurrent traffic or cold-start conditions. The waitlist comment acknowledges this ("sufficient for Phase 1"), but the feedback endpoint has no such note.
Suggested fix: Add a matching Phase 1 caveat comment to the feedback endpoint. For Phase 2, replace with Upstash Redis or a Supabase counter column with TTL.


LOW — Hardcoded #fff bypasses token system

Files:

  • src/routes/[lang]/learn/+page.svelte:202
  • src/routes/[lang]/chart-of-accounts/+page.svelte:423
  • src/routes/[lang]/chart-of-accounts/+page.svelte:458

White text on dark/accent backgrounds is intentional, but bypasses the token system. If the surface color changes, the text remains white with no audit trail.
Suggested fix: Add --text-on-accent: #fff; to src/lib/theme/tokens.ts and replace all three occurrences.


LOW — Hardcoded hex fallbacks in CSS custom properties (bank reconciliation)

File: src/lib/playgrounds/bank-reconciliation/components/ReconciliationFlow.svelte:137,144,207,208,270,275,278,281
Multiple var(--accent, #6ea8fe), var(--green, #22c55e), var(--orange, #f59e0b) — fallback values will silently display wrong colors if tokens aren't injected (e.g., in a test environment).
Suggested fix: Remove the hex fallbacks; the layout's css-generator.ts always injects these properties, making the fallbacks defensive-dead code.


LOW — depreciation-playground.html has no native Svelte counterpart

File: static/playgrounds/depreciation-playground.html
The other three static HTML playgrounds (amortization, CVP, journal-entry) each have a full native Svelte implementation. Depreciation remains static-only, inaccessible to i18n, the preference store, share URLs, and the grading infrastructure.
Suggested fix: Create src/lib/playgrounds/depreciation/ implementing PlaygroundModule from src/lib/contracts/playground.ts.


LOW — Duplicate slug registration silently overwrites

File: src/lib/playgrounds/_registry.ts:14
A duplicate slug logs a warning and silently overwrites the first registration. A mis-import in production could cause the wrong playground to render.
Suggested fix: Throw in development, return-early in production with the slug name in the warning.


Confirmed clean

Concern Result
export let props 0 instances
$: reactive statements 0 instances
on: directives 0 instances
<slot /> 0 instances
$app/stores import 0 instances
Server code outside $lib/server/ Only import type — safe
Missing aria-label on interactive elements None found
User-facing strings outside i18n None found
Unhandled async in API routes All branches handled

2. New Playground Ideas

Audited existing: TVM, Interest, CVP, Bank Reconciliation, Amortization, Journal Entry (Svelte) + Depreciation, CVP, Amortization, Journal Entry (static HTML).


A — Financial Ratio Dashboard

EN: Financial Ratio Analysis · FR: Analyse des Ratios Financiers
Target: Licence 3, Master 1, practitioner
Objective: Ratios are meaningless in isolation; students compute them correctly but can't read them as a cluster. This forces interpretation of liquidity + solvency + profitability together.
Interaction: Input a simplified SYSCOHADA balance sheet + income statement; view computed ratios on a radar chart; drag sliders to stress-test one line and watch which ratios tip into "danger."
Inputs/Outputs: Current assets/liabilities, total assets/debt, revenue, EBIT, net income → current ratio, quick ratio, D/E, interest coverage, ROA, ROE, ROCE; radar chart; alert badges.
Complements: TVM + CVP provide forward-looking analysis; this closes the loop with backward-looking performance measurement.


B — VAT / TVA Return Builder

EN: VAT Return Calculator · FR: Déclaration de TVA
Target: Licence 2, practicing accountant, tax preparer
Objective: Students confuse TVA déductible, TVA collectée, and the net payable/credit position — especially with partial exemption. TVA declarations are the most common compliance task in OHADA-zone firms.
Interaction: Record purchase and sale transactions (with/without TVA at 19.25% CEMAC or configurable UEMOA rates). Playground builds a live TVA summary table and generates the corresponding journal entries.
Inputs/Outputs: Transaction list (HT amount, VAT rate, purchase/sale flag), period → TVA collectée, TVA déductible, net TVA à payer / crédit, journal entries using accounts 4431/4452/4455.
Complements: Journal Entry playground teaches the mechanics; this applies them to the most common real-world compliance workflow.


C — Payroll Slip Builder (Bulletin de Paie)

EN: Payroll Slip Builder · FR: Simulateur de Bulletin de Paie
Target: Licence 3, Master, HR/payroll practitioner
Objective: OHADA-zone payroll has jurisdiction-specific tiered contributions (CNPS, IRPP, CRTV levy). Students apply generic formulas without understanding the contribution structure.
Interaction: Input gross salary + jurisdiction (Cameroon, Côte d'Ivoire, Sénégal — driving different rate tables). Renders a full bulletin de paie and the corresponding journal entries.
Inputs/Outputs: Gross salary, employment category, dependents, jurisdiction → pay-slip table, net salary, employer cost, journal entries (641x, 431x, 447x).
Complements: Extends Journal Entry with payroll-specific chart-of-accounts usage; fills a practitioner gap not covered by any existing playground.


D — Cash Budget Planner (Budget de Trésorerie)

EN: Cash Budget Planner · FR: Budget de Trésorerie
Target: Licence 2/3, small business owner
Objective: Students learn income statements but can't feel the profit-cash gap — a profitable firm can be insolvent. This playground builds that intuition.
Interaction: Build a 6-month rolling cash budget with expected receipts (collection lag configurable at 30/60/90 days) and disbursements. Highlights months with negative cash position and suggests the minimum credit line required.
Inputs/Outputs: Starting balance, 6 months revenue + collection delay, cost structure, tax payment months → monthly budget table, cash flow chart, deficit alert with financing amount needed.
Complements: CVP models profitability; this shows why a profitable CVP outcome can still produce a cash crisis. Natural follow-on exercise in any managerial accounting course.


E — Depreciation Method Comparator (Native Svelte replacement)

EN: Depreciation Method Comparator · FR: Comparaison des Méthodes d'Amortissement
Target: Licence 2, Licence 3
Objective: The static depreciation-playground.html teaches each method in isolation. Students leave without understanding why the method choice matters for tax vs. book reporting.
Interaction: Enter one asset (cost, life, residual value). View all three SYSCOHADA-compliant methods (linear, declining-balance, sum-of-years-digits) side-by-side on overlapping charts. A "tax shield" callout shows NPV of deductions under each method.
Inputs/Outputs: Cost, salvage value, useful life, tax rate, discount rate → three-column schedule, depreciation expense + NBV dual-chart, NPV of tax shield comparison, journal entries.
Complements: Directly replaces the orphaned static/playgrounds/depreciation-playground.html with a native module integrated into i18n, preference store, and share-URL infrastructure.


Generated by automated daily review. Report stored at reports/daily/2026-06-19.md.


Generated by Claude Code

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

vercel Bot commented Jun 19, 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 19, 2026 11:09pm

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