Implement lists module and dev login setup
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# 0002 - List Realtime Uses Postgres Notify And SSE
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
The lists module needs updates from another signed-in household member to appear without a refresh. The app already plans to use Postgres `LISTEN/NOTIFY` bridged to Server-Sent Events for small-scale realtime.
|
||||
|
||||
## Decision
|
||||
|
||||
Each list has a Postgres notification channel named `list:<listId>`. List mutations call `pg_notify` after the database write. The route handler at `/api/lists/[id]/events` verifies the current household can access the list, listens on that one channel, and streams notifications as SSE messages.
|
||||
|
||||
Clients keep one `EventSource` open for the current list. On any message, they reload the list through the existing household-gated query path.
|
||||
|
||||
## Consequences
|
||||
|
||||
This keeps realtime scoped to the module and avoids a separate WebSocket service. The client refreshes the whole list after a notification, which is simple and acceptable for household-sized lists. If future modules need the same pattern, they can use their own entity-scoped channels and SSE route handlers without changing core registries.
|
||||
@@ -0,0 +1,112 @@
|
||||
# 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.
|
||||
|
||||
## Related Fixes Found While Enabling Testing
|
||||
|
||||
- `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
|
||||
|
||||
```powershell
|
||||
docker compose -f docker-compose.dev.yaml up -d
|
||||
pnpm db:migrate
|
||||
pnpm db:seed
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Then open:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:3000/login
|
||||
```
|
||||
|
||||
Click **Dev login**.
|
||||
|
||||
## Current Local E2E Procedure
|
||||
|
||||
Generate auth state after starting the app:
|
||||
|
||||
```powershell
|
||||
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:
|
||||
|
||||
```powershell
|
||||
$env:PLAYWRIGHT_STORAGE_STATE='tests/.auth/dev-user.json'
|
||||
pnpm test:e2e
|
||||
```
|
||||
|
||||
## 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.
|
||||
@@ -0,0 +1,47 @@
|
||||
# 09 — Production dev-login removal gate
|
||||
|
||||
## Goal
|
||||
|
||||
Before the first production deployment, verify that development-only login/test shortcuts cannot be enabled accidentally in production.
|
||||
|
||||
## Depends on
|
||||
|
||||
- 06
|
||||
- 07
|
||||
- local dev-login setup in `docs/dev-login.md`
|
||||
|
||||
## Scope
|
||||
|
||||
- Review all production env sources:
|
||||
- `.env.production.example`
|
||||
- `deploy/compose.yaml`
|
||||
- any host-level Docker Compose override files
|
||||
- deployment secrets on the server
|
||||
- Confirm production does not set:
|
||||
- `ENABLE_DEV_LOGIN=true`
|
||||
- `DEV_LOGIN_EMAIL`
|
||||
- `DEV_LOGIN_NAME`
|
||||
- `DEV_HOUSEHOLD_NAME`
|
||||
- Confirm production Authentik variables are real:
|
||||
- `AUTH_OIDC_ISSUER`
|
||||
- `AUTH_OIDC_CLIENT_ID`
|
||||
- `AUTH_OIDC_CLIENT_SECRET`
|
||||
- Build with production-like env and verify `/login` renders only the SSO login path.
|
||||
- Verify the app still protects private routes without a valid Auth.js session cookie.
|
||||
- Verify real Authentik login creates the expected user, household membership, default calendars, and default lists.
|
||||
- Remove any accidental dev users from the production database.
|
||||
|
||||
## Optional hardening
|
||||
|
||||
- Remove `src/lib/dev-login.ts` and the Dev login form from `src/app/login/page.tsx` entirely before first production deployment.
|
||||
- If retaining the code for future local development, keep the current double gate:
|
||||
- `NODE_ENV !== "production"`
|
||||
- `ENABLE_DEV_LOGIN=true`
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] Production env cannot enable Dev login accidentally.
|
||||
- [ ] `/login` in production does not show **Dev login**.
|
||||
- [ ] Direct dev-login action execution is unavailable in production.
|
||||
- [ ] Real Authentik login works on the production domain.
|
||||
- [ ] No `dev@famapp.local` or configured dev-login user exists in production data.
|
||||
Reference in New Issue
Block a user