@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.
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +2 -2
- package/assets/assets/{AgentSetupPage-Cl9VXxLL.js → AgentSetupPage-DgcU4n6k.js} +1 -1
- package/assets/assets/{AuditHistoryPanel-DLa6Ca5t.js → AuditHistoryPanel-IDTBP47p.js} +1 -1
- package/assets/assets/{BacklinksPage-Dxnz-sUy.js → BacklinksPage-tbfBeOWq.js} +1 -1
- package/assets/assets/{HistoryPage-PU7UNO3T.js → HistoryPage-BT17i1bv.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-DD9_Y-qo.js → MeasurementPropertyPage-CNVW1nD0.js} +1 -1
- package/assets/assets/ProjectPage-BOpHsl0H.js +9 -0
- package/assets/assets/{RunsPage-BCySoVOJ.js → RunsPage-DSbp_ueP.js} +1 -1
- package/assets/assets/{SettingsPage-CDncGwNQ.js → SettingsPage-DhXsS4mE.js} +1 -1
- package/assets/assets/{SiteHealthSection-C4C2LBCJ.js → SiteHealthSection-DDnJ6MmG.js} +2 -2
- package/assets/assets/{ToneBadge-Cvv6Tkk7.js → ToneBadge-BQIKzc8y.js} +1 -1
- package/assets/assets/{TrafficPage-4oknsJk1.js → TrafficPage-2Ix0v2Sw.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-UQKbZgtR.js → TrafficSourceDetailPage-Cytn_uBJ.js} +1 -1
- package/assets/assets/{account-context-BL8j43iU.js → account-context-eRm8f3bl.js} +1 -1
- package/assets/assets/{card-BKud0olB.js → card-CWFz5ZQm.js} +1 -1
- package/assets/assets/{extract-error-message-CvEgflI1.js → extract-error-message-BdsLX91O.js} +1 -1
- package/assets/assets/{format-helpers-B1eNfBmy.js → format-helpers-Dv7wus0N.js} +1 -1
- package/assets/assets/{index-Ci_T3fwM.js → index-CipZo_Z_.js} +4 -4
- package/assets/assets/{query-client-Bf5Rr6po.js → query-client-B4X4SMBT.js} +1 -1
- package/assets/assets/{react-query-CsFtWT8r.js → react-query-6xQVTyvM.js} +1 -1
- package/assets/assets/{react-sigma_core.esm.min-CIzyqOHN.js → react-sigma_core.esm.min-_zOXWmWO.js} +1 -1
- package/assets/assets/{service-CTRAeUEv.js → service-D5-ENCES.js} +1 -1
- package/assets/index.html +7 -7
- package/dist/{ads-EFXCND5Z.js → ads-JR7S3FK6.js} +3 -3
- package/dist/{agent-2MAONYLR.js → agent-AMVJ3FUV.js} +7 -7
- package/dist/{agent-ask-5555LQQL.js → agent-ask-KZTQLKGM.js} +3 -3
- package/dist/{agent-conversations-LYWOS4X3.js → agent-conversations-WJJ2K2ON.js} +3 -3
- package/dist/{agent-memory-HOYIIO66.js → agent-memory-TNWIXVZ5.js} +3 -3
- package/dist/{agent-providers-EYXB2DMX.js → agent-providers-KJVQSN3Q.js} +3 -3
- package/dist/{agent-transcript-BWDOJXPV.js → agent-transcript-PBYDJLYH.js} +3 -3
- package/dist/{analytics-46VKY4SP.js → analytics-CBPNUDES.js} +3 -3
- package/dist/{apply-GII5J3QB.js → apply-ZX4OF5PG.js} +3 -3
- package/dist/{backfill-WSIEPRES.js → backfill-PPRSFYAV.js} +9 -9
- package/dist/{backlinks-GRHTLP5Z.js → backlinks-O4Q6WH53.js} +3 -3
- package/dist/{bing-5QDDHK57.js → bing-SIZPWBYU.js} +3 -3
- package/dist/{bootstrap-GWDFCGEQ.js → bootstrap-XF6DMDQI.js} +10 -10
- package/dist/{cdp-YMIJN52Z.js → cdp-DD7ARB62.js} +7 -7
- package/dist/{chunk-Y3VMSYEG.js → chunk-22XKOBJD.js} +1 -1
- package/dist/{chunk-I62VYS4B.js → chunk-73QOQIFZ.js} +4 -4
- package/dist/{chunk-6AYOWQJ3.js → chunk-C3FQGQDS.js} +3 -3
- package/dist/{chunk-7STLCYWL.js → chunk-CCJIMTYO.js} +5 -5
- package/dist/{chunk-ZGLLSPBB.js → chunk-CKRXLVWQ.js} +2 -2
- package/dist/{chunk-L6IQN2Y5.js → chunk-DIS2JA7D.js} +2 -2
- package/dist/{chunk-7KBFBFDS.js → chunk-DPRGW4BM.js} +4 -4
- package/dist/{chunk-7LVZATRE.js → chunk-G33PG23U.js} +1 -1
- package/dist/{chunk-RYH3XP6J.js → chunk-HQGMIHG6.js} +20 -20
- package/dist/{chunk-AUIHVRJ3.js → chunk-IJF7KNU6.js} +2 -2
- package/dist/{chunk-XR3R5PDK.js → chunk-KJA7V3IT.js} +1 -1
- package/dist/{chunk-UQABYWAX.js → chunk-LSKAENOY.js} +1 -1
- package/dist/{chunk-DKVY6HFW.js → chunk-MFNU4NRS.js} +3 -3
- package/dist/{chunk-PUHALZY7.js → chunk-MLXU4QOF.js} +334 -334
- package/dist/{chunk-7V6DJCZO.js → chunk-N7M7UVYT.js} +1 -1
- package/dist/{chunk-ZYE7D2OC.js → chunk-NCUTFEU4.js} +1 -1
- package/dist/{chunk-WFOIIHAK.js → chunk-NMDXZWFB.js} +2 -2
- package/dist/{chunk-6ZA23GRE.js → chunk-NYTPS5WW.js} +8 -8
- package/dist/{chunk-JP4Q5FEW.js → chunk-OMB3VLDQ.js} +3 -3
- package/dist/{chunk-CNPYR2CQ.js → chunk-PNZE3XLO.js} +1 -1
- package/dist/{chunk-NFZXB5ZV.js → chunk-Q4JRFMCJ.js} +5 -5
- package/dist/{chunk-VLOWXBJS.js → chunk-QT7UBYG7.js} +3 -3
- package/dist/{chunk-DYDLK3YY.js → chunk-RR7ZDGC7.js} +2 -2
- package/dist/{chunk-M6QGMJAQ.js → chunk-T4EGKFOV.js} +1 -1
- package/dist/{chunk-MXQB7AAP.js → chunk-UJ222WSC.js} +1 -1
- package/dist/{chunk-TX4HBLFP.js → chunk-UX667IQM.js} +277 -264
- package/dist/{chunk-CLMJSIZU.js → chunk-VL5LVBLE.js} +1 -1
- package/dist/{chunk-2BJDLTDI.js → chunk-VMLCPTRZ.js} +1 -1
- package/dist/{chunk-V23ALG2D.js → chunk-WACG4O26.js} +2 -2
- package/dist/{chunk-ITYUIHKO.js → chunk-WODZX4Y6.js} +1 -1
- package/dist/{chunk-ZUH7GDQ4.js → chunk-YNPUS3Y7.js} +4 -4
- package/dist/{chunk-4PRXS5JH.js → chunk-YVYID65D.js} +12 -1
- package/dist/{chunk-BAQOH3LE.js → chunk-Z4CVEVP6.js} +3 -3
- package/dist/{chunk-BUED4RWE.js → chunk-ZTO5KPQB.js} +1 -1
- package/dist/{citations-AMOXXK5R.js → citations-DQGMUJYX.js} +3 -3
- package/dist/{cli-catalog-K5EQZBOO.js → cli-catalog-G7USVSOC.js} +3 -3
- package/dist/{cli-commands-NBOP4CQW.js → cli-commands-YUBGTHRG.js} +7 -7
- package/dist/cli.js +13 -13
- package/dist/{competitor-YQBDZE6A.js → competitor-CIKVJ4H4.js} +3 -3
- package/dist/{content-DFZ56U3J.js → content-DPWKB5SO.js} +3 -3
- package/dist/{dashboard-LIPZS22H.js → dashboard-OX2JEGEK.js} +6 -6
- package/dist/{demo-XZJKCQRO.js → demo-NMMLZ6VZ.js} +1 -1
- package/dist/{demo-server-3BCUBH4H.js → demo-server-VD6C773Q.js} +11 -11
- package/dist/{discover-JDJ2O6D6.js → discover-3JGVGPMR.js} +3 -3
- package/dist/{discover-eval-5GST6BOJ.js → discover-eval-HVU24KNC.js} +3 -3
- package/dist/{doctor-2LJGHCIZ.js → doctor-77VPDK2N.js} +3 -3
- package/dist/{evidence-FQKL6ULX.js → evidence-WSSOMBED.js} +3 -3
- package/dist/{export-cmd-KNGYT4JH.js → export-cmd-CPO73FP7.js} +3 -3
- package/dist/{ga-UH4RUHX2.js → ga-QOIYDTEX.js} +9 -5
- package/dist/{gbp-IPMROSVV.js → gbp-JEPBXCS6.js} +3 -3
- package/dist/{google-QU5M737H.js → google-5BZYXAJH.js} +4 -4
- package/dist/{google-marketing-QCLVAP25.js → google-marketing-Q36Q7YFU.js} +1 -1
- package/dist/{health-cmd-7UFZ5MT6.js → health-cmd-5KSRFNNN.js} +3 -3
- package/dist/{history-3H3CKHVR.js → history-WE4K4QIA.js} +3 -3
- package/dist/index.d.ts +11 -11
- package/dist/index.js +24 -24
- package/dist/{init-RZY3NRFZ.js → init-TDAXSYRR.js} +11 -11
- package/dist/{insights-LEVVXDBW.js → insights-K6PVVNZA.js} +3 -3
- package/dist/intelligence-service-GCISXTKM.js +15 -0
- package/dist/{journeys-JMQBUF2E.js → journeys-GD2QE2YK.js} +3 -3
- package/dist/{keys-LF2UMTN6.js → keys-SLJDSG7P.js} +3 -3
- package/dist/{keyword-JSJYNWN2.js → keyword-KDDWSW24.js} +3 -3
- package/dist/{logs-RWUB42V3.js → logs-PMIEBMOW.js} +3 -3
- package/dist/{mcp-FWQXTWAR.js → mcp-E5YLJ4LN.js} +2 -2
- package/dist/mcp.js +9 -9
- package/dist/{measurement-plan-4WXYE6CZ.js → measurement-plan-QZDBAH5D.js} +5 -5
- package/dist/{notify-FBS43GY5.js → notify-3QXR6PO2.js} +3 -3
- package/dist/{organic-evidence-TTXXAHFX.js → organic-evidence-UXEEKJPH.js} +3 -3
- package/dist/{overview-AB5JTMWR.js → overview-2Q4E75BW.js} +4 -4
- package/dist/{project-GSQMF736.js → project-M7VFAIJ2.js} +3 -3
- package/dist/{query-JITDUO3B.js → query-WDQGPIKS.js} +3 -3
- package/dist/{research-UU5W2XPU.js → research-U2GP2EQK.js} +3 -3
- package/dist/{results-export-ZX62A645.js → results-export-SMNP3XZT.js} +3 -3
- package/dist/{run-HXNS5CB3.js → run-CZXLPC3S.js} +4 -4
- package/dist/{schedule-Q4XMBZAH.js → schedule-DVIXJJFI.js} +3 -3
- package/dist/{search-GC4RYLYD.js → search-GFU2VPG4.js} +3 -3
- package/dist/{serve-Z722TPMP.js → serve-C2TW7ZZC.js} +25 -25
- package/dist/{session-JI4YODZS.js → session-5MVIOTFY.js} +12 -12
- package/dist/{settings-5GFLK4DY.js → settings-VYVGART2.js} +3 -3
- package/dist/{skills-B7Z5S3IT.js → skills-EWEPVEDD.js} +2 -2
- package/dist/{snapshot-2JOQFYJE.js → snapshot-L2DX6EBI.js} +3 -3
- package/dist/{src-2UNG3E4M.js → src-RBXPA4CW.js} +2 -2
- package/dist/{status-NKK5MYNE.js → status-ZJLUWVST.js} +4 -4
- package/dist/{technical-aeo-MQLGHVIX.js → technical-aeo-7KRBPNV7.js} +3 -3
- package/dist/{telemetry-J5F2H7OJ.js → telemetry-ZROXU4SH.js} +4 -4
- package/dist/{tools-CXANMI23.js → tools-NDQN64CH.js} +11 -11
- package/dist/{traffic-BVKW6QDD.js → traffic-W3NOHWNK.js} +5 -5
- package/dist/{users-2EKLHWPH.js → users-GGJSWVSI.js} +3 -3
- package/dist/{visibility-stats-HVQ6VUEB.js → visibility-stats-VZ5A7LMI.js} +3 -3
- package/dist/{wordpress-EEYBM634.js → wordpress-JYXIO3DJ.js} +3 -3
- package/package.json +1 -1
- package/assets/assets/ProjectPage-CoaDuk54.js +0 -9
- 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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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(
|
|
56558
|
-
if (range.endDate) conditions.push(
|
|
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
|
-
|
|
56619
|
-
|
|
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
|
-
|
|
56661
|
-
|
|
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
|
-
|
|
57145
|
-
|
|
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
|
-
|
|
57168
|
-
|
|
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
|
-
|
|
57230
|
-
|
|
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
|
-
|
|
57262
|
-
|
|
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:
|
|
57501
|
-
app.db.select({ min:
|
|
57502
|
-
app.db.select({ min:
|
|
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:
|
|
57517
|
-
totalOrganicSessions:
|
|
57518
|
-
totalUsers:
|
|
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:
|
|
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:
|
|
57535
|
-
sessions:
|
|
57536
|
-
organicSessions:
|
|
57537
|
-
directSessions:
|
|
57538
|
-
users:
|
|
57539
|
-
}).from(gaTrafficSnapshots).where(and61(...snapshotConditions)).groupBy(
|
|
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:
|
|
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:
|
|
57553
|
-
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
|
-
|
|
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:
|
|
57586
|
-
}).from(gaSocialReferrals).where(and61(...socialConditions)).groupBy(gaSocialReferrals.source, gaSocialReferrals.medium, gaSocialReferrals.channelGroup).orderBy(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
57785
|
-
|
|
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:
|
|
57806
|
+
sessions: sql26`SUM(${gaSocialReferrals.sessions})`
|
|
57794
57807
|
}).from(gaSocialReferrals).where(and61(
|
|
57795
57808
|
eq73(gaSocialReferrals.projectId, project.id),
|
|
57796
|
-
|
|
57797
|
-
|
|
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:
|
|
57814
|
+
sessions: sql26`SUM(${gaSocialReferrals.sessions})`
|
|
57802
57815
|
}).from(gaSocialReferrals).where(and61(
|
|
57803
57816
|
eq73(gaSocialReferrals.projectId, project.id),
|
|
57804
|
-
|
|
57805
|
-
|
|
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:
|
|
57829
|
-
const sumOrganic = (from, to) => app.db.select({ sessions:
|
|
57830
|
-
const sumDirect = (from, to) => app.db.select({ sessions:
|
|
57831
|
-
const sumAi = (from, to) => app.db.select({ sessions:
|
|
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
|
-
|
|
57834
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
57849
|
-
|
|
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:
|
|
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
|
-
|
|
57855
|
-
|
|
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:
|
|
57859
|
-
const socialSourcePrev = app.db.select({ source: gaSocialReferrals.source, sessions:
|
|
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
|
-
|
|
57884
|
-
|
|
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:
|
|
57896
|
-
organicSessions:
|
|
57897
|
-
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:
|
|
57916
|
-
sessions:
|
|
57917
|
-
organicSessions:
|
|
57918
|
-
users:
|
|
57919
|
-
}).from(gaTrafficSnapshots).where(eq73(gaTrafficSnapshots.projectId, project.id)).groupBy(
|
|
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
|
|
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 =
|
|
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(
|
|
57957
|
-
if (range.endDate) windowFilters.push(
|
|
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(
|
|
57960
|
-
if (query.hostName !== void 0) filters.push(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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:
|
|
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
|
|
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
|
|
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(
|
|
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:
|
|
60267
|
-
total:
|
|
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:
|
|
60271
|
-
total:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
61901
|
-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
62143
|
-
paidSessionsOrHits:
|
|
62144
|
-
organicSessionsOrHits:
|
|
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:
|
|
62172
|
+
const existing = tx.select({ total: sql30`COUNT(*)` }).from(rawEventSamples).where(and67(
|
|
62160
62173
|
eq78(rawEventSamples.sourceId, opts.sourceId),
|
|
62161
|
-
|
|
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
|
|
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
|
-
|
|
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 =
|
|
62319
|
-
const shortest = db.select({ ms:
|
|
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 =
|
|
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:
|
|
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(
|
|
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(
|
|
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
|
-
|
|
62840
|
-
|
|
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
|
-
|
|
62847
|
-
|
|
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
|
-
|
|
62854
|
-
|
|
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
|
-
|
|
62861
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
64895
|
-
paidSessionsOrHits:
|
|
64896
|
-
organicSessionsOrHits:
|
|
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:
|
|
65226
|
+
hits: sql31`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
|
|
65214
65227
|
}).from(crawlerEventsHourly).where(
|
|
65215
65228
|
and69(
|
|
65216
65229
|
eq80(crawlerEventsHourly.sourceId, row.id),
|
|
65217
|
-
|
|
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:
|
|
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
|
-
|
|
65240
|
+
gte20(aiUserFetchEventsHourly.tsHour, since)
|
|
65228
65241
|
)
|
|
65229
65242
|
).get();
|
|
65230
65243
|
const aiTotals = app.db.select({
|
|
65231
|
-
total:
|
|
65232
|
-
nonhop:
|
|
65233
|
-
landed:
|
|
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
|
-
|
|
65250
|
+
gte20(aiReferralEventsHourly.tsHour, since)
|
|
65238
65251
|
)
|
|
65239
65252
|
).get();
|
|
65240
|
-
const sampleTotals = app.db.select({ total:
|
|
65253
|
+
const sampleTotals = app.db.select({ total: sql31`COUNT(*)` }).from(rawEventSamples).where(
|
|
65241
65254
|
and69(
|
|
65242
65255
|
eq80(rawEventSamples.sourceId, row.id),
|
|
65243
|
-
|
|
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
|
-
|
|
65458
|
-
|
|
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:
|
|
65465
|
-
rows:
|
|
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 ?
|
|
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 ?
|
|
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:
|
|
65489
|
-
content:
|
|
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:
|
|
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
|
-
|
|
65533
|
-
|
|
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:
|
|
65539
|
-
rows:
|
|
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 ?
|
|
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:
|
|
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
|
-
|
|
65572
|
-
|
|
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:
|
|
65578
|
-
nonhop:
|
|
65579
|
-
landed:
|
|
65580
|
-
paid:
|
|
65581
|
-
organic:
|
|
65582
|
-
rows:
|
|
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 ?
|
|
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:
|
|
65597
|
-
landed:
|
|
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:
|
|
65653
|
-
app.db.select({ v:
|
|
65654
|
-
app.db.select({ 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
|
|
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(),
|
|
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
|
|
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(),
|
|
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
|
|
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,
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
69103
|
+
gte25(crawlerEventsHourly.tsHour, warnCutoff)
|
|
69091
69104
|
)
|
|
69092
69105
|
).get()?.total ?? 0
|
|
69093
69106
|
);
|
|
69094
69107
|
const recentReferrals = Number(
|
|
69095
|
-
ctx.db.select({ total:
|
|
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
|
-
|
|
69112
|
+
gte25(aiReferralEventsHourly.tsHour, warnCutoff)
|
|
69100
69113
|
)
|
|
69101
69114
|
).get()?.total ?? 0
|
|
69102
69115
|
);
|
|
69103
69116
|
const recentUserFetches = Number(
|
|
69104
|
-
ctx.db.select({ total:
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
69147
|
+
gte25(crawlerEventsHourly.tsHour, failCutoff)
|
|
69135
69148
|
)
|
|
69136
69149
|
).get()?.total ?? 0
|
|
69137
69150
|
);
|
|
69138
69151
|
const olderReferrals = Number(
|
|
69139
|
-
ctx.db.select({ total:
|
|
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
|
-
|
|
69156
|
+
gte25(aiReferralEventsHourly.tsHour, failCutoff)
|
|
69144
69157
|
)
|
|
69145
69158
|
).get()?.total ?? 0
|
|
69146
69159
|
);
|
|
69147
69160
|
const olderUserFetches = Number(
|
|
69148
|
-
ctx.db.select({ total:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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:
|
|
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(
|
|
71843
|
+
filters.push(gte27(siteCrawlSnapshots.createdAt, requestedDate), lt14(siteCrawlSnapshots.createdAt, nextDate2.toISOString()));
|
|
71831
71844
|
}
|
|
71832
|
-
const selectionFilters = scope.scoredOnly ? [...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(
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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:
|
|
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 ?
|
|
72809
|
-
const changedExpression = includeChanged ?
|
|
72810
|
-
const [counts2 = { added: 0, changed: 0 }] = app.db.all(
|
|
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(
|
|
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 ?
|
|
72845
|
-
const changedExpression = includeChanged ?
|
|
72846
|
-
const [counts2 = { added: 0, changed: 0 }] = app.db.all(
|
|
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(
|
|
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" ?
|
|
72895
|
-
const internalPreviousJoin = entity === "link" ?
|
|
72896
|
-
const internalPrevious = entity === "link" ?
|
|
72897
|
-
const internalCurrentJoin = entity === "link" ?
|
|
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" ?
|
|
72900
|
-
const afterRows = includeAfter ? app.db.all(
|
|
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.${
|
|
72904
|
-
FROM ${
|
|
72905
|
-
LEFT JOIN ${
|
|
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.${
|
|
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.${
|
|
72928
|
+
AND current.${sql35.raw(keyColumn)} > ${afterKey}
|
|
72916
72929
|
AND (${afterKind})
|
|
72917
|
-
ORDER BY current.${
|
|
72930
|
+
ORDER BY current.${sql35.raw(keyColumn)} ASC
|
|
72918
72931
|
LIMIT ${wanted2}
|
|
72919
72932
|
`) : [];
|
|
72920
|
-
const removedRows = includeRemoved ? app.db.all(
|
|
72921
|
-
SELECT ${entity} AS entity, 'removed' AS change, previous.${
|
|
72922
|
-
FROM ${
|
|
72923
|
-
LEFT JOIN ${
|
|
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.${
|
|
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.${
|
|
72946
|
+
AND previous.${sql35.raw(keyColumn)} > ${afterKey}
|
|
72934
72947
|
AND current.id IS NULL
|
|
72935
|
-
ORDER BY previous.${
|
|
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(
|
|
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
|
|
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
|
-
|
|
73778
|
+
gte28(researchRuns.createdAt, start),
|
|
73766
73779
|
lt15(researchRuns.createdAt, end),
|
|
73767
|
-
|
|
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
|
-
|
|
73834
|
+
gte28(researchRuns.createdAt, start),
|
|
73822
73835
|
lt15(researchRuns.createdAt, end),
|
|
73823
|
-
|
|
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
|
}
|