---
title: "First Success Validation"
description: "Founder activation smoke — signup session, Postgres CRUD, tunnel ready, optional PaymentConductor membership checkout (migration / onboarding)"
locale: "en"
---
# First Success Validation

> **Success**
> **Done when:** `npm run dev` serves pages, `GET /api/health` is `healthy` (or you fixed `AUTH_SECRET`), one Auth.js sign-in establishes a session, and one authenticated CRUD path works (entities or opportunities). Tunnel `ready` and PaymentConductor membership smoke are **extended** — not blockers for day-one branding.

> **Info**
> Filter with **Founder** / **Developer** in the docs sidebar. Run this **after** [Installation](/docs/getting-started/installation.md) and [Migrations](/docs/getting-started/migrations.md). Core checks are a short browser pass; payments need PSP env + `004_payment_transactions` before you treat checkout as green.

**First success** means the custom `server.ts` / Next app serves pages, **Auth.js v5** can establish a session, **DatabaseService** reads/writes without adapter crashes, and core marketplace routes load. It does **not** require WayForPay, Stripe, PayPal, FCM, or wallet connectivity on day one.

| Pass bar | What must work | Good enough to… |
|----------|----------------|-----------------|
| **Core** | Homepage + `/api/health` + one provider sign-in + one CRUD path | Customize branding, invite testers |
| **Extended** | `GET /api/tunnel/test` → `status: ready`; entities + opportunities UI | Demo realtime / discovery |
| **Optional payment** | Membership initiate → PaymentConductor redirect or credit settle | Sandbox checkout / role-upgrade rehearsal |

## Recommended path

Use LegioX MCP **`legiox-env-validator`** (or ask the agent with the prompt below) **before** chasing UI failures. It reports missing env — it does **not** mutate `.env`, restart processes, or call PSPs until you approve.

**Starter prompt:**

> Validate this clone for first-success smoke: `AUTH_SECRET`, `DB_BACKEND_MODE` / Postgres `DB_*`, and optional `WAYFORPAY_*` / `STRIPE_*` / `PAYPAL_*`. List missing vars and the Core vs Optional-payment checklist from `/docs/getting-started/first-success`. Do not write secrets or restart the server until I approve.

**Inputs checklist**

- Working tree after install + migrations
- `.env.local` from `env.local.template` (or k8s secret mount)
- Browser on `http://localhost:3000` (or your configured site URL)
- Optional: WayForPay / Stripe / PayPal sandbox credentials

## Manual path

### 1 — Dev server

{`npm run dev`}

Expect Next.js ready on `http://localhost:3000`. Package script runs `node --import tsx server.ts`. With `RING_DEPLOY_TARGET=self-hosted`, custom server may log native WSS.

### 2 — Health

{`curl -sS http://localhost:3000/api/health | jq .
curl -I http://localhost:3000/api/health`}

Verified shape (`app/api/health/route.ts`): `status` is `healthy` | `degraded` | `unhealthy` (not `"ok"`). `services.database` is `postgresql` or `firebase`. Missing `AUTH_SECRET` → `degraded` and HTTP **503**. `HEAD` returns **200** when the process is up.

### 3 — Homepage + sign-in

1. Open `/` — expect HTTP **200**; no blank screen or adapter crash in the terminal.
2. Visit `/login` (locale prefix may apply: `/en/login`).
3. Complete **one** provider from `auth.ts`: Google OAuth, Apple, Ring Mailer (OTP / magic link / email+password), Google One Tap, or crypto-wallet credentials. Default tree does **not** ship GitHub/Discord.
4. Confirm session: `/profile` shows user data; refresh persists. Optional: `GET /api/auth/session` with browser cookies returns `{ user: { id, email, role, … } }`.

### 4 — Authenticated CRUD

`/api/entities` and `/api/opportunities` require a session — **401 without cookies is expected**.

After browser login:

1. `/entities` — list + create form submits (visitor may 403 on write — use member/admin test account).
2. `/opportunities` — list loads for your role.

Optional Postgres check:

{`psql "$DATABASE_URL" -c "SELECT COUNT(*) FROM users;"`}

Expect count ≥ 1 after first sign-in. There is **no** `/api/test-db` route — use `psql` or authenticated APIs.

### 5 — Tunnel readiness (extended)

{`curl -sS http://localhost:3000/api/tunnel/test | jq .status, .availableProviders`}

Expect `"ready"` and a provider list from `lib/tunnel/config`. Live SSE: Network tab → `/api/tunnel/sse` after sign-in. See [Tunnel protocol](/docs/features/tunnel-protocol.md).

### 6 — PaymentConductor membership smoke (optional)

Only after [Migrations](/docs/getting-started/migrations.md) applied `004_payment_transactions.sql` and you set processor env from `env.local.template` (`WAYFORPAY_*`, and/or `STRIPE_*`, and/or `PAYPAL_*`).

1. Sign in as a non-admin user who can upgrade (`UPGRADEABLE_ROLES` — not platform-admin purchase).
2. Open `/membership` → choose a higher tier and a configured rail (`card` → WayForPay/Stripe via PaymentConductor, `paypal`, or `credit_balance` if the wallet has balance).
3. Server Action `initiateMembershipPayment` (`app/_actions/membership-payment.ts`) calls `PaymentConductor.createCheckout({ purpose: 'membership_upgrade', … })` (or SubscriptionConductor first for some rails).
4. Expect a redirect URL / form-post fields to the PSP, or an immediate success path for internal credit.
5. Canonical webhooks (production/sandbox callback URLs): `/api/payments/wayforpay/webhook`, `/api/payments/stripe/webhook`, `/api/payments/paypal/webhook` (`getWebhookUrl` in `lib/payments/payment.config.ts`).
6. After Approved / `checkout.session.completed` / PayPal capture handling, UI lands on `/membership/success` or `/membership/failure`.

Do **not** claim production checkout until HMAC/signature verification and return URLs match your public site URL. Deep dive: [PaymentConductor](/docs/features/payment-conductor.md).

### For founders

## Why this matters for your clone

Before stakeholder demos, walk the **member happy path** yourself:

  
- **[Land on the homepage](/docs/getting-started/installation.md)** — No blank screen or database-adapter crash in the terminal.

  
- **[Sign up / sign in](/docs/features/authentication.md)** — Google, Apple, or Ring Mailer — whichever you configured (SMTP or Ethereal).

  
- **[Create an entity](/docs/features/entities.md)** — Proves Postgres JSONB writes and role gates.

  
- **[Membership checkout (optional)](/docs/features/payment-conductor.md)** — Sandbox fee → PaymentConductor → webhook — only after payment env is set.

  Auth + one CRUD flow without push notifications or wallet is still a **valid dev clone**. Wire FCM and PaymentConductor before promising paid membership or store checkout ([Environment](/docs/deployment/environment.md)).

### When to stop and fix

- Repeated Postgres connection failures → [Prerequisites](/docs/getting-started/prerequisites.md) `DB_*` / `DB_BACKEND_MODE`.
- Login redirect loop → `AUTH_SECRET` and OAuth redirect URIs (`http://localhost:3000/api/auth/callback/google`).
- Entity save 403 → expected for **visitor**; sign in as **member** or raise the test account role.
- Membership initiate errors with missing merchant keys → set `WAYFORPAY_*` / Stripe / PayPal before retrying.

### For developers

## Implementation map

| Concern | Verified path |
|---------|----------------|
| Health | `app/api/health/route.ts` |
| Auth providers | `auth.ts` (Google, Apple, Ring Mailer credentials, One Tap, wallet) |
| Membership initiate | `app/_actions/membership-payment.ts` → `PaymentConductor.createCheckout` |
| Conductor | `lib/payments/conductor/payment-conductor.ts` |
| Webhooks | `app/api/payments/{wayforpay\|stripe\|paypal}/webhook/route.ts` |
| Tunnel test | `app/api/tunnel/test/route.ts` (`status: 'ready'` on success) |
| Wallet balance (optional) | `GET /api/wallet/balance` → `{ balance }` or **401** / **404** |
| Scripts | `npm run type-check`, `npm run build` (build runs type-check) |

```mermaid
flowchart LR
  Dev[npm run dev] --> Health[/api/health]
  Health --> Login[/login]
  Login --> PG[(PostgreSQL)]
  Login --> Ent[/entities CRUD]
  Login --> Opp[/opportunities]
  Login --> Tun[/api/tunnel/test]
  Login --> Mem[/membership]
  Mem --> PC[PaymentConductor]
  PC --> WH[/api/payments/.../webhook]
```

> **Warning**
> Health’s Postgres detection uses `DATABASE_BACKEND=postgresql` or `DB_HOST` / `POSTGRES_HOST` — not the string `DB_BACKEND_MODE` alone. Keep both families aligned with `env.local.template` so `services.database` reports `postgresql` when you expect it.

## Checklist summary

| Check | Pass? |
|-------|-------|
| `npm run dev` starts without DB adapter crash | ☐ |
| `GET /api/health` → `healthy` (or fixed `AUTH_SECRET`) | ☐ |
| Sign-in completes for one Auth.js provider | ☐ |
| Entity create/list **or** opportunities list works in UI | ☐ |
| `GET /api/tunnel/test` → `status: ready` | ☐ |
| Optional: membership initiate returns redirect / credit success | ☐ |

## Frequently asked questions

### Impact

#### Will my clone work without payments?

Yes. Core first success is auth + data path. PaymentConductor is optional until you demo paid membership or store checkout.

#### Does tunnel `ready` mean SSE is live?

No. `/api/tunnel/test` confirms config/provider detection. Live streams need a signed-in client hitting `/api/tunnel/sse` (or your configured provider).

### Migration

#### Do I need `004_payment_transactions` for Core?

No. Apply it before Optional payment smoke so the ledger can record membership / store intents.

#### Firebase-only prototype?

`firebase-full` can pass homepage + auth for a prototype, but PaymentConductor depth and ERP/news features expect Postgres-primary (`k8s-postgres-fcm` / `supabase-fcm`). See [Database selection](/docs/customization/database-selection.md).

### Ops

#### Health returns 503 with `degraded` — is the app down?

Process is up; missing `AUTH_SECRET` (Postgres path) or Firebase critical vars degrade status. Set secrets, restart, re-curl.

#### Wallet balance 404?

`GET /api/wallet/balance` returns **404** when no wallet row exists yet — not a Core failure. Create/top-up via wallet flows after auth.

## Related documentation

  
- [getting-started/installation](/docs/getting-started/installation.md) — Prerequisite: install and env before this smoke checklist.

  
- [getting-started/migrations](/docs/getting-started/migrations.md) — Prerequisite: schema + 004_payment_transactions before PaymentConductor smoke.

  
- [features/authentication](/docs/features/authentication.md) — Deep-dive: Auth.js providers and session shape after signup works.

  
- [features/payment-conductor](/docs/features/payment-conductor.md) — Next-step: rails, ledger, and webhooks after membership initiate succeeds.

  
- [getting-started/troubleshooting](/docs/getting-started/troubleshooting.md) — Same-workflow: auth and database fixes when a checklist row stays red.

  
- [getting-started/next-steps](/docs/getting-started/next-steps.md) — Next-step: feature exploration after Core checks are green.
