Imported from hengelsportshort-boop/KVVI (
AGENTS.md). Install upstream withnpx skills add hengelsportshort-boop/KVVI. Copyright stays with the author.
KVVI Website — Richtsnoeren
Absolute regels
- GEEN wijzigingen aan inhoud of werking van de website. Alleen prestatie-optimalisaties zijn toegestaan die geen impact hebben op functionaliteit of zichtbare inhoud.
- Voor elke wijziging vragen of deze door mag gaan.
Opgelost
UK search vond geen UK entries (03-06-2026)
- Oorzaak:
VisstekkenZoek.astro(zoekVisstekken()enzoekOpLocatie()) fetchten alleen/api/visstekkenen/api/visstekken-abc, maar niet/api/visstekken-en. De 20 UK entries uitfisheries.geojsonwaren onzichtbaar in de zoekbalk, ook al stonden ze wel op de kaart. - Fix:
/api/visstekken-entoegevoegd aan beide fetch calls +enDatasamengevoegd inallFeatures.
Encoding: 204 corrupte karakters in abc-sportvissen.geojson (03-06-2026)
- Oorzaak: Tijdens scraping zijn alle niet-ASCII karakters (é, ë, ï, °, à, è, ê, ó, ², etc.) vervangen door U+FFFD (�). De data in
abc-sportvissen.geojsonbevatte 204 van deze vervangingskarakters, zichtbaar in de infopaneel op de hengelmap. - Fix: Python script (
/tmp/fix_geo.py) met context-afhankelijke mapping (~150 patronen) — hersteld op basis van Nederlands, Frans en GPS-coördinaat context. Viajson.load()/json.dump()i.p.v. raw text replacement om JSON-validiteit te garanderen. - Aanvullend:
charset=utf-8toegevoegd aan Content-Type invisstekken.js,visstekken-abc.jsenvisstekken-en.js— voorkomt dat browser JSON als Latin-1 interpreteert. - Let op: Persistent volume op Railway (
/app/public/data) behoudt oude data —start.shoverschrijft bestaande bestanden niet. Bij encoding-fixes in data files moet de admin het bestand herladen via de admin interface ofstart.shaanpassen.
ETag 304 markers verdwijnen (30-05-2026)
- Oorzaak:
laadVisstekken()resettealleVisstekkenFeaturesKvvienalleVisstekkenFeaturesAbcnaarnullvoordat async API calls terugkwamen. Bij 304 waren de caches leeg → geen markers toegevoegd aan nieuwemarkerGroup. - Fix: per-API caches niet resetten in
laadVisstekken(), alleen in initialisatie. Ze blijven behouden tussen 30s refreshes. - Structuur:
processGeoJSON(data, isAbc)— aparte functie voor marker-creatie, gebruikt door zowel 200- als 304-pad.
Admin login (29-05-2026)
- Cross-site POST 403:
security.checkOrigin: falseinastro.config.mjs— Astro v6 blokkeert standaard POST forms achter Fly proxy - ADMIN_KEY leeg bij Docker build:
.envstaat in.dockerignore, dusimport.meta.env.ADMIN_KEYwordt leeg geïnlined tijdens build. Opgelost doorprocess.env.ADMIN_KEYinlogin.astroenmiddleware.ts. - ADMIN_KEY runtime leeg (30-05-2026):
process.env.ADMIN_KEYgafa=0(leeg) op de server, ook al stond de secret als "Deployed". Opgelost door secret opnieuw in te stellen (fly secrets set ADMIN_KEY=<waarde>), wat een herstart van de machine forceert.
iPad login (30-05-2026)
- Oorzaak:
ADMIN_KEYenvironment variable was leeg op de server (a=0), niet gerelateerd aan iPad-specifiek gedrag. Oplossing: secret resetten + machine herstart.
Hengelmap crash (29-05-2026)
- Root cause:
map.on('moveend', resizeCanvas)enmap.on('zoomend', resizeCanvas)stonden op module-top-level (buiten deinitMap()functie). Omdatmappas binneninitMap()wordt aangemaakt, gaf ditTypeError: Cannot read properties of undefined (reading 'on')— de hele module crashte voorinitMap()kon uitvoeren. - Fix: die 3 regels verplaatst naar binnen
initMap(), net na de map creatie. - import('leaflet'): Lokaal dev-mode:
import('leaflet')retourneert module namespace (Module { default: Leaflet }) i.p.v. de constructor direct. Opgelost metmod.default || mod.
FAI panel altijd zichtbaar (29-05-2026)
- Oorzaak:
.fai-panelhaddisplay: block !importantenvisibility: visible !important, waardoorhiddenclass (Tailwind'sdisplay: none) niet werkte. - Fix:
!importantverwijderd vandisplayenvisibilityinFAIPanel.astro.
Huidige optimalisaties (niet ongedaan maken)
- Image optimization:
bin/optimize-images.mjs(draait voor elke build) — PNG→JPEG, max 1920px, kwaliteit 80% - Compressie + caching:
server.mjs— gzip-compressie, Cache-Control (1 jaar) voor statische assets - openai dependency verwijderd (niet gebruikt)
- Google Fonts: preconnect + preload in BaseLayout.astro
- Preconnect/dns-prefetch voor hengelmap: api.open-meteo.com, tile.openstreetmap.org (enkel op /hengelmap)
- Standalone → middleware mode in astro.config.mjs (voor compressie in server.mjs)
- Mobiele optimalisatie (27-05-2026): Touch interactie, hengelmap, homepage, fotos
- Touch & Interactie:
-webkit-tap-highlight-color: transparent,overscroll-behavior: none, safe area insets (env(safe-area-inset-*)),:activestates op.mobile-nav-linken.mobile-bar-btn - Hengelmap:
min-height: 100dvhi.p.v. 600px op mobiel, laad-indicator (#visstekken-loading),verbergLaadIndicator()na fetch - Homepage: compactere hero padding/buttons op mobiel, logo kleiner
w-48 h-48op kleine schermen - Fotos modal: grotere touch targets (
w-16 h-16op mobiel,w-14 h-14op desktop)
- Touch & Interactie:
- Leaflet CSS lokaal (29-05-2026):
/public/lib/leaflet.cssipv unpkg.com preload — sneller (geen externe DNS/SSL), immutable cache (1 jaar), gzip via server.mjs - cron-job.org keep-alive (29-05-2026): elke minuut naar
https://kvvi.onrender.com/— voorkomt VM suspension na 30 min inactiviteit - ETag caching visstekken (30-05-2026):
?t=Date.now()verwijderd uit fetch URLs, vervangen doorIf-None-Matchheaders. Server antwoordt met304(0 KB) zolang data niet wijzigt — bespaart ~45-90 MB/u op mobiel.
Structuur
src/layouts/BaseLayout.astro— hoofdnavigatie (Uitslagen/Specials dropdown via click)src/components/HengelKaart.astro— kaart, wind, FAI, help, lokalisatorsrc/components/VisstekkenZoek.astro— zoekbalk voor visstekken (tekst + locatie) op hengelmapsrc/components/FAIPanel.astro— FAI score panel (weerdata, wind animatie)src/components/WeerOverlay.astro— weerkaartjes op hengelmapsrc/pages/admin/login.astro— admin login (POST form, vergelijkt metprocess.env.ADMIN_KEY)src/middleware.ts— admin auth middleware (controleert cookieadmin_tokentegenprocess.env.ADMIN_KEY)server.mjs— productieserver (starten metnode server.mjs)public/lib/leaflet.css— lokaal geserveerde Leaflet CSSnpm run dev— developmentnpm run build— build (optimizes images first)
Admin
- Login via
/admin/login - WAARSCHUWING:
.envstaat in.dockerignore, dusimport.meta.envwordt leeg tijdens Docker build. Gebruik ALTIJDprocess.envvoor runtime secrets.
Railway
- Host:
kvvi.onrender.com - Deploy trigger:
curl -s -X POST "https://backboard.railway.app/graphql/v2" -H "Authorization: Bearer <token>" -H "Content-Type: application/json" -d '{"query":"mutation { environmentTriggersDeploy(input: { environmentId: \"6d070451-3a0e-478d-91f7-aed2b7104d1c\", projectId: \"19766c01-d253-4bd7-96fe-bdbcbe1bc78f\", serviceId: \"b1442851-f031-4433-a041-4881dc33bbce\" }) }"}' - Project:
distinguished-presence, Service:kvvi - Persistent volume:
/app/public/data— seed data in/app/public/data-seed,start.shkopieert alleen ontbrekende bestanden (behoudt admin-wijzigingen) - ADMIN_KEY is runtime env var via Railway dashboard of
fly secrets(niet meer van toepassing — Railway secrets via dashboard)
Visstekken-data locaties
public/data/hengelmap.csv— KVVI eigen visstekken (Clubvijver, Kanaal Roeselare-Leie, Blankaart, Gaverbeek)public/data/abc-sportvissen.geojson— ABC Sportvissen vislocaties (~45+ locaties, 341 KB)public/data/claudedenys-Hengelen-West-Vlaanderen.geojson— West-Vlaamse visstekken (~40+ locaties, 403 KB)public/data/fisheries.geojson— UK vislocaties (~20 locaties, 403 KB)public/data/legende.json— Groeperingstypes voor visstekken (Polderrivier, Rivier, Kanaal, Commercial, etc.)
Back-ups
backup-visstekken-data/— back-up van alle 4 visstekken-data bestanden (aangemaakt 27-05-2026)