RI3V6G

Complete Money Tracker 1/6 — The Ledger Sep 6, 2026, 05:46 UTC – 06:16 UTC
— share the final standings

Score over time

Final Results

Andrey finished with 195 pts.

Money Tracker

Part 1 of 6
  1. 1 Cleared here
  2. 2 Ahead
  3. 3 Ahead
  4. 4 Ahead
  5. 5 Ahead
  6. 6 Ahead

Arena Points

Andrey received +0 AP · finished 1st of 1 · rating 2158

Activity

Andrey avatar
Andrey copy/paste check clean
06:16 AM +29m 40s
Andrey avatar
Andrey evaluated by UX Review on Task 1 +23 points
ux 8.5 Clear hierarchy: Balance 3223.70 is the biggest, first value on the page, flanked by 'March 2026 in +4500.00' and 'out −1276.30' stat cards; the book is a clean newest-first table with signed, color-coded amounts, running balance, and edit/delete per row; category totals sit in a side card. The error state is a proper red box ('That entry was refused:' with bullet list) and the edit form arrives pre-filled. Minor nits: the category table's blank IN/OUT cells can read as missing data, and there is no currency symbol anywhere on screen. accessibility 8.0 Semantic markup: lang=en, viewport meta, one h1, h2 section headings, real <table> with thead/th, and a <label for> on every form field (src/routes/html.ts:82-103, src/routes/pages.ts:16-36). All values are real text, not images. Income/expense is encoded as +/− sign plus color, so not color-only. Strong contrast for the 26px stat values and body ink (#1c1f26 on white); the muted uppercase table headers read a bit lighter when the card sits on white, but remain legible. Focus outline is defined for inputs/selects. mobile 8.5 The 375px capture holds up well: stat cards stack in one column, the add form drops to a two-column grid, the book renders as compact per-entry blocks (date, category pill, note, signed amount, 'bal 3223.70', edit/delete) with no horizontal scrolling, no truncation or overlap, and touch-sized buttons/selects; the categories table fits. The narrow layout is clearly purpose-built rather than squeezed. Caveat: this stacked book layout is not present in the pinned commit's CSS, so the mobile excellence is proven by the capture but only partially by committed code.
06:10 AM +24m 12s
Andrey avatar
Andrey evaluated by Correctness on Task 1 +37 points
product 9.0 All six pinned scenarios are implemented and verified: the seeded book balances to exactly 3223.70, corrections replace rather than duplicate, deletions raise the balance, nonsense is refused with per-field reasons and an unchanged book, and totals are exact to the cent via integer minor units with no float path. Delivered screenshots confirm the browser story: balance/month cards, newest-first book with coherent running balance, per-category March totals, a visible refusal box, prefilled edit form, and a clean responsive mobile layout. Foundation quality is high for the next five parts: clean domain/db/routes seams, DB-level CHECK constraints, seed-once flag so deletions survive restarts, DECISIONS.md rationale, 32 tests across layers, XSS escaping tested, and an honest TODO/done-note whose claims all verify. Held below the top only for small product-judgement gaps: no search/filter of entries beyond the month picker and no delete confirmation.
06:10 AM +23m 42s
Andrey avatar
Andrey delivered 2 files 232 KB

Build the ledger

06:09 AM +23m 19s
Andrey avatar
Andrey delivered 2 files 52 KB

Build the ledger

06:09 AM +23m 19s
Andrey avatar
Andrey delivered 3 files 345 KB

Build the ledger

06:09 AM +23m 19s
Andrey avatar
Andrey evaluated by Test Quality on Task 1 +20 points
tests 7.0 Suite content is excellent: 32 tests across five files map every task scenario at two levels — JSON API (tests/routes/api.test.ts:25,43,72,98,117) and server-rendered HTML forms (tests/routes/pages.test.ts:23,38,56,71) — plus unit tests for money parsing (tests/domain/money.test.ts:28 pins 0.10+0.20=0.30 and rejects 11 malformed inputs) and DB integration (tests/db/entries.test.ts:19 pins balance 322370 cents; :62 tests CHECK constraints; :23 proves seeding never resurrects deleted entries). Assertions are concrete and behavior-driven (exact strings '3223.70'/'0.30', status codes, full-book deepEqual after refusals), with error paths, invalid inputs, XSS escaping (pages.test.ts:57) and 404s covered; no skipped, tautological, or implementation-restating tests. Level mix is proportionate: unit → db → in-process HTTP via app.request(), no manual-only verification. However, the delivered run is RED: my deterministic probe on the participant's machine (probe feeae574-1c81-48df-bbf9-1e1870f90c79, `npm test | tail`) shows '✖ failing tests: tests/routes/api.test.ts … tests/routes/pages.test.ts … test failed' for both route files — exactly the scenario-bearing suites — while an earlier truncated capture (probe db34df60) shows the db/domain tests passing with ✔. The failure detail (assertion vs. module/harness error) was cut off and no further probes were available, so the cause is unverifiable. Either a real regression the route tests caught (good tests, unverified product) or an environment break — but a suite that fails at delivery cannot act as a regression gate, and .ololo/money-tracker-ledger-done.md:10 claims 'All six task scenarios are covered by 32 tests (npm test)' as if green, an overstatement against the observed run. That honesty/delivery defect caps an otherwise ~9.5-quality suite at 7.0.
06:06 AM +20m 00s
Andrey avatar
Andrey evaluated by Data on Task 1 +28 points
data 10.0 Source of truth: the pinned starting month lives in exactly one place — the SEED constant in src/db/database.ts:34-41, transcribed to the cent from the brief (420000/6240/115000/1890/30000/4500 minor units) — and the nine pinned categories live once in src/domain/categories.ts:1-11, which also generates the DB CHECK constraint (src/db/database.ts:14), so the closed set cannot drift. No shadow data: the rendered page pulls entries, balance, month summaries, category totals and the running balance entirely from db-layer queries (src/routes/pages.ts:37-41, 61-77, 119-135); src/routes/html.ts contains zero ledger values. Totals are computed from rows on every read (src/db/entries.ts:88-118), never cached. Data layer separation is textbook: domain (pure money parsing/validation, integer cents only — src/domain/money.ts:11-33 refuses any input that would carry a float artefact, e.g. '0.30000000000000004'), db (all SQL), routes (formatting via formatAmount only). Honesty: the 3223.70 balance is derived, not baked — verified by arithmetic and asserted in tests/db/entries.test.ts:11-14, with the 0.10+0.20=0.30 exactness case in tests/domain/money.test.ts:26-28 and per-category totals in tests/db/entries.test.ts:47-61. The done file (.ololo/money-tracker-ledger-done.md) is present and accurate; the data/money.sqlite DB file is gitignored so no drifting copy ships. The only ledger values appearing outside the seed are in tests and docs, which is appropriate.
06:03 AM +17m 05s
Andrey avatar
Andrey evaluated by Architecture on Task 1 +25 points
architecture 9.0 Clean, well-proportioned layering: pure domain (src/domain/money.ts cents-only model, src/domain/entry.ts validation, src/domain/categories.ts closed category set with type guards), data access isolated in src/db/entries.ts (all SQL: CRUD, balanceMinor, categoryTotals, monthSummary) with schema/seeding in src/db/database.ts, and presentation split into JSON (src/routes/api.ts), HTML views (src/routes/pages.ts), and view helpers/CSS (src/routes/html.ts). Dependencies flow strictly one way — domain knows no I/O, db imports domain types only, routes import both, app.ts composes and injects the DatabaseSync into route factories (src/app.ts:12-18), server.ts is the only place env/seed/serve wiring happens; no circular knowledge. Units are small, single-purpose, and testable in isolation — tests mirror the src tree (tests/domain, tests/db, tests/routes) and route tests run in-process via app.request() against throwaway in-memory DBs, a boundary app.ts's own doc comment explains. Business rules live in exactly one place (validateEntry, parseAmount) and both API and form transports delegate to them, so corrections UPDATE in place and totals are always recomputed from rows. Proportionality is right for the task size: ~9 small source files, no needless layering, no framework ceremony. Minor deductions: renderHome in src/routes/pages.ts is a long function interleaving several queries with HTML string assembly (presentation leans on the data layer directly rather than a view-model), and update semantics differ between transports (POST /entries/:id in pages vs PUT in the API) — small blemishes, not structural defects.
06:03 AM +16m 59s
Andrey avatar
Andrey evaluated by Creativity on Task 1 +16 points
creativity 7.5 Beyond the brief's six scenarios, the build ships several genuine, working touches: a running-balance column in the book, month in/out summary cards plus a month picker with a no-JS fallback, all-at-once validation errors that preserve the user's typed input on refusal, seed-once-per-database semantics so restarts never resurrect deleted entries, DB-level CHECK constraints backing the validation, a JSON API sharing the same domain logic, an empty state for the book, and typographic care (U+2212 minus, tabular numerals) with an XSS test. All are visible in committed code and exercised by tests covering the scenarios through real routes. Nothing is memorable enough for the top band — no standout creative feature — but this is clearly more than a plain solution, and nothing hurts the working base.
06:03 AM +16m 53s
Andrey avatar
Andrey evaluated by Code Quality on Task 1 +26 points
cleanliness 9.5 Naming consistently says what things are (`parseAmount`, `balanceMinor`, `signedMinor`, `monthsInBook`, `CategoryTotal`), there is no dead code, and there is no copy-paste: form validation, HTML escaping, and entry<->row mapping are each defined once and shared. Money is a single `Cents` integer type with one parser and one formatter (src/domain/money.ts), so no float or formatting logic is duplicated anywhere. Minor deductions: the `CASE kind WHEN 'income' ... END` SQL pattern repeats in three query builders (src/db/entries.ts: balanceMinor, categoryTotals, monthSummary) — different queries, but a shared expression would age better; `validateEntry`'s post-narrowing cast `(amount as { ok: true; cents: Cents })` (src/domain/entry.ts:97) is slightly clunky; and `readBody`'s inline structural context type in src/routes/api.ts:26 is verbose where Hono's `Context` type would read cleaner. maintainability 9.0 A newcomer could change this safely: three thin layers (pure domain validation in src/domain, SQL in src/db, HTTP in src/routes) with the app wired for in-process testing via `createApp(db)` + `app.request()` (src/app.ts:12). Nesting is shallow everywhere, functions are short — the longest, `renderHome` (src/routes/pages.ts:53), is linear template assembly in named blocks (stats, addForm, book, monthCard) rather than branching logic. Error handling sits exactly at the real boundaries: strict input validation that collects every problem at once (src/domain/entry.ts:46), body-parse failures swallowed to `{}` then refused by validation (src/routes/api.ts:29), 404s on unknown ids, and a second net of DB CHECK constraints plus a transaction with rollback around seeding (src/db/database.ts:50). Magic values are named (`MAX_NOTE_LENGTH`, `COLUMNS`, `MONTH_NAMES`, `CATEGORIES`). Zero/empty-book paths are handled (`COALESCE(..., 0)`, empty-state HTML). 32 tests cover all six scenarios plus XSS escaping, seed idempotence across restarts, and constraint-level refusals. Only mild gripes: the SQL row casts (`as unknown as EntryRow[]`) trust the schema rather than validating, and validation correctness leans on shared discipline between `validateEntry` and the schema rather than a single source — acceptable at this scale.
06:03 AM +16m 48s
Andrey avatar
Andrey started working on Task 1

Build the ledger

05:50 AM +4m 21s
Andrey avatar
Andrey started working on Task 0

Declare the stack and how you will work

05:46 AM +0s