Containerise for Dokploy, and a demo login that survives production
Everything needed to build and run this on Dokploy at linkdr.serfaty.site, plus the two things that turned out to be broken the moment it left a laptop. The build did not work in a container at all. `lib/auth.ts` throws when AUTH_SECRET or NEXT_PUBLIC_APP_URL is missing — correct at boot, wrong during `next build`, which imports every route module with NODE_ENV=production and none of the runtime secrets. The only way past it was baking a session key into an image layer, which is worse than the problem the guard exists to prevent. Both checks now skip NEXT_PHASE=phase-production-build and still fire on a real boot. Corepack in node:22.12-alpine ships expired npm registry signing keys and dies before it can download pnpm, so the image installs corepack first and prepares the pinned version explicitly. The image is the standalone trace, which needs outputFileTracingRoot at the REPO root: pnpm hoists to a root .pnpm store and tracing from apps/web silently omits every workspace package. 427MB, runs as non-root, and its healthcheck talks to Postgres — a container that cannot reach its database must never enter rotation, because a deploy that goes green and then 500s does not roll back. DEMO_LOGIN is a login bypass under NODE_ENV=production and there is no honest way to describe it otherwise. It is a separate variable from ALLOW_DEV_LOGIN so that copying a dev .env into a real environment cannot enable it by accident, it still only affects the one seeded number, and it prints a boot warning every single start so it cannot be forgotten. That deployment holds nothing but fixtures. It comes out before the platform sees a real signup. Also: /api/health, and next/image hosts corrected to the Spaces bucket rather than the R2 one this stopped using. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -458,6 +458,35 @@ A "use my current location" control sits below, and on success **must** fill the
|
||||
reverse-geocoded label — a button that silently sets an invisible pin gives the user nothing to
|
||||
check.
|
||||
|
||||
### 6.17 Join as a pro
|
||||
|
||||
The one screen in this product that has to sell something, written under a system that bans
|
||||
marketing heroes and feature grids (§9). The resolution is that it does not describe the
|
||||
offer — it **shows the thing being offered**, then asks for an account.
|
||||
|
||||
Order is fixed:
|
||||
|
||||
1. `overline` kicker, `h1`, one sentence. No stat bar, no logo wall.
|
||||
2. **The preview.** A non-interactive replica of an incoming job request, exactly as a pro
|
||||
would receive it: trade, title, distance, urgency, budget, and the accept/decline pair.
|
||||
It is the single raised element on the screen (§5) and it carries `aria-hidden`, because a
|
||||
sample is not a control — a screen reader offering a fake Accept button is a trap.
|
||||
Label it in visible text as an example; a mock that reads as live data is a lie.
|
||||
3. **How it works** — an ordered list, three items, numeral in a `brand-500` pill. An ordered
|
||||
list, not a grid: these are sequential, and a grid would both break §4 and imply they are not.
|
||||
4. **What you will need** — the credentials `pro.submitForReview` actually gates on, with the
|
||||
same required/optional split the wizard uses. Softening it here to raise sign-ups only moves
|
||||
the drop-off to step four, where the person has already spent their time.
|
||||
5. The primary action, sticky at the bottom (§9).
|
||||
|
||||
Every claim on this screen is load-bearing and must be traceable to behaviour that exists.
|
||||
"We verify ID, insurance and licence" is true; a response time or an earnings figure is not,
|
||||
and neither is a setup duration nobody has measured. Invent nothing here.
|
||||
|
||||
The account note is required, not decorative: `user.setRole` refuses once a job has been
|
||||
posted, so a customer tapping this is creating a *second* account. A screen that lets them
|
||||
believe otherwise produces a support ticket at the worst possible moment.
|
||||
|
||||
---
|
||||
|
||||
## 7. Motion
|
||||
|
||||
Reference in New Issue
Block a user