Files

6.5 KiB

Dev Login And Local Test Setup

This note tracks the development-only work added to make the app easy to run and test without a live Authentik/OIDC setup.

What Was Added

  • .env was created locally with:
    • NEXT_PUBLIC_APP_URL=http://127.0.0.1:3000
    • DATABASE_URL=postgres://famapp:famapp@localhost:5432/famapp
    • ENABLE_DEV_LOGIN=true
    • placeholder OIDC values for local-only development
  • .env.example now documents the dev-login variables:
    • ENABLE_DEV_LOGIN
    • DEV_LOGIN_EMAIL
    • DEV_LOGIN_NAME
    • DEV_HOUSEHOLD_NAME
  • src/lib/dev-login-config.ts contains Edge-safe dev-login constants and feature-flag detection.
  • src/lib/dev-login.ts creates a database-backed Auth.js session for a local dev user.
  • src/app/login/page.tsx shows a Dev login button only when:
    • NODE_ENV !== "production"
    • ENABLE_DEV_LOGIN=true
  • src/middleware.ts was changed to an Edge-safe cookie gate. It no longer imports Auth.js/Drizzle/Postgres into middleware.
  • tests/.auth/ is ignored so generated Playwright session state is never committed.
  • Playwright Chromium was installed locally.
  • tests/.auth/dev-user.json was generated locally from the Dev login flow.
  • drizzle/0005_auth_schema_repair.sql was added to repair local databases that missed the Auth.js schema migration.
  • scripts/seed.ts now exits cleanly after seeding because imported module default helpers use the shared app database client.
  • src/modules/calendar/server/actions.ts no longer calls .partial() on a refined Zod schema.
  • Calendar/list E2E locators were tightened so the suite runs against the current UI.
  • Calendar/list create buttons no longer depend on useTransition pending state for basic enablement.

Current Local Run Procedure

One command starts the database, runs migrations, seeds, and launches the dev server:

pnpm dev:local

The script prints three URLs at startup:

URL Use for
http://localhost:3000 Browser on this machine
http://192.168.x.y:3000 Phone on the same WiFi (general UI testing)
https://dev.yourdomain.com Push notifications + PWA install (needs Caddy — see below)

Then open /login and click Dev login.

HMR and restarts

next dev has hot module replacement — most .ts/.tsx changes apply instantly without a restart.

A full restart (Ctrl+Cpnpm dev:local) is needed for:

  • .env changes
  • next.config.ts changes

Clean slate

To delete all local data and start fresh (e.g. after a destructive schema change):

pnpm dev:reset

HTTPS for push notification and PWA testing (one-time setup)

Service workers and Web Push require HTTPS. The plain LAN address won't work for these. Route through the existing Caddy server on the home server instead — no extra tooling needed.

Step 1 — DHCP reservation

Set a reservation on the router so the dev machine always gets 192.168.x.y.

Step 2 — DNS record

Add a dev.yourdomain.com A record pointing to the same public IP as fam.yourdomain.com.

Step 3 — Windows Firewall

Allow inbound TCP 3000 on the dev machine (run once in an elevated PowerShell):

New-NetFirewallRule -DisplayName "famapp dev" -Direction Inbound `
  -Protocol TCP -LocalPort 3000 -Action Allow

Step 4 — Caddy snippet

Paste deploy/Caddyfile.dev.snippet into the home server Caddyfile and reload:

caddy reload --config /path/to/Caddyfile

After this, https://dev.yourdomain.com proxies to the dev machine with a real Let's Encrypt cert.

Current Local E2E Procedure

Generate auth state after starting the app:

New-Item -ItemType Directory -Force tests\.auth | Out-Null
@'
const { chromium } = require('@playwright/test');
(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('http://127.0.0.1:3000/login');
  await page.getByRole('button', { name: 'Dev login' }).click();
  await page.waitForURL('http://127.0.0.1:3000/');
  await page.context().storageState({ path: 'tests/.auth/dev-user.json' });
  await browser.close();
})();
'@ | node -

Run tests:

$env:PLAYWRIGHT_STORAGE_STATE='tests/.auth/dev-user.json'
pnpm test:e2e

After validation, tear down services started for the test run unless you are intentionally keeping the app open:

# Stop a manually started Next dev server if one is still running on port 3000.
Get-NetTCPConnection -LocalPort 3000 -State Listen -ErrorAction SilentlyContinue |
  Select-Object -ExpandProperty OwningProcess -Unique |
  ForEach-Object { Stop-Process -Id $_ }

# Stop the local database container when the session is finished.
docker compose -f docker-compose.dev.yaml down

Production Removal Plan

Before production deployment, complete the checklist below.

  • Set ENABLE_DEV_LOGIN=false in production secrets.
  • Do not copy local .env to production.
  • Confirm deploy/compose.yaml or production env files do not define:
    • ENABLE_DEV_LOGIN=true
    • DEV_LOGIN_EMAIL
    • DEV_LOGIN_NAME
    • DEV_HOUSEHOLD_NAME
  • Verify /login does not render Dev login when built with production env.
  • Verify direct POSTs to the dev login action fail because createDevSession() checks NODE_ENV !== "production" and ENABLE_DEV_LOGIN=true.
  • Delete any dev users from the production database if they were accidentally created:
    • dev@famapp.local
    • any configured DEV_LOGIN_EMAIL
  • Keep tests/.auth/ ignored and out of production artifacts.
  • Replace placeholder OIDC variables with real Authentik values:
    • AUTH_OIDC_ISSUER
    • AUTH_OIDC_CLIENT_ID
    • AUTH_OIDC_CLIENT_SECRET
  • Confirm Authentik login succeeds against the production domain.
  • Run pnpm build with production-like env before shipping.

Decision For Now

Keep the dev-login code in the repo while active module development is ongoing. It is explicitly gated by environment and avoids requiring Authentik for every local UI/E2E loop.

Before first real production deployment, decide whether to:

  • remove the dev-login code entirely, or
  • keep it behind the existing production-safe gates for future local development.

Removing it entirely is stricter. Keeping it gated is more convenient. The production blocker is not the presence of the code; it is any production environment that enables it.