Skip to content

PR1: server test-infra split + Prisma migration safety net (E2/E1/E10)#3785

Merged
ryota-murakami merged 2 commits into
mainfrom
fix/server-test-infra-migration-safety-net
May 30, 2026
Merged

PR1: server test-infra split + Prisma migration safety net (E2/E1/E10)#3785
ryota-murakami merged 2 commits into
mainfrom
fix/server-test-infra-migration-safety-net

Conversation

@ryota-murakami

@ryota-murakami ryota-murakami commented May 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Safety-net PR for the extension-login-flow feature (the scoped-PAT feature itself lands in #3784). Three independent, low-risk changes that make PR2 safe to build on:

E2 — Vitest web/server project split (vitest.config.ts)
A single jsdom project forced setupTests.ts's window.matchMedia mock onto every test, which throws in Node and blocks DB-free Express unit tests. Split into two Vitest 4 projects: web (jsdom + setupTests, for the SPA / lib / scripts) and server (node, no DOM setup, for server/**). JWT.test.ts (8 tests) now runs under the server project. This is the foundation PR2's PAT-middleware unit tests (U1–U8) build on.

E1 — PAT middleware contract placeholder (server/lib/authenticateStockRequest.contract.test.ts)
7 it.todo capturing the regression guards the PR2 authenticateStockRequest middleware must satisfy — U5 (invalid/revoked PAT must NOT clear the owner's auth cookies / confused-deputy), U6 (malformed header → 401 not 500), U7 (cookie fallback when no Authorization header), U8 (lastUsedAt update), E4 (full session-user hydrate), E14 (single atomic revoked/expired query). It imports nothing from the not-yet-existent middleware so collection stays green; PR2 replaces each todo with a real DB-backed assertion.

E10 — Prisma migrations in the manual deploy script (scripts/deploy)
pnpm deploy shipped server_build but never ran migrations, so a new table (PR2 adds personal_access_tokens) would be missing on the host after a manual deploy. The script now rsyncs prisma/ and runs migrate statusmigrate deploy on the host before the server restarts, aborting on drift/failure — mirroring the existing .github/workflows/deploy.yml safety net. No remote prisma generate is needed: esbuild bundles the Prisma client into server_build (the ../generated/prisma import is relative, so --packages=external doesn't externalize it).

Test Coverage

Test-infra / deploy-script changes — no new application code paths. The new contract test is itself the coverage scaffold for PR2.

  • typecheck: ✅ tsc --noEmit clean
  • lint: ✅ eslint --max-warnings=0 clean
  • test: ✅ 33 files passed | 1 skipped, 79 passed | 7 todo — the "1 skipped" file is the new contract test (all 7 of its tests are it.todo placeholders, so the file has no executable tests yet)

Pre-Landing Review

Self-reviewed and reviewed by the advisor model (the E10 migrate-before-code ordering and the projects split). The E10 ordering was corrected to run migrate deploy before the code rsync, so a failed migration never precedes a PM2 restart. External review by CodeRabbit is expected on this PR.

Intentional behavior changes in scripts/deploy (flagged for the reviewer):

  • adds set -euo pipefail and quotes rsync paths
  • wires the previously-dead usage() into the getopts *) case — unknown flags now error instead of silently doing a full deploy
  • -s and the default path now migrate; -f (frontend-only) skips migrations

Verification

Production-verified the migrate mechanism (the owner took a DB backup and authorized prod verification): on the live host, migrate status → "Database schema is up to date!" (exit 0) and migrate deploy → "No pending migrations to apply." (exit 0). This confirms the abort-on-nonzero logic does not false-trip on a clean deploy. PR1 itself adds no migration, so applying it is a no-op — the real exercise is PR2's personal_access_tokens table.

Notes

This is a focused 3-file safety-net PR. The heavier gstack review passes (specialist army, Codex multi-pass) were skipped as redundant for an infra-only diff that already has advisor review, production verification, and an incoming CodeRabbit review. Rollback is trivial (revert; no schema or runtime behavior changes in PR1).

Closes #3783

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Enhanced deployment process with improved database migration ordering to ensure safer server deployments
    • Updated test infrastructure configuration to support isolated test environments

Review Change Stack

ryota-murakami and others added 2 commits May 30, 2026 22:57
…ract placeholder

E2: a single jsdom project forced setupTests.ts's window.matchMedia mock onto
Express/server tests, which blocks DB-free Node unit tests (the mock throws
without `window`). Split into two Vitest 4 projects — `web` (jsdom + setupTests)
and `server` (node, no DOM setup) — so server/**/*.{spec,test}.ts run in Node.
JWT.test.ts (8 tests) now runs under the server project; the full suite stays
green (79 passed | 7 todo | 1 skipped).

E1: add authenticateStockRequest.contract.test.ts — 7 it.todo capturing the PR2
PAT-middleware regression guards (U5 confused-deputy no-cookie-clear, U6
malformed-header 401-not-500, U7 cookie fallback, U8 lastUsedAt, E4 full
session-user hydrate, E14 single atomic query). It imports nothing from the
not-yet-existent middleware so collection stays green; the server project
collects it in Node (the file reads as the "1 skipped" until PR2 fills it in).

Refs #3783

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…start

E10: `pnpm deploy` rsynced server_build (which already bundles the Prisma client
via the relative `../generated/prisma` import — esbuild's --packages=external does
not externalize relative paths) but never applied migrations, so a newly-added
table would be missing on the host after a manual deploy. scripts/deploy now
rsyncs prisma/ and runs `migrate status` -> `migrate deploy` on the host BEFORE
the server restarts, aborting on drift/failure. This mirrors the safety net in
.github/workflows/deploy.yml so the manual path matches the GitHub Actions path.

Ordering: migrate runs before the new server_build lands, so a failed migration
never precedes a PM2 restart. No remote `prisma generate` is needed — the client
is bundled into server_build.

Other changes (intentional, flagged for review):
- add `set -euo pipefail` and quote rsync paths
- wire the previously-dead usage() to the getopts `*)` case (unknown flags now
  error instead of silently doing a full deploy)
- run migrations for -s and the default path; -f (frontend-only) skips them

Verified on production (DB backed up, owner-authorized): `migrate status` and
`migrate deploy` both exit 0 when the schema is already up to date, so the
abort-on-nonzero logic does not false-trip on a clean deploy.

Refs #3783

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 08b7d422-fb63-4ef9-b794-69370c63806b

📥 Commits

Reviewing files that changed from the base of the PR and between cc32524 and 1170b52.

📒 Files selected for processing (3)
  • scripts/deploy
  • server/lib/authenticateStockRequest.contract.test.ts
  • vitest.config.ts

📝 Walkthrough

Walkthrough

This PR establishes foundational infrastructure for PAT (Personal Access Token) authentication work by enabling server tests with proper node environment isolation and enforcing safe Prisma migrations during deployment. The deploy script gains a remote migration preflight that validates pending schema changes before shipping artifacts, while Vitest's configuration shifts from single-environment to multi-project setup.

Changes

PAT Auth Foundation — Test Infrastructure and Deploy Safety

Layer / File(s) Summary
Deploy Script Remote Migration Safety
scripts/deploy
Script adds strict bash error handling, centralizes LOCAL_ROOT, REMOTE_HOST, and REMOTE_ROOT, introduces run_remote_migrations function that rsyncs Prisma files and runs remote Prisma CLI (migrate status with pattern-based validation, then conditional migrate deploy), and updates -s server-only and default deploy paths to execute migrations before artifact upload while -f frontend-only continues to skip schema work.
Vitest Multi-Project Configuration
vitest.config.ts
Config adds ESM-safe DIR_NAME resolution from import.meta.url, extracts shared SHARED_EXCLUDE glob patterns, and restructures test section from single jsdom environment into projects array: web project runs jsdom tests for frontend/shared/libs with setupFiles: ['setupTests.ts'], while server project runs node environment tests for server/**/*.{spec,test}.{ts,tsx} without DOM setup.
PAT Auth Contract Test Placeholder
server/lib/authenticateStockRequest.contract.test.ts
New Vitest contract test suite containing it.todo cases enumerating expected authenticateStockRequest middleware behaviors: PAT authentication success, user shape parity with cookie-session, atomic revocation/expiration validation, lastUsedAt updates, cookie-session fallback when Authorization header absent, no cookie clearing on invalid PATs, and 401 (not 500) for malformed headers; import of middleware intentionally omitted to prevent future breakage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • laststance/nsx#3772: Normalizes prisma.config.ts DATABASE_URL socketPath → Prisma CLI socket for migrations, coordinating with this PR's remote Prisma CLI invocation.
  • laststance/nsx#3775: Also invokes Prisma CLI via node_modules/prisma/build/index.js for migrate status and migrate deploy in remote deploy workflow.
  • laststance/nsx#3769: Implements hardened deploy SSH workflow with migration-status gating before artifact deploy and restart, matching this PR's preflight validation pattern.

Poem

🐰 A test home for server code so fine,
With migrations checked before we deploy in line,
The paths split clean—web and server each see,
What PAT auth needs, a foundation set free! 🌱

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the three main changes: server test-infra split, Prisma migration safety net, with issue references.
Linked Issues check ✅ Passed All three coding objectives from #3783 are met: E2 splits Vitest projects for server tests in Node; E10 adds Prisma migrations to deploy script; E1 adds placeholder contract test.
Out of Scope Changes check ✅ Passed All changes directly support #3783 objectives: vitest config restructure, deploy script migration safety, and contract test placeholder. No unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/server-test-infra-migration-safety-net

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Comment @coderabbitai help to get the list of available commands and usage tips.

@ryota-murakami ryota-murakami merged commit 19358d2 into main May 30, 2026
13 checks passed
@ryota-murakami ryota-murakami deleted the fix/server-test-infra-migration-safety-net branch May 30, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extension PAT auth — PR1: test infra + migration safety net (E2/E10/E1)

1 participant