Files
boka-gasol247/BACKLOG.md
2026-05-22 20:33:21 +02:00

67 lines
6.7 KiB
Markdown

# Backlog
Prioriterade förbättringar och kända luckor. Top-down ungefär i prioritetsordning.
## Bäställningsdisclaimer
- det är bäställarens ansvar att veta hur mycket dom får lov i sin by.
60 liter per 40 deltagare. 2012 (4,8liter) PC5(12,2 liter) PC10 (23,8 liter)
## P0 — innan skarp lansering
- [ ] **Rate-limit på `POST /api/bookings` och `POST /api/customer/magic-link`**: enkel IP-baserad throttle (t.ex. 5 bokningar/timme/IP) för att stoppa spam/bots. Magic-link-endpointen är extra känslig — utan throttling kan någon trigga obegränsat med mejl. Implementera i respektive route eller via en middleware-wrapper.
- [ ] **Honeypot eller hCaptcha på formuläret**: bokningsformuläret är publikt utan skydd. Honeypot är minimalistiskt och räcker ofta.
- [ ] **Generera riktigt `AUTH_SECRET`**: dokumenterat i README men måste göras manuellt vid deploy.
- [ ] **Verifiera Mailjet-avsändare**: `MAIL_FROM_EMAIL` måste vara verifierad i Mailjet-kontot innan mejl kommer fram.
- [ ] **Skarpa produktpriser och upphämtningstider**: ändra i `prisma/seed.ts` eller via Prisma Studio innan lansering.
- [ ] **Cookie-banner / GDPR-info**: bokningen samlar PII (namn, e-post, org.nummer, adress). Kort policy-text + länk.
- [ ] **Backup-rutin för SQLite-volymen**: cron-jobb på värden som kör `cp` mot en separat disk eller S3.
## P1 — höjer kvaliteten
- [ ] **Admin-UI för produkter och upphämtningstider**: idag måste man köra seed-filen eller Prisma Studio. Lägg till `/admin/products` och `/admin/pickup-slots` med CRUD.
- [ ] **Admin-UI för att skapa fler administratörer**: tabellen `Admin` stöder flera men det finns ingen invite-flow. Antingen self-serve invite via mejl-länk eller manuell skapa-form i admin-panelen.
- [ ] **Kund-avbokning via token-länk**: lägg till `cancelToken``Booking`, inkludera unik avbokningslänk i bekräftelsemejlet. Trigger på `GET /booking/cancel/{token}` med bekräftelsesida.
- [ ] **Lagerbegränsning per produkt**: idag finns kapacitet bara på upphämtnings-slots. Lägg `totalStock``Product` och kontrollera i POST-routen att `Σ confirmed quantity ≤ stock`.
- [ ] **Mailjet Templates (Template-ID) istället för inline HTML**: gör det möjligt att ändra mejldesign utan redeploy. Inline HTML kvar som fallback om template-id saknas.
- [ ] **Resend-bekräftelse loggar**: idag skickar admin-knappen "Resend confirmation" tyst — visa toast/success vid lyckad sändning.
- [ ] **Statusmejl vid byte SCHEDULED/DELIVERED**: kund får idag bara bekräftelse på att begäran är mottagen — borde få mejl när admin schemalägger eller markerar levererat.
- [ ] **Cleanup-jobb för expired customer-tokens**: `CustomerMagicLink` och `CustomerSession` rensas inte automatiskt. Lägg till en cron eller städa i `getCustomerEmail`/`consumeMagicLink`.
- [ ] **Bookings-vy: paginering**: nuvarande tar `take: 200`. Lägg cursor-paginering vid skarp volym.
- [ ] **PDF-faktureringsunderlag per bokning**: utöver CSV — en PDF som matchar fakturamall, lättare att bifoga.
- [ ] **Audit log för admin-actions**: tabell `AuditEvent` med vem som ändrade status, körde resend, etc.
- [ ] **Healthcheck-endpoint**: `GET /api/health` returnerar 200 + `{db: 'ok'}` för proxy/uptime-monitor.
## P2 — bra att ha
- [ ] **Prisma migrate istället för db push**: när schemat är stabilt, kör `prisma migrate dev` initialt och commita migrations-mappen. Byt entrypoint till `migrate deploy`.
- [ ] **Multi-event-stöd**: idag är allt knutet till ett event via `NEXT_PUBLIC_EVENT_NAME`. Lägg till `Event`-tabell med egen produkt- och slot-koppling om systemet ska användas till fler läger.
- [ ] **E-mail verification innan bokning**: skicka kod eller bekräfta via dubbelt opt-in. Idag litar vi på att kunden anger korrekt mejl.
- [ ] **Slot-omval via avbokningslänk**: kunden kan byta upphämtningstid utan att kontakta admin.
- [ ] **Skicka påminnelse-mejl** dagen innan upphämtning (cron + Mailjet).
- [ ] **Status-mejl vid statusbyte**: kunden får mejl när bokningen markeras `INVOICED` eller `CANCELLED`.
- [ ] **Inbjudnings-mejl till nya admins** (kopplat till P1 admin-UI för admins).
- [ ] **Tester**: minst en smoke-test för `POST /api/bookings` (Playwright eller Vitest + Supertest).
- [ ] **CI**: GitHub Actions som kör `npm run build` på PR.
- [ ] **Telemetri / felrapportering**: Sentry eller liknande.
## P3 — framtida överväganden
- [ ] **Postgres istället för SQLite**: när volymen växer eller om vi vill ha managed backups. Prisma byter provider med en rad + ny `DATABASE_URL`.
- [ ] **Prisma 7-uppgradering**: ny `prisma.config.ts` med driver adapter (t.ex. `@prisma/adapter-better-sqlite3`), uppdaterad `PrismaClient`-init. Inte värt det förrän Prisma 7 är stabilare och vi har annat skäl att uppgradera.
- [ ] **Server-side e-postvalidering**: t.ex. DNS/MX-koll eller integration mot Mailjet Address Validation.
- [ ] **Bilder på produkterna i formuläret**: laddas från egen `/public/products/*.webp` eller via en CDN.
- [ ] **Skip-link och bättre a11y-audit**: fokushantering i stegen, ARIA-live för felmeddelanden.
- [ ] **Webhooks från Mailjet** (bounce/spam-rapport) — markerar bokningar med ogiltig e-post.
## Beslutslogg
- **2026-05-22**: `ReplacementRequest` snapshottar pris från `Product` (samma som ny flaska) vid request-tid — fält `sku/nameSv/nameEn/unitPriceOre/vatBp/lineTotalOre`. CSV-export utökad med `LineType=Booking|Replacement`-kolumn; CANCELLED-byten exkluderas, `BillableQuantity` = quantity om `status=DELIVERED` annars 0. En faktura per org = original-rader + levererade byten.
- **2026-05-22**: Kund-portal (`/min-sida`) + flaskbyte tillagt som del av MVP. Magic-link på begäran (kund matar in mejl, får länk via mejl). Token-scope = alla bokningar för mejlen. `ReplacementRequest`-modell kopplad till `BookingItem` + valbar `PickupSlot`. Inga antalsgränser — admin avgör per ärende.
- **2026-05-22**: Valt SQLite + Prisma 5 (inte 7) för MVP. SQLite-fil i Docker-volym räcker för ett event. Prisma 5 fungerar utan `prisma.config.ts`.
- **2026-05-22**: `prisma db push` istället för `migrate deploy` i entrypoint — färre artefakter att hålla reda på i MVP. Byt vid stabilt schema.
- **2026-05-22**: Priser i öre (`Int`) snarare än `Decimal` — enklare och säkrare för en valuta (SEK).
- **2026-05-22**: Egen inline HTML-mall i `src/lib/mailjet.ts` istället för Mailjet Templates — färre externa beroenden för MVP, men ändras inte utan deploy.
- **2026-05-22**: NextAuth Credentials + lokal Admin-tabell (inte magic link) — användaren valde detta för flera admins.
- **2026-05-22**: next-intl med `localePrefix: "as-needed"``/` är svenska, `/en/*` engelska. Switch i header behåller path.