Skip to content

Mobile-first TODO til neste major trinn

Dato: 15. juni 2026

Status: Lopende funnlogg. Kritiske driftsfunn er deployet og verifisert live.

Kontekst:

  • Appen er i drift for Ski GK tenant / clubId 73.
  • Dagens frontend er Angular/Firebase.
  • Neste major trinn er planlagt konvertering til .NET.
  • Denne listen samler feil, svakheter og forbedringer vi finner i mobile-first analysen.
  • Codex-testbrukere er opprettet for user, admin og super_admin.
  • Testbrukere skal slettes med node scripts\firebase\manage-codex-test-users.mjs --cleanup --apply --project=gkit-vtg-app etter analyse/test/deploy.
  • Billing-status for gkit-vtg-app: billingEnabled=false, ingen billing account koblet.

Bruksregel

Hvert funn skal ha:

  • ID
  • Rolle: User, Admin eller AppOwner
  • Skjerm/rute
  • Verifisering: live, lokal build, kodegjennomgang eller antakelse
  • Prioritet: Kritisk, Boor fikses, Polering
  • Tiltaksvindu: Foer konvertering eller Neste major
  • Beskrivelse
  • Anbefalt fix
  • .NET-konverteringsnotat
  • Status

Funn

MF-001: Toppnav "Logg inn" er under anbefalt touch-hoeyde

  • Rolle: User
  • Skjerm/rute: Global toppnavigasjon paa offentlige ruter
  • Verifisering: live, Playwright mot https://gkit-vtg-app.web.app
  • Prioritet: Boor fikses
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Lenken "Logg inn" maales til ca. 81x32 px paa 360, 390 og 430 px mobilbredde. Dette er under anbefalt touch target-hoeyde paa ca. 44 px.
  • Anbefalt fix: Oek vertikal padding/min-height for toppnav-handlinger uten aa endre rollelogikk.
  • .NET-konverteringsnotat: Legg inn felles knapp-/nav-token for minimum touch target i nytt designsystem.
  • Status: Lukket - deployet og verifisert live

MF-002: Tilbake-lenker er visuelt lave paa mobil

  • Rolle: User
  • Skjerm/rute: /kurs-info, /chapter/introduction, /chapter/course-basics, /golfvett, /checklist
  • Verifisering: live, Playwright mot https://gkit-vtg-app.web.app
  • Prioritet: Boor fikses
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Flere tilbake-lenker maales til ca. 23-27 px hoeyde. Bredden er ofte stor nok, men trykkflaten er lav.
  • Anbefalt fix: Gi tilbake-lenker min-height: 44px, sentrert innhold og konsistent mobilstil.
  • .NET-konverteringsnotat: Definer standard "back action" komponent som gjenbrukes paa alle sider.
  • Status: Lukket - deployet og verifisert live

MF-003: Checklist-checkboxer er for smaa for mobil

  • Rolle: User
  • Skjerm/rute: /checklist
  • Verifisering: live, Playwright mot https://gkit-vtg-app.web.app
  • Prioritet: Boor fikses
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Synlige checkboxer maales til ca. 23x23 px. Dette er smaa treffomraader for mobilbrukere.
  • Anbefalt fix: Gjoer hele raden/labelen klikkbar og bruk stoerre visuell checkbox eller custom kontroll.
  • .NET-konverteringsnotat: Bygg checklist som mobil-forst radkomponent med hele raden som interaktivt treffomraade.
  • Status: Lukket - deployet og verifisert live

MF-004: GOBBS-stegknapper ligger rett under anbefalt touch-hoeyde

  • Rolle: User
  • Skjerm/rute: /gobbs
  • Verifisering: live, Playwright mot https://gkit-vtg-app.web.app
  • Prioritet: Polering
  • Tiltaksvindu: Neste major
  • Beskrivelse: GOBBS-knappene maales typisk til ca. 41 px hoeyde paa mobil. Det fungerer, men ligger under 44 px-maalet.
  • Anbefalt fix: Oek min-height og gi knapperekken litt bedre pusteplass.
  • .NET-konverteringsnotat: Ta dette inn i felles segmented-control/pill-button komponent.
  • Status: Lukket - deployet og verifisert live

MF-005: Public User-ruter har ingen horisontal overflow i testede mobilbredder

  • Rolle: User
  • Skjerm/rute: /, /kurs-info, /chapter/introduction, /chapter/course-basics, /gobbs, /golfvett, /checklist, /login, /register
  • Verifisering: live, Playwright mot https://gkit-vtg-app.web.app
  • Prioritet: Polering
  • Tiltaksvindu: Neste major
  • Beskrivelse: 360, 390 og 430 px bredder viste ingen horisontal overflow. Dette er et positivt kontrollfunn, ikke en feil.
  • Anbefalt fix: Ingen umiddelbar fix. Bevar responsiv breddekontroll ved .NET-konvertering.
  • .NET-konverteringsnotat: Legg inn automatisk overflow-sjekk i fremtidig e2e/a11y-test.
  • Status: Lukket som kontrollfunn

MF-006: Beskyttede ruter feiler ved direkte URL eller refresh selv om bruker har aktiv session

  • Rolle: User, Admin, AppOwner
  • Skjerm/rute: /card, /profile, /change-password, /admin
  • Verifisering: live, Playwright med Codex-testbrukere
  • Prioritet: Kritisk
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Etter innlogging fungerer vanlig intern navigasjon, men direkte lasting/reload av beskyttede ruter sender bruker til /login?returnUrl=.... Toppnav viser samtidig innlogget e-post og "Logg ut", som betyr at Firebase-sessionen finnes. Dette tyder paa race i auth guard, der isAuthenticated$ leses foer Firebase auth state er ferdig initialisert.
  • Anbefalt fix: Endre auth guard til aa vente paa eksplisitt auth-initialisering/current user state foer redirect. Ikke bruk initial false fra BehaviorSubject som endelig auth-status.
  • .NET-konverteringsnotat: I ny .NET-app maa auth middleware/client auth-state skille mellom loading, authenticated og anonymous.
  • Status: Lukket - deployet og verifisert live

MF-007: Admin dashboard-statistikk bruker global brukerhenting og feiler for club admin

  • Rolle: Admin
  • Skjerm/rute: /admin, fanen Faglig Dashboard
  • Verifisering: live, Playwright med codex.admin.vtg.73@golfklubb-it.com, Firebase console error
  • Prioritet: Kritisk
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Club admin for clubId 73 ser AKTIVE DELTAKERE 0 av 0 totalt, mens deltakerfanen viser 36 deltakere. Konsollen viser Missing or insufficient permissions. Koden kaller getDashboardStats() uten club-scope, som igjen kaller getAllUsers() globalt. Firestore-reglene stopper global lesing for club admin.
  • Anbefalt fix: La getDashboardStats(clubId?) bruke samme club-scope som deltakerlisten for vanlige admins. Superadmin kan fortsatt bruke global scope.
  • .NET-konverteringsnotat: Skill eksplisitt mellom tenant-scoped stats og global owner stats i API-kontrakten.
  • Status: Lukket - deployet og verifisert live

MF-008: Admin deltakerliste inkluderer admin/testadmin som deltakere

  • Rolle: Admin
  • Skjerm/rute: /admin, fanen Deltakere
  • Verifisering: live, Playwright med codex.admin.vtg.73@golfklubb-it.com
  • Prioritet: Boor fikses
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Deltakerlisten viser 36 rader og inkluderer blant annet Admin User admin@gkit.no og Codex Test Admin. Dette blander operative deltakere og admin-kontoer i samme liste.
  • Anbefalt fix: Filtrer deltakerlisten til role == user for deltaker-/kursarbeid, og ha separat adminbruker-forvaltning hvis nodvendig.
  • .NET-konverteringsnotat: Modellér Participants og Staff/AdminUsers som separate query surfaces.
  • Status: Lukket - deployet og verifisert live

MF-009: Admin deltakerliste har horisontal overflow paa mobil

  • Rolle: Admin
  • Skjerm/rute: /admin, fanen Deltakere
  • Verifisering: live, Playwright ved 390 px bredde
  • Prioritet: Boor fikses
  • Tiltaksvindu: Neste major
  • Beskrivelse: Deltakerlisten bruker tabell og gir horisontal overflow (scrollWidth 392 mot clientWidth 390 i test). Praktisk sett er tabellen tett og krevende paa mobil, selv om overflowen er liten i maaling.
  • Anbefalt fix: Bruk mobilkort/radkomponent for deltakere paa smaa skjermer, med navn, kurs, status og primærhandlinger synlig uten horisontal tabellscroll.
  • .NET-konverteringsnotat: Bygg admin participant list mobile-first som eget view, ikke som nedskalert desktop-tabell.
  • Status: Lukket - deployet og verifisert live

MF-010: Kurs mangler clubId, som gjoer tenant-scope uklart

  • Rolle: Admin, AppOwner
  • Skjerm/rute: /admin, fanene Kurs og Deltakere
  • Verifisering: produksjonsdata read-only via Firebase Admin SDK
  • Prioritet: Boor fikses
  • Tiltaksvindu: Neste major
  • Beskrivelse: Produksjonen har 5 kurs, og alle kontrollerte kursdokumenter mangler clubId. I dagens Ski GK-only drift er dette mindre akutt, men ved flere klubber blir kursvisning og import vanskelig aa sikre per tenant.
  • Anbefalt fix: Innfoer clubId paa kurs og scope adminsporringer til klubb. Migrer eksisterende Ski GK-kurs til clubId 73.
  • .NET-konverteringsnotat: Gjoer tenantId/clubId obligatorisk paa Course-aggregate og alle course queries.
  • Status: Aapen

MF-011: Admin kurs- og oppropsflater har horisontal overflow paa mobil

  • Rolle: Admin
  • Skjerm/rute: /admin, fanen Kurs, og /admin/kurs/:kursId
  • Verifisering: live, Playwright ved 390 px bredde
  • Prioritet: Boor fikses
  • Tiltaksvindu: Neste major
  • Beskrivelse: Kurslisten og kursdetalj maales med horisontal overflow (scrollWidth 392 mot clientWidth 390). Kurslisten er tabellbasert og tett paa mobil.
  • Anbefalt fix: Bruk mobilkort for kursliste og oppropsliste, med primærhandling som tydelig fullbreddeknapp.
  • .NET-konverteringsnotat: Design admin course list og roll-call som mobile-first arbeidsflater, ikke desktop-tabeller.
  • Status: Lukket - deployet og verifisert live

MF-012: Oppropsliste er tom for club admin selv om kurset har deltakere

  • Rolle: Admin
  • Skjerm/rute: /admin/kurs/:kursId
  • Verifisering: live, Playwright med codex.admin.vtg.73@golfklubb-it.com
  • Prioritet: Kritisk
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Kurslisten viser f.eks. 8 / 10 deltakere for kurs, men naar admin aapner oppropslisten vises bare header/nav og ingen deltakerdata. Koden henter brukere med where('courseId', '==', courseId) uten clubId-constraint. Firestore-reglene krever klubbisolering for admin-lesing av users, saa queryen er ikke trygg nok.
  • Anbefalt fix: Legg til clubId-constraint i getUsersByCourse(courseId, clubId) for club admin. Superadmin kan bruke eksplisitt global eller valgt club-scope.
  • .NET-konverteringsnotat: API-endepunkt for course participants maa alltid routes gjennom tenant context og ikke stole paa client-side filtrering.
  • Status: Lukket - deployet og verifisert live

MF-013: Admin "Legg til manuell" og "Rediger" feiler i runtime

  • Rolle: Admin
  • Skjerm/rute: /admin, fanen Deltakere
  • Verifisering: live, Playwright klikk-test uten lagring
  • Prioritet: Kritisk
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Klikk paa Legg til manuell gir TypeError: openAddUserModal is not a function. Klikk paa redigerikon gir TypeError: openEditUserModal is not a function. Knappene finnes i UI, men komponentmetodene mangler.
  • Anbefalt fix: Enten implementer modalene/metodene eller skjul knappene til funksjonen er klar. For drift er det bedre aa skjule brutte handlinger enn aa vise knapper som feiler.
  • .NET-konverteringsnotat: Alle command buttons i ny app maa ha eksplisitt test for handler, loading/error state og ingen no-op/brutte actions.
  • Status: Lukket - deployet og verifisert live

MF-014: AppOwner klubboversikt viser 168 klubber i en lang mobilflate uten soek/filter

  • Rolle: AppOwner
  • Skjerm/rute: /admin, fanen Klubber
  • Verifisering: live, Playwright med codex.owner.vtg@golfklubb-it.com
  • Prioritet: Boor fikses
  • Tiltaksvindu: Neste major
  • Beskrivelse: Mobilflaten lister 168 klubber med kill switch, lisensfelt og lagreknapp per klubb. Dette er tungt aa bruke paa mobil og oeker risikoen for feil klubbhandling.
  • Anbefalt fix: Legg inn soek/filter, fokusert klubbdetaljside og separer lesestatus fra endringsmodus.
  • .NET-konverteringsnotat: AppOwner club management boer bygges som master-detail med eksplisitt valgt klubb og server-side paging/filter.
  • Status: Lukket - deployet og verifisert live

MF-015: AppOwner kill switch er for naer ordinær listevisning

  • Rolle: AppOwner
  • Skjerm/rute: /admin, fanen Klubber
  • Verifisering: live, Playwright read-only og kodegjennomgang
  • Prioritet: Kritisk
  • Tiltaksvindu: Foer konvertering
  • Beskrivelse: Hver klubb har direkte toggle for App Tilgang (Kill Switch) og Lagre Endringer. Det finnes confirm i quickDisableClub, men liste-toggle + save-path bruker saveClubSettings(club) uten tilsvarende eksplisitt konsekvensdialog i koden. For Ski GK/live tenants er dette en hoyrisikohandling.
  • Anbefalt fix: Krev ekstra bekreftelse ved deaktivering, vis klubbnummer/navn tydelig i dialogen, og krev gjerne tekstbekreftelse for clubId ved live tenant.
  • .NET-konverteringsnotat: Kill switch boer vaere en egen privileged command med audit log, reason, confirmation og eventuell two-step commit.
  • Status: Lukket - deployet og verifisert live

MF-016: AppOwner Import Engine mangler eksplisitt maalklubb og ser ikke ferdig koblet

  • Rolle: AppOwner
  • Skjerm/rute: /admin, fanen Import Engine
  • Verifisering: live, Playwright read-only og kodegjennomgang
  • Prioritet: Boor fikses
  • Tiltaksvindu: Neste major
  • Beskrivelse: Importflaten viser filopplasting og knappene Avbryt / Valider & Importer, men koden viser ingen tydelig handler for Valider & Importer i denne AppOwner-flaten og ingen eksplisitt valgt maalklubb. I produksjon er det uklart hva importen vil paavirke.
  • Anbefalt fix: Skjul eller merk flaten som ikke aktiv hvis den ikke er ferdig. Foer faktisk import maa maalklubb, forhåndsvisning, valideringsrapport og bekreftelse vaere eksplisitt.
  • .NET-konverteringsnotat: Import maa bli en server-side workflow med staging, validation, preview og commit per tenant.
  • Status: Lukket - deployet og verifisert live som planlagt/deaktivert flate

MF-017: AppOwner API / Rules-flate er presentasjon uten tydelig funksjon/handler

  • Rolle: AppOwner
  • Skjerm/rute: /admin, fanen API / Rules
  • Verifisering: live, Playwright read-only og kodegjennomgang
  • Prioritet: Boor fikses
  • Tiltaksvindu: Neste major
  • Beskrivelse: Generer API Nøkkel og Lagre Oppsett vises i UI, men kodegjennomgang viser ingen klikkhandlere paa knappene i denne flaten. Mapping-feltene er readonly eksempeldata.
  • Anbefalt fix: Skjul uferdige command-knapper eller merk tydelig som planlagt/ikke aktiv. Ikke vis API-key-generering som operativ funksjon foer backend finnes.
  • .NET-konverteringsnotat: API-nokler maa behandles som hemmeligheter med maskering, rotasjon, audit og server-side lagring.
  • Status: Lukket - deployet og verifisert live som planlagt/deaktivert flate

Kandidater observert foer formell logging

Disse skal bekreftes foer de flyttes til "Funn":

  • /chapter/1 gir "Kapittel ikke funnet"; dette er trolig forventet fordi faktiske kapittel-IDer er tekstbaserte, f.eks. /chapter/introduction. Ikke logget som feil med mindre det finnes eksterne lenker til tallbaserte kapittelruter.