Improve map fallback and verification evidence
Some checks are pending
Quality / full-local-gates (push) Waiting to run
Some checks are pending
Quality / full-local-gates (push) Waiting to run
This commit is contained in:
parent
811ddf4c5c
commit
3c37895969
|
|
@ -176,6 +176,108 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.home-demo-map-fallback {
|
||||
position: relative;
|
||||
display: grid;
|
||||
min-height: inherit;
|
||||
align-content: end;
|
||||
padding: 5.75rem 1.25rem 1.25rem;
|
||||
background:
|
||||
linear-gradient(32deg, transparent 47%, color-mix(in oklab, var(--color-base-content) 14%, transparent) 48% 51%, transparent 52%),
|
||||
linear-gradient(148deg, transparent 42%, color-mix(in oklab, var(--color-base-content) 10%, transparent) 43% 46%, transparent 47%),
|
||||
radial-gradient(circle at 28% 22%, color-mix(in oklab, var(--color-success) 18%, transparent) 0 12%, transparent 13%),
|
||||
radial-gradient(circle at 78% 38%, color-mix(in oklab, var(--color-error) 14%, transparent) 0 10%, transparent 11%),
|
||||
color-mix(in oklab, var(--color-base-200) 86%, var(--color-success) 14%);
|
||||
}
|
||||
|
||||
.home-demo-map-fallback::before {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
content: "";
|
||||
opacity: 0.28;
|
||||
background-image:
|
||||
linear-gradient(color-mix(in oklab, var(--color-base-content) 16%, transparent) 1px, transparent 1px),
|
||||
linear-gradient(90deg, color-mix(in oklab, var(--color-base-content) 16%, transparent) 1px, transparent 1px);
|
||||
background-size: 3.25rem 3.25rem;
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-note {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
max-width: 32rem;
|
||||
margin: 0 0 0.75rem;
|
||||
padding: 0.625rem 0.875rem;
|
||||
border: 1px solid color-mix(in oklab, var(--color-base-content) 12%, transparent);
|
||||
border-radius: 1rem;
|
||||
background: color-mix(in oklab, var(--color-base-100) 94%, transparent);
|
||||
color: color-mix(in oklab, var(--color-base-content) 72%, transparent);
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.35;
|
||||
box-shadow: 0 0.5rem 1.5rem rgb(23 37 31 / 0.08);
|
||||
backdrop-filter: blur(0.5rem);
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-points {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
gap: 0.625rem;
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-point {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
width: min(100%, 23rem);
|
||||
padding: 0.625rem 0.75rem;
|
||||
border: 1px solid color-mix(in oklab, var(--color-base-content) 12%, transparent);
|
||||
border-radius: 1rem;
|
||||
background: color-mix(in oklab, var(--color-base-100) 96%, transparent);
|
||||
box-shadow: 0 0.75rem 2rem rgb(23 37 31 / 0.11);
|
||||
backdrop-filter: blur(0.5rem);
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-point:nth-child(2) {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-marker {
|
||||
display: grid;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border: 0.2rem solid var(--color-base-100);
|
||||
border-radius: 9999px;
|
||||
background: var(--color-success);
|
||||
color: var(--color-success-content);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 900;
|
||||
box-shadow: 0 0.25rem 0.75rem rgb(23 37 31 / 0.18);
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.125rem;
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-copy strong,
|
||||
.home-demo-map-fallback-copy small {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-copy strong {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.home-demo-map-fallback-copy small {
|
||||
color: color-mix(in oklab, var(--color-base-content) 62%, transparent);
|
||||
font-size: 0.6875rem;
|
||||
}
|
||||
|
||||
@keyframes home-map-spin {
|
||||
to {
|
||||
transform: translate(-50%, -50%) rotate(360deg);
|
||||
|
|
|
|||
|
|
@ -51,11 +51,52 @@ const createAidMap = element => {
|
|||
state.element.dataset.mapUnavailable = "true"
|
||||
state.markReady()
|
||||
|
||||
if (state.element.dataset.demoMap !== "true") {
|
||||
const fallback = document.createElement("p")
|
||||
fallback.className = "grid h-full place-items-center p-6 text-center text-sm"
|
||||
fallback.dataset.mapFallback = "true"
|
||||
fallback.textContent = state.element.dataset.mapUnavailableLabel
|
||||
state.element.replaceChildren(fallback)
|
||||
return
|
||||
}
|
||||
|
||||
const fallback = document.createElement("div")
|
||||
fallback.className = "home-demo-map-fallback"
|
||||
fallback.dataset.mapFallback = "true"
|
||||
|
||||
const note = document.createElement("p")
|
||||
note.className = "home-demo-map-fallback-note"
|
||||
note.textContent = state.element.dataset.mapUnavailableLabel
|
||||
fallback.append(note)
|
||||
|
||||
const points = document.createElement("div")
|
||||
points.className = "home-demo-map-fallback-points"
|
||||
|
||||
markerPoints(state.element).forEach((point, index) => {
|
||||
const item = document.createElement("div")
|
||||
item.className = "home-demo-map-fallback-point"
|
||||
|
||||
const marker = document.createElement("span")
|
||||
marker.className = "home-demo-map-fallback-marker"
|
||||
marker.setAttribute("aria-hidden", "true")
|
||||
marker.textContent = String(index + 1)
|
||||
|
||||
const copy = document.createElement("span")
|
||||
copy.className = "home-demo-map-fallback-copy"
|
||||
|
||||
const title = document.createElement("strong")
|
||||
title.textContent = point.title || ""
|
||||
|
||||
const location = document.createElement("small")
|
||||
location.textContent = point.location || ""
|
||||
|
||||
copy.append(title, location)
|
||||
item.append(marker, copy)
|
||||
points.append(item)
|
||||
})
|
||||
|
||||
fallback.append(points)
|
||||
state.element.replaceChildren(fallback)
|
||||
}
|
||||
|
||||
state.renderMarkers = () => {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ results from product limits and unknown production properties.
|
|||
| Consent-driven live tracking | Implemented and cross-client verified | On API 37, Android started `TrackingService` as a location foreground service with a persistent Stop notification. After Home minimized the Activity, an emulator coordinate change reached PostGIS. Notification Stop removed the service, notification, active session, and raw position. | Browsers stop with the page. Android has no `ACCESS_BACKGROUND_LOCATION`, unattended start, or route history. |
|
||||
| Privacy settings | Implemented and browser-verified | The profile exposed hidden, approximate public, exact for active match, and explicit exact-public options. Blocking and current-position cleanup have automated tests. | Exact public location remains a user opt-in; legal privacy and retention text still requires jurisdiction-specific review before launch. |
|
||||
| Reputation and anti-abuse | Implemented at MVP level | Handover codes, two-party completion, double-blind reviews, unique-counterpart ranking, optional movement/proximity evidence, reports, blocks, abuse signals, and moderator audit paths have automated tests. | The system is not bot-proof and does not claim identity verification. No punitive numeric policy is enabled without measured and approved thresholds. |
|
||||
| Account registration and sign-in | Implemented and browser-verified | Email registration sends a confirmation magic link and does not require a password. Confirmed users can keep using magic links or add a password in settings. Google OpenID Connect registration, sign-in, link, unlink, replay prevention, verified-email enforcement, and account-ownership rules are covered by the 260-test suite. A headed Chrome run completed registration, confirmation through Mailpit, password setup, logout, password login, and localized settings with zero console warnings or errors. | The local Compose environment captures email in Mailpit. A production SMTP relay and a real Google Web client are not configured or externally verified. |
|
||||
| Account registration and sign-in | Implemented and browser-verified | Email registration sends a confirmation magic link and does not require a password. Confirmed users can keep using magic links or add a password in settings. Google OpenID Connect registration, sign-in, link, unlink, replay prevention, verified-email enforcement, and account-ownership rules are covered by the 285-test suite. A headed Chrome run against the public test domain created a new account through the real Google provider, stored one confirmed/terms-accepted user and one Google identity, logged out, and logged back in without a second completion step or duplicate row. The same account then completed the isolated Mailpit magic-link flow; the one-time login token was consumed and only a session token remained. | Test email is deliberately captured in its own Mailpit. A production UniSender delivery-format message reached Gmail, but a real production authentication email and the production Google callback remain unexercised until the tested release is explicitly promoted. |
|
||||
| Social profiles | Manual links implemented; optional GitHub verification implemented and automated-tested | Manual links cannot set verification fields. The optional GitHub flow uses state, PKCE, a user-bound one-time session, unique provider ownership, and an audit record. The local protocol drill also performs real HTTP token/user exchanges without returning an access token to the application. | GitHub OAuth credentials are intentionally absent and are not required for registration or the help flow. The real external provider redirect/callback remains disabled and unverified; other providers remain manual/unverified. |
|
||||
| Support and content removal | Implemented and browser-verified | Public support, account deletion, general removal, and TAKE IT DOWN forms create separate audited queues; private email status links verify public contacts; authenticated submissions use the account email; moderator-only operations can update status and notify verified contacts. TAKE IT DOWN accepts URLs/text only and records a 48-hour review due time. | The current product hosts no user media and does not claim TAKE IT DOWN coverage. Staffing, jurisdiction-specific legal classification, final retention rules, actual account erasure/export, and identical-media-copy handling remain operational/legal work. |
|
||||
| Voluntary thanks | Implemented as an external optional link | A helper can expose an optional link after completion; the UI states that the platform does not process the payment. | The platform does not provide payments, escrow, refunds, tax reporting, or payment guarantees. |
|
||||
|
|
@ -24,10 +24,31 @@ results from product limits and unknown production properties.
|
|||
| Multiple web/worker instances | Implemented and locally failure/rollout-verified | The final isolated Compose drill passed BEAM crashes and sequential replacement with 3 web/2 worker replicas: all five nodes joined, PubSub passed, and 744/744 readiness requests succeeded. The project-owned kind cluster replaced all 2 web/2 worker pod UIDs under `maxUnavailable=0`; all four replacement pods joined, PubSub passed, and 363/363 samples ultimately succeeded. | Local PostGIS is a single instance. Production database HA, backups, and recovery are operator work and are not claimed complete. |
|
||||
| Local observability | Implemented and protocol-verified | Pinned Prometheus scraped the exact 3 web and 2 worker targets with a file Bearer credential; Grafana provisioned a healthy datasource and ten-panel web/worker/BEAM/Ecto/Oban dashboard; Alertmanager delivered firing and resolved webhooks for an induced scoped replica stop. | Local delivery does not establish production retention, notification-provider reliability, on-call policy, or measured alert thresholds. |
|
||||
| Encrypted local backup | Implemented and failure-verified | Pinned Restic streamed PostgreSQL custom format into pinned local MinIO with no host plaintext dump, passed full-data checking and a fresh-database restore, rejected a corrupted repository, and published no snapshot for an interrupted upload. The one-run MinIO project and volume were removed after retaining the non-secret evidence. | The drill proves the local mechanism, not off-site durability, database HA, or a production RPO/RTO/retention policy. |
|
||||
| External protocol boundaries | Implemented and locally failure-verified | The production release used its configured Assent/Req and Swoosh/gen_smtp clients against internal-only mocks. GitHub OAuth, Google OIDC discovery/authorization/token/JWKS with nonce and PKCE, and SMTP success/rejection/retry/replay/timeout paths passed. The HTTP push boundary passed disabled, retry, rejection, timeout, and idempotency paths. Request acceptance and new-chat transactions created durable jobs processed by two Oban worker replicas; the chat event completed on Oban attempt 2 after an injected temporary failure. | This does not verify real external provider availability or device delivery. Google/GitHub production clients, production SMTP, FCM/APNs token registration, and provider selection remain external work; SMTP exactly-once delivery is not claimed. |
|
||||
| External protocol boundaries | Implemented and locally failure-verified | The production release used its configured Assent/Req and Swoosh/gen_smtp clients against internal-only mocks. GitHub OAuth, Google OIDC discovery/authorization/token/JWKS with nonce and PKCE, and SMTP success/rejection/retry/replay/timeout paths passed. The HTTP push boundary passed disabled, retry, rejection, timeout, and idempotency paths. Request acceptance and new-chat transactions created durable jobs processed by two Oban worker replicas; the chat event completed on Oban attempt 2 after an injected temporary failure. A separate public test-domain run exercised the real Google OIDC provider, and a production UniSender Go delivery-format message reached Gmail. | The real GitHub provider, the production Google callback, production authentication-email delivery, FCM/APNs token registration, and device delivery remain unverified. SMTP exactly-once delivery is not claimed. |
|
||||
|
||||
## Reproducible checks
|
||||
|
||||
- On 2026-07-21, commit `811ddf4c5c3847fbb0c2861e6e72fcd6a9bd91fe`
|
||||
was deployed only to `https://test.whoneedhelp.com`. Headed Chrome attached to
|
||||
the user's existing dev-port profile completed real Google authorization,
|
||||
one-time account creation, logout, and returning-user Google login. Browser
|
||||
console inspection reported zero errors and zero warnings for the app flow.
|
||||
Read-only PostgreSQL checks observed exactly `1 user / 1 Google identity / 0
|
||||
duplicate provider UIDs`; the user was confirmed, had accepted terms, and
|
||||
had no password. A subsequent email magic-link was delivered to the isolated
|
||||
test Mailpit, required an explicit confirmation POST, signed the same user
|
||||
in, and left `0` reusable `login` tokens and `1` active `session` token.
|
||||
Application logs recorded only the expected 200/302 responses for those
|
||||
paths. Production remained on commit
|
||||
`4f2a9aaacc8eca606f3287df5c8663be49f9595b` during this verification.
|
||||
- A separate non-authentication production delivery-format check was accepted
|
||||
by UniSender Go and observed in Gmail from
|
||||
`Who Need Help <contact@whoneedhelp.com>`. The intended HTTPS test-domain
|
||||
link remained the link's actual destination because link tracking was
|
||||
disabled. UniSender appended its sender attribution and an unsubscribe link
|
||||
on `email.whoneedhelp.com`; this provider-added footer was observed rather
|
||||
than inferred. No account or application database row was created by that
|
||||
delivery check.
|
||||
- On 2026-07-21, `./scripts/test.sh` and the Dockerized `mix precommit` each
|
||||
passed 273 tests after the support/content-removal implementation. The full
|
||||
isolated `./scripts/quality.sh` gate passed compiler, xref, Credo, Sobelow,
|
||||
|
|
@ -50,10 +71,11 @@ results from product limits and unknown production properties.
|
|||
checks. It passed together with GitHub OAuth, SMTP, push, and two-worker Oban
|
||||
paths. Evidence is retained at
|
||||
`output/external-boundaries/google-auth-fixed-20260720`.
|
||||
- Headed Chrome verified the public temporary HTTPS origin through the
|
||||
- In an earlier isolated local run, headed Chrome verified the temporary HTTPS
|
||||
origin through the
|
||||
email-only registration form, Mailpit confirmation link, one-time login,
|
||||
password creation, logout, password login, Russian locale selection, and
|
||||
Google connection settings. The configured Google credential pair is empty,
|
||||
Google connection settings. That run's Google credential pair was empty,
|
||||
so the UI correctly left Google actions disabled. Browser console inspection
|
||||
reported zero errors and zero warnings. The run-owned account and its one
|
||||
cascading login token were removed after read-only relationship checks; no
|
||||
|
|
@ -1138,9 +1160,11 @@ availability, or target-server capacity.
|
|||
|
||||
## Known work before a public production launch
|
||||
|
||||
- Replace the temporary staging origin with the production-owned domain and
|
||||
production infrastructure. The temporary origin is available only while the
|
||||
workstation, Compose stack, VPN path, gateway, and their networks are up.
|
||||
- Promote the tested release from `test.whoneedhelp.com` to the independent
|
||||
production project only after explicit approval. Recheck the production
|
||||
health endpoints, migrations, Google callback, and authentication-email flow
|
||||
after that promotion; the current test origin still depends on its configured
|
||||
workstation/VPN/gateway path.
|
||||
- Confirm the final Android application ID before creating its Play Console
|
||||
listing, publish `/.well-known/assetlinks.json` for that ID and the final
|
||||
signing fingerprint if verified App Links are wanted, and complete store
|
||||
|
|
@ -1151,9 +1175,10 @@ availability, or target-server capacity.
|
|||
- After provider approval, verify that delivered MIME contains neither open nor
|
||||
link tracking and omits the unsubscribe block, then exercise registration and
|
||||
magic-link delivery through the deployed application to a real mailbox.
|
||||
- Deploy the already configured production and staging Google OAuth clients,
|
||||
then exercise registration, sign-in, and settings linking against Google on
|
||||
their exact HTTPS callback origins.
|
||||
- Exercise registration, sign-in, and settings linking against the production
|
||||
Google OAuth client on its exact HTTPS callback origin after the tested
|
||||
release is explicitly promoted. The test client and callback have already
|
||||
completed real registration and returning-user login.
|
||||
- Configure and verify a real mobile push provider and device-token lifecycle
|
||||
if native push is required. The provider-neutral HTTP boundary and product
|
||||
jobs are tested; FCM/APNs device delivery is not.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user