Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ terraform.tfvars
terraform.tfvars.json
tfplan
tfplan.*
.vercel
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ Prefer explicit labels in docs:
- If the user intent is clear and the step is ship-safe, continue to commit and push without asking again.
- Ask before pushing only for risky/destructive/security/billing posture changes, or when the user explicitly asks to hold.

## Infrastructure and environment rule

- Prefer infrastructure-as-code or checked-in configuration for infrastructure, CI settings, and environment variable definitions whenever the platform supports it.
- Especially avoid undocumented dashboard-only environment variables; if a secret value must stay in a provider secret store, commit the expected variable name, scope, owner, and rotation/recreation path.
- Manual provider changes are acceptable only as a bootstrap or emergency step, and should be followed by docs, scripts, Terraform, or workflow changes that make the desired state reproducible.

## Global vs local agent context

- Put repo-wide defaults, durable workflow rules, and opinionated project conventions in `AGENTS.md`.
Expand Down
6 changes: 4 additions & 2 deletions apps/web/e2e/public-routes.smoke.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { test } from "@playwright/test";

import { capturedRoutes } from "./public-routes";
import { capturedRoutes, productionSmokeRoutes } from "./public-routes";

for (const route of capturedRoutes) {
const routes = process.env.PLAYWRIGHT_BASE_URL ? productionSmokeRoutes : capturedRoutes;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 PLAYWRIGHT_BASE_URL as production signal narrows staging smoke coverage

PLAYWRIGHT_BASE_URL is also set when running the mutation-backed hosted flow against a dev/staging target (per the docs: set PLAYWRIGHT_BASE_URL and VRDEX_E2E_BROWSER_TOKEN). If anyone runs this smoke spec against a dev/staging URL that does have fixture data, they'll silently exercise only the 6 production-safe routes rather than the full capturedRoutes set — potentially missing regressions that only surface through fixture-backed routes. A separate env var (e.g. PLAYWRIGHT_PRODUCTION_SMOKE=true) would make the intent explicit.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/e2e/public-routes.smoke.spec.ts
Line: 5

Comment:
**`PLAYWRIGHT_BASE_URL` as production signal narrows staging smoke coverage**

`PLAYWRIGHT_BASE_URL` is also set when running the mutation-backed hosted flow against a dev/staging target (per the docs: `set PLAYWRIGHT_BASE_URL and VRDEX_E2E_BROWSER_TOKEN`). If anyone runs this smoke spec against a dev/staging URL that does have fixture data, they'll silently exercise only the 6 production-safe routes rather than the full `capturedRoutes` set — potentially missing regressions that only surface through fixture-backed routes. A separate env var (e.g. `PLAYWRIGHT_PRODUCTION_SMOKE=true`) would make the intent explicit.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


for (const route of routes) {
test(`${route.name} renders`, async ({ page }) => {
await page.goto(route.path);
await route.expectPage(page);
Expand Down
6 changes: 6 additions & 0 deletions apps/web/e2e/public-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,9 @@ export const capturedRoutes: CapturedRoute[] = [
expectPage: expectEventPage,
},
];

export const productionSmokeRoutes: CapturedRoute[] = capturedRoutes.filter((route) =>
["submit", "sign-in", "privacy-suppression", "event-new-signed-out", "server-status", "deployment"].includes(
route.name,
),
);
Comment on lines +351 to +355
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Silent empty suite if names drift

productionSmokeRoutes is built by filtering capturedRoutes on a hard-coded list of string names. If any of the six names is later renamed (or mistyped here), the filter silently drops it — and if they all disappear, the test suite passes with zero tests, giving false green on production smoke runs. There is no assertion that the filtered list is non-empty or that every listed name resolved to a route.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/e2e/public-routes.ts
Line: 351-355

Comment:
**Silent empty suite if names drift**

`productionSmokeRoutes` is built by filtering `capturedRoutes` on a hard-coded list of string names. If any of the six names is later renamed (or mistyped here), the filter silently drops it — and if they all disappear, the test suite passes with zero tests, giving false green on production smoke runs. There is no assertion that the filtered list is non-empty or that every listed name resolved to a route.

How can I resolve this? If you propose a fix, please make it concise.

13 changes: 13 additions & 0 deletions docs/deployment/convex-environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ VRDex keeps three Convex execution targets separate:

Do not commit deploy keys. Store them in GitHub/hosting secret stores and local ignored env files only.

Current recommendation: define environment variable names and target scopes in docs or IaC first, then set secret values through provider secret stores. Manual Convex dashboard edits should be treated as bootstrap/emergency changes and followed by a reproducibility update here or in automation.

- development cloud URL: `https://scrupulous-corgi-247.convex.cloud`
- production cloud URL: `https://superb-pig-954.convex.cloud`

Expand All @@ -27,6 +29,17 @@ Local ignored env names:
- `CONVEX_URL_DEV`
- `CONVEX_URL_PROD`

## Hosted E2E Helpers

Hosted mutation-backed Playwright runs use only the shared development/staging target. Do not enable these helpers in production.

Development/staging Convex env names:

- `VRDEX_ENABLE_E2E_HELPERS=true`
- `VRDEX_E2E_CONVEX_SECRET`: non-empty sentinel also configured in the hosted app environment

The browser-facing token stays in the web host and GitHub Actions as `VRDEX_E2E_BROWSER_TOKEN` / `VRDEX_HOSTED_E2E_BROWSER_TOKEN`; it is not needed by Convex.

## Notes

There are two similarly named Convex projects in the account history: `vrdex` and `vrdex-85631`. Current recommendation is to keep the `vrdex` line of deployments and archive/delete the other only after confirming no dashboard, env, or deployment history still depends on it.
10 changes: 10 additions & 0 deletions docs/deployment/vercel-preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Run Vercel CLI commands from the repository root once the project root directory

## Repository secrets

Current recommendation: keep repository Actions variables and secrets reproducible through checked-in workflows/docs first, and provider APIs or CLI scripts where practical. Secret values still belong in GitHub/Vercel/Convex secret stores, but their names, scopes, and recreation path should be documented here.

The PR workflow deploys a Vercel preview only when all three repository secrets exist:

- `VERCEL_TOKEN`
Expand All @@ -43,6 +45,14 @@ Set these in the Vercel project as needed:

Do not set `VRDEX_ENABLE_PLAYWRIGHT_FIXTURES` in Vercel. Fixture profiles are for Playwright-only local/CI preview screenshots and must not be exposed from hosted previews.

Hosted dev/staging E2E targets must set these only on the dev/staging environment, not production:

- `VRDEX_ENABLE_E2E_HELPERS=true`
- `VRDEX_E2E_BROWSER_TOKEN`: same value as the GitHub Actions secret `VRDEX_HOSTED_E2E_BROWSER_TOKEN`
- `VRDEX_E2E_CONVEX_SECRET`: non-empty sentinel matching the Convex deployment secret name

Production should keep `VRDEX_ENABLE_E2E_HELPERS=false` or unset, and should not set `VRDEX_ALLOW_PRODUCTION_E2E_HELPERS` unless a human explicitly approves a temporary incident/debug window.

Preview deployment protection must allow unauthenticated reads if the PR preview is meant to be reviewed outside the Vercel dashboard.

## Validation
Expand Down
3 changes: 3 additions & 0 deletions docs/planning/engineering-strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ Infra direction:

- Terraform and/or AWS CDK are both acceptable directions
- choose one primary IaC path before implementation gets too far
- prefer infrastructure-as-code or checked-in config for infrastructure, CI settings, and environment variable definitions whenever the platform supports it
- for secrets that must remain in provider secret stores, commit the expected variable name, environment scope, owning service, and rotation/recreation path instead of relying on dashboard-only tribal knowledge
- treat manual dashboard changes as bootstrap or emergency operations that need a follow-up reproducibility artifact

## Follow-on integration ideas

Expand Down
2 changes: 1 addition & 1 deletion docs/testing/playwright-visual-preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ See `docs/testing/playwright-image-diffing.md` for the committed-baseline image
- Update public route screenshot baselines: `pnpm test:e2e:snapshots:update`
- Reuse already-running local services: set `PLAYWRIGHT_REUSE_SERVER=true` and `PLAYWRIGHT_REUSE_CONVEX=true`
- Run the mutation-backed flow against a hosted dev/staging target: set `PLAYWRIGHT_BASE_URL` and `VRDEX_E2E_BROWSER_TOKEN`, then run `pnpm test:e2e:hosted`
- Run read-only smoke against a hosted production target: set `PLAYWRIGHT_BASE_URL`, then run `pnpm test:e2e:hosted:smoke`
- Run read-only smoke against a hosted production target: set `PLAYWRIGHT_BASE_URL`, then run `pnpm test:e2e:hosted:smoke`. Hosted smoke covers production-safe public routes only; fixture-backed profile/search expectations stay local because Vercel must not expose Playwright fixtures.

PowerShell data-flow run with video:

Expand Down
Loading