Skip to content

fix(e2e): provision fixture user before mobile web Playwright (closes #435)#307

Merged
auerbachb merged 5 commits into
mainfrom
cursor/fix-e2e-setup-email-401-bb9b
May 1, 2026
Merged

fix(e2e): provision fixture user before mobile web Playwright (closes #435)#307
auerbachb merged 5 commits into
mainfrom
cursor/fix-e2e-setup-email-401-bb9b

Conversation

@auerbachb
Copy link
Copy Markdown
Owner

@auerbachb auerbachb commented Apr 30, 2026

User description

Summary

Addresses long-standing 401 on login for credentialed mobile web E2E when the fixture user row is missing from Neon or the stored password hash no longer matches GitHub Actions secrets.

Babysitter follow-up (commit cc7d5c0)

  • CI: E2E_WEB_SETUP_USER=true no longer fails when secrets.E2E_WEB_* / POSTGRES_URL resolve to empty strings. globalSetup logs a warning and skips DB provisioning so mock-based mobile E2E stays green until secrets exist.
  • Workflow: Job-level env includes E2E_TEST_USER_EMAIL / E2E_TEST_USER_PASSWORD fallbacks (Bugbot: empty-string E2E_WEB_* no longer blocks E2E_TEST_USER_*).
  • Review fixes: closePoolDb() after provision; shared scripts/lib/assert-neon-postgres-url.ts; fixture username e2e_ + 12 hex (fits app 3–30 rule); update path checks username collision with another row.

Operator / issue #435

Post diagnostic comment on #435 without pasting secrets. Add repo secrets when ready for real DB alignment.

Closes #435.

Open in Web Open in Cursor 

CodeAnt-AI Description

Set up the mobile web E2E login user before Playwright runs

What Changed

  • Mobile web E2E can now create or refresh the fixture login user before tests start, preventing 401 login failures when the database row is missing or the saved password no longer matches CI secrets.
  • When the required database URL or secrets are not present, setup now skips instead of failing, so mock-based E2E runs keep working.
  • Added a setup command, workflow wiring, and documentation for running credentialed mobile web E2E tests against a remote non-production database.

Impact

✅ Fewer mobile web login failures in E2E
✅ Reliable Playwright runs after DB wipes or secret rotation
✅ Clearer setup for credentialed CI test runs

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Add Neon-guarded upsert for E2E_WEB_EMAIL so login matches CI secrets after
DB wipes or password drift. Wire e2e-mobile workflow with globalSetup and
document fixture secrets plus psql triage in e2e/README.md.

Closes #435

Co-authored-by: Bretton Auerbach <auerbachb@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
still-point Ready Ready Preview, Comment May 1, 2026 1:36pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

📝 Walkthrough

Walkthrough

Adds credential-gated E2E provisioning for mobile web Playwright tests: a conditional globalSetup upserts a test user into a Neon Postgres when CI secrets and E2E_WEB_SETUP_USER=true are present; otherwise tests run with mocked APIs. Also adds provisioning scripts, CI wiring, docs, and pool cleanup.

Changes

Cohort / File(s) Summary
E2E Config & Scripts
\.env.example, playwright.config.ts, package.json, e2e/README.md
Adds commented E2E env placeholders, conditional Playwright globalSetup, an e2e:setup-web-user npm script, and local-run documentation for mocked vs credentialed flows.
CI Workflow
.github/workflows/e2e-mobile.yml
Injects runtime env vars/secrets (email, password, POSTGRES_URL, E2E_WEB_SETUP_USER) into the Playwright e2e job to enable credentialed provisioning when present.
Global Setup & Provisioning
e2e/global-setup.ts, scripts/e2e/provision-e2e-web-user.ts, scripts/e2e/setup-web-user.ts
Adds Playwright globalSetup gating, functions to read credentials, derive deterministic usernames, validate inputs, bcrypt-hash passwords, and atomic upsert of the fixture user in Postgres.
DB Helpers & Seed
scripts/lib/assert-neon-postgres-url.ts, scripts/seed.ts, src/db/pool.ts
Introduces Neon-hosted Postgres URL assertion helper, updates seed to use it and trim POSTGRES_URL, and exports closePoolDb() to clean up the Drizzle Pool.
Policy & Docs
docs/testing/e2e-policy.md
Adds policy documenting credential gating for Playwright mobile web runs and when global setup will provision the fixture user.

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI Job
  participant Playwright as Playwright Runner
  participant GlobalSetup as global-setup.ts
  participant Scripts as provision script
  participant DB as Neon Postgres
  participant Tests as E2E Tests

  CI->>Playwright: start job (env secrets injected)
  Playwright->>GlobalSetup: invoke globalSetup (if E2E_WEB_SETUP_USER=true)
  GlobalSetup->>Scripts: readE2EWebCredentials() & provisionE2EWebUser()
  Scripts->>DB: connect (assert Neon URL) -> upsert user (insert on conflict)
  DB-->>Scripts: upsert result
  Scripts-->>GlobalSetup: success / failure
  GlobalSetup-->>Playwright: continue
  Playwright->>Tests: run tests (real auth if provisioned, else mocked APIs)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • Issue #435: Implements CI-gated fixture user provisioning and globalSetup which directly addresses the setup-email 401 caused by a missing/incorrect E2E fixture user.

Possibly related PRs

  • PR #141: Related — both extract/refactor Neon non-prod Postgres URL validation and update scripts/seed.ts.
  • PR #163: Related — both modify src/db/pool.ts; this PR adds closePoolDb() complementing prior pool changes.
  • PR #222: Related — overlapping changes to E2E configuration, docs, and Playwright/global-setup wiring.

Suggested reviewers

  • codeant-ai

Poem

🐰 I hopped through envs and CI lights,
To seed a user for test-day flights,
With bcrypt paws and Neon cheer,
E2E runs know when I'm near—
Hop hop, the tests are clear!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding fixture user provisioning before mobile web Playwright tests, directly addressing the root cause of recurring 401 errors (#435).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 cursor/fix-e2e-setup-email-401-bb9b

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

@auerbachb auerbachb marked this pull request as ready for review April 30, 2026 23:18
@auerbachb
Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 30, 2026

CodeAnt AI is running the review.

@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

@auerbachb
Copy link
Copy Markdown
Owner Author

@graphite-app re-review

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Apr 30, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 30, 2026

Sequence Diagram

This PR ensures that mobile web Playwright tests automatically upsert a fixture user in the non-production database so the login flow uses credentials aligned with CI secrets, preventing 401 failures when the user row or password hash is out of sync.

sequenceDiagram
    participant CI
    participant Playwright
    participant GlobalSetup
    participant ProvisionScript
    participant Database

    CI->>Playwright: Run mobile web tests with e2e web env
    Playwright->>GlobalSetup: Invoke global setup when setup flag is true
    GlobalSetup->>ProvisionScript: Read web credentials and database url from env
    GlobalSetup->>ProvisionScript: Request provision of fixture web user
    ProvisionScript->>Database: Upsert user with email and password hash
    Database-->>Playwright: Fixture user ready for login tests
Loading

Generated by CodeAnt AI

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit a6dcf7b. Configure here.

Comment thread scripts/e2e/provision-e2e-web-user.ts Outdated
Comment thread scripts/e2e/provision-e2e-web-user.ts Outdated
Comment thread scripts/e2e/provision-e2e-web-user.ts
Comment thread scripts/e2e/provision-e2e-web-user.ts Outdated
Comment thread scripts/e2e/provision-e2e-web-user.ts Outdated
Comment thread scripts/e2e/provision-e2e-web-user.ts Outdated
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 30, 2026

CodeAnt AI finished running the review.

- globalSetup: warn and skip if POSTGRES_URL or creds missing (fixes mobile E2E
  when E2E_WEB_* secrets are not configured yet)
- workflow: job-level env with E2E_TEST_USER_* fallbacks for GitHub secrets
- provision: trim-aware credential fallback, close Neon pool after upsert,
  shared assertNeonNonProdPostgresUrl, username e2e_<12 hex> within 3–30 rule,
  update path checks username collision with other rows
- pool: export closePoolDb for scripts

Co-authored-by: Bretton Auerbach <auerbachb@users.noreply.github.com>
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 30, 2026

CodeAnt AI is reviewing your PR.

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels Apr 30, 2026
Align e2e-policy with e2e/README: when POSTGRES_URL or fixture creds are empty
in CI (e.g. fork PRs), global setup skips DB upsert and mock-api tests run.

Co-authored-by: Bretton Auerbach <auerbachb@users.noreply.github.com>
Comment thread scripts/e2e/provision-e2e-web-user.ts Outdated
Comment thread scripts/e2e/provision-e2e-web-user.ts Outdated
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 30, 2026

CodeAnt AI finished reviewing your PR.

Replace read-then-insert/update with INSERT ... ON CONFLICT DO UPDATE on
users.email so three matrix jobs cannot race on first provision. Keep pre-check
when another row owns the derived username (different email).

Co-authored-by: Bretton Auerbach <auerbachb@users.noreply.github.com>
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

CodeAnt AI is running Incremental review

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels May 1, 2026
@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label May 11, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

Sequence Diagram

This PR adds Playwright global setup and supporting scripts to ensure a credentialed fixture user is upserted in the Neon database before mobile web E2E tests, while safely skipping provisioning when the database URL or secrets are missing.

sequenceDiagram
    participant CI
    participant Playwright
    participant GlobalSetup
    participant Provisioner
    participant Database

    CI->>Playwright: Run mobile web tests with env variables
    Playwright->>GlobalSetup: Invoke global setup
    GlobalSetup->>GlobalSetup: Read db url and fixture credentials

    alt Missing db url or credentials
        GlobalSetup-->>Playwright: Skip fixture user provisioning
    else All config present
        GlobalSetup->>Provisioner: Provision E2E web user
        Provisioner->>Database: Upsert fixture user by email
        Database-->>Provisioner: User ensured for login
        Provisioner-->>Playwright: Setup complete
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels May 11, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

Sequence Diagram

This PR adds a Playwright global setup and supporting scripts that upsert a credentialed fixture user in the Neon database before mobile web E2E tests, or safely skip provisioning when database URL or credentials are missing to avoid spurious 401 failures.

sequenceDiagram
    participant CI as CI e2e mobile job
    participant Playwright
    participant GlobalSetup
    participant Provisioner as E2E user provisioner
    participant Database as Neon database

    CI->>Playwright: Start mobile web tests
    Playwright->>GlobalSetup: Run global setup
    GlobalSetup->>GlobalSetup: Read POSTGRES_URL and fixture credentials

    alt Config present
        GlobalSetup->>Provisioner: Provision E2E user with credentials
        Provisioner->>Database: Upsert user by email with password hash
        Database-->>Provisioner: User ensured
        Provisioner-->>GlobalSetup: Close database pool
    else Missing config
        GlobalSetup-->>Playwright: Skip DB provisioning and log warning
    end
Loading

Generated by CodeAnt AI

Comment thread src/db/pool.ts
Comment on lines +51 to +54
if (globalForPool.__drizzlePool) {
await globalForPool.__drizzlePool.end();
globalForPool.__drizzlePool = undefined;
globalForPool.__poolDb = undefined;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: closePoolDb only clears the cached globals after awaiting end(). If end() throws (network/socket shutdown errors do happen), the stale cached pool/db references remain set, so subsequent calls can keep reusing a broken client and fail repeatedly. Clear/reset cached references in a guaranteed cleanup path so state is consistent even when pool shutdown errors. [missing cleanup]

Severity Level: Major ⚠️
- ❌ Playwright globalSetup may reuse a broken Neon pool.
- ⚠️ E2E web user provisioning can repeatedly fail after shutdown error.
- ⚠️ Future scripts using poolDb inherit inconsistent connection state.
Steps of Reproduction ✅
1. Run mobile web Playwright E2E with `E2E_WEB_SETUP_USER=true`, which configures
`globalSetup` to `./e2e/global-setup.ts` via `playwright.config.ts:10`.

2. In `e2e/global-setup.ts:15–30`, `globalSetup()` calls `provisionE2EWebUser()` from
`scripts/e2e/provision-e2e-web-user.ts:40` after reading credentials and `POSTGRES_URL`,
which in turn uses `poolDb` (imported from `src/db/pool.ts:43`) to perform queries and
thereby initializes `globalForPool.__drizzlePool` and `globalForPool.__poolDb` in
`getPool()` / `getPoolDb()` (`src/db/pool.ts:15–35`).

3. After the queries complete, the `finally` block in `provisionE2EWebUser()`
(`scripts/e2e/provision-e2e-web-user.ts:65–99`) invokes `closePoolDb()`, which executes
the code at `src/db/pool.ts:51–54`: it awaits `globalForPool.__drizzlePool.end()` on line
52 and only then sets `globalForPool.__drizzlePool` and `globalForPool.__poolDb` to
`undefined` on lines 53–54.

4. If `Pool.end()` rejects (e.g., due to a Neon WebSocket/network error) during this
`await` on `src/db/pool.ts:52`, the function throws before reaching lines 53–54, leaving
`globalForPool.__drizzlePool` / `__poolDb` still set; any subsequent call in the same Node
process to `provisionE2EWebUser()` (via `e2e/global-setup.ts` or
`scripts/e2e/setup-web-user.ts:7–23`) or any other code using `poolDb` will see the
cached, already-ended pool in `getPool()` (`src/db/pool.ts:20–28`), reusing a broken
client instead of creating a fresh `Pool`, causing repeated transaction failures until
process restart. This inconsistent cleanup behavior matches the suggestion: there is no
guaranteed reset of cached globals when shutdown fails.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/db/pool.ts
**Line:** 51:54
**Comment:**
	*Missing Cleanup: `closePoolDb` only clears the cached globals after awaiting `end()`. If `end()` throws (network/socket shutdown errors do happen), the stale cached pool/db references remain set, so subsequent calls can keep reusing a broken client and fail repeatedly. Clear/reset cached references in a guaranteed cleanup path so state is consistent even when pool shutdown errors.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels May 11, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

Sequence Diagram

This PR wires Playwright global setup and a provisioning script so that mobile web E2E tests upsert a Neon-hosted fixture user using CI secrets before login, or skip database work when configuration is missing while keeping mock-based tests green.

sequenceDiagram
    participant CI
    participant Playwright
    participant GlobalSetup
    participant NeonDB
    participant Backend

    CI->>Playwright: Run mobile web E2E job
    Playwright->>GlobalSetup: Invoke global setup
    GlobalSetup->>GlobalSetup: Read POSTGRES_URL and E2E web credentials

    alt DB url and credentials present
        GlobalSetup->>NeonDB: Upsert fixture user with configured email and password
        NeonDB-->>GlobalSetup: Fixture user ensured
    else Missing config
        GlobalSetup-->>Playwright: Skip DB provisioning and log warning
    end

    Playwright->>Backend: Login with fixture user
    Backend-->>Playwright: Authenticated session returned
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels May 11, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

Sequence Diagram

This PR adds Playwright global setup and a provisioning script that upserts a Neon-backed fixture user before mobile web E2E tests run, or safely skips provisioning when database or credential configuration is missing.

sequenceDiagram
    participant CI
    participant Playwright
    participant GlobalSetup
    participant Provisioner
    participant Database
    participant Backend

    CI->>Playwright: Run mobile web E2E job
    Playwright->>GlobalSetup: Start global setup
    GlobalSetup->>GlobalSetup: Read database url and fixture credentials

    alt Config present
        GlobalSetup->>Provisioner: Provision E2E web user
        Provisioner->>Database: Upsert fixture user with current password
    else Missing config
        GlobalSetup->>GlobalSetup: Log warning and skip provisioning
    end

    Playwright->>Backend: Execute tests using login flow
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels May 11, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

Sequence Diagram

This PR adds a Playwright global setup that, when enabled in CI, ensures a Neon-hosted database contains a fixture user whose email and password match configured secrets, skipping provisioning when credentials or database URL are missing so mock-based tests still run.

sequenceDiagram
    participant CI Workflow
    participant Playwright
    participant GlobalSetup
    participant Provisioner
    participant Database

    CI Workflow->>Playwright: Run mobile web E2E with setup enabled
    Playwright->>GlobalSetup: Invoke global setup
    GlobalSetup->>GlobalSetup: Read DB URL and fixture credentials

    alt DB URL or credentials missing
        GlobalSetup-->>Playwright: Skip DB provisioning and continue with mock APIs
    else All required values present
        GlobalSetup->>Provisioner: Provision E2E web user with credentials
        Provisioner->>Provisioner: Validate environment and target Neon host
        Provisioner->>Database: Upsert fixture user by email with derived username and password hash
        Database-->>Provisioner: Confirm user inserted or updated
        Provisioner-->>GlobalSetup: Provisioning complete
        GlobalSetup-->>Playwright: Proceed to execute tests
    end
Loading

Generated by CodeAnt AI

Comment on lines +19 to +22
if (!host.endsWith(".neon.tech") && host !== "neon.tech") {
throw new Error(
"Refusing to use POSTGRES_URL: hostname must be a Neon host (*.neon.tech).",
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The hostname check contradicts the stated policy by explicitly allowing neon.tech in addition to *.neon.tech. This lets a non-database apex domain pass validation and pushes failure to a later connection step, defeating the guardrail's intent. Require only subdomain hosts (or document and verify apex separately) so invalid endpoints are rejected early. [incorrect condition logic]

Severity Level: Major ⚠️
- ❌ Seed script accepts invalid Neon URL, fails later during connect.
- ⚠️ E2E user provisioning misreports misconfigured POSTGRES_URL until runtime.
Steps of Reproduction ✅
1. Open `scripts/seed.ts` and note the `main()` entrypoint at lines 53–54 and its
invocation in the same file at lines 216–219 (via `main().catch(...)`), confirming this
script is run directly as a CLI seed.

2. Set environment variables before running the seed: `NODE_ENV` to a non-production
value, `SEED_CONFIRM=still-point-nonprod` (required at lines 59–62), and `POSTGRES_URL` to
an apex Neon host such as `postgres://user:pass@neon.tech/dbname`.

3. Run `node scripts/seed.ts`; inside `main()` the script reads `POSTGRES_URL` at lines
65–68, then calls `assertNeonHostedPostgresUrl(postgresUrl)` at lines 70–71, which uses
`parsed.hostname.toLowerCase()` at line 18 and the guard at lines 19–22:

   - `host` becomes `"neon.tech"`;

   - `host.endsWith(".neon.tech")` is `false`;

   - `host !== "neon.tech"` is `false`;

   so the condition `if (!host.endsWith(".neon.tech") && host !== "neon.tech")` is `false`
   and no error is thrown, despite the comment and error message claiming only
   `*.neon.tech` subdomains are allowed.

4. The script proceeds to create a Neon `Pool` with `process.env.POSTGRES_URL` in
`src/db/pool.ts` at lines 15–27 (via `poolDb.transaction(...)` in `scripts/seed.ts` lines
77–213). Any failure (e.g., DNS or connection failure when targeting `neon.tech`) now
happens later in the transaction instead of being rejected early by
`assertNeonHostedPostgresUrl`, demonstrating that the hostname check is more permissive
than its documented `*.neon.tech` constraint.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** scripts/lib/assert-neon-postgres-url.ts
**Line:** 19:22
**Comment:**
	*Incorrect Condition Logic: The hostname check contradicts the stated policy by explicitly allowing `neon.tech` in addition to `*.neon.tech`. This lets a non-database apex domain pass validation and pushes failure to a later connection step, defeating the guardrail's intent. Require only subdomain hosts (or document and verify apex separately) so invalid endpoints are rejected early.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot removed the size:L This PR changes 100-499 lines, ignoring generated files label May 11, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

Sequence Diagram

This PR adds a Playwright global setup and shared provisioning script that upserts a credentialed fixture user in the Neon database before mobile web E2E tests run, while safely skipping provisioning when database or credential secrets are missing.

sequenceDiagram
    participant CI as CI workflow
    participant PW as Playwright runner
    participant GS as Playwright global setup
    participant Script as Provision script
    participant DB as Neon database

    CI->>PW: Start mobile web E2E job with env vars
    PW->>GS: Invoke global setup
    GS->>GS: Read POSTGRES_URL and fixture credentials

    alt DB url and credentials present
        GS->>Script: Provision E2E web user with email and password
        Script->>DB: Upsert fixture user by email with derived username and password hash
        DB-->>Script: User ensured
        Script-->>GS: Provisioning complete
        GS-->>PW: Continue tests against real backend
    else Missing DB url or credentials
        GS-->>PW: Log warning and skip provisioning (tests use mocked API)
    end
Loading

Generated by CodeAnt AI

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label May 11, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 11, 2026

CodeAnt AI finished running the review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants