mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
The measured first-load gap on / was never the server: FCP painted the SSR shell at ~1.8 s but LCP landed at ~5.5 s (mobile-throttled) because the tiles waited for JS download + hydrate + a CLIENT-side snapshot fetch — while /api/dashboard/snapshot answers in ~8 ms server-side. src/app/page.tsx is now a thin RSC wrapper: it runs the same cached snapshot read the API route uses (extracted to src/lib/dashboard/snapshot-read.ts, one shared SWR cell for both readers) and hands the result to TanStack via HydrationBoundary + dehydrate, so the first HTML carries real tile data and the mounted cell starts warm (staleTime 60 s, refetchOnMount false — no double fetch). Query keys come only from the central factory (dashboardSnapshot(locale) + the dashboardWidgets seed the client cell already performs); the payload is JSON-round-tripped so the hydrated shape is byte-equal to the wire shape. Fail-soft: no session or any builder error renders the page exactly as before. The 1,727-line client page moves unchanged to src/app/page-client.tsx; no component-tree rewrite. Companion: the documented bundle tooling was dead on Turbopack (ANALYZE=1 silent no-op, bundle-report read a webpack-only JSON), so H2/H3-class regressions shipped invisibly. scripts/check-bundle-budget.mjs derives per-route gzip totals from the Turbopack client-reference manifests + rootMainFiles, prints the report (pnpm bundle-report), and enforces bundle-budget.json (pnpm bundle-check): per-route caps, total-client-JS cap, a recharts-duplication guard (fingerprint count must stay 1), and a catalog guard (no message catalog referenced by any route manifest). Wired into the existing e2e workflow after next build. H4
93 lines
2.8 KiB
YAML
93 lines
2.8 KiB
YAML
name: e2e
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
push:
|
|
branches: [main]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
# Cancel in-progress runs when a new commit lands on the same PR.
|
|
concurrency:
|
|
group: e2e-${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
e2e:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
env:
|
|
POSTGRES_USER: healthlog
|
|
POSTGRES_PASSWORD: healthlog
|
|
POSTGRES_DB: healthlog
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U healthlog"
|
|
--health-interval 5s
|
|
--health-timeout 5s
|
|
--health-retries 10
|
|
|
|
env:
|
|
DATABASE_URL: postgresql://healthlog:healthlog@localhost:5432/healthlog?schema=public
|
|
ENCRYPTION_KEYS: '{"v1":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}'
|
|
ENCRYPTION_ACTIVE_KEY_ID: v1
|
|
API_TOKEN_HMAC_KEY: ci-hmac-key-32-bytes-min-padding-x
|
|
AUTH_RP_NAME: HealthLog
|
|
AUTH_RP_ID: localhost
|
|
AUTH_RP_ORIGIN: http://localhost:3000
|
|
NODE_ENV: production
|
|
|
|
steps:
|
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
|
|
|
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
|
|
- run: pnpm install --frozen-lockfile
|
|
|
|
- run: pnpm db:generate
|
|
|
|
- run: pnpm db:migrate:deploy
|
|
|
|
- name: Cache Playwright browsers
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: |
|
|
playwright-${{ runner.os }}-
|
|
|
|
- run: pnpm exec playwright install --with-deps chromium
|
|
|
|
- run: pnpm exec next build
|
|
|
|
# Client-bundle budget gate — rides this job because it is the one
|
|
# place CI already has a production build on disk. Catches the
|
|
# regressions the dead webpack-era tooling (ANALYZE=1, the old
|
|
# bundle-report) let through: a statically imported message catalog
|
|
# (~100 KB gz on every route) or a chart import bypassing the shared
|
|
# chart-runtime boundary (a duplicated ~92 KB gz recharts chunk).
|
|
- run: pnpm bundle-check
|
|
|
|
- run: pnpm exec playwright test
|
|
env:
|
|
E2E_BASE_URL: http://localhost:3000
|
|
|
|
- name: Upload Playwright HTML report on failure
|
|
if: failure()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: playwright-report
|
|
path: playwright-report/
|
|
retention-days: 7
|