OpenAI Build Week mutual-aid app for urgent local voluntary help. https://test.whoneedhelp.com
Go to file
2026-07-18 17:52:41 +03:00
android feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
assets feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
config fix: use rotated database credentials in tests 2026-07-18 17:52:41 +03:00
deploy feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
docs feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
lib chore: move deployment settings into environment 2026-07-18 17:16:28 +03:00
priv feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
rel feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
scripts fix: use rotated database credentials in tests 2026-07-18 17:52:41 +03:00
test feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
.dockerignore feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
.env.example security: rotate local deployment secrets safely 2026-07-18 17:21:42 +03:00
.formatter.exs feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
.gitattributes feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
.gitignore feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
compose.yaml chore: move deployment settings into environment 2026-07-18 17:16:28 +03:00
Dockerfile feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
mix.exs feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
mix.lock feat: implement Who Need Help MVP 2026-07-18 16:52:16 +03:00
README.md security: rotate local deployment secrets safely 2026-07-18 17:21:42 +03:00

Who Need Help

Who Need Help is a working mutual-aid MVP for urgent, local, voluntary help. The first supported scenario is pickup and delivery of a legal medicine that has already been purchased or reserved.

It is not an emergency or medical service, does not prescribe or sell medicine, and does not process payments. A helper may publish an optional external thank-you link; money goes directly between users outside the platform.

What is implemented

  • Phoenix 1.8 LiveView application with email magic-link/password auth and 18+ self-attestation.
  • Data-driven, translated category tree with validated per-category fields, community proposals/votes, and human approve/reject/merge tools.
  • Request lifecycle: open → matched → in_progress → completed, plus cancel and expiry paths.
  • PostgreSQL/PostGIS locations, MapLibre map, private matched chat, Phoenix PubSub/Presence, and optional foreground-only location sharing.
  • Handover code plus both-party confirmation before verified completion.
  • Double-blind reviews, public trust summaries, and a helper leaderboard that prioritizes unique location-supported and handover-verified counterparts before raw totals.
  • Bidirectional discovery blocks, scoped reports, account/request/category moderation, abuse-signal review, and audited moderator access to only the conversation linked by a report.
  • Optional GPS evidence derived from browser accuracy envelopes. Raw current positions are deleted on stop, terminal match state, or participant block.
  • PostgreSQL-backed cross-replica action-limit policies configured by the operator. No unapproved numeric thresholds are enabled by default.
  • Public manual social links, always marked unverified in this MVP.
  • EN/UK/RU UI foundation and installable PWA metadata/service worker.
  • Native Android WebView client with the same authenticated LiveView, map, private chat, and foreground geolocation flows. The reproducible Docker target currently exports a debug APK; production signing and store publication are not configured.
  • Local, advisory Codex category review through the user's ChatGPT-authenticated Codex CLI. It receives a PII-free export and never writes to the database.
  • One immutable release image with web, worker, and one-shot migrate roles.
  • Docker Compose and Helm/kind deployment paths with 2 web and 2 worker replicas by default.

OAuth social verification, public coffee/cinema/hiking activities, background tracking, platform payments, production Android signing/store publication, iOS, automatic punitive fraud decisions, and jurisdiction-specific public-launch policies are deliberately not claimed as complete.

Fast start with Docker Compose

Prerequisite: Docker with the Compose plugin.

./scripts/compose-up.sh

Open:

Compose starts Traefik, PostGIS, Mailpit, a migration runner, 2 web replicas, and 2 Oban worker replicas. It waits for readiness and verifies a PubSub message broadcast from a different BEAM node. Registration emails appear in Mailpit.

Inspect the exact state:

docker compose -p who_need_help ps -a
docker compose -p who_need_help logs -f web worker
./scripts/verify-realtime-cluster.sh compose

Local defaults are intentionally limited to local development. Copy .env.example to .env and replace every secret before any public deployment. Generate independent values with mix phx.gen.secret; do not reuse the session secret as the BEAM cookie or handover secret. External Helm deployments must set app.host, app.scheme, and app.urlPort to the public URL used in email links, and must set app.mapTileUrl to a tile service whose policy and capacity fit the deployment.

Rotate all local application secrets and the existing local PostgreSQL role without printing the generated values:

./scripts/rotate-local-secrets.sh
docker compose up -d --wait

This preserves the named PostgreSQL volume, but invalidates existing browser sessions and changes handover codes for active local requests.

Tests

The reproducible test command builds a dedicated test target and uses the project's PostGIS service:

./scripts/test.sh

It creates/updates only the project-scoped who_need_help_test database.

First administrator

Register and confirm the first account, then explicitly bootstrap it:

./scripts/bootstrap-admin.sh you@example.com --confirm

This succeeds only while no administrator exists and writes an audit event. After bootstrap, an administrator can manage roles in /moderation; the last administrator cannot demote themselves. For kind, append kind:

./scripts/bootstrap-admin.sh you@example.com --confirm kind

Optional shared action limits

RATE_LIMIT_POLICIES_JSON configures atomic PostgreSQL counters shared by every web replica. Its shape is:

{"action_name":{"limit":"POSITIVE_INTEGER","window_seconds":"POSITIVE_INTEGER"}}

The strings above describe the required types and are not a runnable policy. Keep {} until numeric limits have been approved from policy and observed traffic. Supported actions are listed in docs/trust-safety.md.

Local Kubernetes verification

The kind script downloads checksum-verified kubectl, Helm, and kind binaries into .tools/, creates a project-owned cluster, loads the local image, and installs the Helm chart, waits for both Deployments, and verifies cross-node PubSub:

./scripts/kind-up.sh

Open:

The script refuses to modify a pre-existing cluster named who-need-help unless the project ownership marker exists.

For an external cluster, provide a real PostgreSQL/PostGIS service and a pre-created Secret through existingSecret. The chart intentionally has no invented CPU/RAM limits or HPA thresholds; measure this application in the target environment before setting them.

Local Codex category review

Export the redacted proposals from a running release:

docker compose -p who_need_help exec -T web \
  /app/bin/who_need_help eval \
  'WhoNeedHelp.CatalogModeration.export_open_proposals() |> IO.puts()' \
  > proposals.json

Then run the advisory review:

./scripts/codex-review-categories.sh proposals.json recommendations.json

The script exits unless codex login status is exactly Logged in using ChatGPT. It uses no OpenAI API key, no usage-based API billing, and no fallback provider. Recommendations require a human moderator action.

Design documentation

Exact dependency versions are locked in mix.lock, assets/package-lock.json, the Dockerfile, Compose file, and tool bootstrap script.