platform: hello-world — the greetings wall #2
No reviewers
Labels
No labels
agent-work
agent-working
bug
ultracode
No milestone
No project
No assignees
2 participants
Notifications
Total time spent: 33 minutes 53 seconds
Due date
plat
33 minutes 53 seconds
No due date set.
Dependencies
No dependencies set.
Reference
imp-e2e-org/hello-world!2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "prime"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
hello-world was migrated from octocat/Hello-World — a repo whose entire contents are a one-line
READMEreading Hello World!. The platform integration kit (Dockerfile, chart, workflows) landed onprime, but the Dockerfile had nothing to build: nopackage.json, nosrc/, noweb/. That is why the build runs kept dying andpreviewwent red on3ce9becf0b.This PR builds the app that plumbing expects, around the one line the repo has always carried: a wall of hellos.
What changed
The app — Fastify 5 + TypeScript with TypeBox-typed routes (OpenAPI generated from them at
/openapi.json), a React 19 SPA underweb/with aweb/src/ui/component kit, biome lint, and the platform's Bun image unchanged.The wall — twelve greetings ship with it (English through Te reo Māori, inserted by a migration). Anyone can read and filter it; the composer adds a greeting; a Remove button appears only on greetings your account posted, enforced server-side.
Data — Postgres (CNPG) with numbered, append-only migrations in
src/migrate.ts, applied at boot before the pod reports ready, with a 60-second retry window for a cold cluster — matching the chart's startupProbe budget, so the chart's optional migrate Job isn't needed.Docs —
README.md, a realMIGRATION.md(what arrived, what was built, what was decided), andwiki/pages for the flows, the API and the data model.Decisions worth knowing
/api/meis anonymous for every visitor. Gating writes on a sign-in that cannot happen would have shipped an ornament. So: where a sign-in exists, posting requires it and greetings are attributed to the account; where none exists, the wall accepts anonymous greetings signed with an optional "From" name, rate-limited to 10 per IP per 10 minutes. Nothing on a wall of hellos is private, so this costs no confidentiality — and the moment a sign-in exists the app requires it again with no code change. Removing is always identity-bound, so seeded and anonymous greetings belong to nobody.preValidationhook that runs before a body is parsed. In platform mode the app verifies theX-Plat-*headers itself and fails closed whenPLAT_EDGE_TOKENis configured but absent or wrong — a forged header sent straight at the pod gets nothing./readyz(degraded: trueif Postgres was configured but unreachable). Provisioning a database later needs no code change — the migrations take over.BETTER_AUTH_SECRET. Nothing to provision, and sign-out is a cookie clear.Dockerfile,charts/app/,.forgejo/workflows/) is untouched. The original one-lineREADMEis kept as it arrived — it is the provenance, and the homepage quotes it.How verified
npm run lint,npm run typecheckandnpm run buildpass locally on every pushed commit;check/previeware green on the head commitc7cff4c;lint_designreports zero findings (all styling flows through the org token vocabulary).Playwright self-test against the live preview (
https://pr-2-hello-world-imp-e2e-org.open-platform.sh):worker-agent) and clicked Post greeting: the greeting appeared at the top of the wall immediately and the counters moved to 13. Typedwelin the filter → narrowed to Helo, byd! and Hallo, Welt!; typedzzz→ the empty state with its Clear filter button, which restored the wall.browser_console_messages: 0 messages, 0 errors.document.documentElement.scrollWidth === clientWidth === 390and no element extends past the viewport, so there is no page-level horizontal scroll. Posted a second greeting (Icelandic / Halló, heimur!) from the mobile layout — accepted and rendered. Console clean.POSTwas refused401on the earlier build (before the write rule was adapted), and the rate limiter returns429after 10 anonymous posts in the window;DELETEwithout an account is401, someone else's greeting is403, a missing id is404; forgedX-Plat-Userheaders without the edge token leave/api/meanonymous.Preview: https://pr-2-hello-world-imp-e2e-org.open-platform.sh
⚠️ The build run crashed (exit code null). What's pushed here is as far as it got — re-creating the repo retries from scratch, or label this PR
agent-workto have an agent pick it up.⚠️ The build run crashed (exit code null). What's pushed here is as far as it got — re-creating the repo retries from scratch, or label this PR
agent-workto have an agent pick it up.⚠️ The build run crashed (exit code null). What's pushed here is as far as it got — re-creating the repo retries from scratch, or label this PR
agent-workto have an agent pick it up.🏗️ platform: hello-worldto platform: hello-world🤖 The build was interrupted repeatedly — handing what exists to the validator; label
agent-workto continue building.🔴 CI run
previewfailed on3ce9becf0b— queuing an agent to look (addedagent-work).platform: hello-worldto 🏗️ platform: hello-world🔄 worker working… #2 · 33m elapsed · 22+ steps
last action:
mcp__plat__update_issueLive progress — updates while the agent runs; replaced by the final summary on completion.
🔎 Preview is live for QA: https://pr-2-hello-world-imp-e2e-org.open-platform.sh
🏗️ platform: hello-worldto platform: hello-world — the greetings wallIntegration done — this PR (#2, branch
prime) now carries the whole app, and the live preview is up:https://pr-2-hello-world-imp-e2e-org.open-platform.sh
What shipped
The migrated repo was a one-line
READMEand nothing else, so the platform Dockerfile had nothing to build — that is what kept killing the build runs and turnedpreviewred on3ce9becf0b. It now builds a real app around that line: a wall of hellos. Fastify 5 + TypeBox routes with OpenAPI generated from them, a React SPA with aweb/src/ui/kit styled only in org design tokens, Postgres migrations insrc/migrate.tsthat seed twelve greetings, and a volume-backed fallback so the app still serves where no database was provisioned (as here —/readyzsays which store answered).Two judgement calls worth your attention, both in the PR body: posting is open on this deployment because it has no sign-in anyone could use (the forwardAuth edge is off org-wide), rate-limited per IP, and re-gates itself automatically the moment a sign-in exists; and removing is always account-bound, so the seeded and anonymous greetings belong to nobody.
How it was verified
lint,typecheck,buildgreen locally;check/previewgreen on71ea612;lint_designclean. Then I drove the preview with Playwright: posted a greeting at desktop width (it appeared instantly, counters moved), filtered the wall down and into its empty state and back, then re-drove it at 390×844 and posted a second greeting from the mobile layout — no page-level horizontal scroll, zero console messages. Both greetings survived the next redeploy.Next steps
add the
agent-worklabel to any of these to have an agent build it.