Public (slug-gated, auto-allowlisted):
- GET /api/public/feedback/[slug] — instance config
- POST /api/public/feedback/[slug]/submit — form submission (honeypot, rate-limit, required-validation, 423 if closed)
- GET /api/public/feedback/[slug]/posts — chat polling (?since=, hides body of moderated posts)
- POST /api/public/feedback/[slug]/posts — new chat post (honeypot, rate-limit, 423 if closed)
Admin (requireAuth, owner-scoped):
- GET/POST /api/admin/feedback — list/create
- GET/PATCH/DELETE /api/admin/feedback/[id] — detail/update/delete (PATCH closes/reopens, sets closed_at)
- POST /api/admin/feedback/[id]/posts/[post_id]/hide — toggle hidden flag
- GET /api/admin/feedback/[id]/export?format=csv|json — single-file dump
Auth:
- POST /api/auth/sign-in — Supabase email+password, sets access+refresh cookies
- POST /api/auth/sign-out — clears cookies
bun run check: 0 errors, 0 warnings.
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).