Skip to content

chore(release): v1.17.1 - map center, CARTO key, and docs fixes - #24

Merged
d3mocide merged 3 commits into
mainfrom
claude/project-config-docs-audit-g9zk2n
Sep 13, 2026
Merged

chore(release): v1.17.1 - map center, CARTO key, and docs fixes#24
d3mocide merged 3 commits into
mainfrom
claude/project-config-docs-audit-g9zk2n

Conversation

@d3mocide

@d3mocide d3mocide commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Addresses four related configuration and documentation problems, released as v1.17.1 (patch — bug fixes only, no new user-facing features).

1. Map center environment variables had no effect (closes #23)

MapContainer hardcoded Portland, OR and never read VITE_MAP_LAT / VITE_MAP_LNG.

Two faults were stacked here. The variables were unused in the source, and a VITE_-prefixed variable is inlined by Vite at build time — so setting one in docker-compose.yml against the prebuilt ghcr.io image could never have worked regardless of the first bug. Fixing only the hardcoded coordinate would have left the reporter's exact workflow still broken.

  • Initial view now resolves through a new src/utils/runtimeConfig.js: window._env_import.meta.env.VITE_* → default.
  • docker-entrypoint.sh writes MAP_LAT / MAP_LNG / MAP_ZOOM into env-config.js at container start, so a prebuilt image is configurable without a rebuild.
  • VITE_MAP_LAT / VITE_MAP_LNG still accepted as deprecated aliases, so existing compose files keep working.
  • Invalid or out-of-range values warn and fall back instead of handing Leaflet a NaN.
  • public/env-config.js no longer ships populated defaults — because window._env_ takes priority, its baked-in values silently shadowed the VITE_* layer during npm run dev.

New MAP_ZOOM setting for the initial zoom level.

2. CARTO basemap API key

CARTO began watermarking unauthenticated raster tiles in August 2026, so the dark, dark_green and light styles now render with an "API KEY REQUIRED" stamp.

The key is applied server-side only. The browser requests tiles from a same-origin /basemaps/... path; nginx (production) or the Vite dev/preview server (development) appends the key on the way out to CARTO. It is therefore absent from the JS bundle, from env-config.js, and from anything visible in devtools.

CARTO_API_KEY is deliberately not VITE_-prefixed — that prefix is exactly what would inline it into the client bundle and publish it to every visitor.

Hardening in the nginx proxy:

  • Clears the client's query string, so a caller cannot substitute their own key (nginx otherwise appends original args after a rewrite, producing key=ours&key=theirs).
  • Location regex accepts only well-formed {style}/{z}/{x}/{y}.png paths, so it cannot be driven as a general-purpose open proxy.
  • Caches tiles locally (30d / 512MB) so repeat views don't spend the account's monthly quota.
  • nginx.conf is now a template rendered by docker-entrypoint.sh, so the key is supplied at deploy time rather than baked into the published image. Rendering uses sed, not envsubst — the latter comes from gettext, which is not guaranteed present in the nginx base image, and a missing binary there would crash-loop the container on every start.

Without a key nothing hard-breaks — tiles still load watermarked, and the entrypoint logs how to get a free one.

3. .env.example realigned

It documented only two elevation variables and omitted everything else the stack reads. Now covers the basemap key, frontend defaults, elevation, Redis and dev-only settings. Compose substitutes from it (${MAP_LAT:-45.5152}), so a single .env drives both the production and development stacks.

4. Documentation

  • README: version corrected (was pinned at v1.16.1); config table rebuilt — it listed a dark_matter style that does not exist, omitted topo_dark, and covered none of the backend variables; new Basemap API Key section.
  • Documentation/README.md: linked elevation-scan.md, which has never existed (the tool is now Site Analysis). Added the missing Tool Interactions and PWA guide links.
  • interactions.md: duplicated step 3/4 from a copy-paste error; still named the renamed "Elevation Scan" tool; recommended Hata for verifying links, which assumes flat terrain.
  • hardware-settings.md: missing the Lilygo T-Deck and Custom Device presets, misnamed "Station G2 (High Power)", and documented no cable types despite six shipping.
  • site-analyzer.md / rf-simulator.md: predated the Link Matrix, Mesh Topology, Marginal Coverage, per-node coverage colors, WASM ITM and Reliability modes that the README already advertised.

Also removes the VITE_ELEVATION_DATASET read — the /elevation-batch endpoint ignores the dataset field in its request body, so the variable configured nothing.

Version bump

Since this branch is entirely bug fixes, bumped 1.17.01.17.1 (patch), matching the 1.16.1 patch release that preceded it:

  • package.json / package-lock.json version bump (lockfile regenerated via npm install --package-lock-only, not hand-edited)
  • CHANGELOG.md: [Unreleased][1.17.1] - 2026-09-13
  • RELEASE_NOTES.md rewritten for 1.17.1, following the existing patch-release format
  • README.md version header updated to match

Verification

  • npm run lint, npm test (66 passing, including 15 new runtimeConfig tests), npm run build — all clean.
  • nginx config parses (nginx -t) both with and without a key set. The regex needed quoting: nginx reads a bare { in \d{1,2} as the start of a block.
  • Ran nginx against a mock upstream to confirm the key is appended and a client-supplied ?key= is discarded, in both the key-set and no-key states, and again after switching the render step from envsubst to sed (including keys containing &, |, \, /, +, =).
  • Ran nginx against the real CARTO CDN: valid 256×256 PNGs returned, cache MISS then HIT.
  • Built with a canary key in CARTO_API_KEY and confirmed no trace of it in dist/, and that no direct cartocdn.com URLs remain in the bundle.
  • Simulated docker-entrypoint.sh across three cases (key set, deprecated VITE_ aliases, no key) and confirmed the generated env-config.js carries the map settings but never the key.

Docker image build itself was not exercised locally — no daemon available in this environment — so the Dockerfile/entrypoint template path is verified by config-rendering simulation rather than a local image build; this repo's own CI does build the images on this PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UqP5vFS3rXNwGUgAvtRQt6

Four related configuration/documentation problems.

1. Map center env vars had no effect (#23)

MapContainer hardcoded Portland, OR and never read VITE_MAP_LAT/VITE_MAP_LNG.
Two faults were stacked: the variables were unused in the source, and a
VITE_-prefixed variable is inlined by Vite at build time, so setting one in
docker-compose.yml could never reach the prebuilt image regardless.

The initial view now resolves through a new src/utils/runtimeConfig.js
(window._env_ -> import.meta.env.VITE_* -> default), and docker-entrypoint.sh
writes MAP_LAT/MAP_LNG/MAP_ZOOM into env-config.js at container start.
VITE_MAP_LAT/VITE_MAP_LNG remain accepted as deprecated aliases. Invalid or
out-of-range values warn and fall back instead of handing Leaflet a NaN.

public/env-config.js no longer ships populated defaults: because window._env_
takes priority, its baked-in values silently shadowed the VITE_* layer in dev.

2. CARTO basemap API key

CARTO began watermarking unauthenticated raster tiles in August 2026. The key
is applied server-side only -- the browser requests same-origin /basemaps/...
and nginx (prod) or the Vite dev/preview server (dev) appends the key on the
way out, so it is absent from the bundle, from env-config.js and from devtools.
CARTO_API_KEY is deliberately unprefixed; a VITE_ prefix would inline it.

nginx.conf became a template rendered at container start. The proxy clears the
client query string so a caller cannot substitute their own key, restricts the
path to well-formed tile URLs so it is not a general-purpose open proxy, and
caches tiles locally to protect the monthly quota. Verified end to end: nginx
config parses with and without a key, real tiles return as valid PNGs, cache
goes MISS then HIT, and a build with a canary key leaves no trace in dist/.

3. .env.example realigned

It documented only two elevation variables. It now covers the basemap key,
frontend defaults, elevation, Redis and dev-only settings, and Compose
substitutes from it so one .env drives both stacks.

4. Documentation

README version corrected (was pinned at v1.16.1), config table rebuilt -- it
listed a dark_matter style that does not exist and omitted topo_dark and most
backend variables. Documentation/README.md linked elevation-scan.md, which has
never existed. interactions.md had a duplicated step and a stale tool name.
hardware-settings.md was missing presets and all cable types. site-analyzer.md
and rf-simulator.md predated features the README already advertised.

Also removes VITE_ELEVATION_DATASET, which configured nothing: the
/elevation-batch endpoint ignores the dataset field in the request body.

Closes #23

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UqP5vFS3rXNwGUgAvtRQt6
envsubst comes from gettext, which is not something we can rely on being
installed in the nginx base image -- the alpine Dockerfile in nginx's own
repository installs only curl and ca-certificates. If it is absent, the
entrypoint fails under `set -e` and the container crash-loops on every start,
which is a poor trade for a single string substitution.

sed is part of busybox and therefore always present. The replacement escapes
the characters sed treats specially (backslash, `&`, and the `|` delimiter) so
an API key containing any of them still renders correctly.

Verified: entrypoint renders correctly for plain keys and keys containing
& | \ / + =, and for the no-key case; no placeholder is left behind; nginx -t
passes on the rendered config in both states; and the proxy still injects the
key and discards a client-supplied query string when run against a mock
upstream.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UqP5vFS3rXNwGUgAvtRQt6
Patch release for the map-center, CARTO basemap key, and documentation
fixes in this branch -- no new user-facing features, consistent with the
1.16.1 patch release that preceded it.

- package.json / package-lock.json: 1.17.0 -> 1.17.1
- CHANGELOG.md: [Unreleased] -> [1.17.1] - 2026-09-13
- RELEASE_NOTES.md: rewritten for 1.17.1, following the 1.16.1 patch-release
  format
- README.md: version header updated to match

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UqP5vFS3rXNwGUgAvtRQt6
@d3mocide d3mocide changed the title fix(config): repair map center vars, add CARTO key support, realign docs chore(release): v1.17.1 - map center, CARTO key, and docs fixes Sep 13, 2026
@d3mocide
d3mocide marked this pull request as ready for review September 13, 2026 03:29
@d3mocide
d3mocide merged commit 1f3481c into main Sep 13, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Map center variables do not work.

2 participants