The calendar test asserted `[data-date=day] .tevent` had a count of exactly one — the mocked meeting — after dragging its task to the next day. That count assumed the day held nothing but this test's own events. It does not: the suite shares one database, and an earlier test drags a task across a month boundary, which on some dates lands a timed task on this very day. A timed task renders as a `.tevent` too, so the count was two, and the test failed — but only in the full run, and only when the date arithmetic put the two tests on the same cell. Alone it passed, which is exactly the shape of a shared-state collision rather than a real bug. Named, not counted: assert the meeting is still there and the task is no longer in the day's column, which is what "the events stayed, the task moved" actually means — and is true however full another test left the day. Same for the all-day band. No product code changed; the drag and everything it checks are untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
web
The SvelteKit PWA. Not written yet — this directory holds its place so the Docker build has something to copy, and so the frontend stage can tell "not built yet" apart from "the build failed".
The Dockerfile builds this directory when it finds a package.json here, and
otherwise emits a placeholder page. So adding the real app is exactly: put a
SvelteKit project in this directory whose npm run build produces build/.
What it needs to be
- SvelteKit,
adapter-static, output inbuild/. The Go binary embeds that directory at compile time and serves it, falling back toindex.htmlso client-side routes survive a reload. - A PWA: installable, offline reading of already-cached lists, swipe gestures for complete and schedule.
- Nordic minimalism. Dark by default, light available. One accent colour, everything else neutral. Runic mark for Verdande.
- Optimistic on every local action. No spinner ever appears for something the browser could already know the answer to.
Talking to the backend
Same origin — the Go binary serves both. /api/v1 for REST, /api/v1/ws for the
live sync. Session cookie is httpOnly, so the frontend never handles the token
itself.
During development, run the backend on 8080 and point the Vite dev server's proxy at it:
VERDANDE_DATA_DIR=./data VERDANDE_DEV=true go run ./cmd/verdande