Claude guidelines for sales/kommune/
Per-kommune sales pages at /kommune/<slug>/ for cold-outreach to Norwegian kommuner. 357 pages, each showing one kommune's Placepoint footprint. Completely separated from markdown/ - different folder, dedicated docs plugin instance, unlisted (no sidebar, no search index, no sitemap, no nav entry), reachable only via direct link.
For the shared sales-tree blueprint (docs plugin idiom, unlisted+caution block, idempotent gen, meta.json + mdx + conditional blocks, AutogenDisclaimer, sales-helpers.ts), see ../CLAUDE.md. This file holds rules specific to the kommune surface.
Mechanics
- Mounted by the kommune
@docusaurus/plugin-content-docsinstance in../../site/docusaurus.config.tswithid: 'kommune',path: '../sales/kommune',routeBasePath: 'kommune', no sidebar. (URL is/kommune/<slug>/, not/sales/kommune/<slug>/- the kommune surface predates the/sales/prefix.) - Pages are generated by
../../scripts/tour/gen-kommune-pages.tsfrom the registry in../../scripts/tour/data/kommuner.ts. The script is idempotent - it only writes<slug>.mdx/<slug>-meta.jsonfiles that don't already exist, so manually-curated pages (Sandefjord, Oslo) are never overwritten. - Screenshots are produced by
../../scripts/tour/sections/kommune.tsintoimg/<slug>/(gitignored - the full set is 4+ GB). Use the sharded runner../../scripts/tour/run-kommune-shards.shto parallelize. - The kommune.png and aerial-photo
Mer informasjonlinks point at/kartgrensesnittet/kartlag, not the stub/kartgrensesnittet/overblikk.
Env flags for backfills
ONLY_KARTLAG=1- only the 4 kartlag overlays, ~1 min/kommuneONLY_MATCHING_ZOOM=1- only the rådhus-centered zoom shotONLY_FOKUS_BILDER=1- only the aerial-photo shotSKIP_KARTLAG=1- skip overlays in the full flowKARTLAG_TILE_WAIT_MS=<ms>- override the 18 s WMS-tile wait, e.g. 45000 for the natur/Artsdatabanken layer that occasionally times out
Matching-zoom and rådhus-coords
Matching-zoom centers on the rådhus from ./radhus-coords.json (OSM Nominatim → Kartverket Stedsnavn → centroid fallback). Centroids land in forests/fjords for irregular shapes (Gol). The s-value is 20000 (~5 km wide); earlier captures used s=2400 which was too tight to read as a kommune overview.
Property selection (gotoFirstWorkingCadastre)
Ranks: (1) same-knr first (URL contains /cadastres/<knr>/), (2) keyword score (kulturhus > NAV > rådhus > ...), (3) original table order. Without (1), Gol's eiendom shots showed an Oslo property the kommune happens to also own. All four imagery passes require eiendomHasNoImagery() === false; if every pass fails, no eiendom shots are captured and the generator hides the entire "Detaljer per eiendom" block.
Kartlag tile-wait
18 s minimum (6 s left ~6 failures across 1071 shots; 12 s left a handful; 18 s drops below 0.5 %). For re-shoots of slow layers (Artsdatabanken/natur in particular) override with KARTLAG_TILE_WAIT_MS=45000. The "Offentlig ol. bygg" filter on matching-zoom retries up to 5 times (PR #43, was 3) with 5 s waitFor + 5 s scroll + 5 s click + 3 s post-click per attempt, and 3000×attempt inter-attempt waits; logs ! captured WITHOUT filter when all attempts fail.
setBasemap() destroys the cadastre URL
../../scripts/tour/helpers.ts setBasemap() does page.goto(/map?projectId=...) to reach the basemap selector, which kills any /map/cadastres/... URL. After every setBasemap call inside the kommune section we MUST re-navigate to the chosen cadastre URL before shooting; without that step eiendom-fokus-bilder.png, eiendom-3d.png, and the leietagere shots are captured at the bare /map?projectId view with no Eiendom panel. Fixed in PR #43 - the kommune section now does await page.goto(chosenUrl, ...) after each setBasemap.
captureEiendom3d patience
The "Sentrer kartet" target icon takes 5-12 s to render in big cities; an early hard check skipped the 3D shot. clickSentrerKartet(page, { waitForMs }) accepts an optional wait (12 s in 2D, 8 s in 3D in PR #43) and a missing icon is no longer fatal - the cx/cy/cz URL camera params are the fallback. Aremark and similarly rural kommuner show terrain only in 3D, which is the honest representation of Norway's 3D-mesh coverage outside major cities.
Conditional eiendom blocks
The .mdx template hides two blocks when the corresponding meta keys equal meta.matching (the picker's "no real cadastre" sentinel): the aerial-photo shot (meta.eiendomFokusBilder) and the entire "Detaljer per eiendom" section (meta.eiendomFokus). Without these gates, the 338 fallback kommuner rendered 5+ broken images each. The 19 with a real cadastre URL keep the full section. After a re-run that fills in real URLs, regenerate the affected mdx so the block reappears (delete the file, run gen-kommune-pages.ts).
Comprehensive re-shoot pipeline
Use the template under ../../scripts/kommune/ (copy and adapt) to chain:
SKIP_KARTLAG=1 ONLY_MATCHING_ZOOM=1 run-kommune-shards.sh 4 --allbackfill-eiendom-fallback.sh 4KARTLAG_TILE_WAIT_MS=45000 ONLY_KARTLAG=1 run-kommune-shards.sh 4 --all- Delete every generated mdx, regenerate,
upload-images-only.sh,npm run deploy, set-cache-headers, AFD purge. scripts/kommune/verify-screenshots.py
Wall-clock ≈ 9 h with 4 workers per shard.
../../scripts/kommune/wholesale-polish.sh is a related runner that re-shoots only kommuner whose meta.json still has old s=2400 matching-zoom URLs OR fallback eiendomFokus URLs, with batched mdx-regen + incremental deploys after every BATCH_SIZE kommuner. Real-world pacing measured 2026-04-29 with WORKERS=8 BATCH_SIZE=30: ~1h 12m per batch (~50 min sharded tour + ~15-25 min deploy). Resumable: the Step A staging script reads each kommune's meta.json and only includes ones still on s=2400 zoom or fallback eiendomFokus, so already-polished kommuner are skipped automatically.
Auth retry behavior in sharded mode
PR #47 fixed the bug where a single Azure B2C auto-login failure dropped the shard's remaining 2-3 slugs (the manual-login fallback was waiting 120 s for human input that never came in unattended runs). Now: when WORKER_INDEX is set in ../../scripts/tour/auth.ts createAuthenticatedContext and B2C fails, we retry once after a 5 s backoff and then throw immediately if it still fails. The shard exits non-zero quickly so the rest of the batch isn't held up; lost slugs (if any) come back as a small targeted re-shoot via KOMMUNE_SLUGS=<csv> run-kommune-shards.sh. Pre-fix loss rate was ~1 % (1 crash in 4 batches on 2026-04-29 lost herøy-mr, hurdal, ibestad).
Audit storage after a deploy
../../scripts/kommune/verify-screenshots.py lists every kommune/img/<slug>/ blob and cross-checks against the expected per-kommune set (reads meta.json so the conditional aerial shot is checked only where required). Outputs /tmp/kommune-screenshot-audit.txt and /tmp/kommune-screenshot-bad-slugs.txt (comma-separated slug list, ready for KOMMUNE_SLUGS=$(cat ...) re-shoot).