From 06d713fca2538f4eaf0b9be2742d4cce680c12c2 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 14 Apr 2026 13:54:44 +0000 Subject: [PATCH 1/2] Add Cursor Cloud specific instructions to AGENTS.md - Document services overview, required secrets, and dev commands - Note gotchas: npm lockfile, --webpack flag, middleware deprecation warning - Reference pre-existing lint errors to avoid false regression reports Co-authored-by: Sarath Donepudi --- AGENTS.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 29a4ecf..459366f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,3 +11,33 @@ Mapbox does **not** work with SSR. Importing `mapbox-gl` in a code path that run **Required pattern:** load the map UI only on the client with `next/dynamic` and **`{ ssr: false }`**. Never add a Server Component that imports `mapbox-gl` or a module that imports it at top level without this guard. **In this repo:** `components/HomePage.tsx` wraps `MapCanvas` in `dynamic(() => import("@/components/map/MapCanvas"), { ssr: false, ... })`. Keep new Mapbox code behind that boundary (or another `dynamic(..., { ssr: false })`). + +## Cursor Cloud specific instructions + +### Services overview + +**pgtruth** is a Next.js 16 (App Router) crowdsourced PG-review app with a Mapbox map. The backend is Supabase (PostgreSQL + service role key). There is no Docker setup or local database — all persistence goes through the Supabase REST API. + +### Running the app + +- `npm run dev` — starts the dev server on port 3000 (uses `--webpack` flag). +- `npm run build` — production build; also validates TypeScript. +- `npm run lint` — ESLint 9 with `eslint-config-next`. Pre-existing warnings/errors exist in the repo; 4 errors and 13 warnings as of initial setup — do not treat those as regressions. +- `npm test` — Vitest, runs 10 test files (53 tests) in `lib/**/*.test.ts`. Pure unit tests, no external services needed. + +### Required secrets (set via Cursor Secrets) + +| Secret | Required for | +|---|---| +| `NEXT_PUBLIC_SUPABASE_URL` | All data loading / API routes | +| `SUPABASE_SERVICE_ROLE_KEY` | Server-side writes (review submission) | +| `NEXT_PUBLIC_MAPBOX_TOKEN` | Map rendering | + +Without real Supabase + Mapbox tokens the app starts but shows fallback UI (gray map, "Can't load reviews" banner). Lint and tests work without any secrets. + +### Gotchas + +- The lockfile is `package-lock.json` — use **npm**, not pnpm/yarn. +- `next dev` uses `--webpack` (not Turbopack); the build script does too. +- The `middleware.ts` file triggers a deprecation warning ("use proxy instead") — this is expected with Next.js 16 and can be ignored. +- `.env.local` is gitignored; create it from `env.example` and fill in real keys. From a6fb847a6548c28f0f2c25ba36e7e4058bde7934 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 14 Apr 2026 14:59:16 +0000 Subject: [PATCH 2/2] Fix rent label rev count to match pin badge total MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'N rev' text in the map pin rent label used rents.length (only reviews with valid positive rent) instead of reps.length (total reviews at this place). This caused a mismatch with the badge and hover popup which both show total review count. Now all three surfaces — badge, hover, and rent label — show the same total review count. Co-authored-by: Sarath Donepudi --- lib/place-rent-label.test.ts | 5 +++++ lib/place-rent-label.ts | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/place-rent-label.test.ts b/lib/place-rent-label.test.ts index f46b8f0..3bbf570 100644 --- a/lib/place-rent-label.test.ts +++ b/lib/place-rent-label.test.ts @@ -21,4 +21,9 @@ describe("formatMapPinRentLine", () => { const s = formatMapPinRentLine([row(8000), row(28000)]); expect(s).toContain("–"); }); + + it("rev count reflects total reviews, not just those with rent data", () => { + const s = formatMapPinRentLine([row(10000), row(0), row(15000)]); + expect(s).toContain("3 rev"); + }); }); diff --git a/lib/place-rent-label.ts b/lib/place-rent-label.ts index b4b6834..424a633 100644 --- a/lib/place-rent-label.ts +++ b/lib/place-rent-label.ts @@ -24,9 +24,8 @@ export function formatMapPinRentLine(reps: ReportRow[]): string { const med = Math.round(medianSorted(sorted)); const min = sorted[0]!; const max = sorted[sorted.length - 1]!; - const n = rents.length; - const medPart = `Med ${ruShort(med)}/mo · ${n} rev`; + const medPart = `Med ${ruShort(med)}/mo · ${reps.length} rev`; const spread = max - min; const wide = spread > Math.max(4000, med * 0.12) && min !== max;