diff --git a/.agents/PAPERCUTS.md b/.agents/PAPERCUTS.md index 2d7a6ea..f9a941f 100644 --- a/.agents/PAPERCUTS.md +++ b/.agents/PAPERCUTS.md @@ -10,6 +10,7 @@ data, or sensitive paths. ## Open +- [ ] `2026-08-20T20:36:32Z` — `codex` — The PR preview Access check treats an immediate workers.dev 404 as proof the preview is public, even though the same URL can begin returning the expected Access redirect seconds later; retry 404 responses as propagation-era errors before failing and recommending stage destruction. - [ ] `2026-08-18T03:06:44Z` — `claude` — Changing an MCP tool's `outputSchema` while the dev server hot-reloads makes in-flight MCP sessions reject the tool's own (already billed) results — clients validate against the schema cached at connect time, surfacing as "must NOT have additional properties". Note in the MCP dev docs/skill: reconnect the MCP session after any output-schema change before re-testing live. - [ ] `2026-08-05T20:59:09Z` — `codex` — The documented `pnpm seed:rank-tracking` command fails before opening local D1 because `scripts/seed-rank-tracking.ts` imports the provider-aware `src/db/schema` barrel and plain `tsx` cannot load the resulting `cloudflare:workers` URL. Keep the seed script on dialect-local schema imports or run it through a Workers-compatible execution path. (Workaround: seed via raw SQL with `wrangler d1 execute DB --local`.) - [ ] `2026-08-01T16:28:36Z` — `claude` — web's pinned wrangler 4.71.0 fails `kv namespace create` with a bare "Authentication error [code: 10000]" even though the OAuth token has workers_kv write scope; wrangler@4.118.0 succeeds with identical auth. Fix: bump wrangler in web/package.json. diff --git a/src/server/lib/ga4Client.test.ts b/src/server/lib/ga4Client.test.ts index cd1312b..30b1857 100644 --- a/src/server/lib/ga4Client.test.ts +++ b/src/server/lib/ga4Client.test.ts @@ -164,14 +164,6 @@ describe("ga4Client admin API", () => { .mockResolvedValueOnce( jsonResponse({ streamEnabled: true, - scrollsEnabled: true, - outboundClicksEnabled: true, - siteSearchEnabled: true, - videoEngagementEnabled: true, - fileDownloadsEnabled: true, - pageChangesEnabled: true, - formInteractionsEnabled: false, - searchQueryParameter: "q,s", }), ) .mockResolvedValueOnce( @@ -222,7 +214,11 @@ describe("ga4Client admin API", () => { const metrics = await client.listCustomMetrics("properties/11"); expect(streams[0]?.webStreamData?.measurementId).toBe("G-ABC123"); - expect(enhanced.siteSearchEnabled).toBe(true); + expect(enhanced).toMatchObject({ + streamEnabled: true, + siteSearchEnabled: false, + searchQueryParameter: "", + }); expect(keyEvents[0]?.eventName).toBe("purchase"); expect(dimensions[0]?.parameterName).toBe("content_type"); expect(metrics[0]?.parameterName).toBe("quality_score"); diff --git a/src/server/lib/ga4Client.ts b/src/server/lib/ga4Client.ts index 7e9df6b..432d31f 100644 --- a/src/server/lib/ga4Client.ts +++ b/src/server/lib/ga4Client.ts @@ -66,15 +66,16 @@ const dataStreamsResponseSchema = z.object({ nextPageToken: z.string().optional(), }); const enhancedMeasurementSettingsSchema = z.object({ - streamEnabled: z.boolean(), - scrollsEnabled: z.boolean(), - outboundClicksEnabled: z.boolean(), - siteSearchEnabled: z.boolean(), - videoEngagementEnabled: z.boolean(), - fileDownloadsEnabled: z.boolean(), - pageChangesEnabled: z.boolean(), - formInteractionsEnabled: z.boolean(), - searchQueryParameter: z.string(), + // ProtoJSON omits scalar fields at their default values. + streamEnabled: z.boolean().default(false), + scrollsEnabled: z.boolean().default(false), + outboundClicksEnabled: z.boolean().default(false), + siteSearchEnabled: z.boolean().default(false), + videoEngagementEnabled: z.boolean().default(false), + fileDownloadsEnabled: z.boolean().default(false), + pageChangesEnabled: z.boolean().default(false), + formInteractionsEnabled: z.boolean().default(false), + searchQueryParameter: z.string().default(""), uriQueryParameter: z.string().optional().default(""), }); const keyEventSchema = z.object({