Nye-TeeOff/docs/oppgaver.md
Erol Haagenrud d0e60fc271 ikset og deployet. Kort oppsummering av endringen:
backend/weather_forecast.py: weather_sync_loop tar nå en valgfri on_updated-callback som kalles etter hver synkroniseringsrunde, men kun når noe faktisk ble oppdatert.
backend/main.py: sender inn invalidate_public_api_caches(include_place_pages=True) som denne callbacken når værsynken startes ved oppstart.
api-containeren er restartet og kjører rent.
Effekten: neste gang værsynken faktisk endrer noe (skjer omtrent hver time), tømmes backendens interne cache og frontendens unstable_cache for anleggslisten/steds-sidene automatisk — så "Ikke regn meldt"-filteret vil vise fersk værdata i stedet for en fastfrosset snapshot.
2026-07-26 09:10:36 +02:00

7.6 KiB

Oppgaver — teeoff.no

Løpende referanse for arbeid på prosjektet. Bakgrunn og detaljerte funn står i kodeanalyse-2026-07-25.md.

Slik brukes filen:

  • Nye oppgaver legges under riktig seksjon med dato i parentes.
  • Når noe er avklart og klart til å jobbes med, flytt det fra "Trenger avklaring" til "Klar til å gjøres".
  • Når noe er fullført, flytt det til "Gjort" nederst med dato og ev. commit-referanse.

🔴 Sikkerhet (klar til å gjøres)

  • Legg til rate limiting/lockout på /api/auth/login (backend/main.py) — ingen brute-force-beskyttelse på passordfeltet i dag utover 2FA. (2026-07-25)
  • Fjern secret-fallback-kjeden: PUBLIC_SESSION_SECRETJWT_SECRETFRONTEND_REVALIDATE_SECRET. Gi hver sitt eget, obligatoriske secret. (2026-07-25)
  • Lås versjoner i backend/requirements.txt (i dag helt uten pinning). (2026-07-25)
  • Erstatt python-jose (kjente CVE-er) og vurder om passlib (vedlikeholdsmodus) bør byttes ut. (2026-07-25)
  • Fjern facility_contacts_export.csv fra git (committet ved en feil, eid av root i filsystemet) og legg til i .gitignore. (2026-07-25)

🧹 Teknisk gjeld / refaktorering (klar til å gjøres)

  • Del backend/main.py (6501 linjer) opp i APIRouter-moduler: auth, admin, public/facilities, media, scraping-triggere. (2026-07-25)
  • Slå sammen admin/golfpakker, admin/greenfee, admin/medlemskap (frontend) til én gjenbrukbar useDraftReview-hook/komponent — i dag nesten identisk kode tre (fire, inkl. admin/page.tsx) steder. (2026-07-25)
  • Fjern ett av de to identiske revalidate-endepunktene: frontend/src/app/api/admin/revalidate-public/route.ts vs. frontend/src/app/internal/revalidate-public/route.ts. (2026-07-25)
  • Samle duplisert Playwright-/Gemini-boilerplate fra scraperne (scrape_golfpakker.py, scrape_greenfee.py, scrape_membership.py, scrape_vtg.py, scrape_status.py) i scrape_utils.py. (2026-07-25)
  • Konsolider til én Gemini-SDK — i dag installeres både google-genai og google-generativeai, brukt inkonsekvent på tvers av scraperne. (2026-07-25)
  • Splitt opp de største "god components" i frontend etter hvert som de vedlikeholdes: admin/page.tsx (2634 linjer), EditFacilityClient.tsx (1615), FacilityDetailView.tsx (1468), FacilitySearch.tsx (1300), admin/artikler/page.tsx (1144), SimulatorAdminClient.tsx (1024). (2026-07-25)
  • Flytt delte moduler ut av app/-roten til components//en domain-mappe: FacilitySearch.tsx, facilityData.ts, seo.ts. (2026-07-25)
  • Bygg egen, mindre Docker-image for api-tjenesten uten Playwright/Chromium (kun worker trenger nettleseren). (2026-07-25)

Kvalitet / prosess (klar til å gjøres, lavere prioritet)

  • Innfør strukturert logging i backend i stedet for spredte print()-kall. (2026-07-25)
  • Erstatt stumme except:-klausuler (sync_greenfee.py, scrape_nsg_3.py, import_wp.py) med eksplisitt feilhåndtering/logging. (2026-07-25)
  • Skriv et minimum av automatiserte tester (backend: pytest for auth-flyt og kritiske endepunkter; frontend: i det minste ett rammeverk satt opp) — i dag null testdekning. (2026-07-25)
  • Rydd opp i vilkårlige text-[#...]/bg-[#...]-hex-klasser (1294 forekomster) til fordel for tokens fra docs/design-system.md/globals.css. (2026-07-25)
  • Vurder å slå på @typescript-eslint/no-explicit-any igjen og rydde de 100+ eksisterende any-bruken gradvis. (2026-07-25)

🌍 Internasjonal ekspansjon (planlagt, faset) (2026-07-25)

Bakgrunn og vurderte alternativer i kodeanalyse-2026-07-25.md-samtalen. Retningsvalg tatt 2026-07-25: full flerspråklig side (ikke bare DB-oversettelse av innhold), og normalisert hole_points-modell for hullkoordinater.

Fase 1 — Databaselag

  • Migrasjon: legg til country_code (ISO 3166-1 alpha-2) på anleggstabellen, backfill 'NO' på alle eksisterende rader, gjør feltet obligatorisk uten default fremover.
  • Avklar region/fylke-modell for ikke-norske anlegg (dagens REGIONS/fylkesfilter er Norge-spesifikt).
  • Migrasjon: *_translations-tabeller for redaksjonelt innhold (f.eks. facility_translations(facility_id, locale, description, ...), tilsvarende for artikler), én rad per locale, med fallback til 'no'.
  • Migrasjon: course_holes(id, facility_id, hole_number, par, ...) + hole_points(id, hole_id, point_type, geom geography(Point,4326)) med point_type som enum (green_front, green_center, green_back, utvidbart til teested/hasard senere).
  • Bygg admin-verktøy for å registrere hull-punkter (trolig kart-klikk via Leaflet, siden FacilityDetailLeafletMap.tsx allerede finnes).

Fase 2 — UI-i18n-infrastruktur

  • Velg og sett opp i18n-rammeverk for frontend (f.eks. next-intl) med locale-prefikset routing.
  • Avklar: skal URL-slugs oversettes per språk (/en/golf-courses) eller beholdes norske på alle språk (/en/golfbaner)? Må avgjøres før routing-arbeidet starter.
  • Oppdater SEO-laget (seo.ts, sitemap.ts, robots.ts) med hreflang og per-locale sitemap/robots.
  • Bygg språkvelger i UI.

Fase 3 — Oversettelse av faktisk innhold/UI

  • Trekk ut hardkodet norsk UI-tekst til meldingskataloger.
  • Oversett/legg inn innhold for de første ikke-norske anleggene.

Trenger avklaring

  • teecup-blokken i deploy/Caddyfile ruter til teecup-minio, teecup_api, teecup_frontend — tjenester som ikke finnes i dette repoets docker-compose.yml, og viser til "CLAUDE.md-status" i tilsynelatende et annet prosjekt. Er "teecup" en separat applikasjon som deler server med teeoff? Bør det dokumenteres her, eller hører Caddyfile-blokken ikke hjemme i dette repoet? (2026-07-25)
  • Skjema-kilde: Skal schema.sql/init.sql oppdateres til å reflektere faktisk skjema (slik det skapes av ensure_*-funksjonene i main.py), eller skal man gå motsatt vei og fjerne ensure_*-migreringen til fordel for filene i migrations/? Trenger en beslutning om hvilken tilnærming som er "sannheten" videre. (2026-07-25)
  • Ubrukte scripts: scrape_nsg_3.py, scrape_golfamore1.3.py, sync_greenfee.py, sync_weather_forecast.py importeres ikke av verken main.py eller worker.py. Kjøres disse fortsatt manuelt/via ekstern cron på serveren? Skal de beholdes, dokumenteres som manuelle verktøy, eller slettes? (2026-07-25)
  • Admin-brukerscripts: create_admin.py, bootstrap_admin_access.py, update_admin.py overlapper — sistnevntes docstring hevder å være en "trygg erstatning" for de to andre. Kan de to eldre slettes, eller er det en grunn til at alle tre fortsatt finnes? (2026-07-25)
  • Dashboard vs. dedikerte admin-sider: admin/page.tsx inneholder faner som gjør samme jobb som de dedikerte admin/golfpakker, admin/greenfee, admin/medlemskap, admin/vtg-sidene. Er begge i aktiv bruk, eller kan én av de to variantene fases ut? Påvirker hvilken retning refaktoreringen i "Washer"-oppgaven over bør ta. (2026-07-25)

Gjort

  • "Ikke regn meldt"-filteret viste stale værdataweather_sync_loop (backend/weather_forecast.py) oppdaterte facility_weather_forecast hver time, men kalte aldri invalidate_public_api_caches(), så frontendens unstable_cache (uten tidsbasert utløp) og backendens interne cache ble aldri fornyet av værsynken — kun av urelaterte admin-redigeringer. Løst ved å legge til en on_updated-callback i weather_sync_loop som trigger invalidate_public_api_caches(include_place_pages=True) når noe faktisk er oppdatert. api-containeren restartet. (2026-07-26)