doxa-maps/vite.doxa-maps-build-config.json
doxa-maps-88655c70 38a7dbb939
Some checks are pending
build-gate / build (push) Waiting to run
Land the swarm's work: no iframes anywhere, a tree that keeps its shape, deeper facets
Checkpointing thirteen files of agent work that were sitting uncommitted while three
agents wrote to a live tree the Driver was watching through hot reload. Uncommitted work
is work at risk, and a tree being edited under an observer oscillates between states that
look like regressions and are really just partial saves.

The second capability-5 shell now mounts its tabs as real elements too, so no iframe
remains in either shell. It was the last holdout: eight tabs, all iframe mode, each
pointing at a hardcoded built-tree leaf that does not exist under the dev server.

The facet rail keeps its shape when a filter narrows it. Selecting one place took the
rail from sixty-six rows to twenty-one — forty-six rows deleted, none dimmed — so the row
a user was about to click vanished under the cursor, which is what "the buttons went
dead" actually was. Rows whose count falls to zero are now re-admitted at their original
slot and depth, dimmed and inert, which also restores the component's own promise to lose
nothing against the tree it replaced.

Expanding a branch and filtering by it are now separate, visible affordances: the whole
row filters, and expand is a real button with its own hit area and label. Rows that were
never clickable are unmistakably inert rather than silently ignored.

Three more facet axes reach the grid — affinity bloc, engagement status and primary
language — each verified to share a field with an existing prop rather than being mapped
on name resemblance. Two derived facets remain unmapped on purpose: they have no matching
row field, and mapping them would filter confidently to the wrong rows.
2026-09-22 14:51:52 +00:00

41 lines
5.5 KiB
JSON

{
"//": "THE single build-config for this STANDALONE doxa-maps bundler. Edit this ONE file, then run `bun run build`. FIELDS: 'name' = the output folder name the tree is written as. 'paths' = EXTRA folders to copy the whole tree into. EMPTY and normally stays empty: the build writes into public/<name>/ directly, because public/ is the committed served web-root rather than something assembled at build time. STANDALONE NOTE (2026-07-30): the old value ['../../../public/js'] pointed into the dx-life Nuxt app's public dir \u2014 meaningless in this repo, and the whole point of standing this bundler up on its own is that dx-life consumes maps from the CDN instead of hosting a copy. So 'paths' is now EMPTY: the tree is written to ./app/<name>/ only, and that ONE tree is what all three targets consume (Railway/CDN static host, Capacitor webDir, local staging). If you ever want to ALSO publish into a local dx-life checkout, add its path back here. 'embedBaseUrl' = public URL where the <name>/ tree is served, used to build ABSOLUTE paste-anywhere embed snippets for partner sites ('' = RELATIVE ./bundle/profile/... URLs so the dropped folder is position-independent \u2014 keeps the drop-portability gate green and is what Capacitor needs, since the app loads from https://localhost). 'tokenUrl' = the endpoint every generated map page fetches its Mapbox token from \u2014 a URL, NOT a secret. Set it ABSOLUTE (https://doxa.life/api/maps/token) so both a CDN-hosted folder and the mobile app work; the token stays remote and only the URL ships. window.MAP_TOKEN_URL overrides at runtime. Your endpoint must send CORS headers permitting https://localhost (the Capacitor origin) and any partner domain. 'token' = OPT-IN literal token baked into every page \u2014 LEAVE EMPTY; prefer tokenUrl. 'assetsBaseUrl' = where the SHARED asset tree (previews, posters, boundaries) is served from. Vite no longer copies public/ into each bundle (publicDir:false in vite.config.js), so pages are TOLD where the one shared copy lives. EMPTY = a relative path derived per page depth, which keeps a dropped folder self-contained under one web-root. Set it ABSOLUTE (https://maps.doxa.life/assets) for partner embeds and the mobile app, where there is no shared web-root to climb to. Same modular pattern as tokenUrl and window.MAP_APP_API_URL. 'dropin.include' = THE drop-in contract, declared here and nowhere else: the only root entries of public/ that `sync-dropin --from-config` copies into a host \u2014 index.html (the generated root page \u2014 THE PLUGIN STUDIO host, written by internal/generate-tree.mjs; as of 2026-09-22 it mounts <plugin-studio>, it is no longer the staging gallery), __gallery/ (the ARCHIVED bundle-index gallery, internal/generate-gallery.mjs, kept reachable at /__gallery in BOTH the dev and built trees), assets/ (data) and <name>/ (the bundle folders + manifest.json); with --prune everything else in the host's drop-in folder is removed, and `public-hygiene-check --strict` fails on any other root entry. 'dropin.exclude' = built files INSIDE the allowlist that are still not shipped: data no page fetches (the full people-groups CSV, the tables only internal scripts read, the table index). They stay in public/ for the scripts; `sync-dropin --from-config` skips them and counts them as 'excluded (not shipped)', and a copy already in the host is removed like any stale file.",
"name": "doxa-maps",
"paths": [],
"embedBaseUrl": "",
"assetsBaseUrl": "",
"tokenUrl": "",
"token": "pk.eyJ1IjoiZ29zeXN0ZW1zIiwiYSI6ImNtZm9vM291czA3amQya3BzYW42YW9ibTcifQ.52WM0IpxY9FcB0zc9f1zbQ",
"dropin": {
"dest": "../doxa-life/public/embed/doxa-maps-build",
"include": [
"index.html",
"__gallery",
"assets",
"doxa-maps"
],
"exclude": [
"assets/people-groups/people_groups.csv",
"assets/tables/open-doors.json",
"assets/tables/platform-reachability.json",
"assets/tables/index.json"
]
},
"apiBaseUrl": "https://pray.doxa.life",
"gatedProfiles": [
"key-cities"
],
"qaWidget": false,
"//token": [
"THE PUBLIC MAPBOX KEY, BAKED ON PURPOSE (Driver ruling 2026-09-21): 'all maps can use the pk",
"from the api, no problem \u2014 if they want to set a mapbox sk they can'. This is token-ladder",
"RUNG 3 (see internal/generate-tree.mjs:595): rungs 1-3 are used DIRECTLY with no network call,",
"so baking it makes every map work out of the box on ANY host \u2014 including one with no",
"/api/maps/token endpoint and no CORS on the fallback, which is exactly why nuxtbase.app maps",
"were blank. SOURCE OF TRUTH: https://doxa.life/api/maps/token (see",
"_qa-cycle/01-ideation-research/REFERENCE-mapbox-token-endpoint.md). Re-fetch from there rather",
"than copying this literal around. A pk. is a PUBLIC key protected by URL restrictions, not by",
"secrecy \u2014 never put an sk. here; check:public-hygiene still fails the build on sk./tk."
],
"//tokenUrl-2026-09-22": "EMPTIED 2026-09-22. It pointed at https://doxa.life/api/maps/token, which serves the URL-RESTRICTED doxalife token \u2014 tiles 403 from every origin except doxa.life, so the basemap rendered as an empty void while pins drew fine (the Driver's exact report: 'it's loading the pins, but it's not loading the actual underlying map'). That endpoint sits ABOVE the baked token in the ladder, so leaving it set would fetch the broken token and overwrite the good one. Measured: gosystems token = 200 from no-Referer, nuxtbase.app AND localhost; doxalife token = 403 from all three."
}