@canonry/canonry 7.64.2 → 7.64.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +2 -2
  2. package/assets/assets/{AgentSetupPage-Cl9VXxLL.js → AgentSetupPage-DgcU4n6k.js} +1 -1
  3. package/assets/assets/{AuditHistoryPanel-DLa6Ca5t.js → AuditHistoryPanel-IDTBP47p.js} +1 -1
  4. package/assets/assets/{BacklinksPage-Dxnz-sUy.js → BacklinksPage-tbfBeOWq.js} +1 -1
  5. package/assets/assets/{HistoryPage-PU7UNO3T.js → HistoryPage-BT17i1bv.js} +1 -1
  6. package/assets/assets/{MeasurementPropertyPage-DD9_Y-qo.js → MeasurementPropertyPage-CNVW1nD0.js} +1 -1
  7. package/assets/assets/ProjectPage-BOpHsl0H.js +9 -0
  8. package/assets/assets/{RunsPage-BCySoVOJ.js → RunsPage-DSbp_ueP.js} +1 -1
  9. package/assets/assets/{SettingsPage-CDncGwNQ.js → SettingsPage-DhXsS4mE.js} +1 -1
  10. package/assets/assets/{SiteHealthSection-C4C2LBCJ.js → SiteHealthSection-DDnJ6MmG.js} +2 -2
  11. package/assets/assets/{ToneBadge-Cvv6Tkk7.js → ToneBadge-BQIKzc8y.js} +1 -1
  12. package/assets/assets/{TrafficPage-4oknsJk1.js → TrafficPage-2Ix0v2Sw.js} +1 -1
  13. package/assets/assets/{TrafficSourceDetailPage-UQKbZgtR.js → TrafficSourceDetailPage-Cytn_uBJ.js} +1 -1
  14. package/assets/assets/{account-context-BL8j43iU.js → account-context-eRm8f3bl.js} +1 -1
  15. package/assets/assets/{card-BKud0olB.js → card-CWFz5ZQm.js} +1 -1
  16. package/assets/assets/{extract-error-message-CvEgflI1.js → extract-error-message-BdsLX91O.js} +1 -1
  17. package/assets/assets/{format-helpers-B1eNfBmy.js → format-helpers-Dv7wus0N.js} +1 -1
  18. package/assets/assets/{index-Ci_T3fwM.js → index-CipZo_Z_.js} +4 -4
  19. package/assets/assets/{query-client-Bf5Rr6po.js → query-client-B4X4SMBT.js} +1 -1
  20. package/assets/assets/{react-query-CsFtWT8r.js → react-query-6xQVTyvM.js} +1 -1
  21. package/assets/assets/{react-sigma_core.esm.min-CIzyqOHN.js → react-sigma_core.esm.min-_zOXWmWO.js} +1 -1
  22. package/assets/assets/{service-CTRAeUEv.js → service-D5-ENCES.js} +1 -1
  23. package/assets/index.html +7 -7
  24. package/dist/{ads-EFXCND5Z.js → ads-JR7S3FK6.js} +3 -3
  25. package/dist/{agent-2MAONYLR.js → agent-AMVJ3FUV.js} +7 -7
  26. package/dist/{agent-ask-5555LQQL.js → agent-ask-KZTQLKGM.js} +3 -3
  27. package/dist/{agent-conversations-LYWOS4X3.js → agent-conversations-WJJ2K2ON.js} +3 -3
  28. package/dist/{agent-memory-HOYIIO66.js → agent-memory-TNWIXVZ5.js} +3 -3
  29. package/dist/{agent-providers-EYXB2DMX.js → agent-providers-KJVQSN3Q.js} +3 -3
  30. package/dist/{agent-transcript-BWDOJXPV.js → agent-transcript-PBYDJLYH.js} +3 -3
  31. package/dist/{analytics-46VKY4SP.js → analytics-CBPNUDES.js} +3 -3
  32. package/dist/{apply-GII5J3QB.js → apply-ZX4OF5PG.js} +3 -3
  33. package/dist/{backfill-WSIEPRES.js → backfill-PPRSFYAV.js} +9 -9
  34. package/dist/{backlinks-GRHTLP5Z.js → backlinks-O4Q6WH53.js} +3 -3
  35. package/dist/{bing-5QDDHK57.js → bing-SIZPWBYU.js} +3 -3
  36. package/dist/{bootstrap-GWDFCGEQ.js → bootstrap-XF6DMDQI.js} +10 -10
  37. package/dist/{cdp-YMIJN52Z.js → cdp-DD7ARB62.js} +7 -7
  38. package/dist/{chunk-Y3VMSYEG.js → chunk-22XKOBJD.js} +1 -1
  39. package/dist/{chunk-I62VYS4B.js → chunk-73QOQIFZ.js} +4 -4
  40. package/dist/{chunk-6AYOWQJ3.js → chunk-C3FQGQDS.js} +3 -3
  41. package/dist/{chunk-7STLCYWL.js → chunk-CCJIMTYO.js} +5 -5
  42. package/dist/{chunk-ZGLLSPBB.js → chunk-CKRXLVWQ.js} +2 -2
  43. package/dist/{chunk-L6IQN2Y5.js → chunk-DIS2JA7D.js} +2 -2
  44. package/dist/{chunk-7KBFBFDS.js → chunk-DPRGW4BM.js} +4 -4
  45. package/dist/{chunk-7LVZATRE.js → chunk-G33PG23U.js} +1 -1
  46. package/dist/{chunk-RYH3XP6J.js → chunk-HQGMIHG6.js} +20 -20
  47. package/dist/{chunk-AUIHVRJ3.js → chunk-IJF7KNU6.js} +2 -2
  48. package/dist/{chunk-XR3R5PDK.js → chunk-KJA7V3IT.js} +1 -1
  49. package/dist/{chunk-UQABYWAX.js → chunk-LSKAENOY.js} +1 -1
  50. package/dist/{chunk-DKVY6HFW.js → chunk-MFNU4NRS.js} +3 -3
  51. package/dist/{chunk-PUHALZY7.js → chunk-MLXU4QOF.js} +334 -334
  52. package/dist/{chunk-7V6DJCZO.js → chunk-N7M7UVYT.js} +1 -1
  53. package/dist/{chunk-ZYE7D2OC.js → chunk-NCUTFEU4.js} +1 -1
  54. package/dist/{chunk-WFOIIHAK.js → chunk-NMDXZWFB.js} +2 -2
  55. package/dist/{chunk-6ZA23GRE.js → chunk-NYTPS5WW.js} +8 -8
  56. package/dist/{chunk-JP4Q5FEW.js → chunk-OMB3VLDQ.js} +3 -3
  57. package/dist/{chunk-CNPYR2CQ.js → chunk-PNZE3XLO.js} +1 -1
  58. package/dist/{chunk-NFZXB5ZV.js → chunk-Q4JRFMCJ.js} +5 -5
  59. package/dist/{chunk-VLOWXBJS.js → chunk-QT7UBYG7.js} +3 -3
  60. package/dist/{chunk-DYDLK3YY.js → chunk-RR7ZDGC7.js} +2 -2
  61. package/dist/{chunk-M6QGMJAQ.js → chunk-T4EGKFOV.js} +1 -1
  62. package/dist/{chunk-MXQB7AAP.js → chunk-UJ222WSC.js} +1 -1
  63. package/dist/{chunk-TX4HBLFP.js → chunk-UX667IQM.js} +277 -264
  64. package/dist/{chunk-CLMJSIZU.js → chunk-VL5LVBLE.js} +1 -1
  65. package/dist/{chunk-2BJDLTDI.js → chunk-VMLCPTRZ.js} +1 -1
  66. package/dist/{chunk-V23ALG2D.js → chunk-WACG4O26.js} +2 -2
  67. package/dist/{chunk-ITYUIHKO.js → chunk-WODZX4Y6.js} +1 -1
  68. package/dist/{chunk-ZUH7GDQ4.js → chunk-YNPUS3Y7.js} +4 -4
  69. package/dist/{chunk-4PRXS5JH.js → chunk-YVYID65D.js} +12 -1
  70. package/dist/{chunk-BAQOH3LE.js → chunk-Z4CVEVP6.js} +3 -3
  71. package/dist/{chunk-BUED4RWE.js → chunk-ZTO5KPQB.js} +1 -1
  72. package/dist/{citations-AMOXXK5R.js → citations-DQGMUJYX.js} +3 -3
  73. package/dist/{cli-catalog-K5EQZBOO.js → cli-catalog-G7USVSOC.js} +3 -3
  74. package/dist/{cli-commands-NBOP4CQW.js → cli-commands-YUBGTHRG.js} +7 -7
  75. package/dist/cli.js +13 -13
  76. package/dist/{competitor-YQBDZE6A.js → competitor-CIKVJ4H4.js} +3 -3
  77. package/dist/{content-DFZ56U3J.js → content-DPWKB5SO.js} +3 -3
  78. package/dist/{dashboard-LIPZS22H.js → dashboard-OX2JEGEK.js} +6 -6
  79. package/dist/{demo-XZJKCQRO.js → demo-NMMLZ6VZ.js} +1 -1
  80. package/dist/{demo-server-3BCUBH4H.js → demo-server-VD6C773Q.js} +11 -11
  81. package/dist/{discover-JDJ2O6D6.js → discover-3JGVGPMR.js} +3 -3
  82. package/dist/{discover-eval-5GST6BOJ.js → discover-eval-HVU24KNC.js} +3 -3
  83. package/dist/{doctor-2LJGHCIZ.js → doctor-77VPDK2N.js} +3 -3
  84. package/dist/{evidence-FQKL6ULX.js → evidence-WSSOMBED.js} +3 -3
  85. package/dist/{export-cmd-KNGYT4JH.js → export-cmd-CPO73FP7.js} +3 -3
  86. package/dist/{ga-UH4RUHX2.js → ga-QOIYDTEX.js} +9 -5
  87. package/dist/{gbp-IPMROSVV.js → gbp-JEPBXCS6.js} +3 -3
  88. package/dist/{google-QU5M737H.js → google-5BZYXAJH.js} +4 -4
  89. package/dist/{google-marketing-QCLVAP25.js → google-marketing-Q36Q7YFU.js} +1 -1
  90. package/dist/{health-cmd-7UFZ5MT6.js → health-cmd-5KSRFNNN.js} +3 -3
  91. package/dist/{history-3H3CKHVR.js → history-WE4K4QIA.js} +3 -3
  92. package/dist/index.d.ts +11 -11
  93. package/dist/index.js +24 -24
  94. package/dist/{init-RZY3NRFZ.js → init-TDAXSYRR.js} +11 -11
  95. package/dist/{insights-LEVVXDBW.js → insights-K6PVVNZA.js} +3 -3
  96. package/dist/intelligence-service-GCISXTKM.js +15 -0
  97. package/dist/{journeys-JMQBUF2E.js → journeys-GD2QE2YK.js} +3 -3
  98. package/dist/{keys-LF2UMTN6.js → keys-SLJDSG7P.js} +3 -3
  99. package/dist/{keyword-JSJYNWN2.js → keyword-KDDWSW24.js} +3 -3
  100. package/dist/{logs-RWUB42V3.js → logs-PMIEBMOW.js} +3 -3
  101. package/dist/{mcp-FWQXTWAR.js → mcp-E5YLJ4LN.js} +2 -2
  102. package/dist/mcp.js +9 -9
  103. package/dist/{measurement-plan-4WXYE6CZ.js → measurement-plan-QZDBAH5D.js} +5 -5
  104. package/dist/{notify-FBS43GY5.js → notify-3QXR6PO2.js} +3 -3
  105. package/dist/{organic-evidence-TTXXAHFX.js → organic-evidence-UXEEKJPH.js} +3 -3
  106. package/dist/{overview-AB5JTMWR.js → overview-2Q4E75BW.js} +4 -4
  107. package/dist/{project-GSQMF736.js → project-M7VFAIJ2.js} +3 -3
  108. package/dist/{query-JITDUO3B.js → query-WDQGPIKS.js} +3 -3
  109. package/dist/{research-UU5W2XPU.js → research-U2GP2EQK.js} +3 -3
  110. package/dist/{results-export-ZX62A645.js → results-export-SMNP3XZT.js} +3 -3
  111. package/dist/{run-HXNS5CB3.js → run-CZXLPC3S.js} +4 -4
  112. package/dist/{schedule-Q4XMBZAH.js → schedule-DVIXJJFI.js} +3 -3
  113. package/dist/{search-GC4RYLYD.js → search-GFU2VPG4.js} +3 -3
  114. package/dist/{serve-Z722TPMP.js → serve-C2TW7ZZC.js} +25 -25
  115. package/dist/{session-JI4YODZS.js → session-5MVIOTFY.js} +12 -12
  116. package/dist/{settings-5GFLK4DY.js → settings-VYVGART2.js} +3 -3
  117. package/dist/{skills-B7Z5S3IT.js → skills-EWEPVEDD.js} +2 -2
  118. package/dist/{snapshot-2JOQFYJE.js → snapshot-L2DX6EBI.js} +3 -3
  119. package/dist/{src-2UNG3E4M.js → src-RBXPA4CW.js} +2 -2
  120. package/dist/{status-NKK5MYNE.js → status-ZJLUWVST.js} +4 -4
  121. package/dist/{technical-aeo-MQLGHVIX.js → technical-aeo-7KRBPNV7.js} +3 -3
  122. package/dist/{telemetry-J5F2H7OJ.js → telemetry-ZROXU4SH.js} +4 -4
  123. package/dist/{tools-CXANMI23.js → tools-NDQN64CH.js} +11 -11
  124. package/dist/{traffic-BVKW6QDD.js → traffic-W3NOHWNK.js} +5 -5
  125. package/dist/{users-2EKLHWPH.js → users-GGJSWVSI.js} +3 -3
  126. package/dist/{visibility-stats-HVQ6VUEB.js → visibility-stats-VZ5A7LMI.js} +3 -3
  127. package/dist/{wordpress-EEYBM634.js → wordpress-JYXIO3DJ.js} +3 -3
  128. package/package.json +1 -1
  129. package/assets/assets/ProjectPage-CoaDuk54.js +0 -9
  130. package/dist/intelligence-service-GQQNTMUX.js +0 -15
@@ -9,14 +9,14 @@ import {
9
9
  normalizeCloudflareWorkerEvent,
10
10
  sessionizeJourneyRequests,
11
11
  verifyRequestSignature
12
- } from "./chunk-UQABYWAX.js";
12
+ } from "./chunk-LSKAENOY.js";
13
13
  import {
14
14
  currentOutcomeAttribution,
15
15
  getRequestContext,
16
16
  registerRequestContext,
17
17
  requestAuditIdentity,
18
18
  sanitizeRequestContext
19
- } from "./chunk-BUED4RWE.js";
19
+ } from "./chunk-ZTO5KPQB.js";
20
20
  import {
21
21
  SentimentIdempotencyConflict,
22
22
  SentimentRepository,
@@ -154,7 +154,7 @@ import {
154
154
  userSessions,
155
155
  users,
156
156
  writeNegativeReviewMaxStars
157
- } from "./chunk-ZYE7D2OC.js";
157
+ } from "./chunk-NCUTFEU4.js";
158
158
  import {
159
159
  ADS_ACTIVATE_SCOPE,
160
160
  ADS_ACTIVATION_ABSOLUTE_MAX_ENTITIES,
@@ -647,6 +647,7 @@ import {
647
647
  gaOverviewComparisonDaysAgo,
648
648
  gaOverviewComparisonRanges,
649
649
  gaOverviewResponseSchema,
650
+ gaSearchLandingHasSearchData,
650
651
  gaSearchLandingPagesResponseSchema,
651
652
  gaSearchLandingWindowSchema,
652
653
  gaSocialReferralTrendResponseSchema,
@@ -1166,7 +1167,7 @@ import {
1166
1167
  wordpressSchemaDeployResultDtoSchema,
1167
1168
  wordpressSchemaStatusResultDtoSchema,
1168
1169
  wordpressStatusDtoSchema
1169
- } from "./chunk-4PRXS5JH.js";
1170
+ } from "./chunk-YVYID65D.js";
1170
1171
 
1171
1172
  // ../api-routes/src/user-session.ts
1172
1173
  import crypto2 from "crypto";
@@ -56223,7 +56224,7 @@ async function cdpRoutes(app, opts) {
56223
56224
 
56224
56225
  // ../api-routes/src/ga.ts
56225
56226
  import crypto47 from "crypto";
56226
- import { eq as eq73, desc as desc36, and as and61, sql as sql25 } from "drizzle-orm";
56227
+ import { eq as eq73, desc as desc36, and as and61, sql as sql26 } from "drizzle-orm";
56227
56228
 
56228
56229
  // ../api-routes/src/ga-session-history.ts
56229
56230
  function buildSessionHistory(landingPageDays, dailyTotals) {
@@ -56388,7 +56389,7 @@ function findBiggestMover(current, prior) {
56388
56389
 
56389
56390
  // ../api-routes/src/ga-search-landing-pages.ts
56390
56391
  import crypto46 from "crypto";
56391
- import { and as and60, asc as asc16, count as count5, desc as desc35, eq as eq72 } from "drizzle-orm";
56392
+ import { and as and60, asc as asc16, count as count5, desc as desc35, eq as eq72, gte as gte17, lte as lte17, sql as sql25 } from "drizzle-orm";
56392
56393
  function persistSearchLandingSnapshot(db, input) {
56393
56394
  db.transaction((tx) => {
56394
56395
  deleteSearchLandingRows(tx, input.projectId);
@@ -56504,6 +56505,13 @@ function buildGaSearchLandingPages(db, projectName, query, connections) {
56504
56505
  const pageScope = and60(eq72(gaSearchLandingPages.projectId, project.id), eq72(gaSearchLandingPages.windowKey, window2));
56505
56506
  const totalRows = otherProperty ? 0 : db.select({ value: count5() }).from(gaSearchLandingPages).where(pageScope).get()?.value ?? 0;
56506
56507
  const rows = otherProperty ? [] : db.select().from(gaSearchLandingPages).where(pageScope).orderBy(desc35(gaSearchLandingPages.clicks), desc35(gaSearchLandingPages.impressions), asc16(gaSearchLandingPages.landingPage)).limit(limit).offset(offset).all();
56508
+ const total = stored ? toWireMetrics({
56509
+ clicks: stored.totalClicks,
56510
+ impressions: stored.totalImpressions,
56511
+ ctr: stored.totalCtr,
56512
+ averagePosition: stored.totalAveragePosition,
56513
+ activeUsers: stored.totalActiveUsers
56514
+ }) : null;
56507
56515
  return gaSearchLandingPagesResponseSchema.parse({
56508
56516
  source: "ga4-search-console-link",
56509
56517
  status: state?.searchLandingStatus ?? "never-synced",
@@ -56517,13 +56525,7 @@ function buildGaSearchLandingPages(db, projectName, query, connections) {
56517
56525
  timeZone: stored?.timeZone ?? null,
56518
56526
  subjectToThresholding: stored?.subjectToThresholding ?? false,
56519
56527
  dataLossFromOtherRow: stored?.dataLossFromOtherRow ?? false,
56520
- total: stored ? toWireMetrics({
56521
- clicks: stored.totalClicks,
56522
- impressions: stored.totalImpressions,
56523
- ctr: stored.totalCtr,
56524
- averagePosition: stored.totalAveragePosition,
56525
- activeUsers: stored.totalActiveUsers
56526
- }) : null,
56528
+ total,
56527
56529
  reportRowCount: stored?.reportRowCount ?? null,
56528
56530
  rowsCapped: stored?.rowsCapped ?? false,
56529
56531
  totalRows,
@@ -56532,9 +56534,20 @@ function buildGaSearchLandingPages(db, projectName, query, connections) {
56532
56534
  rows: rows.map((row) => ({
56533
56535
  landingPage: row.landingPage,
56534
56536
  ...toWireMetrics(row)
56535
- }))
56537
+ })),
56538
+ searchConsoleLink: stored && total ? searchConsoleLinkFor(db, project.id, total, stored.periodStart, stored.periodEnd) : null
56536
56539
  });
56537
56540
  }
56541
+ function searchConsoleLinkFor(db, projectId, total, windowStart, windowEnd) {
56542
+ const stored = db.select({
56543
+ days: count5(),
56544
+ impressions: sql25`sum(${gscDailyTotals.impressions})`
56545
+ }).from(gscDailyTotals).where(and60(eq72(gscDailyTotals.projectId, projectId), gte17(gscDailyTotals.date, windowStart), lte17(gscDailyTotals.date, windowEnd))).get();
56546
+ const searchConsoleImpressions = stored && stored.days > 0 ? Number(stored.impressions ?? 0) : null;
56547
+ if (gaSearchLandingHasSearchData(total)) return { state: "has-data", searchConsoleImpressions };
56548
+ if (searchConsoleImpressions === null) return { state: "unknown", searchConsoleImpressions };
56549
+ return { state: searchConsoleImpressions > 0 ? "not-linked" : "no-search-data", searchConsoleImpressions };
56550
+ }
56538
56551
  async function gaSearchLandingPagesRoutes(app, opts) {
56539
56552
  app.get("/projects/:name/ga/search-landing-pages", (request) => buildGaSearchLandingPages(app.db, request.params.name, request.query, opts));
56540
56553
  }
@@ -56554,8 +56567,8 @@ function withSessionShares(rows) {
56554
56567
  }
56555
56568
  function dateRangeConditions(column, range) {
56556
56569
  const conditions = [];
56557
- if (range.startDate) conditions.push(sql25`${column} >= ${range.startDate}`);
56558
- if (range.endDate) conditions.push(sql25`${column} <= ${range.endDate}`);
56570
+ if (range.startDate) conditions.push(sql26`${column} >= ${range.startDate}`);
56571
+ if (range.endDate) conditions.push(sql26`${column} <= ${range.endDate}`);
56559
56572
  return conditions;
56560
56573
  }
56561
56574
  var SOCIAL_CHANNEL_GROUPS2 = /* @__PURE__ */ new Set(["Organic Social", "Paid Social"]);
@@ -56615,8 +56628,8 @@ function persistAcquisitionMeasurement(db, input) {
56615
56628
  db.transaction((tx) => {
56616
56629
  tx.delete(gaAcquisitionDaily).where(and61(
56617
56630
  eq73(gaAcquisitionDaily.projectId, input.projectId),
56618
- sql25`${gaAcquisitionDaily.date} >= ${startDate}`,
56619
- sql25`${gaAcquisitionDaily.date} <= ${endDate}`
56631
+ sql26`${gaAcquisitionDaily.date} >= ${startDate}`,
56632
+ sql26`${gaAcquisitionDaily.date} <= ${endDate}`
56620
56633
  )).run();
56621
56634
  for (const row of input.report.rows) {
56622
56635
  tx.insert(gaAcquisitionDaily).values({
@@ -56657,8 +56670,8 @@ function persistLeadMeasurement(db, input) {
56657
56670
  db.transaction((tx) => {
56658
56671
  tx.delete(gaLeadEventsDaily).where(and61(
56659
56672
  eq73(gaLeadEventsDaily.projectId, input.projectId),
56660
- sql25`${gaLeadEventsDaily.date} >= ${startDate}`,
56661
- sql25`${gaLeadEventsDaily.date} <= ${endDate}`
56673
+ sql26`${gaLeadEventsDaily.date} >= ${startDate}`,
56674
+ sql26`${gaLeadEventsDaily.date} <= ${endDate}`
56662
56675
  )).run();
56663
56676
  for (const row of input.report.rows) {
56664
56677
  tx.insert(gaLeadEventsDaily).values({
@@ -57141,8 +57154,8 @@ async function ga4Routes(app, opts) {
57141
57154
  tx.delete(gaTrafficSnapshots).where(
57142
57155
  and61(
57143
57156
  eq73(gaTrafficSnapshots.projectId, project.id),
57144
- sql25`${gaTrafficSnapshots.date} >= ${summary3.periodStart}`,
57145
- sql25`${gaTrafficSnapshots.date} <= ${summary3.periodEnd}`
57157
+ sql26`${gaTrafficSnapshots.date} >= ${summary3.periodStart}`,
57158
+ sql26`${gaTrafficSnapshots.date} <= ${summary3.periodEnd}`
57146
57159
  )
57147
57160
  ).run();
57148
57161
  for (const row of rows) {
@@ -57164,8 +57177,8 @@ async function ga4Routes(app, opts) {
57164
57177
  tx.delete(gaDailyTotals).where(
57165
57178
  and61(
57166
57179
  eq73(gaDailyTotals.projectId, project.id),
57167
- sql25`${gaDailyTotals.date} >= ${dailyTotals.startDate}`,
57168
- sql25`${gaDailyTotals.date} <= ${dailyTotals.endDate}`
57180
+ sql26`${gaDailyTotals.date} >= ${dailyTotals.startDate}`,
57181
+ sql26`${gaDailyTotals.date} <= ${dailyTotals.endDate}`
57169
57182
  )
57170
57183
  ).run();
57171
57184
  for (const row of dailyTotals.rows) {
@@ -57226,8 +57239,8 @@ async function ga4Routes(app, opts) {
57226
57239
  tx.delete(gaAiReferrals).where(
57227
57240
  and61(
57228
57241
  eq73(gaAiReferrals.projectId, project.id),
57229
- sql25`${gaAiReferrals.date} >= ${summary3.periodStart}`,
57230
- sql25`${gaAiReferrals.date} <= ${summary3.periodEnd}`
57242
+ sql26`${gaAiReferrals.date} >= ${summary3.periodStart}`,
57243
+ sql26`${gaAiReferrals.date} <= ${summary3.periodEnd}`
57231
57244
  )
57232
57245
  ).run();
57233
57246
  for (const row of aiReferrals) {
@@ -57258,8 +57271,8 @@ async function ga4Routes(app, opts) {
57258
57271
  tx.delete(gaSocialReferrals).where(
57259
57272
  and61(
57260
57273
  eq73(gaSocialReferrals.projectId, project.id),
57261
- sql25`${gaSocialReferrals.date} >= ${summary3.periodStart}`,
57262
- sql25`${gaSocialReferrals.date} <= ${summary3.periodEnd}`
57274
+ sql26`${gaSocialReferrals.date} >= ${summary3.periodStart}`,
57275
+ sql26`${gaSocialReferrals.date} <= ${summary3.periodEnd}`
57263
57276
  )
57264
57277
  ).run();
57265
57278
  for (const row of socialReferrals) {
@@ -57497,9 +57510,9 @@ async function ga4Routes(app, opts) {
57497
57510
  totalUsers: gaTrafficSummaries.totalUsers
57498
57511
  }).from(gaTrafficSummaries).where(eq73(gaTrafficSummaries.projectId, project.id)).get();
57499
57512
  const retainedBounds = [
57500
- app.db.select({ min: sql25`MIN(${gaTrafficSnapshots.date})`, max: sql25`MAX(${gaTrafficSnapshots.date})` }).from(gaTrafficSnapshots).where(eq73(gaTrafficSnapshots.projectId, project.id)).get(),
57501
- app.db.select({ min: sql25`MIN(${gaAiReferrals.date})`, max: sql25`MAX(${gaAiReferrals.date})` }).from(gaAiReferrals).where(eq73(gaAiReferrals.projectId, project.id)).get(),
57502
- app.db.select({ min: sql25`MIN(${gaSocialReferrals.date})`, max: sql25`MAX(${gaSocialReferrals.date})` }).from(gaSocialReferrals).where(eq73(gaSocialReferrals.projectId, project.id)).get()
57513
+ app.db.select({ min: sql26`MIN(${gaTrafficSnapshots.date})`, max: sql26`MAX(${gaTrafficSnapshots.date})` }).from(gaTrafficSnapshots).where(eq73(gaTrafficSnapshots.projectId, project.id)).get(),
57514
+ app.db.select({ min: sql26`MIN(${gaAiReferrals.date})`, max: sql26`MAX(${gaAiReferrals.date})` }).from(gaAiReferrals).where(eq73(gaAiReferrals.projectId, project.id)).get(),
57515
+ app.db.select({ min: sql26`MIN(${gaSocialReferrals.date})`, max: sql26`MAX(${gaSocialReferrals.date})` }).from(gaSocialReferrals).where(eq73(gaSocialReferrals.projectId, project.id)).get()
57503
57516
  ];
57504
57517
  const retainedDates = retainedBounds.flatMap((bound) => [bound?.min, bound?.max]).filter((date) => Boolean(date));
57505
57518
  const projectSummaryCoversAll = Boolean(
@@ -57513,9 +57526,9 @@ async function ga4Routes(app, opts) {
57513
57526
  const socialConditions = [eq73(gaSocialReferrals.projectId, project.id), ...dateRangeConditions(gaSocialReferrals.date, measuredRange)];
57514
57527
  const snapshotTotalsRow = !denominatorRow ? (() => {
57515
57528
  const summed = app.db.select({
57516
- totalSessions: sql25`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)`,
57517
- totalOrganicSessions: sql25`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)`,
57518
- totalUsers: sql25`COALESCE(SUM(${gaTrafficSnapshots.users}), 0)`
57529
+ totalSessions: sql26`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)`,
57530
+ totalOrganicSessions: sql26`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)`,
57531
+ totalUsers: sql26`COALESCE(SUM(${gaTrafficSnapshots.users}), 0)`
57519
57532
  }).from(gaTrafficSnapshots).where(and61(...snapshotConditions)).get();
57520
57533
  return {
57521
57534
  totalSessions: summed?.totalSessions ?? 0,
@@ -57528,35 +57541,35 @@ async function ga4Routes(app, opts) {
57528
57541
  })() : null;
57529
57542
  const summaryRow = denominatorRow ?? snapshotTotalsRow;
57530
57543
  const directTotalRow = windowSummaryRow ? { totalDirectSessions: windowSummaryRow.totalDirectSessions } : app.db.select({
57531
- totalDirectSessions: sql25`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`
57544
+ totalDirectSessions: sql26`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`
57532
57545
  }).from(gaTrafficSnapshots).where(and61(...snapshotConditions)).get();
57533
57546
  const rows = app.db.select({
57534
- landingPage: sql25`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`,
57535
- sessions: sql25`SUM(${gaTrafficSnapshots.sessions})`,
57536
- organicSessions: sql25`SUM(${gaTrafficSnapshots.organicSessions})`,
57537
- directSessions: sql25`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`,
57538
- users: sql25`SUM(${gaTrafficSnapshots.users})`
57539
- }).from(gaTrafficSnapshots).where(and61(...snapshotConditions)).groupBy(sql25`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`).orderBy(sql25`SUM(${gaTrafficSnapshots.sessions}) DESC`).limit(limit).all();
57547
+ landingPage: sql26`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`,
57548
+ sessions: sql26`SUM(${gaTrafficSnapshots.sessions})`,
57549
+ organicSessions: sql26`SUM(${gaTrafficSnapshots.organicSessions})`,
57550
+ directSessions: sql26`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`,
57551
+ users: sql26`SUM(${gaTrafficSnapshots.users})`
57552
+ }).from(gaTrafficSnapshots).where(and61(...snapshotConditions)).groupBy(sql26`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`).orderBy(sql26`SUM(${gaTrafficSnapshots.sessions}) DESC`).limit(limit).all();
57540
57553
  const aiReferralRows = app.db.select({
57541
57554
  source: gaAiReferrals.source,
57542
57555
  medium: gaAiReferrals.medium,
57543
57556
  trafficClass: gaAiReferrals.trafficClass,
57544
57557
  sourceDimension: gaAiReferrals.sourceDimension,
57545
- sessions: sql25`SUM(${gaAiReferrals.sessions})`
57558
+ sessions: sql26`SUM(${gaAiReferrals.sessions})`
57546
57559
  }).from(gaAiReferrals).where(and61(...aiConditions)).groupBy(gaAiReferrals.source, gaAiReferrals.medium, gaAiReferrals.trafficClass, gaAiReferrals.sourceDimension).all();
57547
57560
  const aiReferralLandingPageRows = app.db.select({
57548
57561
  source: gaAiReferrals.source,
57549
57562
  medium: gaAiReferrals.medium,
57550
57563
  trafficClass: gaAiReferrals.trafficClass,
57551
57564
  sourceDimension: gaAiReferrals.sourceDimension,
57552
- landingPage: sql25`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`,
57553
- sessions: sql25`SUM(${gaAiReferrals.sessions})`
57565
+ landingPage: sql26`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`,
57566
+ sessions: sql26`SUM(${gaAiReferrals.sessions})`
57554
57567
  }).from(gaAiReferrals).where(and61(...aiConditions)).groupBy(
57555
57568
  gaAiReferrals.source,
57556
57569
  gaAiReferrals.medium,
57557
57570
  gaAiReferrals.trafficClass,
57558
57571
  gaAiReferrals.sourceDimension,
57559
- sql25`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`
57572
+ sql26`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`
57560
57573
  ).all();
57561
57574
  const aiRowsForTotals = app.db.select({
57562
57575
  date: gaAiReferrals.date,
@@ -57582,15 +57595,15 @@ async function ga4Routes(app, opts) {
57582
57595
  // is GA's COUNT DISTINCT at that grain, so summing over the window's
57583
57596
  // dates counts a returning visitor once per day they returned. Same
57584
57597
  // conclusion the AI-referral surfaces reached in 4.135.0.
57585
- sessions: sql25`SUM(${gaSocialReferrals.sessions})`
57586
- }).from(gaSocialReferrals).where(and61(...socialConditions)).groupBy(gaSocialReferrals.source, gaSocialReferrals.medium, gaSocialReferrals.channelGroup).orderBy(sql25`SUM(${gaSocialReferrals.sessions}) DESC`).all();
57598
+ sessions: sql26`SUM(${gaSocialReferrals.sessions})`
57599
+ }).from(gaSocialReferrals).where(and61(...socialConditions)).groupBy(gaSocialReferrals.source, gaSocialReferrals.medium, gaSocialReferrals.channelGroup).orderBy(sql26`SUM(${gaSocialReferrals.sessions}) DESC`).all();
57587
57600
  const socialDailyRows = app.db.select({
57588
57601
  date: gaSocialReferrals.date,
57589
57602
  source: gaSocialReferrals.source,
57590
- sessions: sql25`SUM(${gaSocialReferrals.sessions})`
57603
+ sessions: sql26`SUM(${gaSocialReferrals.sessions})`
57591
57604
  }).from(gaSocialReferrals).where(and61(...socialConditions)).groupBy(gaSocialReferrals.date, gaSocialReferrals.source).all();
57592
57605
  const socialTotals = app.db.select({
57593
- sessions: sql25`SUM(${gaSocialReferrals.sessions})`
57606
+ sessions: sql26`SUM(${gaSocialReferrals.sessions})`
57594
57607
  }).from(gaSocialReferrals).where(and61(...socialConditions)).get();
57595
57608
  const latestSync = app.db.select({ syncedAt: gaTrafficSummaries.syncedAt }).from(gaTrafficSummaries).where(eq73(gaTrafficSummaries.projectId, project.id)).orderBy(desc36(gaTrafficSummaries.syncedAt)).limit(1).get();
57596
57609
  const total = summaryRow?.totalSessions ?? 0;
@@ -57721,20 +57734,20 @@ async function ga4Routes(app, opts) {
57721
57734
  source: gaAiReferrals.source,
57722
57735
  medium: gaAiReferrals.medium,
57723
57736
  trafficClass: gaAiReferrals.trafficClass,
57724
- landingPage: sql25`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`,
57737
+ landingPage: sql26`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`,
57725
57738
  sourceDimension: gaAiReferrals.sourceDimension,
57726
57739
  // No `users`: ga-ai-referral-aggregation states the rule for this
57727
57740
  // table, that there is no grain at which the stored users column may be
57728
57741
  // added up. ga4AiReferralDtoSchema.users was deprecated for this in
57729
57742
  // 4.135.0; the history endpoint kept emitting one.
57730
- sessions: sql25`SUM(${gaAiReferrals.sessions})`
57743
+ sessions: sql26`SUM(${gaAiReferrals.sessions})`
57731
57744
  }).from(gaAiReferrals).where(and61(...conditions)).groupBy(
57732
57745
  gaAiReferrals.date,
57733
57746
  gaAiReferrals.source,
57734
57747
  gaAiReferrals.medium,
57735
57748
  gaAiReferrals.trafficClass,
57736
57749
  gaAiReferrals.sourceDimension,
57737
- sql25`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`
57750
+ sql26`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`
57738
57751
  ).orderBy(gaAiReferrals.date).all();
57739
57752
  return rows;
57740
57753
  });
@@ -57779,10 +57792,10 @@ async function ga4Routes(app, opts) {
57779
57792
  d.setDate(d.getDate() - n);
57780
57793
  return fmt(d);
57781
57794
  };
57782
- const sumSocial = (from, to) => app.db.select({ sessions: sql25`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and61(
57795
+ const sumSocial = (from, to) => app.db.select({ sessions: sql26`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and61(
57783
57796
  eq73(gaSocialReferrals.projectId, project.id),
57784
- sql25`${gaSocialReferrals.date} >= ${from}`,
57785
- sql25`${gaSocialReferrals.date} < ${to}`
57797
+ sql26`${gaSocialReferrals.date} >= ${from}`,
57798
+ sql26`${gaSocialReferrals.date} < ${to}`
57786
57799
  )).get();
57787
57800
  const current7d = sumSocial(daysAgo(7), fmt(today));
57788
57801
  const prev7d = sumSocial(daysAgo(14), daysAgo(7));
@@ -57790,19 +57803,19 @@ async function ga4Routes(app, opts) {
57790
57803
  const prev30d = sumSocial(daysAgo(60), daysAgo(30));
57791
57804
  const sourceCurrent = app.db.select({
57792
57805
  source: gaSocialReferrals.source,
57793
- sessions: sql25`SUM(${gaSocialReferrals.sessions})`
57806
+ sessions: sql26`SUM(${gaSocialReferrals.sessions})`
57794
57807
  }).from(gaSocialReferrals).where(and61(
57795
57808
  eq73(gaSocialReferrals.projectId, project.id),
57796
- sql25`${gaSocialReferrals.date} >= ${daysAgo(7)}`,
57797
- sql25`${gaSocialReferrals.date} < ${fmt(today)}`
57809
+ sql26`${gaSocialReferrals.date} >= ${daysAgo(7)}`,
57810
+ sql26`${gaSocialReferrals.date} < ${fmt(today)}`
57798
57811
  )).groupBy(gaSocialReferrals.source).all();
57799
57812
  const sourcePrev = app.db.select({
57800
57813
  source: gaSocialReferrals.source,
57801
- sessions: sql25`SUM(${gaSocialReferrals.sessions})`
57814
+ sessions: sql26`SUM(${gaSocialReferrals.sessions})`
57802
57815
  }).from(gaSocialReferrals).where(and61(
57803
57816
  eq73(gaSocialReferrals.projectId, project.id),
57804
- sql25`${gaSocialReferrals.date} >= ${daysAgo(14)}`,
57805
- sql25`${gaSocialReferrals.date} < ${daysAgo(7)}`
57817
+ sql26`${gaSocialReferrals.date} >= ${daysAgo(14)}`,
57818
+ sql26`${gaSocialReferrals.date} < ${daysAgo(7)}`
57806
57819
  )).groupBy(gaSocialReferrals.source).all();
57807
57820
  const response = {
57808
57821
  socialSessions7d: current7d?.sessions ?? 0,
@@ -57825,16 +57838,16 @@ async function ga4Routes(app, opts) {
57825
57838
  d.setDate(d.getDate() - n);
57826
57839
  return fmt(d);
57827
57840
  };
57828
- const sumTotal = (from, to) => app.db.select({ sessions: sql25`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)` }).from(gaTrafficSnapshots).where(and61(eq73(gaTrafficSnapshots.projectId, project.id), sql25`${gaTrafficSnapshots.date} >= ${from}`, sql25`${gaTrafficSnapshots.date} < ${to}`)).get();
57829
- const sumOrganic = (from, to) => app.db.select({ sessions: sql25`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)` }).from(gaTrafficSnapshots).where(and61(eq73(gaTrafficSnapshots.projectId, project.id), sql25`${gaTrafficSnapshots.date} >= ${from}`, sql25`${gaTrafficSnapshots.date} < ${to}`)).get();
57830
- const sumDirect = (from, to) => app.db.select({ sessions: sql25`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)` }).from(gaTrafficSnapshots).where(and61(eq73(gaTrafficSnapshots.projectId, project.id), sql25`${gaTrafficSnapshots.date} >= ${from}`, sql25`${gaTrafficSnapshots.date} < ${to}`)).get();
57831
- const sumAi = (from, to) => app.db.select({ sessions: sql25`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and61(
57841
+ const sumTotal = (from, to) => app.db.select({ sessions: sql26`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)` }).from(gaTrafficSnapshots).where(and61(eq73(gaTrafficSnapshots.projectId, project.id), sql26`${gaTrafficSnapshots.date} >= ${from}`, sql26`${gaTrafficSnapshots.date} < ${to}`)).get();
57842
+ const sumOrganic = (from, to) => app.db.select({ sessions: sql26`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)` }).from(gaTrafficSnapshots).where(and61(eq73(gaTrafficSnapshots.projectId, project.id), sql26`${gaTrafficSnapshots.date} >= ${from}`, sql26`${gaTrafficSnapshots.date} < ${to}`)).get();
57843
+ const sumDirect = (from, to) => app.db.select({ sessions: sql26`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)` }).from(gaTrafficSnapshots).where(and61(eq73(gaTrafficSnapshots.projectId, project.id), sql26`${gaTrafficSnapshots.date} >= ${from}`, sql26`${gaTrafficSnapshots.date} < ${to}`)).get();
57844
+ const sumAi = (from, to) => app.db.select({ sessions: sql26`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and61(
57832
57845
  eq73(gaAiReferrals.projectId, project.id),
57833
- sql25`${gaAiReferrals.date} >= ${from}`,
57834
- sql25`${gaAiReferrals.date} < ${to}`,
57846
+ sql26`${gaAiReferrals.date} >= ${from}`,
57847
+ sql26`${gaAiReferrals.date} < ${to}`,
57835
57848
  eq73(gaAiReferrals.sourceDimension, "session")
57836
57849
  )).get();
57837
- const sumSocial = (from, to) => app.db.select({ sessions: sql25`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and61(eq73(gaSocialReferrals.projectId, project.id), sql25`${gaSocialReferrals.date} >= ${from}`, sql25`${gaSocialReferrals.date} < ${to}`)).get();
57850
+ const sumSocial = (from, to) => app.db.select({ sessions: sql26`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and61(eq73(gaSocialReferrals.projectId, project.id), sql26`${gaSocialReferrals.date} >= ${from}`, sql26`${gaSocialReferrals.date} < ${to}`)).get();
57838
57851
  const todayStr = fmt(today);
57839
57852
  const buildTrend = (sum) => {
57840
57853
  const c7 = sum(daysAgo(7), todayStr)?.sessions ?? 0;
@@ -57843,20 +57856,20 @@ async function ga4Routes(app, opts) {
57843
57856
  const p30 = sum(daysAgo(60), daysAgo(30))?.sessions ?? 0;
57844
57857
  return { sessions7d: c7, sessionsPrev7d: p7, trend7dPct: deltaPercent(c7, p7), sessions30d: c30, sessionsPrev30d: p30, trend30dPct: deltaPercent(c30, p30) };
57845
57858
  };
57846
- const aiSourceCurrent = app.db.select({ source: gaAiReferrals.source, sessions: sql25`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and61(
57859
+ const aiSourceCurrent = app.db.select({ source: gaAiReferrals.source, sessions: sql26`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and61(
57847
57860
  eq73(gaAiReferrals.projectId, project.id),
57848
- sql25`${gaAiReferrals.date} >= ${daysAgo(7)}`,
57849
- sql25`${gaAiReferrals.date} < ${todayStr}`,
57861
+ sql26`${gaAiReferrals.date} >= ${daysAgo(7)}`,
57862
+ sql26`${gaAiReferrals.date} < ${todayStr}`,
57850
57863
  eq73(gaAiReferrals.sourceDimension, "session")
57851
57864
  )).groupBy(gaAiReferrals.source).all();
57852
- const aiSourcePrev = app.db.select({ source: gaAiReferrals.source, sessions: sql25`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and61(
57865
+ const aiSourcePrev = app.db.select({ source: gaAiReferrals.source, sessions: sql26`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and61(
57853
57866
  eq73(gaAiReferrals.projectId, project.id),
57854
- sql25`${gaAiReferrals.date} >= ${daysAgo(14)}`,
57855
- sql25`${gaAiReferrals.date} < ${daysAgo(7)}`,
57867
+ sql26`${gaAiReferrals.date} >= ${daysAgo(14)}`,
57868
+ sql26`${gaAiReferrals.date} < ${daysAgo(7)}`,
57856
57869
  eq73(gaAiReferrals.sourceDimension, "session")
57857
57870
  )).groupBy(gaAiReferrals.source).all();
57858
- const socialSourceCurrent = app.db.select({ source: gaSocialReferrals.source, sessions: sql25`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and61(eq73(gaSocialReferrals.projectId, project.id), sql25`${gaSocialReferrals.date} >= ${daysAgo(7)}`, sql25`${gaSocialReferrals.date} < ${todayStr}`)).groupBy(gaSocialReferrals.source).all();
57859
- const socialSourcePrev = app.db.select({ source: gaSocialReferrals.source, sessions: sql25`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and61(eq73(gaSocialReferrals.projectId, project.id), sql25`${gaSocialReferrals.date} >= ${daysAgo(14)}`, sql25`${gaSocialReferrals.date} < ${daysAgo(7)}`)).groupBy(gaSocialReferrals.source).all();
57871
+ const socialSourceCurrent = app.db.select({ source: gaSocialReferrals.source, sessions: sql26`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and61(eq73(gaSocialReferrals.projectId, project.id), sql26`${gaSocialReferrals.date} >= ${daysAgo(7)}`, sql26`${gaSocialReferrals.date} < ${todayStr}`)).groupBy(gaSocialReferrals.source).all();
57872
+ const socialSourcePrev = app.db.select({ source: gaSocialReferrals.source, sessions: sql26`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and61(eq73(gaSocialReferrals.projectId, project.id), sql26`${gaSocialReferrals.date} >= ${daysAgo(14)}`, sql26`${gaSocialReferrals.date} < ${daysAgo(7)}`)).groupBy(gaSocialReferrals.source).all();
57860
57873
  const response = {
57861
57874
  total: buildTrend(sumTotal),
57862
57875
  organic: buildTrend(sumOrganic),
@@ -57880,8 +57893,8 @@ async function ga4Routes(app, opts) {
57880
57893
  const to = current?.endDate ?? fallback.current.endDate;
57881
57894
  const daily = app.db.select().from(gaDailyTotals).where(and61(
57882
57895
  eq73(gaDailyTotals.projectId, project.id),
57883
- sql25`${gaDailyTotals.date} >= ${from}`,
57884
- sql25`${gaDailyTotals.date} <= ${to}`
57896
+ sql26`${gaDailyTotals.date} >= ${from}`,
57897
+ sql26`${gaDailyTotals.date} <= ${to}`
57885
57898
  )).all();
57886
57899
  return buildGaOverview({ window: window2, current, previous, daily, fallback });
57887
57900
  });
@@ -57892,9 +57905,9 @@ async function ga4Routes(app, opts) {
57892
57905
  const conditions = [eq73(gaTrafficSnapshots.projectId, project.id), ...dateRangeConditions(gaTrafficSnapshots.date, range)];
57893
57906
  const rows = app.db.select({
57894
57907
  date: gaTrafficSnapshots.date,
57895
- sessions: sql25`SUM(${gaTrafficSnapshots.sessions})`,
57896
- organicSessions: sql25`SUM(${gaTrafficSnapshots.organicSessions})`,
57897
- users: sql25`SUM(${gaTrafficSnapshots.users})`
57908
+ sessions: sql26`SUM(${gaTrafficSnapshots.sessions})`,
57909
+ organicSessions: sql26`SUM(${gaTrafficSnapshots.organicSessions})`,
57910
+ users: sql26`SUM(${gaTrafficSnapshots.users})`
57898
57911
  }).from(gaTrafficSnapshots).where(and61(...conditions)).groupBy(gaTrafficSnapshots.date).orderBy(gaTrafficSnapshots.date).all();
57899
57912
  const totalConditions = [eq73(gaDailyTotals.projectId, project.id), ...dateRangeConditions(gaDailyTotals.date, range)];
57900
57913
  const totals = app.db.select({ date: gaDailyTotals.date, users: gaDailyTotals.users }).from(gaDailyTotals).where(and61(...totalConditions)).all();
@@ -57912,11 +57925,11 @@ async function ga4Routes(app, opts) {
57912
57925
  const project = resolveProject(app.db, request.params.name);
57913
57926
  requireGa4Connection(opts, project.name, project.canonicalDomain);
57914
57927
  const trafficPages = app.db.select({
57915
- landingPage: sql25`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`,
57916
- sessions: sql25`SUM(${gaTrafficSnapshots.sessions})`,
57917
- organicSessions: sql25`SUM(${gaTrafficSnapshots.organicSessions})`,
57918
- users: sql25`SUM(${gaTrafficSnapshots.users})`
57919
- }).from(gaTrafficSnapshots).where(eq73(gaTrafficSnapshots.projectId, project.id)).groupBy(sql25`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`).orderBy(sql25`SUM(${gaTrafficSnapshots.sessions}) DESC`).all();
57928
+ landingPage: sql26`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`,
57929
+ sessions: sql26`SUM(${gaTrafficSnapshots.sessions})`,
57930
+ organicSessions: sql26`SUM(${gaTrafficSnapshots.organicSessions})`,
57931
+ users: sql26`SUM(${gaTrafficSnapshots.users})`
57932
+ }).from(gaTrafficSnapshots).where(eq73(gaTrafficSnapshots.projectId, project.id)).groupBy(sql26`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`).orderBy(sql26`SUM(${gaTrafficSnapshots.sessions}) DESC`).all();
57920
57933
  return {
57921
57934
  pages: trafficPages.map((r) => ({
57922
57935
  landingPage: r.landingPage,
@@ -57929,7 +57942,7 @@ async function ga4Routes(app, opts) {
57929
57942
  }
57930
57943
 
57931
57944
  // ../api-routes/src/ga-acquisition.ts
57932
- import { and as and62, asc as asc17, count as count6, desc as desc37, eq as eq74, gte as gte17, lte as lte17, sql as sql26 } from "drizzle-orm";
57945
+ import { and as and62, asc as asc17, count as count6, desc as desc37, eq as eq74, gte as gte18, lte as lte18, sql as sql27 } from "drizzle-orm";
57933
57946
  async function gaAcquisitionRoutes(app) {
57934
57947
  app.get("/projects/:name/ga/acquisition", async (request) => {
57935
57948
  const project = resolveProject(app.db, request.params.name);
@@ -57943,7 +57956,7 @@ async function gaAcquisitionRoutes(app) {
57943
57956
  const groupBy = query.groupBy === void 0 ? [...gaAcquisitionDimensionSchema.options] : [...new Set(query.groupBy.split(",").map((key) => gaAcquisitionDimensionSchema.parse(key.trim())))];
57944
57957
  const limit = query.limit ?? 100;
57945
57958
  const offset = query.offset ?? 0;
57946
- const landingPage = sql26`coalesce(${gaAcquisitionDaily.landingPageNormalized}, ${gaAcquisitionDaily.landingPage})`;
57959
+ const landingPage = sql27`coalesce(${gaAcquisitionDaily.landingPageNormalized}, ${gaAcquisitionDaily.landingPage})`;
57947
57960
  const dimensions = {
57948
57961
  date: gaAcquisitionDaily.date,
57949
57962
  channelGroup: gaAcquisitionDaily.channelGroup,
@@ -57953,22 +57966,22 @@ async function gaAcquisitionRoutes(app) {
57953
57966
  landingPage
57954
57967
  };
57955
57968
  const windowFilters = [eq74(gaAcquisitionDaily.projectId, project.id)];
57956
- if (range.startDate) windowFilters.push(gte17(gaAcquisitionDaily.date, range.startDate));
57957
- if (range.endDate) windowFilters.push(lte17(gaAcquisitionDaily.date, range.endDate));
57969
+ if (range.startDate) windowFilters.push(gte18(gaAcquisitionDaily.date, range.startDate));
57970
+ if (range.endDate) windowFilters.push(lte18(gaAcquisitionDaily.date, range.endDate));
57958
57971
  const filters = [...windowFilters];
57959
- if (query.channel !== void 0) filters.push(sql26`lower(${gaAcquisitionDaily.channelGroup}) = lower(${query.channel})`);
57960
- if (query.hostName !== void 0) filters.push(sql26`lower(${gaAcquisitionDaily.hostName}) = lower(${query.hostName})`);
57972
+ if (query.channel !== void 0) filters.push(sql27`lower(${gaAcquisitionDaily.channelGroup}) = lower(${query.channel})`);
57973
+ if (query.hostName !== void 0) filters.push(sql27`lower(${gaAcquisitionDaily.hostName}) = lower(${query.hostName})`);
57961
57974
  if (query.source !== void 0) filters.push(eq74(gaAcquisitionDaily.source, query.source));
57962
57975
  if (query.medium !== void 0) filters.push(eq74(gaAcquisitionDaily.medium, query.medium));
57963
57976
  const selectedLandingPage = query.landingPage === void 0 ? void 0 : normalizeUrlPath(query.landingPage) ?? query.landingPage;
57964
- if (selectedLandingPage !== void 0) filters.push(sql26`${landingPage} = ${selectedLandingPage}`);
57977
+ if (selectedLandingPage !== void 0) filters.push(sql27`${landingPage} = ${selectedLandingPage}`);
57965
57978
  const pathPrefix = normalizePathPrefix(query.pathPrefix);
57966
57979
  if (pathPrefix && pathPrefix !== "/") {
57967
- const pathname = sql26`case when instr(${landingPage}, '?') = 0 then ${landingPage} else substr(${landingPage}, 1, instr(${landingPage}, '?') - 1) end`;
57980
+ const pathname = sql27`case when instr(${landingPage}, '?') = 0 then ${landingPage} else substr(${landingPage}, 1, instr(${landingPage}, '?') - 1) end`;
57968
57981
  filters.push(literalPathPrefixCondition(pathname, pathPrefix));
57969
57982
  }
57970
57983
  const where = and62(...filters);
57971
- const sessions = sql26`coalesce(sum(${gaAcquisitionDaily.sessions}), 0)`.mapWith(Number);
57984
+ const sessions = sql27`coalesce(sum(${gaAcquisitionDaily.sessions}), 0)`.mapWith(Number);
57972
57985
  const selected = Object.fromEntries(groupBy.map((key) => [key, dimensions[key]]));
57973
57986
  const grouped = app.db.select({ ...selected, sessions }).from(gaAcquisitionDaily).where(where).groupBy(...groupBy.map((key) => dimensions[key]));
57974
57987
  const totalRows = app.db.select({ total: count6() }).from(grouped.as("grouped_acquisition")).get().total;
@@ -57979,7 +57992,7 @@ async function gaAcquisitionRoutes(app) {
57979
57992
  ...groupBy.filter((key) => key !== GaAcquisitionDimensions.date).map((key) => asc17(dimensions[key]))
57980
57993
  ];
57981
57994
  const rows = grouped.orderBy(...order).limit(limit).offset(offset).all();
57982
- const coverage = app.db.select({ earliestDate: sql26`min(${gaAcquisitionDaily.date})`, latestDate: sql26`max(${gaAcquisitionDaily.date})` }).from(gaAcquisitionDaily).where(eq74(gaAcquisitionDaily.projectId, project.id)).get();
57995
+ const coverage = app.db.select({ earliestDate: sql27`min(${gaAcquisitionDaily.date})`, latestDate: sql27`max(${gaAcquisitionDaily.date})` }).from(gaAcquisitionDaily).where(eq74(gaAcquisitionDaily.projectId, project.id)).get();
57983
57996
  const channelGroups = app.db.selectDistinct({ channel: gaAcquisitionDaily.channelGroup }).from(gaAcquisitionDaily).where(and62(...windowFilters)).orderBy(asc17(gaAcquisitionDaily.channelGroup)).all().map((row) => row.channel);
57984
57997
  const state = app.db.select().from(gaMeasurementSyncStates).where(eq74(gaMeasurementSyncStates.projectId, project.id)).get();
57985
57998
  const response = {
@@ -59713,7 +59726,7 @@ async function wordpressRoutes(app, opts) {
59713
59726
 
59714
59727
  // ../api-routes/src/backlinks.ts
59715
59728
  import crypto49 from "crypto";
59716
- import { and as and65, asc as asc18, desc as desc38, eq as eq76, sql as sql27 } from "drizzle-orm";
59729
+ import { and as and65, asc as asc18, desc as desc38, eq as eq76, sql as sql28 } from "drizzle-orm";
59717
59730
 
59718
59731
  // ../integration-commoncrawl/src/constants.ts
59719
59732
  import os2 from "os";
@@ -60021,7 +60034,7 @@ async function queryBacklinks(opts) {
60021
60034
  const reversed = opts.targets.map(reverseDomain);
60022
60035
  const targetList = reversed.map(quote).join(", ");
60023
60036
  const limitClause = opts.limitPerTarget ? `QUALIFY row_number() OVER (PARTITION BY t.target_rev_domain ORDER BY v.num_hosts DESC) <= ${Math.floor(opts.limitPerTarget)}` : "";
60024
- const sql36 = `
60037
+ const sql37 = `
60025
60038
  WITH vertices AS (
60026
60039
  SELECT * FROM read_csv(
60027
60040
  ${quote(opts.vertexPath)},
@@ -60057,7 +60070,7 @@ async function queryBacklinks(opts) {
60057
60070
  const conn = await instance.connect();
60058
60071
  let rows;
60059
60072
  try {
60060
- const reader = await conn.runAndReadAll(sql36);
60073
+ const reader = await conn.runAndReadAll(sql37);
60061
60074
  rows = reader.getRowObjects();
60062
60075
  } finally {
60063
60076
  conn.disconnectSync?.();
@@ -60263,12 +60276,12 @@ function computeFilteredSummary(db, base) {
60263
60276
  );
60264
60277
  const filteredCondition = and65(baseDomainCondition, backlinkCrawlerExclusionClause());
60265
60278
  const unfilteredAgg = db.select({
60266
- count: sql27`count(*)`,
60267
- total: sql27`coalesce(sum(${backlinkDomains.numHosts}), 0)`
60279
+ count: sql28`count(*)`,
60280
+ total: sql28`coalesce(sum(${backlinkDomains.numHosts}), 0)`
60268
60281
  }).from(backlinkDomains).where(baseDomainCondition).get();
60269
60282
  const filteredAgg = db.select({
60270
- count: sql27`count(*)`,
60271
- total: sql27`coalesce(sum(${backlinkDomains.numHosts}), 0)`
60283
+ count: sql28`count(*)`,
60284
+ total: sql28`coalesce(sum(${backlinkDomains.numHosts}), 0)`
60272
60285
  }).from(backlinkDomains).where(filteredCondition).get();
60273
60286
  const top10Rows = db.select({ numHosts: backlinkDomains.numHosts }).from(backlinkDomains).where(filteredCondition).orderBy(desc38(backlinkDomains.numHosts)).limit(10).all();
60274
60287
  const totalLinkingDomains = Number(filteredAgg?.count ?? 0);
@@ -60294,7 +60307,7 @@ function buildSourceAvailability(db, projectId, source, connected2, excludeCrawl
60294
60307
  const summary3 = db.select().from(backlinkSummaries).where(and65(eq76(backlinkSummaries.projectId, projectId), eq76(backlinkSummaries.source, source))).orderBy(desc38(backlinkSummaries.queriedAt)).limit(1).get();
60295
60308
  let totalLinkingDomains = summary3?.totalLinkingDomains ?? 0;
60296
60309
  if (summary3 && excludeCrawlers) {
60297
- const filtered = db.select({ count: sql27`count(*)` }).from(backlinkDomains).where(and65(
60310
+ const filtered = db.select({ count: sql28`count(*)` }).from(backlinkDomains).where(and65(
60298
60311
  eq76(backlinkDomains.projectId, projectId),
60299
60312
  eq76(backlinkDomains.source, source),
60300
60313
  eq76(backlinkDomains.release, summary3.release),
@@ -60482,7 +60495,7 @@ async function backlinksRoutes(app, opts) {
60482
60495
  eq76(backlinkDomains.release, targetRelease)
60483
60496
  );
60484
60497
  const domainCondition = excludeCrawlers ? and65(baseDomainCondition, backlinkCrawlerExclusionClause()) : baseDomainCondition;
60485
- const totalRow = app.db.select({ count: sql27`count(*)` }).from(backlinkDomains).where(domainCondition).get();
60498
+ const totalRow = app.db.select({ count: sql28`count(*)` }).from(backlinkDomains).where(domainCondition).get();
60486
60499
  const rows = app.db.select({
60487
60500
  linkingDomain: backlinkDomains.linkingDomain,
60488
60501
  numHosts: backlinkDomains.numHosts,
@@ -60532,7 +60545,7 @@ async function backlinksRoutes(app, opts) {
60532
60545
  import crypto52 from "crypto";
60533
60546
  import { isIP } from "net";
60534
60547
  import { isDeepStrictEqual } from "util";
60535
- import { and as and69, desc as desc39, eq as eq80, gt as gt7, gte as gte19, inArray as inArray35, lt as lt13, lte as lte20, sql as sql30 } from "drizzle-orm";
60548
+ import { and as and69, desc as desc39, eq as eq80, gt as gt7, gte as gte20, inArray as inArray35, lt as lt13, lte as lte21, sql as sql31 } from "drizzle-orm";
60536
60549
 
60537
60550
  // ../api-routes/src/traffic-limits.ts
60538
60551
  var VERCEL_MAX_SYNC_WINDOW_MS = 24 * 60 * 6e4;
@@ -61875,10 +61888,10 @@ async function ackCloudflareQueueMessages(client, options) {
61875
61888
 
61876
61889
  // ../api-routes/src/traffic-event-ingest.ts
61877
61890
  import crypto51 from "crypto";
61878
- import { and as and67, eq as eq78, gte as gte18, lt as lt12, lte as lte18, sql as sql29 } from "drizzle-orm";
61891
+ import { and as and67, eq as eq78, gte as gte19, lt as lt12, lte as lte19, sql as sql30 } from "drizzle-orm";
61879
61892
 
61880
61893
  // ../api-routes/src/raw-event-sample-retention.ts
61881
- import { and as and66, eq as eq77, lt as lt11, sql as sql28 } from "drizzle-orm";
61894
+ import { and as and66, eq as eq77, lt as lt11, sql as sql29 } from "drizzle-orm";
61882
61895
  var RAW_EVENT_SAMPLE_RETENTION_MS = 30 * 24 * 60 * 6e4;
61883
61896
  var RAW_EVENT_SAMPLE_RETENTION_SWEEP_INTERVAL_MS = 24 * 60 * 6e4;
61884
61897
  var CANONICAL_UTC_TIMESTAMP_GLOB = "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]Z";
@@ -61889,16 +61902,16 @@ function rawEventSampleRetentionCutoff(referenceAt) {
61889
61902
  }
61890
61903
  function deleteExpiredRawEventSamples(db, cutoff, sourceId) {
61891
61904
  const sourceScope = sourceId === void 0 ? void 0 : eq77(rawEventSamples.sourceId, sourceId);
61892
- db.delete(rawEventSamples).where(and66(sourceScope, sql28`julianday(${rawEventSamples.ts}) IS NULL`)).run();
61905
+ db.delete(rawEventSamples).where(and66(sourceScope, sql29`julianday(${rawEventSamples.ts}) IS NULL`)).run();
61893
61906
  db.delete(rawEventSamples).where(and66(
61894
61907
  sourceScope,
61895
- sql28`${rawEventSamples.ts} GLOB ${CANONICAL_UTC_TIMESTAMP_GLOB}`,
61908
+ sql29`${rawEventSamples.ts} GLOB ${CANONICAL_UTC_TIMESTAMP_GLOB}`,
61896
61909
  lt11(rawEventSamples.ts, cutoff)
61897
61910
  )).run();
61898
61911
  db.delete(rawEventSamples).where(and66(
61899
61912
  sourceScope,
61900
- sql28`${rawEventSamples.ts} NOT GLOB ${CANONICAL_UTC_TIMESTAMP_GLOB}`,
61901
- sql28`julianday(${rawEventSamples.ts}) < julianday(${cutoff})`
61913
+ sql29`${rawEventSamples.ts} NOT GLOB ${CANONICAL_UTC_TIMESTAMP_GLOB}`,
61914
+ sql29`julianday(${rawEventSamples.ts}) < julianday(${cutoff})`
61902
61915
  )).run();
61903
61916
  }
61904
61917
  function enforceRawEventSampleRetention(db, sourceId, referenceAt) {
@@ -61944,7 +61957,7 @@ function writeTrafficEventBatch(opts) {
61944
61957
  let aiReferralHits = 0;
61945
61958
  let unknownHits = 0;
61946
61959
  opts.db.transaction((tx) => {
61947
- tx.update(trafficSources).set({ updatedAt: sql29`${trafficSources.updatedAt}` }).where(eq78(trafficSources.id, opts.sourceId)).run();
61960
+ tx.update(trafficSources).set({ updatedAt: sql30`${trafficSources.updatedAt}` }).where(eq78(trafficSources.id, opts.sourceId)).run();
61948
61961
  const source = tx.select().from(trafficSources).where(eq78(trafficSources.id, opts.sourceId)).get();
61949
61962
  opts.validateSource(source);
61950
61963
  const rawSampleCutoff = enforceRawEventSampleRetention(
@@ -61954,7 +61967,7 @@ function writeTrafficEventBatch(opts) {
61954
61967
  );
61955
61968
  tx.delete(trafficEventReceipts).where(and67(
61956
61969
  eq78(trafficEventReceipts.sourceId, opts.sourceId),
61957
- lte18(trafficEventReceipts.expiresAt, opts.receivedAt)
61970
+ lte19(trafficEventReceipts.expiresAt, opts.receivedAt)
61958
61971
  )).run();
61959
61972
  const claimedEvents = [];
61960
61973
  for (const event of opts.events) {
@@ -62005,7 +62018,7 @@ function writeTrafficEventBatch(opts) {
62005
62018
  crawlerEventsHourly.status
62006
62019
  ],
62007
62020
  set: {
62008
- hits: sql29`${crawlerEventsHourly.hits} + ${bucket.hits}`,
62021
+ hits: sql30`${crawlerEventsHourly.hits} + ${bucket.hits}`,
62009
62022
  sampledUserAgent: bucket.sampledUserAgent,
62010
62023
  updatedAt: opts.receivedAt
62011
62024
  }
@@ -62036,7 +62049,7 @@ function writeTrafficEventBatch(opts) {
62036
62049
  crawlerVerificationManifestsHourly.manifestId
62037
62050
  ],
62038
62051
  set: {
62039
- hits: sql29`${crawlerVerificationManifestsHourly.hits} + ${bucket.hits}`,
62052
+ hits: sql30`${crawlerVerificationManifestsHourly.hits} + ${bucket.hits}`,
62040
62053
  manifestJson: bucket.verificationManifest,
62041
62054
  updatedAt: opts.receivedAt
62042
62055
  }
@@ -62070,7 +62083,7 @@ function writeTrafficEventBatch(opts) {
62070
62083
  aiUserFetchEventsHourly.status
62071
62084
  ],
62072
62085
  set: {
62073
- hits: sql29`${aiUserFetchEventsHourly.hits} + ${bucket.hits}`,
62086
+ hits: sql30`${aiUserFetchEventsHourly.hits} + ${bucket.hits}`,
62074
62087
  sampledUserAgent: bucket.sampledUserAgent,
62075
62088
  updatedAt: opts.receivedAt
62076
62089
  }
@@ -62101,7 +62114,7 @@ function writeTrafficEventBatch(opts) {
62101
62114
  aiUserFetchVerificationManifestsHourly.manifestId
62102
62115
  ],
62103
62116
  set: {
62104
- hits: sql29`${aiUserFetchVerificationManifestsHourly.hits} + ${bucket.hits}`,
62117
+ hits: sql30`${aiUserFetchVerificationManifestsHourly.hits} + ${bucket.hits}`,
62105
62118
  manifestJson: bucket.verificationManifest,
62106
62119
  updatedAt: opts.receivedAt
62107
62120
  }
@@ -62139,9 +62152,9 @@ function writeTrafficEventBatch(opts) {
62139
62152
  aiReferralEventsHourly.status
62140
62153
  ],
62141
62154
  set: {
62142
- sessionsOrHits: sql29`${aiReferralEventsHourly.sessionsOrHits} + ${bucket.hits}`,
62143
- paidSessionsOrHits: sql29`${aiReferralEventsHourly.paidSessionsOrHits} + ${bucket.paidHits}`,
62144
- organicSessionsOrHits: sql29`${aiReferralEventsHourly.organicSessionsOrHits} + ${bucket.organicHits}`,
62155
+ sessionsOrHits: sql30`${aiReferralEventsHourly.sessionsOrHits} + ${bucket.hits}`,
62156
+ paidSessionsOrHits: sql30`${aiReferralEventsHourly.paidSessionsOrHits} + ${bucket.paidHits}`,
62157
+ organicSessionsOrHits: sql30`${aiReferralEventsHourly.organicSessionsOrHits} + ${bucket.organicHits}`,
62145
62158
  updatedAt: opts.receivedAt
62146
62159
  }
62147
62160
  }).run();
@@ -62156,9 +62169,9 @@ function writeTrafficEventBatch(opts) {
62156
62169
  if (!hour || hourlySampleLimit === 0) continue;
62157
62170
  let remaining = remainingSamplesByHour.get(hour.start);
62158
62171
  if (remaining === void 0) {
62159
- const existing = tx.select({ total: sql29`COUNT(*)` }).from(rawEventSamples).where(and67(
62172
+ const existing = tx.select({ total: sql30`COUNT(*)` }).from(rawEventSamples).where(and67(
62160
62173
  eq78(rawEventSamples.sourceId, opts.sourceId),
62161
- gte18(rawEventSamples.ts, hour.start),
62174
+ gte19(rawEventSamples.ts, hour.start),
62162
62175
  lt12(rawEventSamples.ts, hour.end)
62163
62176
  )).get();
62164
62177
  remaining = Math.max(0, hourlySampleLimit - Number(existing?.total ?? 0));
@@ -62216,7 +62229,7 @@ function writeTrafficEventBatch(opts) {
62216
62229
  }
62217
62230
 
62218
62231
  // ../api-routes/src/traffic-sync-lease.ts
62219
- import { and as and68, eq as eq79, isNull as isNull13, lte as lte19, or as or18 } from "drizzle-orm";
62232
+ import { and as and68, eq as eq79, isNull as isNull13, lte as lte20, or as or18 } from "drizzle-orm";
62220
62233
  function leaseExpiresAt(now, ttlMs) {
62221
62234
  const nowMs = Date.parse(now);
62222
62235
  if (!Number.isFinite(nowMs)) throw new RangeError("Traffic sync lease now must be an ISO instant");
@@ -62233,7 +62246,7 @@ function tryClaimTrafficSyncLease(input) {
62233
62246
  eq79(trafficSources.id, input.sourceId),
62234
62247
  or18(
62235
62248
  isNull13(trafficSources.syncLeaseOwner),
62236
- lte19(trafficSources.syncLeaseExpiresAt, input.now),
62249
+ lte20(trafficSources.syncLeaseExpiresAt, input.now),
62237
62250
  eq79(trafficSources.syncLeaseOwner, input.owner)
62238
62251
  )
62239
62252
  )).run();
@@ -62315,13 +62328,13 @@ async function loadQueueReceiptPolicy(db, sourceId, readRetentionSeconds, warn2)
62315
62328
  const ttlMs = liveTtlMs;
62316
62329
  const now = (/* @__PURE__ */ new Date()).toISOString();
62317
62330
  const alive = and69(eq80(trafficEventReceipts.sourceId, sourceId), gt7(trafficEventReceipts.expiresAt, now));
62318
- const lifetimeMs = sql30`(julianday(${trafficEventReceipts.expiresAt}) - julianday(${trafficEventReceipts.receivedAt})) * ${DAY_MS3}`;
62319
- const shortest = db.select({ ms: sql30`min(${lifetimeMs})` }).from(trafficEventReceipts).where(alive).get()?.ms ?? null;
62331
+ const lifetimeMs = sql31`(julianday(${trafficEventReceipts.expiresAt}) - julianday(${trafficEventReceipts.receivedAt})) * ${DAY_MS3}`;
62332
+ const shortest = db.select({ ms: sql31`min(${lifetimeMs})` }).from(trafficEventReceipts).where(alive).get()?.ms ?? null;
62320
62333
  if (shortest !== null && shortest < ttlMs - 1e3) {
62321
- const extended = sql30`strftime('%Y-%m-%dT%H:%M:%fZ', julianday(${trafficEventReceipts.receivedAt}) + ${ttlMs / DAY_MS3})`;
62334
+ const extended = sql31`strftime('%Y-%m-%dT%H:%M:%fZ', julianday(${trafficEventReceipts.receivedAt}) + ${ttlMs / DAY_MS3})`;
62322
62335
  db.update(trafficEventReceipts).set({ expiresAt: extended }).where(and69(alive, lt13(trafficEventReceipts.expiresAt, extended))).run();
62323
62336
  }
62324
- const floorExpiry = db.select({ at: sql30`max(${trafficEventReceipts.expiresAt})` }).from(trafficEventReceipts).where(and69(alive, sql30`${lifetimeMs} < ${CLOUDFLARE_QUEUE_RECEIPT_TTL_MS - 1e3}`)).get()?.at ?? null;
62337
+ const floorExpiry = db.select({ at: sql31`max(${trafficEventReceipts.expiresAt})` }).from(trafficEventReceipts).where(and69(alive, sql31`${lifetimeMs} < ${CLOUDFLARE_QUEUE_RECEIPT_TTL_MS - 1e3}`)).get()?.at ?? null;
62325
62338
  const floorMs = floorExpiry ? Date.parse(floorExpiry) : 0;
62326
62339
  return { ttlMsAt: (receivedAt) => Math.max(ttlMs, floorMs - Date.parse(receivedAt)) };
62327
62340
  }
@@ -62530,7 +62543,7 @@ function crawlerVerificationProvenance(db, projectId, events) {
62530
62543
  manifestId: crawlerVerificationManifestsHourly.manifestId,
62531
62544
  manifest: crawlerVerificationManifestsHourly.manifestJson,
62532
62545
  hits: crawlerVerificationManifestsHourly.hits
62533
- }).from(crawlerVerificationManifestsHourly).where(sql30`(
62546
+ }).from(crawlerVerificationManifestsHourly).where(sql31`(
62534
62547
  ${crawlerVerificationManifestsHourly.projectId},
62535
62548
  ${crawlerVerificationManifestsHourly.sourceId},
62536
62549
  ${crawlerVerificationManifestsHourly.tsHour},
@@ -62564,7 +62577,7 @@ function aiUserFetchVerificationProvenance(db, projectId, events) {
62564
62577
  manifestId: aiUserFetchVerificationManifestsHourly.manifestId,
62565
62578
  manifest: aiUserFetchVerificationManifestsHourly.manifestJson,
62566
62579
  hits: aiUserFetchVerificationManifestsHourly.hits
62567
- }).from(aiUserFetchVerificationManifestsHourly).where(sql30`(
62580
+ }).from(aiUserFetchVerificationManifestsHourly).where(sql31`(
62568
62581
  ${aiUserFetchVerificationManifestsHourly.projectId},
62569
62582
  ${aiUserFetchVerificationManifestsHourly.sourceId},
62570
62583
  ${aiUserFetchVerificationManifestsHourly.tsHour},
@@ -62836,29 +62849,29 @@ async function runBackfillTaskHoldingLease(options, signal) {
62836
62849
  tx.delete(crawlerEventsHourly).where(
62837
62850
  and69(
62838
62851
  eq80(crawlerEventsHourly.sourceId, sourceRow2.id),
62839
- gte19(crawlerEventsHourly.tsHour, windowStartIso),
62840
- lte20(crawlerEventsHourly.tsHour, windowEndIso)
62852
+ gte20(crawlerEventsHourly.tsHour, windowStartIso),
62853
+ lte21(crawlerEventsHourly.tsHour, windowEndIso)
62841
62854
  )
62842
62855
  ).run();
62843
62856
  tx.delete(aiUserFetchEventsHourly).where(
62844
62857
  and69(
62845
62858
  eq80(aiUserFetchEventsHourly.sourceId, sourceRow2.id),
62846
- gte19(aiUserFetchEventsHourly.tsHour, windowStartIso),
62847
- lte20(aiUserFetchEventsHourly.tsHour, windowEndIso)
62859
+ gte20(aiUserFetchEventsHourly.tsHour, windowStartIso),
62860
+ lte21(aiUserFetchEventsHourly.tsHour, windowEndIso)
62848
62861
  )
62849
62862
  ).run();
62850
62863
  tx.delete(aiReferralEventsHourly).where(
62851
62864
  and69(
62852
62865
  eq80(aiReferralEventsHourly.sourceId, sourceRow2.id),
62853
- gte19(aiReferralEventsHourly.tsHour, windowStartIso),
62854
- lte20(aiReferralEventsHourly.tsHour, windowEndIso)
62866
+ gte20(aiReferralEventsHourly.tsHour, windowStartIso),
62867
+ lte21(aiReferralEventsHourly.tsHour, windowEndIso)
62855
62868
  )
62856
62869
  ).run();
62857
62870
  tx.delete(rawEventSamples).where(
62858
62871
  and69(
62859
62872
  eq80(rawEventSamples.sourceId, sourceRow2.id),
62860
- gte19(rawEventSamples.ts, windowStartIso),
62861
- lte20(rawEventSamples.ts, windowEndIso)
62873
+ gte20(rawEventSamples.ts, windowStartIso),
62874
+ lte21(rawEventSamples.ts, windowEndIso)
62862
62875
  )
62863
62876
  ).run();
62864
62877
  for (const bucket of report.crawlerEventsHourly) {
@@ -62887,7 +62900,7 @@ async function runBackfillTaskHoldingLease(options, signal) {
62887
62900
  crawlerEventsHourly.status
62888
62901
  ],
62889
62902
  set: {
62890
- hits: sql30`${crawlerEventsHourly.hits} + ${bucket.hits}`,
62903
+ hits: sql31`${crawlerEventsHourly.hits} + ${bucket.hits}`,
62891
62904
  sampledUserAgent: bucket.sampledUserAgent,
62892
62905
  updatedAt: finishedAt
62893
62906
  }
@@ -62918,7 +62931,7 @@ async function runBackfillTaskHoldingLease(options, signal) {
62918
62931
  crawlerVerificationManifestsHourly.manifestId
62919
62932
  ],
62920
62933
  set: {
62921
- hits: sql30`${crawlerVerificationManifestsHourly.hits} + ${bucket.hits}`,
62934
+ hits: sql31`${crawlerVerificationManifestsHourly.hits} + ${bucket.hits}`,
62922
62935
  manifestJson: bucket.verificationManifest,
62923
62936
  updatedAt: finishedAt
62924
62937
  }
@@ -62951,7 +62964,7 @@ async function runBackfillTaskHoldingLease(options, signal) {
62951
62964
  aiUserFetchEventsHourly.status
62952
62965
  ],
62953
62966
  set: {
62954
- hits: sql30`${aiUserFetchEventsHourly.hits} + ${bucket.hits}`,
62967
+ hits: sql31`${aiUserFetchEventsHourly.hits} + ${bucket.hits}`,
62955
62968
  sampledUserAgent: bucket.sampledUserAgent,
62956
62969
  updatedAt: finishedAt
62957
62970
  }
@@ -62982,7 +62995,7 @@ async function runBackfillTaskHoldingLease(options, signal) {
62982
62995
  aiUserFetchVerificationManifestsHourly.manifestId
62983
62996
  ],
62984
62997
  set: {
62985
- hits: sql30`${aiUserFetchVerificationManifestsHourly.hits} + ${bucket.hits}`,
62998
+ hits: sql31`${aiUserFetchVerificationManifestsHourly.hits} + ${bucket.hits}`,
62986
62999
  manifestJson: bucket.verificationManifest,
62987
63000
  updatedAt: finishedAt
62988
63001
  }
@@ -64754,7 +64767,7 @@ async function trafficRoutes(app, opts) {
64754
64767
  crawlerEventsHourly.status
64755
64768
  ],
64756
64769
  set: {
64757
- hits: sql30`${crawlerEventsHourly.hits} + ${bucket.hits}`,
64770
+ hits: sql31`${crawlerEventsHourly.hits} + ${bucket.hits}`,
64758
64771
  sampledUserAgent: bucket.sampledUserAgent,
64759
64772
  updatedAt: finishedAt
64760
64773
  }
@@ -64785,7 +64798,7 @@ async function trafficRoutes(app, opts) {
64785
64798
  crawlerVerificationManifestsHourly.manifestId
64786
64799
  ],
64787
64800
  set: {
64788
- hits: sql30`${crawlerVerificationManifestsHourly.hits} + ${bucket.hits}`,
64801
+ hits: sql31`${crawlerVerificationManifestsHourly.hits} + ${bucket.hits}`,
64789
64802
  manifestJson: bucket.verificationManifest,
64790
64803
  updatedAt: finishedAt
64791
64804
  }
@@ -64819,7 +64832,7 @@ async function trafficRoutes(app, opts) {
64819
64832
  aiUserFetchEventsHourly.status
64820
64833
  ],
64821
64834
  set: {
64822
- hits: sql30`${aiUserFetchEventsHourly.hits} + ${bucket.hits}`,
64835
+ hits: sql31`${aiUserFetchEventsHourly.hits} + ${bucket.hits}`,
64823
64836
  sampledUserAgent: bucket.sampledUserAgent,
64824
64837
  updatedAt: finishedAt
64825
64838
  }
@@ -64850,7 +64863,7 @@ async function trafficRoutes(app, opts) {
64850
64863
  aiUserFetchVerificationManifestsHourly.manifestId
64851
64864
  ],
64852
64865
  set: {
64853
- hits: sql30`${aiUserFetchVerificationManifestsHourly.hits} + ${bucket.hits}`,
64866
+ hits: sql31`${aiUserFetchVerificationManifestsHourly.hits} + ${bucket.hits}`,
64854
64867
  manifestJson: bucket.verificationManifest,
64855
64868
  updatedAt: finishedAt
64856
64869
  }
@@ -64891,9 +64904,9 @@ async function trafficRoutes(app, opts) {
64891
64904
  // colliding bucket adds its paid and organic arrivals to the ones
64892
64905
  // already there rather than overwriting a single label.
64893
64906
  set: {
64894
- sessionsOrHits: sql30`${aiReferralEventsHourly.sessionsOrHits} + ${bucket.hits}`,
64895
- paidSessionsOrHits: sql30`${aiReferralEventsHourly.paidSessionsOrHits} + ${bucket.paidHits}`,
64896
- organicSessionsOrHits: sql30`${aiReferralEventsHourly.organicSessionsOrHits} + ${bucket.organicHits}`,
64907
+ sessionsOrHits: sql31`${aiReferralEventsHourly.sessionsOrHits} + ${bucket.hits}`,
64908
+ paidSessionsOrHits: sql31`${aiReferralEventsHourly.paidSessionsOrHits} + ${bucket.paidHits}`,
64909
+ organicSessionsOrHits: sql31`${aiReferralEventsHourly.organicSessionsOrHits} + ${bucket.organicHits}`,
64897
64910
  updatedAt: finishedAt
64898
64911
  }
64899
64912
  }).run();
@@ -65210,37 +65223,37 @@ async function trafficRoutes(app, opts) {
65210
65223
  function buildSourceDetail(projectId, row, since) {
65211
65224
  const crawlerPathRows = app.db.select({
65212
65225
  pathNormalized: crawlerEventsHourly.pathNormalized,
65213
- hits: sql30`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
65226
+ hits: sql31`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
65214
65227
  }).from(crawlerEventsHourly).where(
65215
65228
  and69(
65216
65229
  eq80(crawlerEventsHourly.sourceId, row.id),
65217
- gte19(crawlerEventsHourly.tsHour, since)
65230
+ gte20(crawlerEventsHourly.tsHour, since)
65218
65231
  )
65219
65232
  ).groupBy(crawlerEventsHourly.pathNormalized).all();
65220
65233
  const crawlerSegments = segmentCrawlerHits(
65221
65234
  crawlerPathRows.map((r) => ({ pathNormalized: r.pathNormalized, hits: Number(r.hits) }))
65222
65235
  );
65223
65236
  const crawlerTotal = crawlerSegments.content + crawlerSegments.sitemap + crawlerSegments.robots + crawlerSegments.asset + crawlerSegments.other;
65224
- const aiUserFetchTotals = app.db.select({ total: sql30`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
65237
+ const aiUserFetchTotals = app.db.select({ total: sql31`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
65225
65238
  and69(
65226
65239
  eq80(aiUserFetchEventsHourly.sourceId, row.id),
65227
- gte19(aiUserFetchEventsHourly.tsHour, since)
65240
+ gte20(aiUserFetchEventsHourly.tsHour, since)
65228
65241
  )
65229
65242
  ).get();
65230
65243
  const aiTotals = app.db.select({
65231
- total: sql30`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
65232
- nonhop: sql30`COALESCE(SUM(CASE WHEN ${referralLandedCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`,
65233
- landed: sql30`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`
65244
+ total: sql31`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
65245
+ nonhop: sql31`COALESCE(SUM(CASE WHEN ${referralLandedCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`,
65246
+ landed: sql31`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`
65234
65247
  }).from(aiReferralEventsHourly).where(
65235
65248
  and69(
65236
65249
  eq80(aiReferralEventsHourly.sourceId, row.id),
65237
- gte19(aiReferralEventsHourly.tsHour, since)
65250
+ gte20(aiReferralEventsHourly.tsHour, since)
65238
65251
  )
65239
65252
  ).get();
65240
- const sampleTotals = app.db.select({ total: sql30`COUNT(*)` }).from(rawEventSamples).where(
65253
+ const sampleTotals = app.db.select({ total: sql31`COUNT(*)` }).from(rawEventSamples).where(
65241
65254
  and69(
65242
65255
  eq80(rawEventSamples.sourceId, row.id),
65243
- gte19(rawEventSamples.ts, since)
65256
+ gte20(rawEventSamples.ts, since)
65244
65257
  )
65245
65258
  ).get();
65246
65259
  const latestRun = app.db.select().from(runs).where(
@@ -65454,22 +65467,22 @@ async function trafficRoutes(app, opts) {
65454
65467
  if (kind === "all" || kind === TrafficEventKinds.crawler) {
65455
65468
  const crawlerFilters = [
65456
65469
  eq80(crawlerEventsHourly.projectId, project.id),
65457
- gte19(crawlerEventsHourly.tsHour, sinceIso),
65458
- lte20(crawlerEventsHourly.tsHour, untilIso)
65470
+ gte20(crawlerEventsHourly.tsHour, sinceIso),
65471
+ lte21(crawlerEventsHourly.tsHour, untilIso)
65459
65472
  ];
65460
65473
  if (sourceIdParam) crawlerFilters.push(eq80(crawlerEventsHourly.sourceId, sourceIdParam));
65461
65474
  const crawlerWhere = and69(...crawlerFilters);
65462
65475
  const pathTotals = app.db.select({
65463
65476
  pathNormalized: crawlerEventsHourly.pathNormalized,
65464
- hits: sql30`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`,
65465
- rows: sql30`COUNT(*)`
65477
+ hits: sql31`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`,
65478
+ rows: sql31`COUNT(*)`
65466
65479
  }).from(crawlerEventsHourly).where(crawlerWhere).groupBy(crawlerEventsHourly.pathNormalized).all();
65467
65480
  crawlerSegments = segmentCrawlerHits(
65468
65481
  pathTotals.map((r) => ({ pathNormalized: r.pathNormalized, hits: Number(r.hits) }))
65469
65482
  );
65470
65483
  crawlerTotal = crawlerSegments.content + crawlerSegments.sitemap + crawlerSegments.robots + crawlerSegments.asset + crawlerSegments.other;
65471
65484
  totalEventRows += pathTotals.reduce((sum, row) => sum + Number(row.rows), 0);
65472
- const crawlerSeriesBucket = granularity === TrafficSeriesGranularities.day ? sql30`substr(${crawlerEventsHourly.tsHour}, 1, 10)` : crawlerEventsHourly.tsHour;
65485
+ const crawlerSeriesBucket = granularity === TrafficSeriesGranularities.day ? sql31`substr(${crawlerEventsHourly.tsHour}, 1, 10)` : crawlerEventsHourly.tsHour;
65473
65486
  const distinctPaths = pathTotals.map((r) => ({ pathNormalized: r.pathNormalized }));
65474
65487
  const contentPaths = [];
65475
65488
  const infraPaths = [];
@@ -65481,12 +65494,12 @@ async function trafficRoutes(app, opts) {
65481
65494
  const listed = useContentList ? contentPaths : infraPaths;
65482
65495
  const IN_LIST_CAP = 2e4;
65483
65496
  const listFitsInSql = listed.length <= IN_LIST_CAP;
65484
- const contentExpr = listed.length === 0 ? useContentList ? sql30`0` : sql30`${crawlerEventsHourly.hits}` : useContentList ? sql30`CASE WHEN ${inArray35(crawlerEventsHourly.pathNormalized, listed)} THEN ${crawlerEventsHourly.hits} ELSE 0 END` : sql30`CASE WHEN ${inArray35(crawlerEventsHourly.pathNormalized, listed)} THEN 0 ELSE ${crawlerEventsHourly.hits} END`;
65497
+ const contentExpr = listed.length === 0 ? useContentList ? sql31`0` : sql31`${crawlerEventsHourly.hits}` : useContentList ? sql31`CASE WHEN ${inArray35(crawlerEventsHourly.pathNormalized, listed)} THEN ${crawlerEventsHourly.hits} ELSE 0 END` : sql31`CASE WHEN ${inArray35(crawlerEventsHourly.pathNormalized, listed)} THEN 0 ELSE ${crawlerEventsHourly.hits} END`;
65485
65498
  if (listFitsInSql) {
65486
65499
  const crawlerSeries = app.db.select({
65487
65500
  bucket: crawlerSeriesBucket,
65488
- hits: sql30`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`,
65489
- content: sql30`COALESCE(SUM(${contentExpr}), 0)`
65501
+ hits: sql31`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`,
65502
+ content: sql31`COALESCE(SUM(${contentExpr}), 0)`
65490
65503
  }).from(crawlerEventsHourly).where(crawlerWhere).groupBy(crawlerSeriesBucket).all();
65491
65504
  for (const row of crawlerSeries) {
65492
65505
  const point = trafficSeriesPoint(seriesByBucket, String(row.bucket));
@@ -65498,7 +65511,7 @@ async function trafficRoutes(app, opts) {
65498
65511
  const grouped = app.db.select({
65499
65512
  bucket: crawlerSeriesBucket,
65500
65513
  pathNormalized: crawlerEventsHourly.pathNormalized,
65501
- hits: sql30`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
65514
+ hits: sql31`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
65502
65515
  }).from(crawlerEventsHourly).where(crawlerWhere).groupBy(crawlerSeriesBucket, crawlerEventsHourly.pathNormalized).all();
65503
65516
  for (const row of grouped) {
65504
65517
  const point = trafficSeriesPoint(seriesByBucket, String(row.bucket));
@@ -65529,21 +65542,21 @@ async function trafficRoutes(app, opts) {
65529
65542
  if (kind === "all" || kind === TrafficEventKinds["ai-user-fetch"]) {
65530
65543
  const userFetchFilters = [
65531
65544
  eq80(aiUserFetchEventsHourly.projectId, project.id),
65532
- gte19(aiUserFetchEventsHourly.tsHour, sinceIso),
65533
- lte20(aiUserFetchEventsHourly.tsHour, untilIso)
65545
+ gte20(aiUserFetchEventsHourly.tsHour, sinceIso),
65546
+ lte21(aiUserFetchEventsHourly.tsHour, untilIso)
65534
65547
  ];
65535
65548
  if (sourceIdParam) userFetchFilters.push(eq80(aiUserFetchEventsHourly.sourceId, sourceIdParam));
65536
65549
  const userFetchWhere = and69(...userFetchFilters);
65537
65550
  const total = app.db.select({
65538
- total: sql30`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)`,
65539
- rows: sql30`COUNT(*)`
65551
+ total: sql31`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)`,
65552
+ rows: sql31`COUNT(*)`
65540
65553
  }).from(aiUserFetchEventsHourly).where(userFetchWhere).get();
65541
65554
  aiUserFetchTotal = Number(total?.total ?? 0);
65542
65555
  totalEventRows += Number(total?.rows ?? 0);
65543
- const userFetchSeriesBucket = granularity === TrafficSeriesGranularities.day ? sql30`substr(${aiUserFetchEventsHourly.tsHour}, 1, 10)` : aiUserFetchEventsHourly.tsHour;
65556
+ const userFetchSeriesBucket = granularity === TrafficSeriesGranularities.day ? sql31`substr(${aiUserFetchEventsHourly.tsHour}, 1, 10)` : aiUserFetchEventsHourly.tsHour;
65544
65557
  const userFetchSeries = app.db.select({
65545
65558
  bucket: userFetchSeriesBucket,
65546
- hits: sql30`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)`
65559
+ hits: sql31`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)`
65547
65560
  }).from(aiUserFetchEventsHourly).where(userFetchWhere).groupBy(userFetchSeriesBucket).all();
65548
65561
  for (const row of userFetchSeries) {
65549
65562
  trafficSeriesPoint(seriesByBucket, row.bucket).aiUserFetchHits = Number(row.hits);
@@ -65568,18 +65581,18 @@ async function trafficRoutes(app, opts) {
65568
65581
  if (kind === "all" || kind === TrafficEventKinds["ai-referral"]) {
65569
65582
  const aiFilters = [
65570
65583
  eq80(aiReferralEventsHourly.projectId, project.id),
65571
- gte19(aiReferralEventsHourly.tsHour, sinceIso),
65572
- lte20(aiReferralEventsHourly.tsHour, untilIso)
65584
+ gte20(aiReferralEventsHourly.tsHour, sinceIso),
65585
+ lte21(aiReferralEventsHourly.tsHour, untilIso)
65573
65586
  ];
65574
65587
  if (sourceIdParam) aiFilters.push(eq80(aiReferralEventsHourly.sourceId, sourceIdParam));
65575
65588
  const aiWhere = and69(...aiFilters);
65576
65589
  const total = app.db.select({
65577
- total: sql30`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
65578
- nonhop: sql30`COALESCE(SUM(CASE WHEN ${referralLandedCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`,
65579
- landed: sql30`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`,
65580
- paid: sql30`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.paidSessionsOrHits} ELSE 0 END), 0)`,
65581
- organic: sql30`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.organicSessionsOrHits} ELSE 0 END), 0)`,
65582
- rows: sql30`COUNT(*)`
65590
+ total: sql31`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
65591
+ nonhop: sql31`COALESCE(SUM(CASE WHEN ${referralLandedCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`,
65592
+ landed: sql31`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`,
65593
+ paid: sql31`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.paidSessionsOrHits} ELSE 0 END), 0)`,
65594
+ organic: sql31`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.organicSessionsOrHits} ELSE 0 END), 0)`,
65595
+ rows: sql31`COUNT(*)`
65583
65596
  }).from(aiReferralEventsHourly).where(aiWhere).get();
65584
65597
  aiReferralTotalHits = Number(total?.total ?? 0);
65585
65598
  aiReferralNonHopHits = Number(total?.nonhop ?? 0);
@@ -65590,11 +65603,11 @@ async function trafficRoutes(app, opts) {
65590
65603
  Number(total?.organic ?? 0)
65591
65604
  );
65592
65605
  totalEventRows += Number(total?.rows ?? 0);
65593
- const referralSeriesBucket = granularity === TrafficSeriesGranularities.day ? sql30`substr(${aiReferralEventsHourly.tsHour}, 1, 10)` : aiReferralEventsHourly.tsHour;
65606
+ const referralSeriesBucket = granularity === TrafficSeriesGranularities.day ? sql31`substr(${aiReferralEventsHourly.tsHour}, 1, 10)` : aiReferralEventsHourly.tsHour;
65594
65607
  const referralSeries = app.db.select({
65595
65608
  bucket: referralSeriesBucket,
65596
- hits: sql30`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
65597
- landed: sql30`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`
65609
+ hits: sql31`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
65610
+ landed: sql31`COALESCE(SUM(CASE WHEN ${countableReferralCondition()} THEN ${aiReferralEventsHourly.sessionsOrHits} ELSE 0 END), 0)`
65598
65611
  }).from(aiReferralEventsHourly).where(aiWhere).groupBy(referralSeriesBucket).all();
65599
65612
  for (const row of referralSeries) {
65600
65613
  const point = trafficSeriesPoint(seriesByBucket, row.bucket);
@@ -65649,9 +65662,9 @@ async function trafficRoutes(app, opts) {
65649
65662
  const points = completeTrafficSeries(since, until, granularity, seriesByBucket);
65650
65663
  const coverageScope = (col, srcCol) => sourceIdParam ? and69(eq80(col, project.id), eq80(srcCol, sourceIdParam)) : eq80(col, project.id);
65651
65664
  const firsts = [
65652
- app.db.select({ v: sql30`MIN(${crawlerEventsHourly.tsHour})` }).from(crawlerEventsHourly).where(coverageScope(crawlerEventsHourly.projectId, crawlerEventsHourly.sourceId)).get()?.v,
65653
- app.db.select({ v: sql30`MIN(${aiUserFetchEventsHourly.tsHour})` }).from(aiUserFetchEventsHourly).where(coverageScope(aiUserFetchEventsHourly.projectId, aiUserFetchEventsHourly.sourceId)).get()?.v,
65654
- app.db.select({ v: sql30`MIN(${aiReferralEventsHourly.tsHour})` }).from(aiReferralEventsHourly).where(coverageScope(aiReferralEventsHourly.projectId, aiReferralEventsHourly.sourceId)).get()?.v
65665
+ app.db.select({ v: sql31`MIN(${crawlerEventsHourly.tsHour})` }).from(crawlerEventsHourly).where(coverageScope(crawlerEventsHourly.projectId, crawlerEventsHourly.sourceId)).get()?.v,
65666
+ app.db.select({ v: sql31`MIN(${aiUserFetchEventsHourly.tsHour})` }).from(aiUserFetchEventsHourly).where(coverageScope(aiUserFetchEventsHourly.projectId, aiUserFetchEventsHourly.sourceId)).get()?.v,
65667
+ app.db.select({ v: sql31`MIN(${aiReferralEventsHourly.tsHour})` }).from(aiReferralEventsHourly).where(coverageScope(aiReferralEventsHourly.projectId, aiReferralEventsHourly.sourceId)).get()?.v
65655
65668
  ].filter((v) => typeof v === "string" && v.length > 0);
65656
65669
  const coverageStart = firsts.length ? firsts.slice().sort()[0] : null;
65657
65670
  const bucketStartMs = (bucket) => Date.parse(
@@ -65725,7 +65738,7 @@ async function trafficRoutes(app, opts) {
65725
65738
  }
65726
65739
 
65727
65740
  // ../api-routes/src/doctor/checks/report-sweeps.ts
65728
- import { and as and70, asc as asc19, eq as eq81, gte as gte20, lte as lte21 } from "drizzle-orm";
65741
+ import { and as and70, asc as asc19, eq as eq81, gte as gte21, lte as lte22 } from "drizzle-orm";
65729
65742
 
65730
65743
  // ../api-routes/src/visibility-attribution.ts
65731
65744
  function buildQueryAttribution2(projectQueries) {
@@ -65847,7 +65860,7 @@ var reportSweepsCheck = {
65847
65860
  const graded = gradedReportMonths(reportMonths, now);
65848
65861
  const months = reportMonths.map((month) => {
65849
65862
  const bounds = calendarMonthBounds(month);
65850
- const monthRuns = ctx.db.select().from(runs).where(and70(eq81(runs.projectId, ctx.project.id), eq81(runs.kind, RunKinds["answer-visibility"]), notProbeRun(), gte20(runs.createdAt, bounds.since), lte21(runs.createdAt, bounds.until))).orderBy(asc19(runs.createdAt), asc19(runs.id)).all();
65863
+ const monthRuns = ctx.db.select().from(runs).where(and70(eq81(runs.projectId, ctx.project.id), eq81(runs.kind, RunKinds["answer-visibility"]), notProbeRun(), gte21(runs.createdAt, bounds.since), lte22(runs.createdAt, bounds.until))).orderBy(asc19(runs.createdAt), asc19(runs.id)).all();
65851
65864
  const evidence = monthRuns.map((run) => inspectSweep(ctx, run));
65852
65865
  return {
65853
65866
  month,
@@ -65870,7 +65883,7 @@ var reportSweepsCheck = {
65870
65883
  };
65871
65884
 
65872
65885
  // ../api-routes/src/doctor/checks/report-models.ts
65873
- import { and as and71, eq as eq82, gte as gte21, inArray as inArray36, lte as lte22 } from "drizzle-orm";
65886
+ import { and as and71, eq as eq82, gte as gte22, inArray as inArray36, lte as lte23 } from "drizzle-orm";
65874
65887
  var reportModelsCheck = {
65875
65888
  id: "report.models",
65876
65889
  category: CheckCategories.providers,
@@ -65885,7 +65898,7 @@ var reportModelsCheck = {
65885
65898
  const months = reportMonths.flatMap((month) => {
65886
65899
  const bounds = calendarMonthBounds(month);
65887
65900
  const previous = new Date(Date.parse(bounds.since) - 1).toISOString().slice(0, 7);
65888
- const observations = ctx.db.select({ provider: querySnapshots.provider, model: querySnapshots.model, at: runs.createdAt }).from(querySnapshots).innerJoin(runs, eq82(runs.id, querySnapshots.runId)).where(and71(eq82(runs.projectId, ctx.project.id), eq82(runs.kind, RunKinds["answer-visibility"]), inArray36(runs.status, [RunStatuses.completed, RunStatuses.partial]), notProbeRun(), gte21(runs.createdAt, bounds.since), lte22(runs.createdAt, bounds.until))).all();
65901
+ const observations = ctx.db.select({ provider: querySnapshots.provider, model: querySnapshots.model, at: runs.createdAt }).from(querySnapshots).innerJoin(runs, eq82(runs.id, querySnapshots.runId)).where(and71(eq82(runs.projectId, ctx.project.id), eq82(runs.kind, RunKinds["answer-visibility"]), inArray36(runs.status, [RunStatuses.completed, RunStatuses.partial]), notProbeRun(), gte22(runs.createdAt, bounds.since), lte23(runs.createdAt, bounds.until))).all();
65889
65902
  return readVisibilityContinuity(ctx.db, ctx.project.name, { from: previous, to: month }).map(({ frame, continuity: continuity2 }) => ({
65890
65903
  month,
65891
65904
  previousMonth: previous,
@@ -67543,7 +67556,7 @@ async function probeApiHost(host, options = {}) {
67543
67556
  }
67544
67557
 
67545
67558
  // ../api-routes/src/doctor/checks/integration-sync.ts
67546
- import { and as and75, count as count7, desc as desc42, eq as eq89, gte as gte22, gt as gt8, inArray as inArray39, isNull as isNull14, notInArray as notInArray3, or as or19 } from "drizzle-orm";
67559
+ import { and as and75, count as count7, desc as desc42, eq as eq89, gte as gte23, gt as gt8, inArray as inArray39, isNull as isNull14, notInArray as notInArray3, or as or19 } from "drizzle-orm";
67547
67560
  var SYNC_FAILURE_WINDOW = 3;
67548
67561
  var SUMMARY_ERROR_LIMIT = 300;
67549
67562
  var FINISHED_STATUSES = [RunStatuses.completed, RunStatuses.partial, RunStatuses.failed];
@@ -67635,7 +67648,7 @@ function readSyncRunState(db, projectId, kind, options = {}) {
67635
67648
  ...options.sourceId ? [eq89(runs.sourceId, options.sourceId)] : [],
67636
67649
  ...options.nothingToSyncErrors?.length ? [or19(isNull14(runs.error), notInArray3(runs.error, [...options.nothingToSyncErrors]))] : []
67637
67650
  );
67638
- const graded = options.since ? and75(scope, gte22(runs.createdAt, options.since)) : scope;
67651
+ const graded = options.since ? and75(scope, gte23(runs.createdAt, options.since)) : scope;
67639
67652
  const recent = db.select({ id: runs.id, status: runs.status, trigger: runs.trigger, error: runs.error, createdAt: runs.createdAt }).from(runs).where(and75(graded, inArray39(runs.status, FINISHED_STATUSES))).orderBy(desc42(runs.createdAt)).limit(SYNC_FAILURE_WINDOW).all();
67640
67653
  const lastSuccess = db.select({ createdAt: runs.createdAt, finishedAt: runs.finishedAt }).from(runs).where(and75(graded, inArray39(runs.status, SUCCESS_STATUSES))).orderBy(desc42(runs.createdAt)).limit(1).get();
67641
67654
  const failureCount = db.select({ count: count7() }).from(runs).where(and75(lastSuccess ? and75(graded, gt8(runs.createdAt, lastSuccess.createdAt)) : graded, eq89(runs.status, RunStatuses.failed))).get();
@@ -68198,7 +68211,7 @@ var PLACES_CHECK_BY_ID = Object.fromEntries(
68198
68211
  );
68199
68212
 
68200
68213
  // ../api-routes/src/doctor/checks/gbp-reviews.ts
68201
- import { and as and77, desc as desc43, eq as eq93, gte as gte23, inArray as inArray40, sql as sql31 } from "drizzle-orm";
68214
+ import { and as and77, desc as desc43, eq as eq93, gte as gte24, inArray as inArray40, sql as sql32 } from "drizzle-orm";
68202
68215
  var REVIEW_EVENTS = /* @__PURE__ */ new Set(["review.negative", "review.rating-dropped"]);
68203
68216
  var V4_ACCESS_REMEDIATION = "Business Profile reviews use the legacy My Business API (mybusiness.googleapis.com), which Google enables per Cloud project only on request; the API Library and `gcloud services enable` cannot turn it on. Open the enable link in the API access approval email as the approved account, or reply to the access-request thread asking Google to enable mybusiness.googleapis.com for your project number, then run `canonry gbp sync`.";
68204
68217
  var reviewsAccessCheck = {
@@ -68311,7 +68324,7 @@ var reviewDeliveryCheck = {
68311
68324
  return { status: CheckStatuses.skipped, code: "gbp.reviews.delivery.no-project", summary: "Project context required.", remediation: null };
68312
68325
  }
68313
68326
  const since = new Date(Date.now() - UNDELIVERED_ATTENTION_DAYS * 864e5).toISOString();
68314
- const lastTouched = sql31`coalesce(${reviewWebhookDeliveries.attemptedAt}, ${reviewWebhookDeliveries.createdAt})`;
68327
+ const lastTouched = sql32`coalesce(${reviewWebhookDeliveries.attemptedAt}, ${reviewWebhookDeliveries.createdAt})`;
68315
68328
  const rows = ctx.db.select({
68316
68329
  id: reviewWebhookDeliveries.id,
68317
68330
  notificationId: reviewWebhookDeliveries.notificationId,
@@ -68322,7 +68335,7 @@ var reviewDeliveryCheck = {
68322
68335
  }).from(reviewWebhookDeliveries).where(and77(
68323
68336
  eq93(reviewWebhookDeliveries.projectId, ctx.project.id),
68324
68337
  inArray40(reviewWebhookDeliveries.state, [ReviewDeliveryStates.Uncertain, ReviewDeliveryStates.Failed]),
68325
- gte23(lastTouched, since)
68338
+ gte24(lastTouched, since)
68326
68339
  )).orderBy(desc43(lastTouched)).all();
68327
68340
  if (rows.length === 0) {
68328
68341
  return {
@@ -68906,7 +68919,7 @@ var RUNTIME_STATE_CHECKS = [
68906
68919
  ];
68907
68920
 
68908
68921
  // ../api-routes/src/doctor/checks/traffic-source.ts
68909
- import { and as and78, desc as desc44, eq as eq94, gte as gte24, inArray as inArray41, isNotNull as isNotNull9, ne as ne16, sql as sql32 } from "drizzle-orm";
68922
+ import { and as and78, desc as desc44, eq as eq94, gte as gte25, inArray as inArray41, isNotNull as isNotNull9, ne as ne16, sql as sql33 } from "drizzle-orm";
68910
68923
  var RECENT_DATA_WARN_DAYS = 7;
68911
68924
  var RECENT_DATA_FAIL_DAYS = 30;
68912
68925
  function isCloudflareDirectPush(source) {
@@ -69083,29 +69096,29 @@ var recentDataCheck = {
69083
69096
  const warnCutoff = new Date(now.getTime() - RECENT_DATA_WARN_DAYS * 24 * 60 * 6e4).toISOString();
69084
69097
  const failCutoff = new Date(now.getTime() - RECENT_DATA_FAIL_DAYS * 24 * 60 * 6e4).toISOString();
69085
69098
  const recentCrawlers = Number(
69086
- ctx.db.select({ total: sql32`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
69099
+ ctx.db.select({ total: sql33`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
69087
69100
  and78(
69088
69101
  eq94(crawlerEventsHourly.projectId, ctx.project.id),
69089
69102
  inArray41(crawlerEventsHourly.sourceId, activeSourceIds),
69090
- gte24(crawlerEventsHourly.tsHour, warnCutoff)
69103
+ gte25(crawlerEventsHourly.tsHour, warnCutoff)
69091
69104
  )
69092
69105
  ).get()?.total ?? 0
69093
69106
  );
69094
69107
  const recentReferrals = Number(
69095
- ctx.db.select({ total: sql32`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
69108
+ ctx.db.select({ total: sql33`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
69096
69109
  and78(
69097
69110
  eq94(aiReferralEventsHourly.projectId, ctx.project.id),
69098
69111
  inArray41(aiReferralEventsHourly.sourceId, activeSourceIds),
69099
- gte24(aiReferralEventsHourly.tsHour, warnCutoff)
69112
+ gte25(aiReferralEventsHourly.tsHour, warnCutoff)
69100
69113
  )
69101
69114
  ).get()?.total ?? 0
69102
69115
  );
69103
69116
  const recentUserFetches = Number(
69104
- ctx.db.select({ total: sql32`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
69117
+ ctx.db.select({ total: sql33`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
69105
69118
  and78(
69106
69119
  eq94(aiUserFetchEventsHourly.projectId, ctx.project.id),
69107
69120
  inArray41(aiUserFetchEventsHourly.sourceId, activeSourceIds),
69108
- gte24(aiUserFetchEventsHourly.tsHour, warnCutoff)
69121
+ gte25(aiUserFetchEventsHourly.tsHour, warnCutoff)
69109
69122
  )
69110
69123
  ).get()?.total ?? 0
69111
69124
  );
@@ -69127,29 +69140,29 @@ var recentDataCheck = {
69127
69140
  };
69128
69141
  }
69129
69142
  const olderCrawlers = Number(
69130
- ctx.db.select({ total: sql32`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
69143
+ ctx.db.select({ total: sql33`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
69131
69144
  and78(
69132
69145
  eq94(crawlerEventsHourly.projectId, ctx.project.id),
69133
69146
  inArray41(crawlerEventsHourly.sourceId, activeSourceIds),
69134
- gte24(crawlerEventsHourly.tsHour, failCutoff)
69147
+ gte25(crawlerEventsHourly.tsHour, failCutoff)
69135
69148
  )
69136
69149
  ).get()?.total ?? 0
69137
69150
  );
69138
69151
  const olderReferrals = Number(
69139
- ctx.db.select({ total: sql32`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
69152
+ ctx.db.select({ total: sql33`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
69140
69153
  and78(
69141
69154
  eq94(aiReferralEventsHourly.projectId, ctx.project.id),
69142
69155
  inArray41(aiReferralEventsHourly.sourceId, activeSourceIds),
69143
- gte24(aiReferralEventsHourly.tsHour, failCutoff)
69156
+ gte25(aiReferralEventsHourly.tsHour, failCutoff)
69144
69157
  )
69145
69158
  ).get()?.total ?? 0
69146
69159
  );
69147
69160
  const olderUserFetches = Number(
69148
- ctx.db.select({ total: sql32`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
69161
+ ctx.db.select({ total: sql33`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
69149
69162
  and78(
69150
69163
  eq94(aiUserFetchEventsHourly.projectId, ctx.project.id),
69151
69164
  inArray41(aiUserFetchEventsHourly.sourceId, activeSourceIds),
69152
- gte24(aiUserFetchEventsHourly.tsHour, failCutoff)
69165
+ gte25(aiUserFetchEventsHourly.tsHour, failCutoff)
69153
69166
  )
69154
69167
  ).get()?.total ?? 0
69155
69168
  );
@@ -70404,7 +70417,7 @@ async function statusRoutes(app, opts) {
70404
70417
 
70405
70418
  // ../api-routes/src/discovery/routes.ts
70406
70419
  import crypto54 from "crypto";
70407
- import { and as and80, desc as desc46, eq as eq96, gte as gte25, inArray as inArray42, isNull as isNull16, or as or20 } from "drizzle-orm";
70420
+ import { and as and80, desc as desc46, eq as eq96, gte as gte26, inArray as inArray42, isNull as isNull16, or as or20 } from "drizzle-orm";
70408
70421
  var MAX_INFLIGHT_DISCOVERY_AGE_MS = 2 * 60 * 60 * 1e3;
70409
70422
  async function discoveryRoutes(app, opts) {
70410
70423
  app.post("/projects/:name/discover/run", async (request, reply) => {
@@ -70464,7 +70477,7 @@ async function discoveryRoutes(app, opts) {
70464
70477
  DiscoverySessionStatuses.seeding,
70465
70478
  DiscoverySessionStatuses.probing
70466
70479
  ]),
70467
- gte25(discoverySessions.createdAt, ageFloorIso)
70480
+ gte26(discoverySessions.createdAt, ageFloorIso)
70468
70481
  )).orderBy(desc46(discoverySessions.createdAt)).get();
70469
70482
  if (existing && existing.runId) {
70470
70483
  return { reused: true, sessionId: existing.id, runId: existing.runId };
@@ -71167,12 +71180,12 @@ function dedupeStrings(input) {
71167
71180
 
71168
71181
  // ../api-routes/src/technical-aeo.ts
71169
71182
  import crypto56 from "crypto";
71170
- import { and as and82, asc as asc21, count as count8, desc as desc47, eq as eq99, gte as gte26, inArray as inArray43, isNotNull as isNotNull10, isNull as isNull17, lt as lt14, or as or21, sql as sql34 } from "drizzle-orm";
71183
+ import { and as and82, asc as asc21, count as count8, desc as desc47, eq as eq99, gte as gte27, inArray as inArray43, isNotNull as isNotNull10, isNull as isNull17, lt as lt14, or as or21, sql as sql35 } from "drizzle-orm";
71171
71184
  import { alias } from "drizzle-orm/sqlite-core";
71172
71185
 
71173
71186
  // ../api-routes/src/technical-aeo-issues.ts
71174
71187
  import { createHash as createHash10 } from "crypto";
71175
- import { and as and81, asc as asc20, eq as eq98, gt as gt9, sql as sql33 } from "drizzle-orm";
71188
+ import { and as and81, asc as asc20, eq as eq98, gt as gt9, sql as sql34 } from "drizzle-orm";
71176
71189
  var ADVISORY_CODES = /* @__PURE__ */ new Set([
71177
71190
  "entity-consistency.title.short",
71178
71191
  "site.duplicate-title",
@@ -71322,7 +71335,7 @@ function readSiteAuditIssues(input) {
71322
71335
  eq98(siteCrawlPages.runId, snapshot.runId),
71323
71336
  eq98(siteCrawlPages.attemptId, snapshot.attemptId)
71324
71337
  );
71325
- const size = db.select({ bytes: sql33`coalesce(sum(length(cast(${siteCrawlPages.auditFields} as blob)) + length(cast(${siteCrawlPages.url} as blob))), 0)` }).from(siteCrawlPages).where(scope).get()?.bytes ?? 0;
71338
+ const size = db.select({ bytes: sql34`coalesce(sum(length(cast(${siteCrawlPages.auditFields} as blob)) + length(cast(${siteCrawlPages.url} as blob))), 0)` }).from(siteCrawlPages).where(scope).get()?.bytes ?? 0;
71326
71339
  if (size + crossBytes > MAX_EVIDENCE_BYTES) {
71327
71340
  throw validationError("Stored audit exceeds the 128 MiB issue-evidence read budget");
71328
71341
  }
@@ -71701,7 +71714,7 @@ function linkKindFilter(linkKind) {
71701
71714
  }
71702
71715
  var graphSourceNode = alias(siteCrawlGraphNodes, "site_crawl_graph_source_node");
71703
71716
  var graphTargetNode = alias(siteCrawlGraphNodes, "site_crawl_graph_target_node");
71704
- var PAGE_CHANGE_PREDICATE = sql34`(
71717
+ var PAGE_CHANGE_PREDICATE = sql35`(
71705
71718
  current.url IS NOT previous.url
71706
71719
  OR current.final_url IS NOT previous.final_url
71707
71720
  OR current.path IS NOT previous.path
@@ -71723,7 +71736,7 @@ var PAGE_CHANGE_PREDICATE = sql34`(
71723
71736
  OR current.link_score_raw IS NOT previous.link_score_raw
71724
71737
  OR current.link_score_normalized IS NOT previous.link_score_normalized
71725
71738
  )`;
71726
- var LINK_CHANGE_PREDICATE = sql34`(
71739
+ var LINK_CHANGE_PREDICATE = sql35`(
71727
71740
  current.source_node_key IS NOT previous.source_node_key
71728
71741
  OR current.source_url IS NOT previous.source_url
71729
71742
  OR current.target_node_key IS NOT previous.target_node_key
@@ -71808,12 +71821,12 @@ async function technicalAeoRoutes(app, opts) {
71808
71821
  ];
71809
71822
  const availableScanDatesFor = (projectId, requestedDate) => {
71810
71823
  if (!requestedDate) return void 0;
71811
- const date = sql34`substr(${siteCrawlSnapshots.createdAt}, 1, 10)`;
71824
+ const date = sql35`substr(${siteCrawlSnapshots.createdAt}, 1, 10)`;
71812
71825
  const filters = visibleCrawlFilters(projectId);
71813
71826
  const allDates = and82(...filters);
71814
- const matchingDates = and82(...filters, eq99(sql34`substr(${siteCrawlSnapshots.createdAt}, 6, 5)`, requestedDate.slice(5)));
71827
+ const matchingDates = and82(...filters, eq99(sql35`substr(${siteCrawlSnapshots.createdAt}, 6, 5)`, requestedDate.slice(5)));
71815
71828
  const readDates = (where) => app.db.select({ date }).from(siteCrawlSnapshots).innerJoin(runs, eq99(siteCrawlSnapshots.runId, runs.id)).where(where).groupBy(date).orderBy(desc47(date)).limit(10).all().map((row) => row.date);
71816
- const countDates = (where) => app.db.select({ value: sql34`count(distinct ${date})` }).from(siteCrawlSnapshots).innerJoin(runs, eq99(siteCrawlSnapshots.runId, runs.id)).where(where).get()?.value ?? 0;
71829
+ const countDates = (where) => app.db.select({ value: sql35`count(distinct ${date})` }).from(siteCrawlSnapshots).innerJoin(runs, eq99(siteCrawlSnapshots.runId, runs.id)).where(where).get()?.value ?? 0;
71817
71830
  return {
71818
71831
  recentDates: readDates(allDates),
71819
71832
  totalDates: countDates(allDates),
@@ -71827,11 +71840,11 @@ async function technicalAeoRoutes(app, opts) {
71827
71840
  if (requestedDate) {
71828
71841
  const nextDate2 = /* @__PURE__ */ new Date(`${requestedDate}T00:00:00.000Z`);
71829
71842
  nextDate2.setUTCDate(nextDate2.getUTCDate() + 1);
71830
- filters.push(gte26(siteCrawlSnapshots.createdAt, requestedDate), lt14(siteCrawlSnapshots.createdAt, nextDate2.toISOString()));
71843
+ filters.push(gte27(siteCrawlSnapshots.createdAt, requestedDate), lt14(siteCrawlSnapshots.createdAt, nextDate2.toISOString()));
71831
71844
  }
71832
- const selectionFilters = scope.scoredOnly ? [...filters, sql34`exists (select 1 from ${siteAuditSnapshots} where ${siteAuditSnapshots.projectId} = ${siteCrawlSnapshots.projectId} and ${siteAuditSnapshots.runId} = ${siteCrawlSnapshots.runId})`] : filters;
71845
+ const selectionFilters = scope.scoredOnly ? [...filters, sql35`exists (select 1 from ${siteAuditSnapshots} where ${siteAuditSnapshots.projectId} = ${siteCrawlSnapshots.projectId} and ${siteAuditSnapshots.runId} = ${siteCrawlSnapshots.runId})`] : filters;
71833
71846
  const selected = app.db.select({ snapshot: siteCrawlSnapshots, runStatus: runs.status }).from(siteCrawlSnapshots).innerJoin(runs, eq99(siteCrawlSnapshots.runId, runs.id)).where(and82(...selectionFilters, runId ? eq99(siteCrawlSnapshots.runId, runId) : void 0)).orderBy(
71834
- desc47(sql34`substr(${siteCrawlSnapshots.createdAt}, 1, 10)`),
71847
+ desc47(sql35`substr(${siteCrawlSnapshots.createdAt}, 1, 10)`),
71835
71848
  desc47(siteCrawlSnapshots.complete),
71836
71849
  desc47(siteCrawlSnapshots.pagesFetched),
71837
71850
  desc47(siteCrawlSnapshots.createdAt),
@@ -71843,7 +71856,7 @@ async function technicalAeoRoutes(app, opts) {
71843
71856
  nextDate.setUTCDate(nextDate.getUTCDate() + 1);
71844
71857
  const sameDate = and82(
71845
71858
  ...filters,
71846
- gte26(siteCrawlSnapshots.createdAt, date),
71859
+ gte27(siteCrawlSnapshots.createdAt, date),
71847
71860
  lt14(siteCrawlSnapshots.createdAt, nextDate.toISOString())
71848
71861
  );
71849
71862
  const sameDateRunCount = app.db.select({ value: count8() }).from(siteCrawlSnapshots).innerJoin(runs, eq99(siteCrawlSnapshots.runId, runs.id)).where(sameDate).get()?.value ?? 0;
@@ -71877,9 +71890,9 @@ async function technicalAeoRoutes(app, opts) {
71877
71890
  notProbeRun(),
71878
71891
  ...recordedBefore ? [lt14(siteAuditSnapshots.createdAt, recordedBefore)] : []
71879
71892
  ];
71880
- const complete = sql34`case when ${runs.status} = ${RunStatuses.completed} then 1 else 0 end`;
71893
+ const complete = sql35`case when ${runs.status} = ${RunStatuses.completed} then 1 else 0 end`;
71881
71894
  const selectAudit = (pinnedRunId) => app.db.select({ snap: siteAuditSnapshots, runStatus: runs.status }).from(siteAuditSnapshots).innerJoin(runs, eq99(siteAuditSnapshots.runId, runs.id)).where(and82(...filters, pinnedRunId ? eq99(siteAuditSnapshots.runId, pinnedRunId) : void 0)).orderBy(
71882
- desc47(sql34`substr(${siteAuditSnapshots.createdAt}, 1, 10)`),
71895
+ desc47(sql35`substr(${siteAuditSnapshots.createdAt}, 1, 10)`),
71883
71896
  desc47(complete),
71884
71897
  desc47(siteAuditSnapshots.pagesAudited),
71885
71898
  desc47(siteAuditSnapshots.createdAt),
@@ -71901,7 +71914,7 @@ async function technicalAeoRoutes(app, opts) {
71901
71914
  nextDate.setUTCDate(nextDate.getUTCDate() + 1);
71902
71915
  const sameDate = and82(
71903
71916
  ...filters,
71904
- gte26(siteAuditSnapshots.createdAt, date),
71917
+ gte27(siteAuditSnapshots.createdAt, date),
71905
71918
  lt14(siteAuditSnapshots.createdAt, nextDate.toISOString())
71906
71919
  );
71907
71920
  const sameDateRunCount = app.db.select({ value: count8() }).from(siteAuditSnapshots).innerJoin(runs, eq99(siteAuditSnapshots.runId, runs.id)).where(sameDate).get()?.value ?? 0;
@@ -71929,9 +71942,9 @@ async function technicalAeoRoutes(app, opts) {
71929
71942
  };
71930
71943
  const detailScopeFor = (projectId, snapshot) => snapshot.detailsAvailable && snapshot.attemptId ? { projectId, runId: snapshot.runId, attemptId: snapshot.attemptId } : null;
71931
71944
  const crawlReasonGroups = (where) => {
71932
- const canonicalOther = sql34`case when ${siteCrawlPages.canonicalNodeKey} is not null
71945
+ const canonicalOther = sql35`case when ${siteCrawlPages.canonicalNodeKey} is not null
71933
71946
  and ${siteCrawlPages.canonicalNodeKey} <> ${siteCrawlPages.nodeKey} then 1 else 0 end`;
71934
- const canonicalReason = sql34`exists (select 1 from json_each(${siteCrawlPages.indexabilityReasons})
71947
+ const canonicalReason = sql35`exists (select 1 from json_each(${siteCrawlPages.indexabilityReasons})
71935
71948
  where value = ${SiteCrawlIndexabilityReasons.canonicalToOther})`;
71936
71949
  const groups = app.db.select({
71937
71950
  fetchState: siteCrawlPages.fetchState,
@@ -71940,7 +71953,7 @@ async function technicalAeoRoutes(app, opts) {
71940
71953
  canonicalOther,
71941
71954
  canonicalReason,
71942
71955
  pages: count8(),
71943
- exampleUrl: sql34`min(${siteCrawlPages.url})`
71956
+ exampleUrl: sql35`min(${siteCrawlPages.url})`
71944
71957
  }).from(siteCrawlPages).where(where).groupBy(
71945
71958
  siteCrawlPages.fetchState,
71946
71959
  siteCrawlPages.indexabilityState,
@@ -72805,9 +72818,9 @@ async function technicalAeoRoutes(app, opts) {
72805
72818
  const summary4 = { pages: zero2(), links: zero2() };
72806
72819
  if (scopeFilter !== "links") {
72807
72820
  if (includeAdded || includeChanged) {
72808
- const addedExpression = includeAdded ? sql34`COALESCE(SUM(CASE WHEN previous.id IS NULL THEN 1 ELSE 0 END), 0)` : sql34`0`;
72809
- const changedExpression = includeChanged ? sql34`COALESCE(SUM(CASE WHEN previous.id IS NOT NULL AND ${PAGE_CHANGE_PREDICATE} THEN 1 ELSE 0 END), 0)` : sql34`0`;
72810
- const [counts2 = { added: 0, changed: 0 }] = app.db.all(sql34`
72821
+ const addedExpression = includeAdded ? sql35`COALESCE(SUM(CASE WHEN previous.id IS NULL THEN 1 ELSE 0 END), 0)` : sql35`0`;
72822
+ const changedExpression = includeChanged ? sql35`COALESCE(SUM(CASE WHEN previous.id IS NOT NULL AND ${PAGE_CHANGE_PREDICATE} THEN 1 ELSE 0 END), 0)` : sql35`0`;
72823
+ const [counts2 = { added: 0, changed: 0 }] = app.db.all(sql35`
72811
72824
  SELECT ${addedExpression} AS added, ${changedExpression} AS changed
72812
72825
  FROM site_crawl_pages AS current
72813
72826
  LEFT JOIN site_crawl_pages AS previous
@@ -72823,7 +72836,7 @@ async function technicalAeoRoutes(app, opts) {
72823
72836
  summary4.pages.changed = Number(counts2.changed);
72824
72837
  }
72825
72838
  if (includeRemoved) {
72826
- const [counts2 = { removed: 0 }] = app.db.all(sql34`
72839
+ const [counts2 = { removed: 0 }] = app.db.all(sql35`
72827
72840
  SELECT COUNT(*) AS removed
72828
72841
  FROM site_crawl_pages AS previous
72829
72842
  LEFT JOIN site_crawl_pages AS current
@@ -72841,9 +72854,9 @@ async function technicalAeoRoutes(app, opts) {
72841
72854
  }
72842
72855
  if (scopeFilter !== "pages") {
72843
72856
  if (includeAdded || includeChanged) {
72844
- const addedExpression = includeAdded ? sql34`COALESCE(SUM(CASE WHEN previous.id IS NULL THEN 1 ELSE 0 END), 0)` : sql34`0`;
72845
- const changedExpression = includeChanged ? sql34`COALESCE(SUM(CASE WHEN previous.id IS NOT NULL AND ${LINK_CHANGE_PREDICATE} THEN 1 ELSE 0 END), 0)` : sql34`0`;
72846
- const [counts2 = { added: 0, changed: 0 }] = app.db.all(sql34`
72857
+ const addedExpression = includeAdded ? sql35`COALESCE(SUM(CASE WHEN previous.id IS NULL THEN 1 ELSE 0 END), 0)` : sql35`0`;
72858
+ const changedExpression = includeChanged ? sql35`COALESCE(SUM(CASE WHEN previous.id IS NOT NULL AND ${LINK_CHANGE_PREDICATE} THEN 1 ELSE 0 END), 0)` : sql35`0`;
72859
+ const [counts2 = { added: 0, changed: 0 }] = app.db.all(sql35`
72847
72860
  SELECT ${addedExpression} AS added, ${changedExpression} AS changed
72848
72861
  FROM site_crawl_edges AS current
72849
72862
  LEFT JOIN site_crawl_edges AS previous
@@ -72861,7 +72874,7 @@ async function technicalAeoRoutes(app, opts) {
72861
72874
  summary4.links.changed = Number(counts2.changed);
72862
72875
  }
72863
72876
  if (includeRemoved) {
72864
- const [counts2 = { removed: 0 }] = app.db.all(sql34`
72877
+ const [counts2 = { removed: 0 }] = app.db.all(sql35`
72865
72878
  SELECT COUNT(*) AS removed
72866
72879
  FROM site_crawl_edges AS previous
72867
72880
  LEFT JOIN site_crawl_edges AS current
@@ -72891,48 +72904,48 @@ async function technicalAeoRoutes(app, opts) {
72891
72904
  const includeRemoved = changeFilter === "all" || changeFilter === "removed";
72892
72905
  const table = entity === "page" ? "site_crawl_pages" : "site_crawl_edges";
72893
72906
  const keyColumn = entity === "page" ? "node_key" : "edge_key";
72894
- const internalCurrent = entity === "link" ? sql34`AND current.internal = 1` : sql34``;
72895
- const internalPreviousJoin = entity === "link" ? sql34`AND previous.internal = 1` : sql34``;
72896
- const internalPrevious = entity === "link" ? sql34`AND previous.internal = 1` : sql34``;
72897
- const internalCurrentJoin = entity === "link" ? sql34`AND current.internal = 1` : sql34``;
72907
+ const internalCurrent = entity === "link" ? sql35`AND current.internal = 1` : sql35``;
72908
+ const internalPreviousJoin = entity === "link" ? sql35`AND previous.internal = 1` : sql35``;
72909
+ const internalPrevious = entity === "link" ? sql35`AND previous.internal = 1` : sql35``;
72910
+ const internalCurrentJoin = entity === "link" ? sql35`AND current.internal = 1` : sql35``;
72898
72911
  const difference2 = entity === "page" ? PAGE_CHANGE_PREDICATE : LINK_CHANGE_PREDICATE;
72899
- const afterKind = changeFilter === "added" ? sql34`previous.id IS NULL` : changeFilter === "changed" ? sql34`previous.id IS NOT NULL AND ${difference2}` : sql34`previous.id IS NULL OR (previous.id IS NOT NULL AND ${difference2})`;
72900
- const afterRows = includeAfter ? app.db.all(sql34`
72912
+ const afterKind = changeFilter === "added" ? sql35`previous.id IS NULL` : changeFilter === "changed" ? sql35`previous.id IS NOT NULL AND ${difference2}` : sql35`previous.id IS NULL OR (previous.id IS NOT NULL AND ${difference2})`;
72913
+ const afterRows = includeAfter ? app.db.all(sql35`
72901
72914
  SELECT ${entity} AS entity,
72902
72915
  CASE WHEN previous.id IS NULL THEN 'added' ELSE 'changed' END AS change,
72903
- current.${sql34.raw(keyColumn)} AS key
72904
- FROM ${sql34.raw(table)} AS current
72905
- LEFT JOIN ${sql34.raw(table)} AS previous
72916
+ current.${sql35.raw(keyColumn)} AS key
72917
+ FROM ${sql35.raw(table)} AS current
72918
+ LEFT JOIN ${sql35.raw(table)} AS previous
72906
72919
  ON previous.project_id = ${beforeScope.projectId}
72907
72920
  AND previous.run_id = ${beforeScope.runId}
72908
72921
  AND previous.attempt_id = ${beforeScope.attemptId}
72909
72922
  ${internalPreviousJoin}
72910
- AND previous.${sql34.raw(keyColumn)} = current.${sql34.raw(keyColumn)}
72923
+ AND previous.${sql35.raw(keyColumn)} = current.${sql35.raw(keyColumn)}
72911
72924
  WHERE current.project_id = ${afterScope.projectId}
72912
72925
  AND current.run_id = ${afterScope.runId}
72913
72926
  AND current.attempt_id = ${afterScope.attemptId}
72914
72927
  ${internalCurrent}
72915
- AND current.${sql34.raw(keyColumn)} > ${afterKey}
72928
+ AND current.${sql35.raw(keyColumn)} > ${afterKey}
72916
72929
  AND (${afterKind})
72917
- ORDER BY current.${sql34.raw(keyColumn)} ASC
72930
+ ORDER BY current.${sql35.raw(keyColumn)} ASC
72918
72931
  LIMIT ${wanted2}
72919
72932
  `) : [];
72920
- const removedRows = includeRemoved ? app.db.all(sql34`
72921
- SELECT ${entity} AS entity, 'removed' AS change, previous.${sql34.raw(keyColumn)} AS key
72922
- FROM ${sql34.raw(table)} AS previous
72923
- LEFT JOIN ${sql34.raw(table)} AS current
72933
+ const removedRows = includeRemoved ? app.db.all(sql35`
72934
+ SELECT ${entity} AS entity, 'removed' AS change, previous.${sql35.raw(keyColumn)} AS key
72935
+ FROM ${sql35.raw(table)} AS previous
72936
+ LEFT JOIN ${sql35.raw(table)} AS current
72924
72937
  ON current.project_id = ${afterScope.projectId}
72925
72938
  AND current.run_id = ${afterScope.runId}
72926
72939
  AND current.attempt_id = ${afterScope.attemptId}
72927
72940
  ${internalCurrentJoin}
72928
- AND current.${sql34.raw(keyColumn)} = previous.${sql34.raw(keyColumn)}
72941
+ AND current.${sql35.raw(keyColumn)} = previous.${sql35.raw(keyColumn)}
72929
72942
  WHERE previous.project_id = ${beforeScope.projectId}
72930
72943
  AND previous.run_id = ${beforeScope.runId}
72931
72944
  AND previous.attempt_id = ${beforeScope.attemptId}
72932
72945
  ${internalPrevious}
72933
- AND previous.${sql34.raw(keyColumn)} > ${afterKey}
72946
+ AND previous.${sql35.raw(keyColumn)} > ${afterKey}
72934
72947
  AND current.id IS NULL
72935
- ORDER BY previous.${sql34.raw(keyColumn)} ASC
72948
+ ORDER BY previous.${sql35.raw(keyColumn)} ASC
72936
72949
  LIMIT ${wanted2}
72937
72950
  `) : [];
72938
72951
  const merged = [];
@@ -73449,7 +73462,7 @@ async function technicalAeoRoutes(app, opts) {
73449
73462
  // a fabricated broken link shown to a client is not worth the saved
73450
73463
  // predicate. Applied to `total` as well as the rows, or the count would
73451
73464
  // promise a page the list cannot fill.
73452
- isNotNull10(sql34`json_extract(${siteCrawlFindings.evidence}, '$.statusCode')`)
73465
+ isNotNull10(sql35`json_extract(${siteCrawlFindings.evidence}, '$.statusCode')`)
73453
73466
  );
73454
73467
  const total = app.db.select({ value: count8() }).from(siteCrawlFindings).where(where).get()?.value ?? 0;
73455
73468
  const limit = parseBoundedLimit(request.query.limit, 100, 200);
@@ -73698,7 +73711,7 @@ async function technicalAeoRoutes(app, opts) {
73698
73711
  // ../api-routes/src/research.ts
73699
73712
  import crypto57 from "crypto";
73700
73713
  import { z as z7 } from "zod";
73701
- import { and as and83, count as count9, desc as desc48, eq as eq100, gte as gte27, lt as lt15, or as or22, sql as sql35 } from "drizzle-orm";
73714
+ import { and as and83, count as count9, desc as desc48, eq as eq100, gte as gte28, lt as lt15, or as or22, sql as sql36 } from "drizzle-orm";
73702
73715
  var sameLocation = (a, b) => a.label === b.label && a.city === b.city && a.region === b.region && a.country === b.country && a.timezone === b.timezone;
73703
73716
  var BATCH_RECEIPT_PREFIX = "__canonry_research_batch__:";
73704
73717
  async function researchRoutes(app, opts) {
@@ -73762,9 +73775,9 @@ async function researchRoutes(app, opts) {
73762
73775
  const { start, end, date } = utcDayBounds(now);
73763
73776
  const used = tx.select({ value: count9() }).from(researchRuns).where(and83(
73764
73777
  eq100(researchRuns.projectId, project.id),
73765
- gte27(researchRuns.createdAt, start),
73778
+ gte28(researchRuns.createdAt, start),
73766
73779
  lt15(researchRuns.createdAt, end),
73767
- sql35`(json_extract(${researchRuns.initiatedBy}, '$.role') = ${UserRoles.viewer} OR json_extract(${researchRuns.initiatedBy}, '$.limited') = 1)`
73780
+ sql36`(json_extract(${researchRuns.initiatedBy}, '$.role') = ${UserRoles.viewer} OR json_extract(${researchRuns.initiatedBy}, '$.limited') = 1)`
73768
73781
  )).get()?.value ?? 0;
73769
73782
  if (used >= viewerDailyRunLimit) {
73770
73783
  throw researchDailyLimitExceeded(project.name, viewerDailyRunLimit, date);
@@ -73818,9 +73831,9 @@ async function researchRoutes(app, opts) {
73818
73831
  const { start, end, date } = utcDayBounds(now);
73819
73832
  const used = tx.select({ value: count9() }).from(researchRuns).where(and83(
73820
73833
  eq100(researchRuns.projectId, project.id),
73821
- gte27(researchRuns.createdAt, start),
73834
+ gte28(researchRuns.createdAt, start),
73822
73835
  lt15(researchRuns.createdAt, end),
73823
- sql35`(json_extract(${researchRuns.initiatedBy}, '$.role') = ${UserRoles.viewer} OR json_extract(${researchRuns.initiatedBy}, '$.limited') = 1)`
73836
+ sql36`(json_extract(${researchRuns.initiatedBy}, '$.role') = ${UserRoles.viewer} OR json_extract(${researchRuns.initiatedBy}, '$.limited') = 1)`
73824
73837
  )).get()?.value ?? 0;
73825
73838
  if (used + prepared.length > viewerDailyRunLimit) throw researchDailyLimitExceeded(project.name, viewerDailyRunLimit, date);
73826
73839
  }