Skip to content

fix(setup): make a fresh clone runnable + prove RLS denies cross-user access - #2

Merged
Shailesh93602 merged 1 commit into
mainfrom
test/verification
Aug 16, 2026
Merged

Shailesh93602 merged 1 commit into
mainfrom
test/verification

Conversation

@Shailesh93602

Copy link
Copy Markdown
Owner

Verification pass on a clean clone of main (Node 22, npm 10, macOS). Everything below was reproduced from a fresh git clone, not from the local working copy.

What a stranger hit

Step (README, as written) Result on main
npm install works — postinstall: prisma generate succeeds with no env vars
cp .env.example .env fails — cp: .env.example: No such file or directory. .gitignore's .env* never let the template into the repo
npx prisma generate works
npx prisma migrate dev / db push fails — Error: The datasource.url property is required in your Prisma config file. DEBUG=prisma:config* shows why: No config file found in the current working directory. Prisma 7.8 only looks in the cwd, and the config lives at prisma/prisma.config.ts
npm run dev / npm run build needs DATABASE_URL; build dies at page-data collection with Error: DATABASE_URL is not defined — true but undocumented
npm test (Playwright) needs npx playwright install (undocumented) and a live Supabase project + service-role key

So the documented setup path was broken in two places before anyone could see the app.

Fixes

  • .env.example now ships — !.env.example negation in .gitignore, template extended with DIRECT_URL, SUPABASE_SERVICE_ROLE_KEY, CRON_SECRET, NEXT_PUBLIC_SITE_URL, RLS_TEST_DATABASE_URL. Placeholders only.
  • prisma.config.ts moved to the repo root so the CLI actually loads it. npx prisma db push verified working afterwards.
  • dotenv declared in devDependencies — prisma.config.ts imports it but it was only present transitively via prisma.
  • hooks/useRealtimeLogs.ts subscribed to a table that does not exist. It listened on daily_logs / user_id / problems_solved, but schema.prisma has no @@map, so the real names are "DailyLog" / "userId" / "problemsSolved". The subscription could never fire — the "realtime" feature was dead. Names corrected. Not verifiable offline: needs a live Supabase check plus ALTER PUBLICATION supabase_realtime ADD TABLE "DailyLog";.
  • playwright.config.ts: reuseExistingServer: !process.env.CI. It was unconditionally true, so a run would happily test whatever else was listening on :3000 (that actually happened during this verification — an unrelated dev server held the port).
  • README rewritten to match the code. Removed "Framer Motion for buttery-smooth micro-animations" — framer-motion is not a dependency and is imported nowhere — and the "edge computing" claim (everything is the Node runtime). Added the live URL, the 37 unit tests + what CI gates, the RLS section, npx playwright install, and the e2e credential prerequisites.

RLS is now proven, not asserted

prisma/migrations/001_enable_rls.sql was real and complete (RLS enabled + a policy on all 8 user-owned tables), but nothing tested that it denies anything. Added prisma/rls/verify-rls.sql and npm run test:rls:

createdb devtrack_rls
DIRECT_URL=postgresql://localhost:5432/devtrack_rls npx prisma db push
RLS_TEST_DATABASE_URL=postgresql://localhost:5432/devtrack_rls npm run test:rls

It stands up the Supabase pieces the policies depend on (auth.uid(), the authenticated/anon roles), \ir-includes the real policy file, seeds two users, then asserts as user A that every cross-user read, update, delete and forged insert is denied on all 8 tables and that an anonymous client sees zero rows — while user A's own access still works. Any leak raises and exits non-zero. One transaction, rolled back, and it refuses to run against a Supabase database.

Results on local Postgres 16:

NOTICE:  RLS enabled + policy present on all 8 user-owned tables
NOTICE:  reads denied across all 8 tables
NOTICE:  writes denied (update, delete, forged insert)
NOTICE:  owner access still works
NOTICE:  anonymous access denied
 RLS VERIFIED: cross-user reads and writes are denied on all 8 tables   (exit 0)

Negative control (same script with the policy include removed, fresh DB): ERROR: Tables without RLS coverage: User (RLS not enabled), DailyLog (RLS not enabled), ..., exit 3 — so the test is not vacuous.

The README now also states the honest scope: RLS protects the Realtime/PostgREST paths; the app's own reads go through Prisma as the table owner, which bypasses RLS, so server-side isolation still comes from the userId filters in lib/services/*.

Gate

Ran exactly what .github/workflows/ci.yml runs, all green:

  • npx prisma generate ✅
  • npm run type-check ✅
  • npm run lint ✅
  • npm run test:unit ✅ — 37 passed (date 15, streak 10, scoring 7, recommendations 5), matching the claim exactly

Plus, on a fresh git archive of this branch: npm install → cp .env.example .env → npx prisma db push → apply RLS → npm run test:rls (exit 0) → npm run dev serving 200s.

Still open (not fixed here)

  • The Playwright suite cannot pass without credentials. Real run against a live dev server with dummy Supabase keys: setup fails at page.waitForURL(/.*dashboard.*/) after 30s, then 1 failed, 75 did not run for chromium — 226 tests across 3 browsers, none executed. Needs a dedicated Supabase test project.
  • No LICENSE file — an unlicensed public repo is "all rights reserved" to a reader.
  • No screenshot or demo GIF in the README.
  • types/index.ts:54 still has // TODO: Add milestone types when created.
  • docs/archive/tests/*.txt are committed stale test-failure logs.
  • /api/health still does not exist, and /api/cron/keepalive is unauthenticated when CRON_SECRET is unset.

No secrets are or ever were tracked in git (git ls-files | grep -i env is empty across all history); test-results/ and playwright-report/ are correctly ignored.

…ross-user access

A clean `git clone` could not follow the README past step 2:

- `.gitignore`'s `.env*` swallowed `.env.example`, so `cp .env.example .env`
  failed. Added a `!.env.example` negation and committed a placeholder-only
  template that also documents DIRECT_URL, SUPABASE_SERVICE_ROLE_KEY,
  CRON_SECRET and NEXT_PUBLIC_SITE_URL.
- `prisma/prisma.config.ts` was never loaded by the Prisma CLI (7.8 only looks
  in the cwd), so `prisma migrate dev` / `db push` died with "The datasource.url
  property is required in your Prisma config file" even with a correct .env.
  Moved it to the repo root; `db push` now works.
- `dotenv` is imported by prisma.config.ts but was only present as a transitive
  dependency of prisma; declared it in devDependencies.

RLS was version-controlled but nothing proved it denied anything. Added
`prisma/rls/verify-rls.sql` + `npm run test:rls`: it stands up the Supabase
pieces the policies depend on (auth.uid(), the authenticated/anon roles),
applies the real 001_enable_rls.sql, seeds two users, then asserts that user A
is denied every cross-user read, update, delete and forged insert across all 8
tables, and that an anonymous client sees nothing. One transaction, rolled back;
refuses to run against a Supabase database. Verified green on Postgres 16 and
verified red (exit 3) when the policy file is not applied.

Also:
- hooks/useRealtimeLogs.ts subscribed to `daily_logs` / `user_id` /
  `problems_solved`, but schema.prisma declares no @@Map, so the real names are
  "DailyLog" / "userId" / "problemsSolved" — the subscription could never fire.
  Corrected, with a note that the table must be added to the supabase_realtime
  publication.
- playwright.config.ts: reuseExistingServer is now !process.env.CI, so CI can't
  silently test whatever else happens to be listening on :3000.
- README: dropped the Framer Motion claim (not a dependency, never imported) and
  the "edge computing" claim (everything is the Node runtime); added the live
  URL, the unit-test/CI story, the RLS section, `npx playwright install`, and
  the credentials the e2e suite actually needs.
@vercel

vercel Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
dev-track Ready Ready Preview Aug 15, 2026 11:55am

@Shailesh93602
Shailesh93602 merged commit 2be419a into main Aug 16, 2026
4 checks passed
@Shailesh93602
Shailesh93602 deleted the test/verification branch August 16, 2026 06:40

This branch was successfully deployed

1 active deployment
Preview — 16baaf97 Deployed Aug 15, 2026 by vercel[bot]
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.

1 participant