Consolidate open PRs and feature branches into a single mergeable branch#119
Merged
RJK134 merged 28 commits intoMay 8, 2026
Merged
Conversation
- Add AbortSignal.timeout(8000) to fetchStatus so the loading spinner cannot hang indefinitely when the demo DB is unreachable. - Fix Data Counts grid: replace grid-cols-3 sm:grid-cols-7 with grid-cols-2 xs:grid-cols-3 sm:grid-cols-4 — the 7-column row overflowed at 375 px (iPhone SE / 14) and clipped text. - Shorten full-day workflow button label on xs viewports via a hidden/inline-block swap so the button fits a single line. - Remove stale /api/setup POST reference from runAction; the endpoint now returns 410 Gone (Phase 16 slice 7) — calling it would show an unhandled 410 in the results panel. - Create HANDOFF.md summarising iPhone QA status and caveats.
Tomorrow's client demo runs on an iPhone via a Pinggy HTTPS tunnel.
The demo brief asks for live Google Maps (geocoding + Route
Optimization) but simulated WhatsApp + email so a stray click can't
text a real customer mid-walkthrough.
Today DEMO_MODE is a single global flag — flipping it true to enable
the auth bypass and the messaging simulators *also* simulates Google.
There's no way to mix.
This PR adds a per-integration override for Maps only, and ships a
copy-pasteable iPhone-via-Pinggy runbook that uses it.
- lib/demo/demo-mode.ts:
- isLiveMapsForced() — reads EQUISMILE_LIVE_MAPS=true. Defaults to
false. Only the Maps client should consult this; WhatsApp +
email stay gated by isDemoMode() alone.
- setLiveMapsForced() — test override matching setDemoMode() shape.
- lib/integrations/google-maps.client.ts:
- getMode() now returns 'live' when DEMO_MODE=true AND
EQUISMILE_LIVE_MAPS=true (and credentials are present).
Defensive fallback to 'demo' if credentials are missing —
EQUISMILE_LIVE_MAPS=true with no API key still simulates rather
than failing the demo with a runtime error.
- Function name uses `isLiveMapsForced` rather than `useLiveMaps`
to avoid eslint-react-hooks/rules-of-hooks misclassifying the
`use` prefix as a React hook.
- __tests__/unit/integrations/google-maps-optimize.test.ts:
- 3 new cases — DEMO_MODE+override calls live API, DEMO_MODE
without override simulates, override-with-no-creds still
simulates. Existing 8 tests untouched.
- .env.example: EQUISMILE_LIVE_MAPS documented next to DEMO_MODE
with the explicit "real Google billing applies" warning.
- docs/DEMO_RUNBOOK.md (new): operator runbook covering pre-flight,
the .env.local block (DEMO_MODE + EQUISMILE_LIVE_MAPS + the
Pinggy-aware AUTH_URL / NEXT_PUBLIC_APP_URL), reset-and-rehearse
loop, sign-in shortcut, eight-page walkthrough script keyed off
the seed-demo fixtures (Mistral urgent / Sarah Mitchell routine /
Villeneuve→Aigle route), mobile sanity checklist at 390 px, and
a failure-modes table for the obvious gotchas.
Drive-by: __tests__/unit/offline/queue-replay.test.ts had two
TS errors after PR #65 made `sequence?: number` optional but didn't
update the call sites that pushed `req.sequence` into a
`number[]`. Loosened those two arrays to `Array<number | undefined>`
to match the type. Already passing CI on main, but the local
typecheck flagged it; fixing here as a tiny drive-by.
Verification (local, on a fresh checkout against this branch):
- npm run lint ✓
- npm run typecheck ✓
- npx prisma validate ✓ (with stub DATABASE_URL — same shape as CI)
- npm run test ✓ — 1000/1000 (was 997 baseline + 3 new)
- npm run build ✓
Mobile rehearsal at 390 px on the Pinggy tunnel is the next step
(D3 in the plan); operator runs it. Anything broken on that pass
goes into the same PR.
https://claude.ai/code/session_01WGFmhpjAsc2nq4uyw8YBvS
…form Three demo-readiness deliverables for tomorrow's iPhone-via-Pinggy client session, all within the existing PR #66 scope (no new code, no schema, no tests change). - scripts/windows/DEMO.bat: prints an "Integration status" block after loading .env so the operator can confirm at a glance whether the demo will run with live Google Maps + simulated messaging (the safe shape) or all-simulated. Specifically warns when EQUISMILE_LIVE_MAPS=true is set but GOOGLE_MAPS_API_KEY or GCP_PROJECT_ID is missing — the client falls back to the simulator silently in that case, which we want surfaced before showtime, not during. The footer also now points at docs/DEMO_RUNBOOK.md and the new UAT files. - docs/uat/UAT_VET_PERSONA.md (new): Dr. Rachel Kemp profile, matching the seeded demo-staff-rachel (founder + lead vet, rachel@equismile.example, brand-colour maroon). Covers her typical Tuesday, what she will and won't tolerate, what's in scope vs out of scope for the session, and which seeded fixtures map to her real coverage area (Mistral / Sophie Dupuis FR urgent / Sarah Mitchell routine / Villeneuve→Aigle route). Designed so the test reads as one continuous narrative rather than "I'm a generic admin pretending to be a vet." - docs/uat/UAT_FEEDBACK_REPORT.md (new): browser-readable fillable form covering all 12 demo surfaces (sign-in, dashboard, enquiries, triage, planning, route generation with live Google, route review, appointments, completed, bilingual, mobile polish at 390px, offline). Each section has tick-box pass/fail/partial + structured checks + free-form notes. Bottom-of-form has a numbered findings log with severity, a separate "lack-of-function" list (enhancements vs bugs), and an overall verdict with the "would you use this Tuesday?" gate. Form opens in any browser via GitHub markdown render or a local markdown preview. The vet fills it in during/after the session and either pastes into a GitHub PR comment, emails it, or hands it over in person. - scripts/windows/README.md: new "Client-demo flow" section documenting the .env additions for live Maps + Pinggy, with cross-references to DEMO_RUNBOOK and the two UAT files. Verification: lint, typecheck, prisma validate, test (1000/1000), build all green locally — same green state as the previous commit on this branch. https://claude.ai/code/session_01WGFmhpjAsc2nq4uyw8YBvS
Companion to docs/uat/UAT_VET_PERSONA.md and
docs/uat/UAT_FEEDBACK_REPORT.md (markdown). The vet wanted to fill
the report in the browser instead of editing markdown — this is the
direct delivery on that ask.
- public/uat-feedback.html — single self-contained static file:
- Mobile-first at 390 px (iPhone Safari is the target). 44 px
minimum tap targets, safe-area-inset-aware, brand-maroon header.
- 12 sections matching the markdown report 1:1: sign-in,
dashboard, enquiries, triage, planning, route generation (live
Google), route review, appointments, completed, bilingual,
mobile polish, offline. Each has Pass / Partial / Fail radios,
structured pass/fail checklist, and a free-form notes textarea.
- Findings log table (5 rows pre-rendered + "+ Add row" button)
with severity dropdown and repro selector.
- Lack-of-function + enhancement-ideas free-form textareas.
- Overall verdict block — "Would you use this Tuesday?" three-way,
biggest-fix, biggest-cheer, free-form summary.
- Persistence: localStorage auto-save on every input. Survives a
page refresh or accidental tab close. "Clear" button at the
bottom for a fresh start. Save status shown live ("Saved locally
✓ HH:MM:SS").
- Export: "Copy report" opens a modal with the full report rendered
as markdown (matches docs/uat/UAT_FEEDBACK_REPORT.md shape) ready
to paste into a GitHub PR comment, email, or Slack DM.
"Download .md" saves it as a file.
- No build step. No JS framework. No external dependencies. Static
HTML+CSS+inline JS. Next.js serves anything in public/ directly,
so it's reachable at:
http://localhost:3000/uat-feedback.html (laptop)
https://<tunnel>.pinggy.io/uat-feedback.html (iPhone via Pinggy)
The page does not require auth — it's a feedback form, not part
of the operational app, so the vet can hit it without going
through demo sign-in first.
- No code/server/test changes. Static asset only.
Verification: lint + typecheck still green.
https://claude.ai/code/session_01WGFmhpjAsc2nq4uyw8YBvS
Two papercuts caught during the live rehearsal of tomorrow's iPhone
demo. Both are demo-only (production unaffected).
- scripts/windows/DEMO.bat:
- Sets a deterministic demo-only AUTH_SECRET if .env doesn't
provide one. Without this, Auth.js v5 returns 500 on every
/api/auth/session call and the dashboard never loads after
sign-in. The default is intentionally non-secret and the value
starts with "demo-" so the integration-status block at startup
can flag it ("AUTH_SECRET = demo fallback") versus a real .env
value ("AUTH_SECRET = from .env"), versus the failure mode
where neither is set ("[WARNING] not set - Auth.js will 500").
- Same shape as the existing DATABASE_URL fallback above it. .env
still wins because it's loaded after these defaults.
- docs/DEMO_RUNBOOK.md:
- New §4a "First-time browser setup" — explains the symptom an
operator hits when the browser has previously cached an older
EquiSmile build (PWA service worker replays the old login page
with the production CSP, which includes upgrade-insecure-
requests, which silently rewrites the form POST to HTTPS,
which then doesn't match the HTTP-only allow-list in the
current CSP). Step-by-step fix for both Chrome/Edge DevTools
and iPhone Safari → Website Data.
- New §4b "Auth.js 500 on /api/auth/session" — the AUTH_SECRET
diagnostic, with the integration-status string the operator
will see in DEMO.bat at startup.
- Two new rows in §8 "Failure modes" table, cross-referencing
the new sections, so the operator can find the fix from
either entry point.
Verification: lint + typecheck green. No code change, no test
change. Bat-file change is local to DEMO.bat only; LAUNCH.bat,
production deploys, and CI all unchanged.
https://claude.ai/code/session_01WGFmhpjAsc2nq4uyw8YBvS
A fresh demo run without AUTH_URL set in .env hits this every time: [auth][error] UntrustedHost: Host must be trusted. URL was: http://localhost:3000/api/auth/session [auth][error] UntrustedHost: Host must be trusted. URL was: http://0.0.0.0:3000/api/auth/session Two distinct host strings show up because DEMO.bat binds the Next server with HOSTNAME=0.0.0.0 (correct, the Pinggy tunnel needs it), so Next's own SSR fetches use 0.0.0.0:3000 while the browser hits localhost:3000. Auth.js v5 rejects both unless trustHost is on. Today the gate was `trustHost: Boolean(process.env.AUTH_URL)` — correct for production behind a known proxy, but breaks the demo shape where neither AUTH_URL nor a known proxy host is set, AND where the bind hostname differs from the browser hostname. - auth.ts: trustHost now ORs with `DEMO_MODE === 'true'`. Demo mode unconditionally trusts whatever Host header arrives. The trust boundary is already loosened by DEMO_MODE elsewhere (CSP relaxed in lib/security/headers.ts, form-action allow-list, /api/demo/ sign-in bypass), so this is consistent. Production / non-demo deploys still require explicit AUTH_URL — unchanged behaviour. - scripts/windows/DEMO.bat: belt-and-braces — sets a fallback AUTH_URL=http://localhost:3000 alongside the existing AUTH_SECRET fallback. .env still wins because it's loaded after these defaults. Auth.js callbacks construct absolute redirect URLs from AUTH_URL, so providing it explicitly avoids any guesswork even with the trustHost loosening above. Verification: lint, typecheck, test (1000/1000) all green. No production code path changed — the OR with `DEMO_MODE === 'true'` short-circuits to the existing `Boolean(process.env.AUTH_URL)` when DEMO_MODE is unset. Closes the second blocker hit during today's iPhone-via-Pinggy rehearsal. First blocker (CSP form-action via stale SW cache) was addressed in 19836d6. https://claude.ai/code/session_01WGFmhpjAsc2nq4uyw8YBvS
The dashboard's "Triage Tasks" panel was rendering raw enum values
(URGENT_REVIEW, CLARIFY_SYMPTOMS, ASK_FOR_POSTCODE, ASK_HORSE_COUNT,
MANUAL_CLASSIFICATION) where the triage page itself maps them through
i18n via taskTypeLabel + t().
Mirrors the pattern at app/[locale]/triage/page.tsx:184–193 and 321:
- Adds useTranslations('triage') as tTriage.
- Adds the same taskTypeLabel(taskType) mapping.
- Replaces {task.taskType} with {tTriage(taskTypeLabel(task.taskType))}.
All five enum values are already keyed in messages/{en,fr}.json under
the triage namespace (urgentReview, askPostcode, askHorseCount,
clarifySymptoms, manualClassification). Fallback returns the raw
value if the map ever drifts out of sync.
Closes Finding 7 of docs/UAT_v1_1_TRIAGE_round2.md.
https://claude.ai/code/session_01PF4MU4P4Ytt9UcuVsbAzT5
Both dashboard and triage pages had an identical taskTypeLabel mapping copy-pasted between them. Move it to lib/utils/task-type-label.ts so future enum or translation key changes only need to be made in one place.
…-001 Fixes Vercel build failure (PrismaClientKnownRequestError P2003 on Invoice_visitOutcomeId_fkey). The demo seed for invoice demo-inv-001 referenced visitOutcomeId 'demo-outcome-completed', which is never created. Actual VisitOutcome rows use IDs of the form demo-outcome-001..008. This commit retargets demo-inv-001 to the first valid outcome id.
demo-outcome-001 belongs to Marie's first visit; use demo-outcome-005 for customer demo-cust-jeanluc to keep invoice–outcome customer alignment. Applied via @cursor push command
Co-authored-by: Richard Knapp <RJK134@users.noreply.github.com>
Agent-Logs-Url: https://github.com/RJK134/EquiSmile/sessions/80cffda9-167f-49c6-85a9-cd617d839dcc Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
Agent-Logs-Url: https://github.com/RJK134/EquiSmile/sessions/e6b49b31-b24c-4fa8-9203-7768350a1cbe Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
Agent-Logs-Url: https://github.com/RJK134/EquiSmile/sessions/80cffda9-167f-49c6-85a9-cd617d839dcc Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/RJK134/EquiSmile/sessions/80cffda9-167f-49c6-85a9-cd617d839dcc Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
Co-authored-by: Richard Knapp <RJK134@users.noreply.github.com>
Agent-Logs-Url: https://github.com/RJK134/EquiSmile/sessions/9ea8e98d-e479-4ece-9130-11de6f3585a3 Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
Agent-Logs-Url: https://github.com/RJK134/EquiSmile/sessions/9ea8e98d-e479-4ece-9130-11de6f3585a3 Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
… outcome Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
…UTH fixes, demo runbook # Conflicts: # auth.ts # docs/DEMO_RUNBOOK.md # lib/demo/demo-mode.ts # lib/integrations/google-maps.client.ts Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
…n-link audit Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
…ility # Conflicts: # app/[locale]/dashboard/page.tsx # app/[locale]/triage/page.tsx Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
…view feedback) Agent-Logs-Url: https://github.com/RJK134/EquiSmile/sessions/9679dd49-fcf3-47e2-8f8f-23b647c3c28b Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Copilot AI
added a commit
that referenced
this pull request
May 8, 2026
…onical utility - Re-point dashboard and triage page imports from lib/utils/task-type-label to the canonical lib/utils/triage-task-type (landed via PR #119) - Simplify call sites to direct t(taskTypeLabel(...)) — safe because TRIAGE_TASK_TYPE_LABEL_MAP is typed against the full TriageTaskType enum, so all known values are covered; unknown values fall back to the raw string - Remove superseded lib/utils/task-type-label.ts - Rename __tests__/unit/utils/task-type-label.test.ts → __tests__/unit/utils/triage-task-type.test.ts; update import and fallback assertions to match the canonical utility's string-return contract Co-authored-by: RJK134 <167345619+RJK134@users.noreply.github.com>
6 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
This PR consolidates multiple open PRs/feature branches into a single mergeable branch, resolving conflicts against current main, de-duplicating an overlapping task-label refactor, and improving the demo/UAT workflow (auth stability, live-Google-maps override, mobile demo UX, and operator/UAT documentation/assets).
Changes:
- Demo reliability/UX: add fetch timeouts, mobile layout fixes, and improved demo workflow scripting (including an integration-status readout).
- Demo configuration/auth: case-insensitive
EQUISMILE_LIVE_MAPSoverride and demo-modetrustHostbehavior in Auth.js config. - UAT collateral + seed correction: add UAT persona/report templates and a browser-fillable feedback form; fix demo seed invoice → visitOutcome linkage and add tests.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/windows/README.md | Documents the Windows demo flow (Pinggy + live Google Maps) and links to runbook/UAT docs. |
| scripts/windows/DEMO.bat | Adds demo-safe Auth.js defaults, prints integration status at startup, and improves operator guidance for mobile tunnel usage. |
| public/uat-feedback.html | Adds a standalone, locally-persisted UAT feedback form with markdown export. |
| prisma/seed-demo.ts | Fixes demo-inv-001 to reference a valid, customer-aligned VisitOutcome. |
| lib/demo/demo-mode.ts | Makes EQUISMILE_LIVE_MAPS parsing case-insensitive. |
| HANDOFF.md | Adds an iPhone demo QA handoff note and known caveats. |
| docs/uat/UAT_VET_PERSONA.md | Adds the vet persona used during UAT, aligned to seeded demo fixtures. |
| docs/uat/UAT_FEEDBACK_REPORT.md | Adds a markdown-based UAT feedback template (tick-box walkthrough + findings log). |
| docs/DEMO_RUNBOOK.md | Expands the runbook with service-worker cache troubleshooting and Auth.js AUTH_SECRET troubleshooting. |
| auth.ts | Extends Auth.js trustHost behavior to include DEMO_MODE=true. |
| app/[locale]/triage/page.tsx | Removes leftover whitespace from the refactor merge. |
| app/[locale]/demo/page.tsx | Adds abort/timeouts for demo status/actions, refines mobile layout, and improves action-result rendering on small screens. |
| tests/unit/utils/task-type-label.test.ts | Adds unit coverage for taskTypeLabel’s mapping + fallback behavior. |
| tests/unit/seed.test.ts | Adds a guard test verifying the corrected invoice → outcome linkage in the demo seed file. |
| tests/integration/demo-mode.integration.test.ts | Adds integration coverage for case-insensitive EQUISMILE_LIVE_MAPS handling and ensures env/test cleanup. |
| if (sec.checks && sec.checks.length) { | ||
| html += '<ul class="checks">'; | ||
| sec.checks.forEach((c, i) => { | ||
| html += `<li><input type="checkbox" id="${sec.id}_chk${i}" data-key="${sec.id}.checks.${i}" /><span>${c}</span></li>`; |
Comment on lines
+636
to
+641
| document.getElementById('btn-export').addEventListener('click', () => { | ||
| exportText.value = buildMarkdown(); | ||
| if (typeof dlg.showModal === 'function') dlg.showModal(); | ||
| else dlg.setAttribute('open', ''); | ||
| }); | ||
| document.getElementById('dlg-close').addEventListener('click', () => dlg.close()); |
Comment on lines
+572
to
+580
| const m = state.meta || {}; | ||
| lines.push('| Field | Value |'); | ||
| lines.push('|---|---|'); | ||
| lines.push(`| Tester | ${m.tester || ''} |`); | ||
| lines.push(`| Date | ${m.date || ''} |`); | ||
| lines.push(`| Build | ${m.build || ''} |`); | ||
| lines.push(`| Device | ${m.device || ''} |`); | ||
| lines.push(`| Network | ${m.network || ''} |`); | ||
| lines.push(`| Tunnel URL | ${m.tunnel || ''} |`); |
RJK134
approved these changes
May 8, 2026
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The repo had 4 open PRs (#85, #116, #117, #118) and 6 active feature branches diverging from
main, with PR #118 declaring conflicts and PR #85 effectively superseded by a utility that landed onmainindependently. This branch merges all relevant work into one, resolves conflicts against currentmain, and de-duplicates the overlapping refactor.Merges
fix/seed-demo-invoice-fk— clean. Repointsdemo-inv-001.visitOutcomeId→demo-outcome-005(customer-aligned todemo-cust-jeanluc) and adds a seed-time guard test.feature/demo-live-maps-override— conflicts inauth.ts,lib/demo/demo-mode.ts,lib/integrations/google-maps.client.ts,docs/DEMO_RUNBOOK.md. AddsEQUISMILE_LIVE_MAPSenv override,/uat-feedback.html, AUTH_SECRET demo fallback, runbook overhaul.demo-mobile-fixes— clean. Mobile grid fix, AbortSignal timeouts (8s status / 30s actions), drops stale/api/setupPOST (endpoint is GET-only/410 in demo),HANDOFF.md.cursor/task-type-label-utility— superseded. Duplicatelib/utils/task-type-label.tsdeleted; the +7 PR tests repointed at the canonicallib/utils/triage-task-type.ts(unknown-type expectationnull→ fallback-to-raw to match main's contract); imports in dashboard/triage converged.Conflict resolutions of note
auth.tstrustHost— combined main'sAUTH_URL || VERCELwith PR feat(demo): LIVE_MAPS override, UAT feedback form, AUTH fixes, demo runbook updates #118'sDEMO_MODErequirement:Preserves Vercel-preview posture; only loosens host trust under DEMO_MODE.
lib/demo/demo-mode.ts— kept case-insensitiveEQUISMILE_LIVE_MAPS?.toLowerCase() === 'true'.docs/DEMO_RUNBOOK.md— kept main's accurate field references (checks.googleMaps.status,Pierre Rochat, full route-run yard names) and folded in PR feat(demo): LIVE_MAPS override, UAT feedback form, AUTH fixes, demo runbook updates #118's additive §4a (service-worker cache caveat) + §4b (AUTH_SECRET 500 troubleshooting) and two new failure-mode rows.app/[locale]/triage/page.tsx— removed deadtaskLabelKey != nullternaries left over from the refactor merge; the canonicaltaskTypeLabelreturnsstring.Branches with no PR
cursor/invoice-customer-outcome-mismatch-b241— sole unique commit superseded by fix(seed-demo): link demo invoice to matching outcome #117's outcome choice.cursor/live-maps-configuration-bugs-828c— sole unique commit removessetLiveMapsForced, but it's used by__tests__/integration/demo-mode.integration.test.ts. Skipped; its case-insensitive parsing change is preserved via the feat(demo): LIVE_MAPS override, UAT feedback form, AUTH fixes, demo runbook updates #118 resolution.Risk
auth.tsadds DEMO_MODE to the trustHost OR. Production (DEMO_MODE unset) is unchanged.EQUISMILE_LIVE_MAPS=trueconsumes real Google API quota; documented in.env.exampleand runbook §7.Follow-ups for the maintainer
auth.tsresolution.copilot/automate-commit-push-merge,copilot/evaluate-equismile-system,copilot/research-equismile-repo,copilot/review-gitum-login-authentication,copilot/setup-equismile-product-demo) plus the 6 consolidated above.