- `aggregateResults` ingests rating maps, tallies per-option counts +
histogram (1-5 buckets) + running sum, then `finalise` computes per-option
means and sorts options by mean desc with tiebreaks (count of 5s, then
4s, then total count, then id). Question-level `count` reflects
submissions that rated at least one option.
- Out-of-range, fractional, and non-integer ratings are silently dropped —
the aggregator never trusts user data, schema validates it on submit.
- CSV export expands a date_ranked_choice question into one column per
option named `<qid>[<optid>]`. JSON export is unchanged (it serialises
the rating map directly).
- New `results.test.ts` covers: per-option counts and means, histogram
tallying, mean-with-tiebreak ordering, ignoring bad ratings, and missing
answers. Wires the file into the `bun test` script.
Refs m/fdbck#1.
Bootstrap from /home/m/dev/web/msbls.de template:
- SvelteKit 2.15 + Svelte 5 + adapter-node + bun + vite 6
- Deps trimmed: @supabase/supabase-js, postgres, zod (+ dev: kit, vite-plugin-svelte, svelte-check, typescript)
- No mbrian-core submodule (irrelevant for fdbck)
- src/app.html minimal (no fonts, no theme toggler)
- src/app.d.ts declares App.Locals { userId: string | null }
- robots.txt Disallow: / (whole app is naked, per-link or auth-only)
- .env.example: Supabase + PUBLIC_SITE_URL + optional COOKIE_DOMAIN
Initial mai init scaffolding (.claude, .m, .mcp.json, AGENTS.md) bundled in
this first commit since the repo was empty before bootstrap.
Spawned from m/flexsiebels.de#63 pivot — see docs/plans/feedback-feature.md
for the full spec (copied in next commit).