Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/sprints/backlog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Produktbacklog"
description: "Alla kända stories och uppgifter, speglar roadmap.md. Plockas in i sprintar vid behov."
category: sprint
status: active
last_updated: 2026-05-13
last_updated: 2026-05-14
tags: [backlog, roadmap, planning]
sections:
- Blockerare
Expand Down Expand Up @@ -54,7 +54,7 @@ sections:
| withApiHandler resterande routes (131 st) | Löpande | Opportunistiskt |
| console.* i legacy docs | 0.5 dag | Låg prioritet |
| **BDD integrationstester — horses, booking-series, bookings POST, group-bookings join** | 1 dag | Kärndomäner saknar integration: Horses (8 routes, noll integration), Booking-series (3 routes, precis releasad), `POST /api/bookings` (viktigaste CREATE-routen), `POST /api/group-bookings/join` (Serializable-transaktion). 18/181 routes har integration totalt. Audit: [bdd-coverage-audit-2026-04-25.md](../research/bdd-coverage-audit-2026-04-25.md). |
| **Pre-existing fail i `booking-series/route.test.ts` (8 tester)** | 2-4h | 8 av 17 tester i `src/app/api/booking-series/route.test.ts` failar på både `main` och `staging`. Verifierat 2026-05-08 under S67-0-arbete: failet är oberoende av S67-0 men blockerar pre-push-hooken för alla feature-branches (måste pushas med `--no-verify`). Felet är inte regression från en specifik PR utan har funnits en längre tid (sannolikt sedan recurring_bookings-arbetet). **Åtgärd:** isolera och fixa testerna, eller uppdatera dem till matchande nuvarande kodbeteende. **Effekt vid fix:** pre-push-hooken kan användas utan override för alla framtida pushes, mindre risk att andra fail döljs av `--no-verify`. Hittad: 2026-05-08 (S67-0). |
| ~~**Pre-existing fail i `booking-series/route.test.ts` (8 tester)**~~ FIXAD 2026-05-14 | ~~2-4h~~ 10 min | **Root cause: time-bomb-test.** Test-fixture hade hårdkodat `firstBookingDate: "2026-05-01"` (commit `f9b47c43d`, 2026-02-17). När dagens datum passerade 2026-05-01 började route:s `firstBookingDate.refine(val => new Date(val) >= today)` returnera 400 istället för 201. Production-koden är korrekt — testet var fel. Fixad med dynamiskt datum (`Date.now() + 30 dagar`). Pre-push-hook kan nu användas utan `--no-verify`. Backlog-uppskattning på 2-4h var ~24x överskattad eftersom rotorsaken inte hade analyserats. Se follow-up "Audit hårdkodade framtida datum i tester" nedan. |
| **Hårdkodad fel domän i `data-retention-warning.ts`** | 10 min | `src/lib/email/templates/data-retention-warning.ts:4` har fallback `https://equinet.vercel.app` (utan `-app`) — fungerar inte. Bör använda samma logik som övriga email-templates: `process.env.APP_URL \|\| 'http://localhost:3000'`. Hittad 2026-04-30 vid felsökning av password reset till localhost. |
| **CI-guard: kräv APP_URL i prod-build** | 1-2h | `APP_URL` saknades i Vercel prod-env i månader → alla email-länkar pekade på `http://localhost:3000` (password reset, bokningsbekräftelser, route-announcements m.fl.). Lägg till build-time-validering som faller om kritiska env-variabler saknas i prod (APP_URL, DATABASE_URL, NEXT_PUBLIC_SUPABASE_URL, RESEND_API_KEY, STRIPE_SECRET_KEY). Förslag: `scripts/check-prod-env.ts` körs i `prebuild` när `VERCEL_ENV=production`. |
| **Fixa fire-and-forget i AuthService och övriga notifiers (HÖG PRIO)** | 1-2h | `AuthService.requestPasswordReset` (rad 396-401) skickar `emailService.sendPasswordReset(...).catch(() => {})` och returnerar response omedelbart. I Vercel/Fluid Compute kan function-instansen termineras innan fetch-anropet mot Resend slutförs → mail skickas aldrig. **Bevis 2026-04-30**: Tre password reset-försök, mail #1 vann racen mot termination, mail #2 och #3 hann ALDRIG fram till Resend (token i DB, inget i Resend dashboard). Tyst leveransbortfall i prod. **Påverkan**: Kan drabba alla fire-and-forget i kodbasen — `RouteAnnouncementNotifier` och fler. **Fix**: ersätt `.catch(() => {})` med `await waitUntil(...)` från `@vercel/functions`, eller blockerande `await`. Audit alla fire-and-forget i kodbasen (`grep -rn "\.catch(() => {})" src/`). |
Expand All @@ -63,6 +63,7 @@ sections:
| **URL-konfigurationsmatris** | 30 min | Skapa `docs/operations/url-configuration.md` som listar alla URL-config-platser och vad varje styr: Vercel `APP_URL`, Supabase Site URL + Redirect URLs, Stripe webhook endpoint, Resend domän-verifiering, ev. iOS prod-URL i `AppConfig.swift`. Vi har precis brunnit oss på trippel-miss (APP_URL + Site URL + Redirect URLs alla satta fel) — dokumentationen ska göra det tydligt vad som måste uppdateras vid byte av domän. Inkluderar checklista och länkar till dashboard-vägar. |
| **Städa Vercel env-variabler med literal `\\n` på slutet** | 15 min | `NEXT_PUBLIC_SUPABASE_URL` och `NEXT_PUBLIC_SUPABASE_ANON_KEY` i Vercel prod har literal backslash-n (`\\n`) på slutet av värdena. Next.js runtime kan strippa det, men `vercel env pull` skriver det som literal i .env-filen vilket bryter direktanrop mot Supabase API från lokala scripts. Hittad 2026-04-30. Fix: Vercel UI → respektive variabel → ta bort `\\n`-suffixet → spara → redeploy. |
| **Help-data drift protection** | 15-30 min | CI-validation som regenererar `articles-data.ts` och diffar mot committed version — failar PR om out-of-sync. Plus README-rad om `npm run generate:help`-workflow. Bevisat behov efter PR #333 (2026-05-13): staging hade tom hjälpsektion eftersom build-time-generator + `.vercelignore` (`*.md`) filtrerade bort markdown-källor. Detaljerad story med A/B/C/D-alternativ: [help-data-drift-protection.md](../stories/help-data-drift-protection.md). |
| **Audit hårdkodade framtida datum i tester (time-bomb-audit)** | 30 min – 1h | Pre-existing booking-series-fail (fixad 2026-05-14) hade rotorsak i hårdkodat `firstBookingDate: "2026-05-01"` som tickade ner till "förflutet" och bröt 8 tester samtidigt. Risk: fler test-fixtures i `src/**/*.test.ts` och `e2e/**` kan ha samma time-bomb. **Åtgärd:** (1) `grep -rE '"20[2-3][0-9]-[0-1][0-9]-[0-3][0-9]"' src/**/*.test.ts e2e/**` för att hitta alla hårdkodade datum-strängar i tester, (2) byt till dynamiska datum där schemat har relativ validering (`>= today`, `< now + N`), (3) överväg ESLint-regel eller pre-commit-check som varnar för hårdkodade datum-strängar i `.test.ts`-filer. **Värde:** förhindrar framtida `--no-verify`-vana som maskerar verkliga regressioner. Hittad 2026-05-14 vid 5 Whys på booking-series-fail. |

## Kodeffektivitet (tech debt)

Expand Down
8 changes: 7 additions & 1 deletion src/app/api/booking-series/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,16 @@ function makeRequest(body: object): NextRequest {
})
}

// Use a dynamic future date (30 days ahead) so the test does not
// time-bomb when the hard-coded date drifts into the past. The route
// schema's `firstBookingDate.refine(val => new Date(val) >= today)`
// is correct production behavior — the test must move forward with us.
const validBody = {
providerId: "a0000000-0000-4000-a000-000000000001",
serviceId: "a0000000-0000-4000-a000-000000000003",
firstBookingDate: "2026-05-01",
firstBookingDate: new Date(Date.now() + 30 * 86400000)
.toISOString()
.split("T")[0],
startTime: "10:00",
intervalWeeks: 2,
totalOccurrences: 4,
Expand Down