@ainyc/canonry 4.114.0 → 4.115.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/assets/assets/{BacklinksPage-pxm5QdkH.js → BacklinksPage-DhXsZ8Sb.js} +1 -1
  2. package/assets/assets/{ChartPrimitives-lKnj_JyP.js → ChartPrimitives-Cdj0P8uG.js} +1 -1
  3. package/assets/assets/ProjectPage-DAWtJQ3w.js +7 -0
  4. package/assets/assets/{RunRow-BCinrp7o.js → RunRow-GJ_2CEif.js} +1 -1
  5. package/assets/assets/{RunsPage-CRoqsHH6.js → RunsPage-upaDiLFK.js} +1 -1
  6. package/assets/assets/{SettingsPage-BEJ39Z1y.js → SettingsPage-FbmEaN16.js} +1 -1
  7. package/assets/assets/{TrafficPage-DwlIys8k.js → TrafficPage-Di0H5JRu.js} +1 -1
  8. package/assets/assets/{TrafficSourceDetailPage-BxZdMbPs.js → TrafficSourceDetailPage-Bc2mxXSV.js} +1 -1
  9. package/assets/assets/{arrow-left-Bh1K7Q5q.js → arrow-left-yOCIy3_x.js} +1 -1
  10. package/assets/assets/{extract-error-message-CC-RB1fH.js → extract-error-message-tCNIzznL.js} +1 -1
  11. package/assets/assets/index-Bb5yUz7k.css +1 -0
  12. package/assets/assets/{index--YS3kkht.js → index-D0ZdnFQf.js} +43 -43
  13. package/assets/assets/{trash-2-uW1qyzpW.js → trash-2-gRyTO-PS.js} +1 -1
  14. package/assets/index.html +2 -2
  15. package/dist/{chunk-3VSTTH4M.js → chunk-BXNFOGDF.js} +227 -187
  16. package/dist/{chunk-WMWZW34J.js → chunk-PGVGHGIX.js} +3 -3
  17. package/dist/cli.js +3 -3
  18. package/dist/index.js +3 -3
  19. package/dist/{intelligence-service-I5EQ77KZ.js → intelligence-service-2C7H4C6A.js} +1 -1
  20. package/dist/mcp.js +1 -1
  21. package/package.json +9 -9
  22. package/assets/assets/ProjectPage-38ZIpkmq.js +0 -7
  23. package/assets/assets/index-CReX5Jn9.css +0 -1
  24. /package/dist/{chunk-DUBZH5JW.js → chunk-MO7GPMNV.js} +0 -0
@@ -276,7 +276,7 @@ import {
276
276
  } from "./chunk-VEUBAZRG.js";
277
277
 
278
278
  // src/intelligence-service.ts
279
- import { eq as eq38, desc as desc18, asc as asc6, and as and29, ne as ne5, or as or6, inArray as inArray14, gte as gte7, lte as lte4 } from "drizzle-orm";
279
+ import { eq as eq38, desc as desc18, asc as asc6, and as and30, ne as ne5, or as or6, inArray as inArray14, gte as gte7, lte as lte4 } from "drizzle-orm";
280
280
 
281
281
  // ../db/src/client.ts
282
282
  import { mkdirSync } from "fs";
@@ -6706,7 +6706,7 @@ async function queryRoutes(app, opts) {
6706
6706
 
6707
6707
  // ../api-routes/src/competitors.ts
6708
6708
  import crypto6 from "crypto";
6709
- import { eq as eq5 } from "drizzle-orm";
6709
+ import { and as and2, eq as eq5 } from "drizzle-orm";
6710
6710
  function normalizeCompetitor(domain) {
6711
6711
  const reg = registrableDomain(domain);
6712
6712
  if (reg) return reg;
@@ -6725,11 +6725,14 @@ function normalizeCompetitorList(domains) {
6725
6725
  }
6726
6726
  return result;
6727
6727
  }
6728
+ function serializeCompetitor(row) {
6729
+ return { id: row.id, domain: row.domain, createdAt: row.createdAt };
6730
+ }
6728
6731
  async function competitorRoutes(app) {
6729
6732
  app.get("/projects/:name/competitors", async (request, reply) => {
6730
6733
  const project = resolveProject(app.db, request.params.name);
6731
6734
  const rows = app.db.select().from(competitors).where(eq5(competitors.projectId, project.id)).all();
6732
- return reply.send(rows.map((r) => ({ id: r.id, domain: r.domain, createdAt: r.createdAt })));
6735
+ return reply.send(rows.map(serializeCompetitor));
6733
6736
  });
6734
6737
  app.put("/projects/:name/competitors", async (request, reply) => {
6735
6738
  const project = resolveProject(app.db, request.params.name);
@@ -6759,7 +6762,7 @@ async function competitorRoutes(app) {
6759
6762
  });
6760
6763
  });
6761
6764
  const rows = app.db.select().from(competitors).where(eq5(competitors.projectId, project.id)).all();
6762
- return reply.send(rows.map((r) => ({ id: r.id, domain: r.domain, createdAt: r.createdAt })));
6765
+ return reply.send(rows.map(serializeCompetitor));
6763
6766
  });
6764
6767
  app.post("/projects/:name/competitors", async (request, reply) => {
6765
6768
  const project = resolveProject(app.db, request.params.name);
@@ -6791,7 +6794,7 @@ async function competitorRoutes(app) {
6791
6794
  });
6792
6795
  });
6793
6796
  const rows = app.db.select().from(competitors).where(eq5(competitors.projectId, project.id)).all();
6794
- return reply.send(rows.map((r) => ({ id: r.id, domain: r.domain, createdAt: r.createdAt })));
6797
+ return reply.send(rows.map(serializeCompetitor));
6795
6798
  });
6796
6799
  app.delete("/projects/:name/competitors", async (request, reply) => {
6797
6800
  const project = resolveProject(app.db, request.params.name);
@@ -6813,7 +6816,26 @@ async function competitorRoutes(app) {
6813
6816
  });
6814
6817
  });
6815
6818
  const rows = app.db.select().from(competitors).where(eq5(competitors.projectId, project.id)).all();
6816
- return reply.send(rows.map((r) => ({ id: r.id, domain: r.domain, createdAt: r.createdAt })));
6819
+ return reply.send(rows.map(serializeCompetitor));
6820
+ });
6821
+ app.delete("/projects/:name/competitors/:id", async (request, reply) => {
6822
+ const project = resolveProject(app.db, request.params.name);
6823
+ const competitor = app.db.select().from(competitors).where(and2(eq5(competitors.projectId, project.id), eq5(competitors.id, request.params.id))).get();
6824
+ if (!competitor) {
6825
+ throw notFound("Competitor", request.params.id);
6826
+ }
6827
+ app.db.transaction((tx) => {
6828
+ tx.delete(competitors).where(eq5(competitors.id, competitor.id)).run();
6829
+ writeAuditLog(tx, auditFromRequest(request, {
6830
+ projectId: project.id,
6831
+ actor: "api",
6832
+ action: "competitors.deleted",
6833
+ entityType: "competitor",
6834
+ entityId: competitor.id,
6835
+ diff: { deleted: [competitor.domain] }
6836
+ }));
6837
+ });
6838
+ return reply.status(204).send();
6817
6839
  });
6818
6840
  }
6819
6841
  function parseCompetitorBatch(value) {
@@ -6829,12 +6851,12 @@ function parseCompetitorBatch(value) {
6829
6851
 
6830
6852
  // ../api-routes/src/runs.ts
6831
6853
  import crypto8 from "crypto";
6832
- import { and as and3, eq as eq7, asc, desc, or as or2, sql as sql5 } from "drizzle-orm";
6854
+ import { and as and4, eq as eq7, asc, desc, or as or2, sql as sql5 } from "drizzle-orm";
6833
6855
  import { gte } from "drizzle-orm";
6834
6856
 
6835
6857
  // ../api-routes/src/run-queue.ts
6836
6858
  import crypto7 from "crypto";
6837
- import { and as and2, eq as eq6, or } from "drizzle-orm";
6859
+ import { and as and3, eq as eq6, or } from "drizzle-orm";
6838
6860
  function queueRunIfProjectIdle(db, params) {
6839
6861
  const createdAt = params.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
6840
6862
  const kind = params.kind ?? "answer-visibility";
@@ -6842,7 +6864,7 @@ function queueRunIfProjectIdle(db, params) {
6842
6864
  const runId = crypto7.randomUUID();
6843
6865
  return db.transaction((tx) => {
6844
6866
  const activeRun = tx.select().from(runs).where(
6845
- and2(
6867
+ and3(
6846
6868
  eq6(runs.projectId, params.projectId),
6847
6869
  or(eq6(runs.status, "queued"), eq6(runs.status, "running"))
6848
6870
  )
@@ -6925,7 +6947,7 @@ async function runRoutes(app, opts) {
6925
6947
  throw validationError("No locations configured for this project");
6926
6948
  }
6927
6949
  const result = app.db.transaction((tx) => {
6928
- const activeRun = tx.select({ id: runs.id }).from(runs).where(and3(
6950
+ const activeRun = tx.select({ id: runs.id }).from(runs).where(and4(
6929
6951
  eq7(runs.projectId, project.id),
6930
6952
  or2(eq7(runs.status, "queued"), eq7(runs.status, "running"))
6931
6953
  )).get();
@@ -6998,15 +7020,15 @@ async function runRoutes(app, opts) {
6998
7020
  const parsedLimit = parseInt(request.query.limit ?? "", 10);
6999
7021
  const limit = Number.isNaN(parsedLimit) || parsedLimit <= 0 ? void 0 : parsedLimit;
7000
7022
  const kind = parseListKind(request.query.kind);
7001
- const where = kind ? and3(eq7(runs.projectId, project.id), eq7(runs.kind, kind)) : eq7(runs.projectId, project.id);
7023
+ const where = kind ? and4(eq7(runs.projectId, project.id), eq7(runs.kind, kind)) : eq7(runs.projectId, project.id);
7002
7024
  const rows = limit == null ? app.db.select().from(runs).where(where).orderBy(asc(runs.createdAt)).all() : app.db.select().from(runs).where(where).orderBy(desc(runs.createdAt)).limit(limit).all().reverse();
7003
7025
  return reply.send(rows.map(formatRun));
7004
7026
  });
7005
7027
  app.get("/projects/:name/runs/latest", async (request, reply) => {
7006
7028
  const project = resolveProject(app.db, request.params.name);
7007
- const countRow = app.db.select({ count: sql5`count(*)` }).from(runs).where(and3(eq7(runs.projectId, project.id), notProbeRun())).get();
7029
+ const countRow = app.db.select({ count: sql5`count(*)` }).from(runs).where(and4(eq7(runs.projectId, project.id), notProbeRun())).get();
7008
7030
  const totalRuns = countRow?.count ?? 0;
7009
- const latestRun = app.db.select().from(runs).where(and3(eq7(runs.projectId, project.id), notProbeRun())).orderBy(desc(runs.createdAt), desc(runs.id)).limit(1).get();
7031
+ const latestRun = app.db.select().from(runs).where(and4(eq7(runs.projectId, project.id), notProbeRun())).orderBy(desc(runs.createdAt), desc(runs.id)).limit(1).get();
7010
7032
  if (!latestRun) {
7011
7033
  return reply.send({ totalRuns: 0, run: null });
7012
7034
  }
@@ -7025,7 +7047,7 @@ async function runRoutes(app, opts) {
7025
7047
  if (kind) filters.push(eq7(runs.kind, kind));
7026
7048
  const scopedProjectId = request.apiKey?.projectId;
7027
7049
  if (scopedProjectId) filters.push(eq7(runs.projectId, scopedProjectId));
7028
- const rows = app.db.select().from(runs).where(and3(...filters)).orderBy(desc(runs.createdAt), desc(runs.id)).limit(limit).all();
7050
+ const rows = app.db.select().from(runs).where(and4(...filters)).orderBy(desc(runs.createdAt), desc(runs.id)).limit(limit).all();
7029
7051
  return reply.send(rows.map(formatRun));
7030
7052
  });
7031
7053
  app.post("/runs", async (request, reply) => {
@@ -7236,7 +7258,7 @@ function loadRunDetail(app, run) {
7236
7258
 
7237
7259
  // ../api-routes/src/apply.ts
7238
7260
  import crypto10 from "crypto";
7239
- import { and as and4, eq as eq8 } from "drizzle-orm";
7261
+ import { and as and5, eq as eq8 } from "drizzle-orm";
7240
7262
 
7241
7263
  // ../api-routes/src/schedule-utils.ts
7242
7264
  import { CronExpressionParser } from "cron-parser";
@@ -7679,7 +7701,7 @@ async function applyRoutes(app, opts) {
7679
7701
  });
7680
7702
  const AV_KIND = SchedulableRunKinds["answer-visibility"];
7681
7703
  if (resolvedSchedule) {
7682
- const existingSched = tx.select().from(schedules).where(and4(eq8(schedules.projectId, projectId), eq8(schedules.kind, AV_KIND))).get();
7704
+ const existingSched = tx.select().from(schedules).where(and5(eq8(schedules.projectId, projectId), eq8(schedules.kind, AV_KIND))).get();
7683
7705
  if (existingSched) {
7684
7706
  tx.update(schedules).set({
7685
7707
  cronExpr: resolvedSchedule.cronExpr,
@@ -7705,9 +7727,9 @@ async function applyRoutes(app, opts) {
7705
7727
  }
7706
7728
  scheduleAction = "upsert";
7707
7729
  } else if (deleteSchedule) {
7708
- const existingSched = tx.select().from(schedules).where(and4(eq8(schedules.projectId, projectId), eq8(schedules.kind, AV_KIND))).get();
7730
+ const existingSched = tx.select().from(schedules).where(and5(eq8(schedules.projectId, projectId), eq8(schedules.kind, AV_KIND))).get();
7709
7731
  if (existingSched) {
7710
- tx.delete(schedules).where(and4(eq8(schedules.projectId, projectId), eq8(schedules.kind, AV_KIND))).run();
7732
+ tx.delete(schedules).where(and5(eq8(schedules.projectId, projectId), eq8(schedules.kind, AV_KIND))).run();
7711
7733
  scheduleAction = "delete";
7712
7734
  }
7713
7735
  }
@@ -7791,7 +7813,7 @@ function normalizeCompetitorList2(domains) {
7791
7813
  }
7792
7814
 
7793
7815
  // ../api-routes/src/history.ts
7794
- import { and as and5, eq as eq9, desc as desc2, inArray as inArray2 } from "drizzle-orm";
7816
+ import { and as and6, eq as eq9, desc as desc2, inArray as inArray2 } from "drizzle-orm";
7795
7817
 
7796
7818
  // ../api-routes/src/notification-redaction.ts
7797
7819
  var REDACTED_URL = {
@@ -7849,7 +7871,7 @@ async function historyRoutes(app) {
7849
7871
  const project = resolveProject(app.db, request.params.name);
7850
7872
  const limit = parseInt(request.query.limit ?? "50", 10);
7851
7873
  const offset = parseInt(request.query.offset ?? "0", 10);
7852
- const projectRuns = app.db.select({ id: runs.id }).from(runs).where(and5(eq9(runs.projectId, project.id), notProbeRun())).all();
7874
+ const projectRuns = app.db.select({ id: runs.id }).from(runs).where(and6(eq9(runs.projectId, project.id), notProbeRun())).all();
7853
7875
  if (projectRuns.length === 0) {
7854
7876
  return reply.send({ snapshots: [], total: 0 });
7855
7877
  }
@@ -7898,7 +7920,7 @@ async function historyRoutes(app) {
7898
7920
  app.get("/projects/:name/timeline", async (request, reply) => {
7899
7921
  const project = resolveProject(app.db, request.params.name);
7900
7922
  const projectQueries = app.db.select().from(queries).where(eq9(queries.projectId, project.id)).all();
7901
- const projectRuns = app.db.select().from(runs).where(and5(eq9(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all();
7923
+ const projectRuns = app.db.select().from(runs).where(and6(eq9(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all();
7902
7924
  if (projectRuns.length === 0 || projectQueries.length === 0) {
7903
7925
  return reply.send([]);
7904
7926
  }
@@ -8109,13 +8131,13 @@ function formatAuditEntry(row) {
8109
8131
  }
8110
8132
 
8111
8133
  // ../api-routes/src/analytics.ts
8112
- import { and as and6, eq as eq10, desc as desc3, inArray as inArray3 } from "drizzle-orm";
8134
+ import { and as and7, eq as eq10, desc as desc3, inArray as inArray3 } from "drizzle-orm";
8113
8135
  async function analyticsRoutes(app) {
8114
8136
  app.get("/projects/:name/analytics/metrics", async (request, reply) => {
8115
8137
  const project = resolveProject(app.db, request.params.name);
8116
8138
  const window = parseWindow(request.query.window);
8117
8139
  const cutoff = windowCutoff(window);
8118
- const projectRuns = app.db.select().from(runs).where(and6(eq10(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
8140
+ const projectRuns = app.db.select().from(runs).where(and7(eq10(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
8119
8141
  if (projectRuns.length === 0) {
8120
8142
  return reply.send({
8121
8143
  window,
@@ -8167,14 +8189,14 @@ async function analyticsRoutes(app) {
8167
8189
  const project = resolveProject(app.db, request.params.name);
8168
8190
  const window = parseWindow(request.query.window);
8169
8191
  const cutoff = windowCutoff(window);
8170
- const completedRuns = app.db.select().from(runs).where(and6(eq10(runs.projectId, project.id), notProbeRun())).orderBy(desc3(runs.createdAt), desc3(runs.id)).all().filter((r) => r.status === "completed" || r.status === "partial");
8192
+ const completedRuns = app.db.select().from(runs).where(and7(eq10(runs.projectId, project.id), notProbeRun())).orderBy(desc3(runs.createdAt), desc3(runs.id)).all().filter((r) => r.status === "completed" || r.status === "partial");
8171
8193
  const latestGroup = groupRunsByCreatedAt(completedRuns)[0] ?? [];
8172
8194
  const latestGroupRunIds = latestGroup.map((r) => r.id);
8173
8195
  const latestRun = pickGroupRepresentative(latestGroup);
8174
8196
  if (!latestRun) {
8175
8197
  return reply.send({ cited: [], gap: [], uncited: [], mentionedQueries: [], mentionGap: [], notMentioned: [], runId: "", window });
8176
8198
  }
8177
- const windowRuns = app.db.select().from(runs).where(and6(eq10(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
8199
+ const windowRuns = app.db.select().from(runs).where(and7(eq10(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
8178
8200
  const windowRunIds = windowRuns.map((r) => r.id);
8179
8201
  const runIdToCreatedAt = new Map(windowRuns.map((r) => [r.id, r.createdAt]));
8180
8202
  const consistencyMap = /* @__PURE__ */ new Map();
@@ -8305,7 +8327,7 @@ async function analyticsRoutes(app) {
8305
8327
  const mapped = surfaceClassFromCompetitorType(row.competitorType);
8306
8328
  if (mapped) storedSurfaceClasses.set(normalizeProjectDomain(row.domain), mapped);
8307
8329
  }
8308
- const windowRuns = app.db.select().from(runs).where(and6(eq10(runs.projectId, project.id), notProbeRun())).orderBy(desc3(runs.createdAt), desc3(runs.id)).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
8330
+ const windowRuns = app.db.select().from(runs).where(and7(eq10(runs.projectId, project.id), notProbeRun())).orderBy(desc3(runs.createdAt), desc3(runs.id)).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
8309
8331
  if (windowRuns.length === 0) {
8310
8332
  return reply.send({
8311
8333
  overall: [],
@@ -8570,7 +8592,7 @@ function buildCategoryCounts(counts2) {
8570
8592
  }
8571
8593
 
8572
8594
  // ../api-routes/src/intelligence.ts
8573
- import { eq as eq11, desc as desc4, and as and7, inArray as inArray4, like } from "drizzle-orm";
8595
+ import { eq as eq11, desc as desc4, and as and8, inArray as inArray4, like } from "drizzle-orm";
8574
8596
  var SEVERITY_RANK = { low: 0, medium: 1, high: 2, critical: 3 };
8575
8597
  function severitiesAtOrAbove(min) {
8576
8598
  const floor = SEVERITY_RANK[min];
@@ -8710,7 +8732,7 @@ async function intelligenceRoutes(app) {
8710
8732
  }
8711
8733
  limit = parsed;
8712
8734
  }
8713
- const rows = app.db.select().from(insights).where(conditions.length === 1 ? conditions[0] : and7(...conditions)).orderBy(desc4(insights.createdAt)).all();
8735
+ const rows = app.db.select().from(insights).where(conditions.length === 1 ? conditions[0] : and8(...conditions)).orderBy(desc4(insights.createdAt)).all();
8714
8736
  const showDismissed = request.query.dismissed === "true";
8715
8737
  let result = rows.filter((r) => showDismissed || !r.dismissed).map(mapInsightRow);
8716
8738
  if (limit !== void 0) result = result.slice(0, limit);
@@ -8735,7 +8757,7 @@ async function intelligenceRoutes(app) {
8735
8757
  });
8736
8758
  app.get("/projects/:name/health/latest", async (request, reply) => {
8737
8759
  const project = resolveProject(app.db, request.params.name);
8738
- const projectVisRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(and7(
8760
+ const projectVisRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(and8(
8739
8761
  eq11(runs.projectId, project.id),
8740
8762
  eq11(runs.kind, RunKinds["answer-visibility"]),
8741
8763
  inArray4(runs.status, [RunStatuses.completed, RunStatuses.partial]),
@@ -8746,7 +8768,7 @@ async function intelligenceRoutes(app) {
8746
8768
  const latestGroup = groupRunsByCreatedAt(projectVisRuns)[0] ?? [];
8747
8769
  const latestGroupRunIds = latestGroup.map((r) => r.id);
8748
8770
  if (latestGroupRunIds.length > 0) {
8749
- const groupRows = app.db.select().from(healthSnapshots).where(and7(
8771
+ const groupRows = app.db.select().from(healthSnapshots).where(and8(
8750
8772
  eq11(healthSnapshots.projectId, project.id),
8751
8773
  inArray4(healthSnapshots.runId, latestGroupRunIds)
8752
8774
  )).all();
@@ -8770,14 +8792,14 @@ async function intelligenceRoutes(app) {
8770
8792
  }
8771
8793
 
8772
8794
  // ../api-routes/src/report.ts
8773
- import { and as and11, desc as desc7, eq as eq15, gte as gte2, inArray as inArray6, lt, lte, ne as ne2, or as or3, sql as sql7 } from "drizzle-orm";
8795
+ import { and as and12, desc as desc7, eq as eq15, gte as gte2, inArray as inArray6, lt, lte, ne as ne2, or as or3, sql as sql7 } from "drizzle-orm";
8774
8796
 
8775
8797
  // ../api-routes/src/content.ts
8776
8798
  import crypto11 from "crypto";
8777
- import { and as and9, desc as desc6, eq as eq13 } from "drizzle-orm";
8799
+ import { and as and10, desc as desc6, eq as eq13 } from "drizzle-orm";
8778
8800
 
8779
8801
  // ../api-routes/src/content-data.ts
8780
- import { and as and8, eq as eq12, desc as desc5, inArray as inArray5 } from "drizzle-orm";
8802
+ import { and as and9, eq as eq12, desc as desc5, inArray as inArray5 } from "drizzle-orm";
8781
8803
  var RECENT_RUNS_WINDOW = 5;
8782
8804
  function loadOrchestratorInput(db, project, locationFilter = void 0) {
8783
8805
  const projectId = project.id;
@@ -8907,7 +8929,7 @@ function listCompetitorDomains(db, projectId) {
8907
8929
  }
8908
8930
  function listRecentAnswerVisibilityRunIds(db, projectId, limit, locationFilter) {
8909
8931
  const rows = db.select({ id: runs.id, location: runs.location }).from(runs).where(
8910
- and8(
8932
+ and9(
8911
8933
  eq12(runs.projectId, projectId),
8912
8934
  eq12(runs.kind, RunKinds["answer-visibility"]),
8913
8935
  // Queued/running/failed/cancelled runs may have partial or no
@@ -9278,7 +9300,7 @@ async function contentRoutes(app, opts = {}) {
9278
9300
  dismissedAt: now
9279
9301
  }
9280
9302
  }).run();
9281
- const row = app.db.select().from(contentTargetDismissals).where(and9(
9303
+ const row = app.db.select().from(contentTargetDismissals).where(and10(
9282
9304
  eq13(contentTargetDismissals.projectId, project.id),
9283
9305
  eq13(contentTargetDismissals.targetRef, targetRef)
9284
9306
  )).get();
@@ -9288,7 +9310,7 @@ async function contentRoutes(app, opts = {}) {
9288
9310
  app.delete("/projects/:name/content/dismissals/:targetRef", async (request, reply) => {
9289
9311
  const project = resolveProject(app.db, request.params.name);
9290
9312
  const { targetRef } = request.params;
9291
- const result = app.db.delete(contentTargetDismissals).where(and9(
9313
+ const result = app.db.delete(contentTargetDismissals).where(and10(
9292
9314
  eq13(contentTargetDismissals.projectId, project.id),
9293
9315
  eq13(contentTargetDismissals.targetRef, targetRef)
9294
9316
  )).run();
@@ -9299,7 +9321,7 @@ async function contentRoutes(app, opts = {}) {
9299
9321
  });
9300
9322
  app.get("/projects/:name/content/recommendations/:targetRef/analysis", async (request, reply) => {
9301
9323
  const project = resolveProject(app.db, request.params.name);
9302
- const row = app.db.select().from(recommendationExplanations).where(and9(
9324
+ const row = app.db.select().from(recommendationExplanations).where(and10(
9303
9325
  eq13(recommendationExplanations.projectId, project.id),
9304
9326
  eq13(recommendationExplanations.targetRef, request.params.targetRef)
9305
9327
  )).orderBy(desc6(recommendationExplanations.generatedAt)).limit(1).get();
@@ -9327,7 +9349,7 @@ async function contentRoutes(app, opts = {}) {
9327
9349
  throw notFound("contentRecommendation", targetRef);
9328
9350
  }
9329
9351
  if (!body.forceRefresh) {
9330
- const cached = app.db.select().from(recommendationExplanations).where(and9(
9352
+ const cached = app.db.select().from(recommendationExplanations).where(and10(
9331
9353
  eq13(recommendationExplanations.projectId, project.id),
9332
9354
  eq13(recommendationExplanations.targetRef, targetRef)
9333
9355
  )).orderBy(desc6(recommendationExplanations.generatedAt)).limit(1).get();
@@ -9366,7 +9388,7 @@ async function contentRoutes(app, opts = {}) {
9366
9388
  generatedAt: now
9367
9389
  }
9368
9390
  }).run();
9369
- const row = app.db.select().from(recommendationExplanations).where(and9(
9391
+ const row = app.db.select().from(recommendationExplanations).where(and10(
9370
9392
  eq13(recommendationExplanations.projectId, project.id),
9371
9393
  eq13(recommendationExplanations.targetRef, targetRef),
9372
9394
  eq13(recommendationExplanations.promptVersion, result.promptVersion)
@@ -9450,7 +9472,7 @@ async function contentRoutes(app, opts = {}) {
9450
9472
  generatedAt: now
9451
9473
  }
9452
9474
  }).run();
9453
- const row = app.db.select().from(recommendationBriefs).where(and9(
9475
+ const row = app.db.select().from(recommendationBriefs).where(and10(
9454
9476
  eq13(recommendationBriefs.projectId, project.id),
9455
9477
  eq13(recommendationBriefs.targetRef, targetRef),
9456
9478
  eq13(recommendationBriefs.promptVersion, result.promptVersion)
@@ -9480,7 +9502,7 @@ function lookupCachedBrief(db, projectId, targetRef, promptVersion) {
9480
9502
  if (promptVersion !== void 0) {
9481
9503
  conditions.push(eq13(recommendationBriefs.promptVersion, promptVersion));
9482
9504
  }
9483
- return db.select().from(recommendationBriefs).where(and9(...conditions)).orderBy(desc6(recommendationBriefs.generatedAt)).limit(1).get();
9505
+ return db.select().from(recommendationBriefs).where(and10(...conditions)).orderBy(desc6(recommendationBriefs.generatedAt)).limit(1).get();
9484
9506
  }
9485
9507
  function parseLimitParam(raw) {
9486
9508
  if (raw === void 0) return void 0;
@@ -9506,7 +9528,7 @@ function winnabilityClassRank(winnabilityClass) {
9506
9528
  }
9507
9529
 
9508
9530
  // ../api-routes/src/gsc-totals.ts
9509
- import { and as and10, asc as asc2, eq as eq14, sql as sql6 } from "drizzle-orm";
9531
+ import { and as and11, asc as asc2, eq as eq14, sql as sql6 } from "drizzle-orm";
9510
9532
  function readGscDailyTotals(db, projectId, startDate, endDate) {
9511
9533
  const rows = db.select({
9512
9534
  date: gscDailyTotals.date,
@@ -9514,7 +9536,7 @@ function readGscDailyTotals(db, projectId, startDate, endDate) {
9514
9536
  impressions: gscDailyTotals.impressions,
9515
9537
  position: gscDailyTotals.position
9516
9538
  }).from(gscDailyTotals).where(
9517
- and10(
9539
+ and11(
9518
9540
  eq14(gscDailyTotals.projectId, projectId),
9519
9541
  sql6`${gscDailyTotals.date} >= ${startDate}`,
9520
9542
  sql6`${gscDailyTotals.date} <= ${endDate}`
@@ -11945,7 +11967,7 @@ function buildGscSection(db, projectId, projectBrandNames, canonicalDomain, trac
11945
11967
  function buildGaSection(db, projectId, windowDays) {
11946
11968
  const gaWindowKey = GA_WINDOW_SUMMARY_KEYS[windowDays];
11947
11969
  const windowSummary = gaWindowKey ? db.select().from(gaTrafficWindowSummaries).where(
11948
- and11(
11970
+ and12(
11949
11971
  eq15(gaTrafficWindowSummaries.projectId, projectId),
11950
11972
  eq15(gaTrafficWindowSummaries.windowKey, gaWindowKey)
11951
11973
  )
@@ -12123,7 +12145,7 @@ function nonSubresourceReferralPathCondition() {
12123
12145
  }
12124
12146
  function buildServerActivity(db, projectId, windowDays) {
12125
12147
  const sourceRows = db.select({ id: trafficSources.id }).from(trafficSources).where(
12126
- and11(
12148
+ and12(
12127
12149
  eq15(trafficSources.projectId, projectId),
12128
12150
  ne2(trafficSources.status, TrafficSourceStatuses.archived)
12129
12151
  )
@@ -12139,7 +12161,7 @@ function buildServerActivity(db, projectId, windowDays) {
12139
12161
  const trendStart = new Date(trendStartMs).toISOString();
12140
12162
  const sumVerifiedCrawlers = (windowStartIso, windowEndIso, exclusiveEnd = false) => Number(
12141
12163
  db.select({ total: sql7`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
12142
- and11(
12164
+ and12(
12143
12165
  eq15(crawlerEventsHourly.projectId, projectId),
12144
12166
  eq15(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
12145
12167
  gte2(crawlerEventsHourly.tsHour, windowStartIso),
@@ -12149,7 +12171,7 @@ function buildServerActivity(db, projectId, windowDays) {
12149
12171
  );
12150
12172
  const sumUnverifiedCrawlers = (windowStartIso, windowEndIso, exclusiveEnd = false) => Number(
12151
12173
  db.select({ total: sql7`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
12152
- and11(
12174
+ and12(
12153
12175
  eq15(crawlerEventsHourly.projectId, projectId),
12154
12176
  ne2(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
12155
12177
  gte2(crawlerEventsHourly.tsHour, windowStartIso),
@@ -12159,7 +12181,7 @@ function buildServerActivity(db, projectId, windowDays) {
12159
12181
  );
12160
12182
  const sumReferrals = (windowStartIso, windowEndIso, exclusiveEnd = false) => Number(
12161
12183
  db.select({ total: sql7`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
12162
- and11(
12184
+ and12(
12163
12185
  eq15(aiReferralEventsHourly.projectId, projectId),
12164
12186
  nonSubresourceReferralPathCondition(),
12165
12187
  gte2(aiReferralEventsHourly.tsHour, windowStartIso),
@@ -12169,7 +12191,7 @@ function buildServerActivity(db, projectId, windowDays) {
12169
12191
  );
12170
12192
  const sumUserFetches = (windowStartIso, windowEndIso, exclusiveEnd = false) => Number(
12171
12193
  db.select({ total: sql7`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
12172
- and11(
12194
+ and12(
12173
12195
  eq15(aiUserFetchEventsHourly.projectId, projectId),
12174
12196
  gte2(aiUserFetchEventsHourly.tsHour, windowStartIso),
12175
12197
  exclusiveEnd ? lt(aiUserFetchEventsHourly.tsHour, windowEndIso) : lte(aiUserFetchEventsHourly.tsHour, windowEndIso)
@@ -12189,7 +12211,7 @@ function buildServerActivity(db, projectId, windowDays) {
12189
12211
  verificationStatus: crawlerEventsHourly.verificationStatus,
12190
12212
  hits: sql7`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
12191
12213
  }).from(crawlerEventsHourly).where(
12192
- and11(
12214
+ and12(
12193
12215
  eq15(crawlerEventsHourly.projectId, projectId),
12194
12216
  gte2(crawlerEventsHourly.tsHour, headlineStart),
12195
12217
  lte(crawlerEventsHourly.tsHour, headlineEnd)
@@ -12199,7 +12221,7 @@ function buildServerActivity(db, projectId, windowDays) {
12199
12221
  operator: crawlerEventsHourly.operator,
12200
12222
  hits: sql7`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
12201
12223
  }).from(crawlerEventsHourly).where(
12202
- and11(
12224
+ and12(
12203
12225
  eq15(crawlerEventsHourly.projectId, projectId),
12204
12226
  eq15(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
12205
12227
  gte2(crawlerEventsHourly.tsHour, priorStart),
@@ -12210,7 +12232,7 @@ function buildServerActivity(db, projectId, windowDays) {
12210
12232
  operator: aiReferralEventsHourly.operator,
12211
12233
  hits: sql7`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`
12212
12234
  }).from(aiReferralEventsHourly).where(
12213
- and11(
12235
+ and12(
12214
12236
  eq15(aiReferralEventsHourly.projectId, projectId),
12215
12237
  nonSubresourceReferralPathCondition(),
12216
12238
  gte2(aiReferralEventsHourly.tsHour, headlineStart),
@@ -12221,7 +12243,7 @@ function buildServerActivity(db, projectId, windowDays) {
12221
12243
  operator: aiUserFetchEventsHourly.operator,
12222
12244
  hits: sql7`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)`
12223
12245
  }).from(aiUserFetchEventsHourly).where(
12224
- and11(
12246
+ and12(
12225
12247
  eq15(aiUserFetchEventsHourly.projectId, projectId),
12226
12248
  gte2(aiUserFetchEventsHourly.tsHour, headlineStart),
12227
12249
  lte(aiUserFetchEventsHourly.tsHour, headlineEnd)
@@ -12265,7 +12287,7 @@ function buildServerActivity(db, projectId, windowDays) {
12265
12287
  hits: sql7`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`,
12266
12288
  operators: sql7`COUNT(DISTINCT ${crawlerEventsHourly.operator})`
12267
12289
  }).from(crawlerEventsHourly).where(
12268
- and11(
12290
+ and12(
12269
12291
  eq15(crawlerEventsHourly.projectId, projectId),
12270
12292
  eq15(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
12271
12293
  gte2(crawlerEventsHourly.tsHour, headlineStart),
@@ -12282,7 +12304,7 @@ function buildServerActivity(db, projectId, windowDays) {
12282
12304
  arrivals: sql7`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
12283
12305
  landingPaths: sql7`COUNT(DISTINCT ${aiReferralEventsHourly.landingPathNormalized})`
12284
12306
  }).from(aiReferralEventsHourly).where(
12285
- and11(
12307
+ and12(
12286
12308
  eq15(aiReferralEventsHourly.projectId, projectId),
12287
12309
  nonSubresourceReferralPathCondition(),
12288
12310
  gte2(aiReferralEventsHourly.tsHour, headlineStart),
@@ -12299,7 +12321,7 @@ function buildServerActivity(db, projectId, windowDays) {
12299
12321
  arrivals: sql7`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
12300
12322
  products: sql7`COUNT(DISTINCT ${aiReferralEventsHourly.product})`
12301
12323
  }).from(aiReferralEventsHourly).where(
12302
- and11(
12324
+ and12(
12303
12325
  eq15(aiReferralEventsHourly.projectId, projectId),
12304
12326
  nonSubresourceReferralPathCondition(),
12305
12327
  gte2(aiReferralEventsHourly.tsHour, headlineStart),
@@ -12315,7 +12337,7 @@ function buildServerActivity(db, projectId, windowDays) {
12315
12337
  date: sql7`SUBSTR(${crawlerEventsHourly.tsHour}, 1, 10)`,
12316
12338
  hits: sql7`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
12317
12339
  }).from(crawlerEventsHourly).where(
12318
- and11(
12340
+ and12(
12319
12341
  eq15(crawlerEventsHourly.projectId, projectId),
12320
12342
  eq15(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
12321
12343
  gte2(crawlerEventsHourly.tsHour, trendStart),
@@ -12326,7 +12348,7 @@ function buildServerActivity(db, projectId, windowDays) {
12326
12348
  date: sql7`SUBSTR(${aiReferralEventsHourly.tsHour}, 1, 10)`,
12327
12349
  hits: sql7`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`
12328
12350
  }).from(aiReferralEventsHourly).where(
12329
- and11(
12351
+ and12(
12330
12352
  eq15(aiReferralEventsHourly.projectId, projectId),
12331
12353
  nonSubresourceReferralPathCondition(),
12332
12354
  gte2(aiReferralEventsHourly.tsHour, trendStart),
@@ -12337,7 +12359,7 @@ function buildServerActivity(db, projectId, windowDays) {
12337
12359
  date: sql7`SUBSTR(${aiUserFetchEventsHourly.tsHour}, 1, 10)`,
12338
12360
  hits: sql7`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)`
12339
12361
  }).from(aiUserFetchEventsHourly).where(
12340
- and11(
12362
+ and12(
12341
12363
  eq15(aiUserFetchEventsHourly.projectId, projectId),
12342
12364
  gte2(aiUserFetchEventsHourly.tsHour, trendStart),
12343
12365
  lte(aiUserFetchEventsHourly.tsHour, headlineEnd)
@@ -12422,7 +12444,7 @@ function buildIndexingHealth(db, projectId) {
12422
12444
  return null;
12423
12445
  }
12424
12446
  function buildCitationsTrend(db, projectId, queryLookup, locationFilter) {
12425
- const visibilityRuns = db.select().from(runs).where(and11(eq15(runs.projectId, projectId), eq15(runs.kind, RunKinds["answer-visibility"]), notProbeRun())).all().filter((r) => locationFilter === void 0 || (r.location ?? null) === locationFilter);
12447
+ const visibilityRuns = db.select().from(runs).where(and12(eq15(runs.projectId, projectId), eq15(runs.kind, RunKinds["answer-visibility"]), notProbeRun())).all().filter((r) => locationFilter === void 0 || (r.location ?? null) === locationFilter);
12426
12448
  const totalQueries = queryLookup.byId.size;
12427
12449
  const points = [];
12428
12450
  for (const run of visibilityRuns) {
@@ -12470,7 +12492,7 @@ function buildCitationsTrend(db, projectId, queryLookup, locationFilter) {
12470
12492
  }
12471
12493
  function buildInsightList(db, projectId, locationFilter) {
12472
12494
  const recentRunIds = db.select({ id: runs.id, location: runs.location }).from(runs).where(
12473
- and11(
12495
+ and12(
12474
12496
  eq15(runs.projectId, projectId),
12475
12497
  eq15(runs.kind, RunKinds["answer-visibility"]),
12476
12498
  or3(eq15(runs.status, RunStatuses.completed), eq15(runs.status, RunStatuses.partial)),
@@ -12478,7 +12500,7 @@ function buildInsightList(db, projectId, locationFilter) {
12478
12500
  )
12479
12501
  ).orderBy(desc7(runs.createdAt)).all().filter((r) => locationFilter === void 0 || (r.location ?? null) === locationFilter).slice(0, INSIGHT_LOOKBACK_RUNS).map((r) => r.id);
12480
12502
  if (recentRunIds.length === 0) return [];
12481
- const rows = db.select().from(insights).where(and11(eq15(insights.projectId, projectId), inArray6(insights.runId, recentRunIds))).orderBy(desc7(insights.createdAt)).all();
12503
+ const rows = db.select().from(insights).where(and12(eq15(insights.projectId, projectId), inArray6(insights.runId, recentRunIds))).orderBy(desc7(insights.createdAt)).all();
12482
12504
  const severityRank = { critical: 0, high: 1, medium: 2, low: 3 };
12483
12505
  const flat = rows.filter((r) => !r.dismissed).map((r) => {
12484
12506
  const recommendation = r.recommendation;
@@ -13030,7 +13052,7 @@ function buildProjectReport(db, projectName, periodDays) {
13030
13052
  const project = resolveProject(db, projectName);
13031
13053
  const queryLookup = loadQueryLookup(db, project.id);
13032
13054
  const comparisonWindowDays = reportComparisonWindowDays(periodDays);
13033
- const allRuns = db.select().from(runs).where(and11(eq15(runs.projectId, project.id), notProbeRun())).orderBy(desc7(runs.createdAt), desc7(runs.id)).all();
13055
+ const allRuns = db.select().from(runs).where(and12(eq15(runs.projectId, project.id), notProbeRun())).orderBy(desc7(runs.createdAt), desc7(runs.id)).all();
13034
13056
  const visibilityRuns = allRuns.filter((r) => r.kind === RunKinds["answer-visibility"]);
13035
13057
  const completedVisRunGroups = groupRunsByCreatedAt(
13036
13058
  visibilityRuns.filter((r) => r.status === RunStatuses.completed || r.status === RunStatuses.partial)
@@ -13266,7 +13288,7 @@ async function reportRoutes(app) {
13266
13288
  }
13267
13289
 
13268
13290
  // ../api-routes/src/citations.ts
13269
- import { and as and12, eq as eq16, inArray as inArray7 } from "drizzle-orm";
13291
+ import { and as and13, eq as eq16, inArray as inArray7 } from "drizzle-orm";
13270
13292
  async function citationRoutes(app) {
13271
13293
  app.get("/projects/:name/citations/visibility", async (request, reply) => {
13272
13294
  const project = resolveProject(app.db, request.params.name);
@@ -13275,7 +13297,7 @@ async function citationRoutes(app) {
13275
13297
  if (projectQueries.length === 0) {
13276
13298
  return reply.send(emptyCitationVisibility("no-queries"));
13277
13299
  }
13278
- const projectRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(and12(eq16(runs.projectId, project.id), notProbeRun())).all();
13300
+ const projectRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(and13(eq16(runs.projectId, project.id), notProbeRun())).all();
13279
13301
  if (projectRuns.length === 0) {
13280
13302
  return reply.send(emptyCitationVisibility("no-runs-yet"));
13281
13303
  }
@@ -13431,7 +13453,7 @@ function normalizeDomain2(domain) {
13431
13453
  }
13432
13454
 
13433
13455
  // ../api-routes/src/visibility-stats.ts
13434
- import { and as and13, desc as desc8, eq as eq17, inArray as inArray8 } from "drizzle-orm";
13456
+ import { and as and14, desc as desc8, eq as eq17, inArray as inArray8 } from "drizzle-orm";
13435
13457
  function round42(value) {
13436
13458
  return Math.round(value * 1e4) / 1e4;
13437
13459
  }
@@ -13583,7 +13605,7 @@ async function visibilityStatsRoutes(app) {
13583
13605
  lastRuns = n;
13584
13606
  }
13585
13607
  const projectQueries = app.db.select({ id: queries.id, query: queries.query }).from(queries).where(eq17(queries.projectId, project.id)).all();
13586
- let projectRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt, status: runs.status }).from(runs).where(and13(eq17(runs.projectId, project.id), eq17(runs.kind, RunKinds["answer-visibility"]), notProbeRun())).orderBy(desc8(runs.createdAt)).all().filter((r) => r.status === RunStatuses.completed || r.status === RunStatuses.partial);
13608
+ let projectRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt, status: runs.status }).from(runs).where(and14(eq17(runs.projectId, project.id), eq17(runs.kind, RunKinds["answer-visibility"]), notProbeRun())).orderBy(desc8(runs.createdAt)).all().filter((r) => r.status === RunStatuses.completed || r.status === RunStatuses.partial);
13587
13609
  if (sinceMs !== null) projectRuns = projectRuns.filter((r) => Date.parse(r.createdAt) >= sinceMs);
13588
13610
  if (untilMs !== null) projectRuns = projectRuns.filter((r) => Date.parse(r.createdAt) <= untilMs);
13589
13611
  if (lastRuns !== null) projectRuns = projectRuns.slice(0, lastRuns);
@@ -13653,7 +13675,7 @@ async function visibilityStatsRoutes(app) {
13653
13675
  }
13654
13676
 
13655
13677
  // ../api-routes/src/composites.ts
13656
- import { eq as eq18, and as and14, desc as desc9, sql as sql8, like as like2, or as or4, inArray as inArray9 } from "drizzle-orm";
13678
+ import { eq as eq18, and as and15, desc as desc9, sql as sql8, like as like2, or as or4, inArray as inArray9 } from "drizzle-orm";
13657
13679
  var TOP_INSIGHT_LIMIT = 5;
13658
13680
  var SEARCH_HIT_HARD_LIMIT = 50;
13659
13681
  var SEARCH_SNIPPET_RADIUS = 80;
@@ -13671,7 +13693,7 @@ async function compositeRoutes(app) {
13671
13693
  const project = resolveProject(app.db, request.params.name);
13672
13694
  const filterLocation = (request.query.location ?? "").trim() || null;
13673
13695
  const sinceIso = parseSinceFilter(request.query.since);
13674
- const allRunsRaw = app.db.select().from(runs).where(and14(eq18(runs.projectId, project.id), notProbeRun())).orderBy(desc9(runs.createdAt), desc9(runs.id)).all();
13696
+ const allRunsRaw = app.db.select().from(runs).where(and15(eq18(runs.projectId, project.id), notProbeRun())).orderBy(desc9(runs.createdAt), desc9(runs.id)).all();
13675
13697
  const allRuns = allRunsRaw.filter((r) => runMatchesFilters(r, filterLocation, sinceIso));
13676
13698
  const totalRuns = allRuns.length;
13677
13699
  const visibilityRuns = allRuns.filter((r) => r.kind === RunKinds["answer-visibility"]);
@@ -13827,7 +13849,7 @@ async function compositeRoutes(app) {
13827
13849
  rawResponse: querySnapshots.rawResponse,
13828
13850
  createdAt: querySnapshots.createdAt
13829
13851
  }).from(querySnapshots).innerJoin(queries, eq18(querySnapshots.queryId, queries.id)).where(
13830
- and14(
13852
+ and15(
13831
13853
  eq18(queries.projectId, project.id),
13832
13854
  or4(
13833
13855
  sql8`${querySnapshots.answerText} LIKE ${pattern} ESCAPE '\\'`,
@@ -13838,7 +13860,7 @@ async function compositeRoutes(app) {
13838
13860
  )
13839
13861
  ).orderBy(desc9(querySnapshots.createdAt)).limit(limit + 1).all());
13840
13862
  const insightMatches = app.db.select().from(insights).where(
13841
- and14(
13863
+ and15(
13842
13864
  eq18(insights.projectId, project.id),
13843
13865
  or4(
13844
13866
  like2(insights.title, pattern),
@@ -14055,7 +14077,7 @@ function buildSuggestedQueriesFromGsc(app, projectId, trackedQueries) {
14055
14077
  // NULLIF guards the degenerate impressions=0 case (SQLite returns NULL,
14056
14078
  // which the JS coerces to 0 — caught by the impression floor anyway).
14057
14079
  avgPosition: sql8`COALESCE(SUM(${gscSearchData.position} * ${gscSearchData.impressions}) * 1.0 / NULLIF(SUM(${gscSearchData.impressions}), 0), 0)`
14058
- }).from(gscSearchData).where(and14(
14080
+ }).from(gscSearchData).where(and15(
14059
14081
  eq18(gscSearchData.projectId, projectId),
14060
14082
  sql8`${gscSearchData.date} >= ${cutoff}`,
14061
14083
  sql8`${gscSearchData.impressions} > 0`
@@ -14570,6 +14592,13 @@ var queryIdParameter = {
14570
14592
  description: "Query ID.",
14571
14593
  schema: stringSchema
14572
14594
  };
14595
+ var competitorIdParameter = {
14596
+ name: "id",
14597
+ in: "path",
14598
+ required: true,
14599
+ description: "Competitor ID.",
14600
+ schema: stringSchema
14601
+ };
14573
14602
  var notificationIdParameter = {
14574
14603
  name: "id",
14575
14604
  in: "path",
@@ -15258,6 +15287,17 @@ var routeCatalog = [
15258
15287
  400: errorResponse("Invalid competitor delete request.")
15259
15288
  }
15260
15289
  },
15290
+ {
15291
+ method: "delete",
15292
+ path: "/api/v1/projects/{name}/competitors/{id}",
15293
+ summary: "Delete competitor",
15294
+ tags: ["competitors"],
15295
+ parameters: [nameParameter, competitorIdParameter],
15296
+ responses: {
15297
+ 204: { description: "Competitor deleted." },
15298
+ 404: errorResponse("Project or competitor not found.")
15299
+ }
15300
+ },
15261
15301
  {
15262
15302
  method: "post",
15263
15303
  path: "/api/v1/projects/{name}/runs",
@@ -18979,7 +19019,7 @@ async function telemetryRoutes(app, opts) {
18979
19019
 
18980
19020
  // ../api-routes/src/schedules.ts
18981
19021
  import crypto13 from "crypto";
18982
- import { and as and15, eq as eq20 } from "drizzle-orm";
19022
+ import { and as and16, eq as eq20 } from "drizzle-orm";
18983
19023
  function parseKindParam(raw) {
18984
19024
  if (raw === void 0 || raw === null || raw === "") return SchedulableRunKinds["answer-visibility"];
18985
19025
  const parsed = schedulableRunKindSchema.safeParse(raw);
@@ -19051,7 +19091,7 @@ async function scheduleRoutes(app, opts) {
19051
19091
  }
19052
19092
  const now = (/* @__PURE__ */ new Date()).toISOString();
19053
19093
  const enabledBool = enabled !== false;
19054
- const existing = app.db.select().from(schedules).where(and15(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19094
+ const existing = app.db.select().from(schedules).where(and16(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19055
19095
  if (existing) {
19056
19096
  app.db.update(schedules).set({
19057
19097
  cronExpr,
@@ -19085,13 +19125,13 @@ async function scheduleRoutes(app, opts) {
19085
19125
  diff: { kind, cronExpr, preset, timezone, providers, sourceId }
19086
19126
  });
19087
19127
  opts.onScheduleUpdated?.("upsert", project.id, kind);
19088
- const schedule = app.db.select().from(schedules).where(and15(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19128
+ const schedule = app.db.select().from(schedules).where(and16(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19089
19129
  return reply.status(existing ? 200 : 201).send(formatSchedule(schedule));
19090
19130
  });
19091
19131
  app.get("/projects/:name/schedule", async (request, reply) => {
19092
19132
  const project = resolveProject(app.db, request.params.name);
19093
19133
  const kind = parseKindParam(request.query?.kind);
19094
- const schedule = app.db.select().from(schedules).where(and15(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19134
+ const schedule = app.db.select().from(schedules).where(and16(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19095
19135
  if (!schedule) {
19096
19136
  throw notFound("Schedule", `${request.params.name} (kind=${kind})`);
19097
19137
  }
@@ -19100,7 +19140,7 @@ async function scheduleRoutes(app, opts) {
19100
19140
  app.delete("/projects/:name/schedule", async (request, reply) => {
19101
19141
  const project = resolveProject(app.db, request.params.name);
19102
19142
  const kind = parseKindParam(request.query?.kind);
19103
- const schedule = app.db.select().from(schedules).where(and15(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19143
+ const schedule = app.db.select().from(schedules).where(and16(eq20(schedules.projectId, project.id), eq20(schedules.kind, kind))).get();
19104
19144
  if (!schedule) {
19105
19145
  throw notFound("Schedule", `${request.params.name} (kind=${kind})`);
19106
19146
  }
@@ -19257,7 +19297,7 @@ function formatNotification(row) {
19257
19297
 
19258
19298
  // ../api-routes/src/google.ts
19259
19299
  import crypto18 from "crypto";
19260
- import { eq as eq22, and as and16, desc as desc11, sql as sql9, inArray as inArray10 } from "drizzle-orm";
19300
+ import { eq as eq22, and as and17, desc as desc11, sql as sql9, inArray as inArray10 } from "drizzle-orm";
19261
19301
 
19262
19302
  // ../api-routes/src/gbp-summary.ts
19263
19303
  function computeMetricTotals(rows) {
@@ -21237,7 +21277,7 @@ async function googleRoutes(app, opts) {
21237
21277
  if (page) conditions.push(sql9`${gscSearchData.page} LIKE ${"%" + escapeLikePattern(page) + "%"} ESCAPE '\\'`);
21238
21278
  const limitVal = Math.max(parseInt(limit ?? "500", 10) || 0, 1);
21239
21279
  const offsetVal = Math.max(parseInt(offset ?? "0", 10) || 0, 0);
21240
- const rows = app.db.select().from(gscSearchData).where(and16(...conditions)).orderBy(desc11(gscSearchData.date)).limit(limitVal).offset(offsetVal).all();
21280
+ const rows = app.db.select().from(gscSearchData).where(and17(...conditions)).orderBy(desc11(gscSearchData.date)).limit(limitVal).offset(offsetVal).all();
21241
21281
  return rows.map((r) => ({
21242
21282
  date: r.date,
21243
21283
  query: r.query,
@@ -21265,7 +21305,7 @@ async function googleRoutes(app, opts) {
21265
21305
  date: gscSearchData.date,
21266
21306
  clicks: sql9`COALESCE(SUM(${gscSearchData.clicks}), 0)`,
21267
21307
  impressions: sql9`COALESCE(SUM(${gscSearchData.impressions}), 0)`
21268
- }).from(gscSearchData).where(and16(...conditions)).groupBy(gscSearchData.date).orderBy(gscSearchData.date).all();
21308
+ }).from(gscSearchData).where(and17(...conditions)).groupBy(gscSearchData.date).orderBy(gscSearchData.date).all();
21269
21309
  const daily = mergeGscDailyTotalsWithFallback(
21270
21310
  dailyTotals,
21271
21311
  dimensionedRows.map((r) => ({
@@ -21358,7 +21398,7 @@ async function googleRoutes(app, opts) {
21358
21398
  const { url, limit } = request.query;
21359
21399
  const conditions = [eq22(gscUrlInspections.projectId, project.id)];
21360
21400
  if (url) conditions.push(eq22(gscUrlInspections.url, url));
21361
- const rows = app.db.select().from(gscUrlInspections).where(and16(...conditions)).orderBy(desc11(gscUrlInspections.inspectedAt)).limit(parseInt(limit ?? "100", 10)).all();
21401
+ const rows = app.db.select().from(gscUrlInspections).where(and17(...conditions)).orderBy(desc11(gscUrlInspections.inspectedAt)).limit(parseInt(limit ?? "100", 10)).all();
21362
21402
  return rows.map((r) => ({
21363
21403
  id: r.id,
21364
21404
  url: r.url,
@@ -21853,7 +21893,7 @@ async function googleRoutes(app, opts) {
21853
21893
  app.db.transaction((tx) => {
21854
21894
  if (switching) clearGbpProjectData(tx, project.id);
21855
21895
  for (const remote of remoteLocations) {
21856
- const existing = tx.select().from(gbpLocations).where(and16(eq22(gbpLocations.projectId, project.id), eq22(gbpLocations.locationName, remote.name))).get();
21896
+ const existing = tx.select().from(gbpLocations).where(and17(eq22(gbpLocations.projectId, project.id), eq22(gbpLocations.locationName, remote.name))).get();
21857
21897
  const profile = buildLocationProfileFields(remote);
21858
21898
  if (existing) {
21859
21899
  tx.update(gbpLocations).set({
@@ -21950,7 +21990,7 @@ async function googleRoutes(app, opts) {
21950
21990
  throw validationError(parsed.error.issues[0]?.message ?? "Invalid selection request");
21951
21991
  }
21952
21992
  const { selected } = parsed.data;
21953
- const existing = app.db.select().from(gbpLocations).where(and16(eq22(gbpLocations.projectId, project.id), eq22(gbpLocations.locationName, locationName))).get();
21993
+ const existing = app.db.select().from(gbpLocations).where(and17(eq22(gbpLocations.projectId, project.id), eq22(gbpLocations.locationName, locationName))).get();
21954
21994
  if (!existing) throw notFound("GBP location", locationName);
21955
21995
  const now = (/* @__PURE__ */ new Date()).toISOString();
21956
21996
  app.db.transaction((tx) => {
@@ -22010,7 +22050,7 @@ async function googleRoutes(app, opts) {
22010
22050
  const conditions = [eq22(gbpDailyMetrics.projectId, project.id)];
22011
22051
  if (request.query.locationName) conditions.push(eq22(gbpDailyMetrics.locationName, request.query.locationName));
22012
22052
  if (request.query.metric) conditions.push(eq22(gbpDailyMetrics.metric, request.query.metric));
22013
- const rows = app.db.select().from(gbpDailyMetrics).where(and16(...conditions)).orderBy(desc11(gbpDailyMetrics.date)).all();
22053
+ const rows = app.db.select().from(gbpDailyMetrics).where(and17(...conditions)).orderBy(desc11(gbpDailyMetrics.date)).all();
22014
22054
  return {
22015
22055
  metrics: rows.map((r) => ({ locationName: r.locationName, date: r.date, metric: r.metric, value: r.value })),
22016
22056
  total: rows.length
@@ -22020,7 +22060,7 @@ async function googleRoutes(app, opts) {
22020
22060
  const project = resolveProject(app.db, request.params.name);
22021
22061
  const conditions = [eq22(gbpKeywordImpressions.projectId, project.id)];
22022
22062
  if (request.query.locationName) conditions.push(eq22(gbpKeywordImpressions.locationName, request.query.locationName));
22023
- const rows = app.db.select().from(gbpKeywordImpressions).where(and16(...conditions)).all();
22063
+ const rows = app.db.select().from(gbpKeywordImpressions).where(and17(...conditions)).all();
22024
22064
  rows.sort((a, b) => (b.valueCount ?? -1) - (a.valueCount ?? -1));
22025
22065
  const thresholded = rows.filter((r) => r.valueThreshold !== null).length;
22026
22066
  return {
@@ -22040,7 +22080,7 @@ async function googleRoutes(app, opts) {
22040
22080
  const project = resolveProject(app.db, request.params.name);
22041
22081
  const conditions = [eq22(gbpPlaceActions.projectId, project.id)];
22042
22082
  if (request.query.locationName) conditions.push(eq22(gbpPlaceActions.locationName, request.query.locationName));
22043
- const rows = app.db.select().from(gbpPlaceActions).where(and16(...conditions)).all();
22083
+ const rows = app.db.select().from(gbpPlaceActions).where(and17(...conditions)).all();
22044
22084
  return {
22045
22085
  placeActions: rows.map((r) => ({
22046
22086
  locationName: r.locationName,
@@ -22057,7 +22097,7 @@ async function googleRoutes(app, opts) {
22057
22097
  const project = resolveProject(app.db, request.params.name);
22058
22098
  const conditions = [eq22(gbpLodgingSnapshots.projectId, project.id)];
22059
22099
  if (request.query.locationName) conditions.push(eq22(gbpLodgingSnapshots.locationName, request.query.locationName));
22060
- const rows = app.db.select().from(gbpLodgingSnapshots).where(and16(...conditions)).orderBy(desc11(gbpLodgingSnapshots.syncedAt)).all();
22100
+ const rows = app.db.select().from(gbpLodgingSnapshots).where(and17(...conditions)).orderBy(desc11(gbpLodgingSnapshots.syncedAt)).all();
22061
22101
  const latestByLocation = /* @__PURE__ */ new Map();
22062
22102
  for (const row of rows) {
22063
22103
  if (!latestByLocation.has(row.locationName)) latestByLocation.set(row.locationName, row);
@@ -22074,7 +22114,7 @@ async function googleRoutes(app, opts) {
22074
22114
  const project = resolveProject(app.db, request.params.name);
22075
22115
  const conditions = [eq22(gbpAttributesSnapshots.projectId, project.id)];
22076
22116
  if (request.query.locationName) conditions.push(eq22(gbpAttributesSnapshots.locationName, request.query.locationName));
22077
- const rows = app.db.select().from(gbpAttributesSnapshots).where(and16(...conditions)).orderBy(desc11(gbpAttributesSnapshots.syncedAt)).all();
22117
+ const rows = app.db.select().from(gbpAttributesSnapshots).where(and17(...conditions)).orderBy(desc11(gbpAttributesSnapshots.syncedAt)).all();
22078
22118
  const latestByLocation = /* @__PURE__ */ new Map();
22079
22119
  for (const row of rows) {
22080
22120
  if (!latestByLocation.has(row.locationName)) latestByLocation.set(row.locationName, row);
@@ -22094,7 +22134,7 @@ async function googleRoutes(app, opts) {
22094
22134
  const project = resolveProject(app.db, request.params.name);
22095
22135
  const conditions = [eq22(gbpPlaceDetails.projectId, project.id)];
22096
22136
  if (request.query.locationName) conditions.push(eq22(gbpPlaceDetails.locationName, request.query.locationName));
22097
- const rows = app.db.select().from(gbpPlaceDetails).where(and16(...conditions)).orderBy(desc11(gbpPlaceDetails.syncedAt)).all();
22137
+ const rows = app.db.select().from(gbpPlaceDetails).where(and17(...conditions)).orderBy(desc11(gbpPlaceDetails.syncedAt)).all();
22098
22138
  const latestByLocation = /* @__PURE__ */ new Map();
22099
22139
  for (const row of rows) {
22100
22140
  if (!latestByLocation.has(row.locationName)) latestByLocation.set(row.locationName, row);
@@ -22113,7 +22153,7 @@ async function googleRoutes(app, opts) {
22113
22153
  app.get("/projects/:name/gbp/summary", async (request) => {
22114
22154
  const project = resolveProject(app.db, request.params.name);
22115
22155
  const locationName = request.query.locationName ?? null;
22116
- const locationNames = locationName ? [locationName] : app.db.select({ n: gbpLocations.locationName }).from(gbpLocations).where(and16(eq22(gbpLocations.projectId, project.id), eq22(gbpLocations.selected, true))).all().map((r) => r.n);
22156
+ const locationNames = locationName ? [locationName] : app.db.select({ n: gbpLocations.locationName }).from(gbpLocations).where(and17(eq22(gbpLocations.projectId, project.id), eq22(gbpLocations.selected, true))).all().map((r) => r.n);
22117
22157
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
22118
22158
  if (locationNames.length === 0) {
22119
22159
  return buildGbpSummary({
@@ -22127,10 +22167,10 @@ async function googleRoutes(app, opts) {
22127
22167
  locationProfiles: []
22128
22168
  });
22129
22169
  }
22130
- const metricRows = app.db.select().from(gbpDailyMetrics).where(and16(eq22(gbpDailyMetrics.projectId, project.id), inArray10(gbpDailyMetrics.locationName, locationNames))).all();
22131
- const keywordRows = app.db.select().from(gbpKeywordImpressions).where(and16(eq22(gbpKeywordImpressions.projectId, project.id), inArray10(gbpKeywordImpressions.locationName, locationNames))).all();
22132
- const placeActionRows = app.db.select().from(gbpPlaceActions).where(and16(eq22(gbpPlaceActions.projectId, project.id), inArray10(gbpPlaceActions.locationName, locationNames))).all();
22133
- const lodgingRows = app.db.select().from(gbpLodgingSnapshots).where(and16(eq22(gbpLodgingSnapshots.projectId, project.id), inArray10(gbpLodgingSnapshots.locationName, locationNames))).orderBy(desc11(gbpLodgingSnapshots.syncedAt)).all();
22170
+ const metricRows = app.db.select().from(gbpDailyMetrics).where(and17(eq22(gbpDailyMetrics.projectId, project.id), inArray10(gbpDailyMetrics.locationName, locationNames))).all();
22171
+ const keywordRows = app.db.select().from(gbpKeywordImpressions).where(and17(eq22(gbpKeywordImpressions.projectId, project.id), inArray10(gbpKeywordImpressions.locationName, locationNames))).all();
22172
+ const placeActionRows = app.db.select().from(gbpPlaceActions).where(and17(eq22(gbpPlaceActions.projectId, project.id), inArray10(gbpPlaceActions.locationName, locationNames))).all();
22173
+ const lodgingRows = app.db.select().from(gbpLodgingSnapshots).where(and17(eq22(gbpLodgingSnapshots.projectId, project.id), inArray10(gbpLodgingSnapshots.locationName, locationNames))).orderBy(desc11(gbpLodgingSnapshots.syncedAt)).all();
22134
22174
  const latestLodgingByLocation = /* @__PURE__ */ new Map();
22135
22175
  for (const row of lodgingRows) {
22136
22176
  if (!latestLodgingByLocation.has(row.locationName)) {
@@ -22144,7 +22184,7 @@ async function googleRoutes(app, opts) {
22144
22184
  regularHours: gbpLocations.regularHours,
22145
22185
  primaryPhone: gbpLocations.primaryPhone,
22146
22186
  openStatus: gbpLocations.openStatus
22147
- }).from(gbpLocations).where(and16(eq22(gbpLocations.projectId, project.id), inArray10(gbpLocations.locationName, locationNames))).all();
22187
+ }).from(gbpLocations).where(and17(eq22(gbpLocations.projectId, project.id), inArray10(gbpLocations.locationName, locationNames))).all();
22148
22188
  return buildGbpSummary({
22149
22189
  locationName,
22150
22190
  locationCount: locationNames.length,
@@ -22160,7 +22200,7 @@ async function googleRoutes(app, opts) {
22160
22200
 
22161
22201
  // ../api-routes/src/ads.ts
22162
22202
  import crypto19 from "crypto";
22163
- import { eq as eq23, and as and17, asc as asc3, gte as gte3, lte as lte2, inArray as inArray11 } from "drizzle-orm";
22203
+ import { eq as eq23, and as and18, asc as asc3, gte as gte3, lte as lte2, inArray as inArray11 } from "drizzle-orm";
22164
22204
  function statusDto(row) {
22165
22205
  if (!row) return { connected: false };
22166
22206
  return {
@@ -22276,7 +22316,7 @@ async function adsRoutes(app, opts) {
22276
22316
  if (!row) {
22277
22317
  throw validationError('No ads connection for this project. Run "canonry ads connect" first.');
22278
22318
  }
22279
- const inFlight = app.db.select({ id: runs.id, status: runs.status }).from(runs).where(and17(
22319
+ const inFlight = app.db.select({ id: runs.id, status: runs.status }).from(runs).where(and18(
22280
22320
  eq23(runs.projectId, project.id),
22281
22321
  eq23(runs.kind, RunKinds["ads-sync"]),
22282
22322
  inArray11(runs.status, [RunStatuses.queued, RunStatuses.running])
@@ -22361,7 +22401,7 @@ async function adsRoutes(app, opts) {
22361
22401
  if (entityId) conditions.push(eq23(adsInsightsDaily.entityId, entityId));
22362
22402
  if (from) conditions.push(gte3(adsInsightsDaily.date, from));
22363
22403
  if (to) conditions.push(lte2(adsInsightsDaily.date, to));
22364
- const rows = app.db.select().from(adsInsightsDaily).where(and17(...conditions)).orderBy(asc3(adsInsightsDaily.date)).all();
22404
+ const rows = app.db.select().from(adsInsightsDaily).where(and18(...conditions)).orderBy(asc3(adsInsightsDaily.date)).all();
22365
22405
  const dtoRows = rows.map((row) => ({
22366
22406
  level: row.level,
22367
22407
  entityId: row.entityId,
@@ -22383,7 +22423,7 @@ async function adsRoutes(app, opts) {
22383
22423
  const campaignCount = app.db.select().from(adsCampaigns).where(eq23(adsCampaigns.projectId, project.id)).all().length;
22384
22424
  const adGroupCount = app.db.select().from(adsAdGroups).where(eq23(adsAdGroups.projectId, project.id)).all().length;
22385
22425
  const adCount = app.db.select().from(adsAds).where(eq23(adsAds.projectId, project.id)).all().length;
22386
- const campaignInsights = app.db.select().from(adsInsightsDaily).where(and17(
22426
+ const campaignInsights = app.db.select().from(adsInsightsDaily).where(and18(
22387
22427
  eq23(adsInsightsDaily.projectId, project.id),
22388
22428
  eq23(adsInsightsDaily.level, "campaign")
22389
22429
  )).all();
@@ -22425,7 +22465,7 @@ async function adsRoutes(app, opts) {
22425
22465
 
22426
22466
  // ../api-routes/src/bing.ts
22427
22467
  import crypto20 from "crypto";
22428
- import { eq as eq24, and as and18, desc as desc12 } from "drizzle-orm";
22468
+ import { eq as eq24, and as and19, desc as desc12 } from "drizzle-orm";
22429
22469
 
22430
22470
  // ../integration-bing/src/constants.ts
22431
22471
  var BING_WMT_API_BASE = "https://ssl.bing.com/webmaster/api.svc/json";
@@ -22900,7 +22940,7 @@ async function bingRoutes(app, opts) {
22900
22940
  requireConnectionStore();
22901
22941
  const project = resolveProject(app.db, request.params.name);
22902
22942
  const { url, limit } = request.query;
22903
- const whereClause = url ? and18(eq24(bingUrlInspections.projectId, project.id), eq24(bingUrlInspections.url, url)) : eq24(bingUrlInspections.projectId, project.id);
22943
+ const whereClause = url ? and19(eq24(bingUrlInspections.projectId, project.id), eq24(bingUrlInspections.url, url)) : eq24(bingUrlInspections.projectId, project.id);
22904
22944
  const filtered = app.db.select().from(bingUrlInspections).where(whereClause).orderBy(desc12(bingUrlInspections.inspectedAt)).limit(Math.max(1, Math.min(parseInt(limit ?? "100", 10) || 100, 1e3))).all();
22905
22945
  return filtered.map((r) => ({
22906
22946
  id: r.id,
@@ -23132,7 +23172,7 @@ async function bingRoutes(app, opts) {
23132
23172
  import fs from "fs";
23133
23173
  import path from "path";
23134
23174
  import os from "os";
23135
- import { eq as eq25, and as and19 } from "drizzle-orm";
23175
+ import { eq as eq25, and as and20 } from "drizzle-orm";
23136
23176
  function getScreenshotDir() {
23137
23177
  return path.join(os.homedir(), ".canonry", "screenshots");
23138
23178
  }
@@ -23207,7 +23247,7 @@ async function cdpRoutes(app, opts) {
23207
23247
  async (request, reply) => {
23208
23248
  const project = resolveProject(app.db, request.params.name);
23209
23249
  const { runId } = request.params;
23210
- const run = app.db.select().from(runs).where(and19(eq25(runs.id, runId), eq25(runs.projectId, project.id))).get();
23250
+ const run = app.db.select().from(runs).where(and20(eq25(runs.id, runId), eq25(runs.projectId, project.id))).get();
23211
23251
  if (!run) {
23212
23252
  const err = notFound("Run", runId);
23213
23253
  return reply.code(err.statusCode).send(err.toJSON());
@@ -23304,7 +23344,7 @@ async function cdpRoutes(app, opts) {
23304
23344
 
23305
23345
  // ../api-routes/src/ga.ts
23306
23346
  import crypto21 from "crypto";
23307
- import { eq as eq26, desc as desc13, and as and20, sql as sql10 } from "drizzle-orm";
23347
+ import { eq as eq26, desc as desc13, and as and21, sql as sql10 } from "drizzle-orm";
23308
23348
  function gaLog(level, action, ctx) {
23309
23349
  const entry = { ts: (/* @__PURE__ */ new Date()).toISOString(), level, module: "GA4Routes", action, ...ctx };
23310
23350
  const stream = level === "error" ? process.stderr : process.stdout;
@@ -23599,7 +23639,7 @@ async function ga4Routes(app, opts) {
23599
23639
  app.db.transaction((tx) => {
23600
23640
  if (syncTraffic) {
23601
23641
  tx.delete(gaTrafficSnapshots).where(
23602
- and20(
23642
+ and21(
23603
23643
  eq26(gaTrafficSnapshots.projectId, project.id),
23604
23644
  sql10`${gaTrafficSnapshots.date} >= ${summary.periodStart}`,
23605
23645
  sql10`${gaTrafficSnapshots.date} <= ${summary.periodEnd}`
@@ -23623,7 +23663,7 @@ async function ga4Routes(app, opts) {
23623
23663
  }
23624
23664
  if (syncAi) {
23625
23665
  tx.delete(gaAiReferrals).where(
23626
- and20(
23666
+ and21(
23627
23667
  eq26(gaAiReferrals.projectId, project.id),
23628
23668
  sql10`${gaAiReferrals.date} >= ${summary.periodStart}`,
23629
23669
  sql10`${gaAiReferrals.date} <= ${summary.periodEnd}`
@@ -23649,7 +23689,7 @@ async function ga4Routes(app, opts) {
23649
23689
  }
23650
23690
  if (syncSocial) {
23651
23691
  tx.delete(gaSocialReferrals).where(
23652
- and20(
23692
+ and21(
23653
23693
  eq26(gaSocialReferrals.projectId, project.id),
23654
23694
  sql10`${gaSocialReferrals.date} >= ${summary.periodStart}`,
23655
23695
  sql10`${gaSocialReferrals.date} <= ${summary.periodEnd}`
@@ -23753,7 +23793,7 @@ async function ga4Routes(app, opts) {
23753
23793
  totalDirectSessions: gaTrafficWindowSummaries.totalDirectSessions,
23754
23794
  totalUsers: gaTrafficWindowSummaries.totalUsers
23755
23795
  }).from(gaTrafficWindowSummaries).where(
23756
- and20(
23796
+ and21(
23757
23797
  eq26(gaTrafficWindowSummaries.projectId, project.id),
23758
23798
  eq26(gaTrafficWindowSummaries.windowKey, window)
23759
23799
  )
@@ -23762,7 +23802,7 @@ async function ga4Routes(app, opts) {
23762
23802
  totalSessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)`,
23763
23803
  totalOrganicSessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)`,
23764
23804
  totalUsers: sql10`COALESCE(SUM(${gaTrafficSnapshots.users}), 0)`
23765
- }).from(gaTrafficSnapshots).where(and20(...snapshotConditions)).get() : null;
23805
+ }).from(gaTrafficSnapshots).where(and21(...snapshotConditions)).get() : null;
23766
23806
  const summaryRow = cutoffDate ? windowSummaryRow ?? snapshotTotalsRow : app.db.select({
23767
23807
  totalSessions: gaTrafficSummaries.totalSessions,
23768
23808
  totalOrganicSessions: gaTrafficSummaries.totalOrganicSessions,
@@ -23770,7 +23810,7 @@ async function ga4Routes(app, opts) {
23770
23810
  }).from(gaTrafficSummaries).where(eq26(gaTrafficSummaries.projectId, project.id)).get();
23771
23811
  const directTotalRow = windowSummaryRow ? { totalDirectSessions: windowSummaryRow.totalDirectSessions } : app.db.select({
23772
23812
  totalDirectSessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`
23773
- }).from(gaTrafficSnapshots).where(and20(...snapshotConditions)).get();
23813
+ }).from(gaTrafficSnapshots).where(and21(...snapshotConditions)).get();
23774
23814
  const summaryMeta = app.db.select({
23775
23815
  periodStart: gaTrafficSummaries.periodStart,
23776
23816
  periodEnd: gaTrafficSummaries.periodEnd
@@ -23781,14 +23821,14 @@ async function ga4Routes(app, opts) {
23781
23821
  organicSessions: sql10`SUM(${gaTrafficSnapshots.organicSessions})`,
23782
23822
  directSessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`,
23783
23823
  users: sql10`SUM(${gaTrafficSnapshots.users})`
23784
- }).from(gaTrafficSnapshots).where(and20(...snapshotConditions)).groupBy(sql10`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`).orderBy(sql10`SUM(${gaTrafficSnapshots.sessions}) DESC`).limit(limit).all();
23824
+ }).from(gaTrafficSnapshots).where(and21(...snapshotConditions)).groupBy(sql10`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`).orderBy(sql10`SUM(${gaTrafficSnapshots.sessions}) DESC`).limit(limit).all();
23785
23825
  const aiReferralRows = app.db.select({
23786
23826
  source: gaAiReferrals.source,
23787
23827
  medium: gaAiReferrals.medium,
23788
23828
  sourceDimension: gaAiReferrals.sourceDimension,
23789
23829
  sessions: sql10`SUM(${gaAiReferrals.sessions})`,
23790
23830
  users: sql10`SUM(${gaAiReferrals.users})`
23791
- }).from(gaAiReferrals).where(and20(...aiConditions)).groupBy(gaAiReferrals.source, gaAiReferrals.medium, gaAiReferrals.sourceDimension).all();
23831
+ }).from(gaAiReferrals).where(and21(...aiConditions)).groupBy(gaAiReferrals.source, gaAiReferrals.medium, gaAiReferrals.sourceDimension).all();
23792
23832
  const aiReferralLandingPageRows = app.db.select({
23793
23833
  source: gaAiReferrals.source,
23794
23834
  medium: gaAiReferrals.medium,
@@ -23796,7 +23836,7 @@ async function ga4Routes(app, opts) {
23796
23836
  landingPage: sql10`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`,
23797
23837
  sessions: sql10`SUM(${gaAiReferrals.sessions})`,
23798
23838
  users: sql10`SUM(${gaAiReferrals.users})`
23799
- }).from(gaAiReferrals).where(and20(...aiConditions)).groupBy(
23839
+ }).from(gaAiReferrals).where(and21(...aiConditions)).groupBy(
23800
23840
  gaAiReferrals.source,
23801
23841
  gaAiReferrals.medium,
23802
23842
  gaAiReferrals.sourceDimension,
@@ -23833,7 +23873,7 @@ async function ga4Routes(app, opts) {
23833
23873
  channelGroup: gaAiReferrals.channelGroup,
23834
23874
  sessions: sql10`COALESCE(SUM(${gaAiReferrals.sessions}), 0)`,
23835
23875
  users: sql10`COALESCE(SUM(${gaAiReferrals.users}), 0)`
23836
- }).from(gaAiReferrals).where(and20(...aiConditions, eq26(gaAiReferrals.sourceDimension, "session"))).groupBy(gaAiReferrals.channelGroup).all();
23876
+ }).from(gaAiReferrals).where(and21(...aiConditions, eq26(gaAiReferrals.sourceDimension, "session"))).groupBy(gaAiReferrals.channelGroup).all();
23837
23877
  const aiSessionsByChannelGroup = /* @__PURE__ */ new Map();
23838
23878
  let aiBySessionUsers = 0;
23839
23879
  for (const row of aiBySessionRows) {
@@ -23847,11 +23887,11 @@ async function ga4Routes(app, opts) {
23847
23887
  channelGroup: gaSocialReferrals.channelGroup,
23848
23888
  sessions: sql10`SUM(${gaSocialReferrals.sessions})`,
23849
23889
  users: sql10`SUM(${gaSocialReferrals.users})`
23850
- }).from(gaSocialReferrals).where(and20(...socialConditions)).groupBy(gaSocialReferrals.source, gaSocialReferrals.medium, gaSocialReferrals.channelGroup).orderBy(sql10`SUM(${gaSocialReferrals.sessions}) DESC`).all();
23890
+ }).from(gaSocialReferrals).where(and21(...socialConditions)).groupBy(gaSocialReferrals.source, gaSocialReferrals.medium, gaSocialReferrals.channelGroup).orderBy(sql10`SUM(${gaSocialReferrals.sessions}) DESC`).all();
23851
23891
  const socialTotals = app.db.select({
23852
23892
  sessions: sql10`SUM(${gaSocialReferrals.sessions})`,
23853
23893
  users: sql10`SUM(${gaSocialReferrals.users})`
23854
- }).from(gaSocialReferrals).where(and20(...socialConditions)).get();
23894
+ }).from(gaSocialReferrals).where(and21(...socialConditions)).get();
23855
23895
  const latestSync = app.db.select({ syncedAt: gaTrafficSummaries.syncedAt }).from(gaTrafficSummaries).where(eq26(gaTrafficSummaries.projectId, project.id)).orderBy(desc13(gaTrafficSummaries.syncedAt)).limit(1).get();
23856
23896
  const total = summaryRow?.totalSessions ?? 0;
23857
23897
  const totalDirectSessions = directTotalRow?.totalDirectSessions ?? 0;
@@ -23942,7 +23982,7 @@ async function ga4Routes(app, opts) {
23942
23982
  sourceDimension: gaAiReferrals.sourceDimension,
23943
23983
  sessions: sql10`SUM(${gaAiReferrals.sessions})`,
23944
23984
  users: sql10`SUM(${gaAiReferrals.users})`
23945
- }).from(gaAiReferrals).where(and20(...conditions)).groupBy(
23985
+ }).from(gaAiReferrals).where(and21(...conditions)).groupBy(
23946
23986
  gaAiReferrals.date,
23947
23987
  gaAiReferrals.source,
23948
23988
  gaAiReferrals.medium,
@@ -23964,7 +24004,7 @@ async function ga4Routes(app, opts) {
23964
24004
  channelGroup: gaSocialReferrals.channelGroup,
23965
24005
  sessions: gaSocialReferrals.sessions,
23966
24006
  users: gaSocialReferrals.users
23967
- }).from(gaSocialReferrals).where(and20(...conditions)).orderBy(gaSocialReferrals.date).all();
24007
+ }).from(gaSocialReferrals).where(and21(...conditions)).orderBy(gaSocialReferrals.date).all();
23968
24008
  return rows;
23969
24009
  });
23970
24010
  app.get("/projects/:name/ga/social-referral-trend", async (request, _reply) => {
@@ -23977,7 +24017,7 @@ async function ga4Routes(app, opts) {
23977
24017
  d.setDate(d.getDate() - n);
23978
24018
  return fmt(d);
23979
24019
  };
23980
- const sumSocial = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and20(
24020
+ const sumSocial = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and21(
23981
24021
  eq26(gaSocialReferrals.projectId, project.id),
23982
24022
  sql10`${gaSocialReferrals.date} >= ${from}`,
23983
24023
  sql10`${gaSocialReferrals.date} < ${to}`
@@ -23990,7 +24030,7 @@ async function ga4Routes(app, opts) {
23990
24030
  const sourceCurrent = app.db.select({
23991
24031
  source: gaSocialReferrals.source,
23992
24032
  sessions: sql10`SUM(${gaSocialReferrals.sessions})`
23993
- }).from(gaSocialReferrals).where(and20(
24033
+ }).from(gaSocialReferrals).where(and21(
23994
24034
  eq26(gaSocialReferrals.projectId, project.id),
23995
24035
  sql10`${gaSocialReferrals.date} >= ${daysAgo(7)}`,
23996
24036
  sql10`${gaSocialReferrals.date} < ${fmt(today)}`
@@ -23998,7 +24038,7 @@ async function ga4Routes(app, opts) {
23998
24038
  const sourcePrev = app.db.select({
23999
24039
  source: gaSocialReferrals.source,
24000
24040
  sessions: sql10`SUM(${gaSocialReferrals.sessions})`
24001
- }).from(gaSocialReferrals).where(and20(
24041
+ }).from(gaSocialReferrals).where(and21(
24002
24042
  eq26(gaSocialReferrals.projectId, project.id),
24003
24043
  sql10`${gaSocialReferrals.date} >= ${daysAgo(14)}`,
24004
24044
  sql10`${gaSocialReferrals.date} < ${daysAgo(7)}`
@@ -24040,16 +24080,16 @@ async function ga4Routes(app, opts) {
24040
24080
  return fmt(d);
24041
24081
  };
24042
24082
  const pct = (cur, prev) => prev === 0 ? null : Math.round((cur - prev) / prev * 100);
24043
- const sumTotal = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)` }).from(gaTrafficSnapshots).where(and20(eq26(gaTrafficSnapshots.projectId, project.id), sql10`${gaTrafficSnapshots.date} >= ${from}`, sql10`${gaTrafficSnapshots.date} < ${to}`)).get();
24044
- const sumOrganic = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)` }).from(gaTrafficSnapshots).where(and20(eq26(gaTrafficSnapshots.projectId, project.id), sql10`${gaTrafficSnapshots.date} >= ${from}`, sql10`${gaTrafficSnapshots.date} < ${to}`)).get();
24045
- const sumDirect = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)` }).from(gaTrafficSnapshots).where(and20(eq26(gaTrafficSnapshots.projectId, project.id), sql10`${gaTrafficSnapshots.date} >= ${from}`, sql10`${gaTrafficSnapshots.date} < ${to}`)).get();
24046
- const sumAi = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and20(
24083
+ const sumTotal = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)` }).from(gaTrafficSnapshots).where(and21(eq26(gaTrafficSnapshots.projectId, project.id), sql10`${gaTrafficSnapshots.date} >= ${from}`, sql10`${gaTrafficSnapshots.date} < ${to}`)).get();
24084
+ const sumOrganic = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)` }).from(gaTrafficSnapshots).where(and21(eq26(gaTrafficSnapshots.projectId, project.id), sql10`${gaTrafficSnapshots.date} >= ${from}`, sql10`${gaTrafficSnapshots.date} < ${to}`)).get();
24085
+ const sumDirect = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)` }).from(gaTrafficSnapshots).where(and21(eq26(gaTrafficSnapshots.projectId, project.id), sql10`${gaTrafficSnapshots.date} >= ${from}`, sql10`${gaTrafficSnapshots.date} < ${to}`)).get();
24086
+ const sumAi = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and21(
24047
24087
  eq26(gaAiReferrals.projectId, project.id),
24048
24088
  sql10`${gaAiReferrals.date} >= ${from}`,
24049
24089
  sql10`${gaAiReferrals.date} < ${to}`,
24050
24090
  eq26(gaAiReferrals.sourceDimension, "session")
24051
24091
  )).get();
24052
- const sumSocial = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and20(eq26(gaSocialReferrals.projectId, project.id), sql10`${gaSocialReferrals.date} >= ${from}`, sql10`${gaSocialReferrals.date} < ${to}`)).get();
24092
+ const sumSocial = (from, to) => app.db.select({ sessions: sql10`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and21(eq26(gaSocialReferrals.projectId, project.id), sql10`${gaSocialReferrals.date} >= ${from}`, sql10`${gaSocialReferrals.date} < ${to}`)).get();
24053
24093
  const todayStr = fmt(today);
24054
24094
  const buildTrend = (sum) => {
24055
24095
  const c7 = sum(daysAgo(7), todayStr)?.sessions ?? 0;
@@ -24058,13 +24098,13 @@ async function ga4Routes(app, opts) {
24058
24098
  const p30 = sum(daysAgo(60), daysAgo(30))?.sessions ?? 0;
24059
24099
  return { sessions7d: c7, sessionsPrev7d: p7, trend7dPct: pct(c7, p7), sessions30d: c30, sessionsPrev30d: p30, trend30dPct: pct(c30, p30) };
24060
24100
  };
24061
- const aiSourceCurrent = app.db.select({ source: gaAiReferrals.source, sessions: sql10`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and20(
24101
+ const aiSourceCurrent = app.db.select({ source: gaAiReferrals.source, sessions: sql10`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and21(
24062
24102
  eq26(gaAiReferrals.projectId, project.id),
24063
24103
  sql10`${gaAiReferrals.date} >= ${daysAgo(7)}`,
24064
24104
  sql10`${gaAiReferrals.date} < ${todayStr}`,
24065
24105
  eq26(gaAiReferrals.sourceDimension, "session")
24066
24106
  )).groupBy(gaAiReferrals.source).all();
24067
- const aiSourcePrev = app.db.select({ source: gaAiReferrals.source, sessions: sql10`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and20(
24107
+ const aiSourcePrev = app.db.select({ source: gaAiReferrals.source, sessions: sql10`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and21(
24068
24108
  eq26(gaAiReferrals.projectId, project.id),
24069
24109
  sql10`${gaAiReferrals.date} >= ${daysAgo(14)}`,
24070
24110
  sql10`${gaAiReferrals.date} < ${daysAgo(7)}`,
@@ -24084,8 +24124,8 @@ async function ga4Routes(app, opts) {
24084
24124
  }
24085
24125
  return mover;
24086
24126
  };
24087
- const socialSourceCurrent = app.db.select({ source: gaSocialReferrals.source, sessions: sql10`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and20(eq26(gaSocialReferrals.projectId, project.id), sql10`${gaSocialReferrals.date} >= ${daysAgo(7)}`, sql10`${gaSocialReferrals.date} < ${todayStr}`)).groupBy(gaSocialReferrals.source).all();
24088
- const socialSourcePrev = app.db.select({ source: gaSocialReferrals.source, sessions: sql10`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and20(eq26(gaSocialReferrals.projectId, project.id), sql10`${gaSocialReferrals.date} >= ${daysAgo(14)}`, sql10`${gaSocialReferrals.date} < ${daysAgo(7)}`)).groupBy(gaSocialReferrals.source).all();
24127
+ const socialSourceCurrent = app.db.select({ source: gaSocialReferrals.source, sessions: sql10`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and21(eq26(gaSocialReferrals.projectId, project.id), sql10`${gaSocialReferrals.date} >= ${daysAgo(7)}`, sql10`${gaSocialReferrals.date} < ${todayStr}`)).groupBy(gaSocialReferrals.source).all();
24128
+ const socialSourcePrev = app.db.select({ source: gaSocialReferrals.source, sessions: sql10`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and21(eq26(gaSocialReferrals.projectId, project.id), sql10`${gaSocialReferrals.date} >= ${daysAgo(14)}`, sql10`${gaSocialReferrals.date} < ${daysAgo(7)}`)).groupBy(gaSocialReferrals.source).all();
24089
24129
  return {
24090
24130
  total: buildTrend(sumTotal),
24091
24131
  organic: buildTrend(sumOrganic),
@@ -24107,7 +24147,7 @@ async function ga4Routes(app, opts) {
24107
24147
  sessions: sql10`SUM(${gaTrafficSnapshots.sessions})`,
24108
24148
  organicSessions: sql10`SUM(${gaTrafficSnapshots.organicSessions})`,
24109
24149
  users: sql10`SUM(${gaTrafficSnapshots.users})`
24110
- }).from(gaTrafficSnapshots).where(and20(...conditions)).groupBy(gaTrafficSnapshots.date).orderBy(gaTrafficSnapshots.date).all();
24150
+ }).from(gaTrafficSnapshots).where(and21(...conditions)).groupBy(gaTrafficSnapshots.date).orderBy(gaTrafficSnapshots.date).all();
24111
24151
  return rows.map((r) => ({
24112
24152
  date: r.date,
24113
24153
  sessions: r.sessions ?? 0,
@@ -25771,7 +25811,7 @@ async function wordpressRoutes(app, opts) {
25771
25811
 
25772
25812
  // ../api-routes/src/backlinks.ts
25773
25813
  import crypto23 from "crypto";
25774
- import { and as and22, asc as asc4, desc as desc14, eq as eq27, sql as sql11 } from "drizzle-orm";
25814
+ import { and as and23, asc as asc4, desc as desc14, eq as eq27, sql as sql11 } from "drizzle-orm";
25775
25815
 
25776
25816
  // ../integration-commoncrawl/src/constants.ts
25777
25817
  import os2 from "os";
@@ -26174,7 +26214,7 @@ function pruneCachedRelease(release, opts = {}) {
26174
26214
  }
26175
26215
 
26176
26216
  // ../api-routes/src/backlinks-filter.ts
26177
- import { and as and21, ne as ne3, notLike } from "drizzle-orm";
26217
+ import { and as and22, ne as ne3, notLike } from "drizzle-orm";
26178
26218
  var BACKLINK_FILTER_PATTERNS = [
26179
26219
  "*.google.com",
26180
26220
  "*.googleusercontent.com",
@@ -26197,7 +26237,7 @@ function backlinkCrawlerExclusionClause() {
26197
26237
  conditions.push(ne3(backlinkDomains.linkingDomain, pattern));
26198
26238
  }
26199
26239
  }
26200
- const combined = and21(...conditions);
26240
+ const combined = and22(...conditions);
26201
26241
  if (!combined) throw new Error("BACKLINK_FILTER_PATTERNS is unexpectedly empty");
26202
26242
  return combined;
26203
26243
  }
@@ -26272,7 +26312,7 @@ function latestSummaryForProject(db, projectId, source, release) {
26272
26312
  eq27(backlinkSummaries.source, source)
26273
26313
  ];
26274
26314
  if (release) conditions.push(eq27(backlinkSummaries.release, release));
26275
- return db.select().from(backlinkSummaries).where(and22(...conditions)).orderBy(desc14(backlinkSummaries.queriedAt)).limit(1).get();
26315
+ return db.select().from(backlinkSummaries).where(and23(...conditions)).orderBy(desc14(backlinkSummaries.queriedAt)).limit(1).get();
26276
26316
  }
26277
26317
  function parseExcludeCrawlers(value) {
26278
26318
  if (!value) return false;
@@ -26280,12 +26320,12 @@ function parseExcludeCrawlers(value) {
26280
26320
  return lower === "1" || lower === "true" || lower === "yes";
26281
26321
  }
26282
26322
  function computeFilteredSummary(db, base) {
26283
- const baseDomainCondition = and22(
26323
+ const baseDomainCondition = and23(
26284
26324
  eq27(backlinkDomains.projectId, base.projectId),
26285
26325
  eq27(backlinkDomains.source, base.source),
26286
26326
  eq27(backlinkDomains.release, base.release)
26287
26327
  );
26288
- const filteredCondition = and22(baseDomainCondition, backlinkCrawlerExclusionClause());
26328
+ const filteredCondition = and23(baseDomainCondition, backlinkCrawlerExclusionClause());
26289
26329
  const unfilteredAgg = db.select({
26290
26330
  count: sql11`count(*)`,
26291
26331
  total: sql11`coalesce(sum(${backlinkDomains.numHosts}), 0)`
@@ -26315,10 +26355,10 @@ function computeFilteredSummary(db, base) {
26315
26355
  };
26316
26356
  }
26317
26357
  function buildSourceAvailability(db, projectId, source, connected, excludeCrawlers) {
26318
- const summary = db.select().from(backlinkSummaries).where(and22(eq27(backlinkSummaries.projectId, projectId), eq27(backlinkSummaries.source, source))).orderBy(desc14(backlinkSummaries.queriedAt)).limit(1).get();
26358
+ const summary = db.select().from(backlinkSummaries).where(and23(eq27(backlinkSummaries.projectId, projectId), eq27(backlinkSummaries.source, source))).orderBy(desc14(backlinkSummaries.queriedAt)).limit(1).get();
26319
26359
  let totalLinkingDomains = summary?.totalLinkingDomains ?? 0;
26320
26360
  if (summary && excludeCrawlers) {
26321
- const filtered = db.select({ count: sql11`count(*)` }).from(backlinkDomains).where(and22(
26361
+ const filtered = db.select({ count: sql11`count(*)` }).from(backlinkDomains).where(and23(
26322
26362
  eq27(backlinkDomains.projectId, projectId),
26323
26363
  eq27(backlinkDomains.source, source),
26324
26364
  eq27(backlinkDomains.release, summary.release),
@@ -26501,12 +26541,12 @@ async function backlinksRoutes(app, opts) {
26501
26541
  const limit = Math.min(Math.max(parseInt(request.query.limit ?? "50", 10) || 50, 1), 500);
26502
26542
  const offset = Math.max(parseInt(request.query.offset ?? "0", 10) || 0, 0);
26503
26543
  const excludeCrawlers = parseExcludeCrawlers(request.query.excludeCrawlers);
26504
- const baseDomainCondition = and22(
26544
+ const baseDomainCondition = and23(
26505
26545
  eq27(backlinkDomains.projectId, project.id),
26506
26546
  eq27(backlinkDomains.source, source),
26507
26547
  eq27(backlinkDomains.release, targetRelease)
26508
26548
  );
26509
- const domainCondition = excludeCrawlers ? and22(baseDomainCondition, backlinkCrawlerExclusionClause()) : baseDomainCondition;
26549
+ const domainCondition = excludeCrawlers ? and23(baseDomainCondition, backlinkCrawlerExclusionClause()) : baseDomainCondition;
26510
26550
  const totalRow = app.db.select({ count: sql11`count(*)` }).from(backlinkDomains).where(domainCondition).get();
26511
26551
  const rows = app.db.select({
26512
26552
  linkingDomain: backlinkDomains.linkingDomain,
@@ -26530,7 +26570,7 @@ async function backlinksRoutes(app, opts) {
26530
26570
  async (request, reply) => {
26531
26571
  const project = resolveProject(app.db, request.params.name);
26532
26572
  const source = parseSourceParam(request.query.source);
26533
- const rows = app.db.select().from(backlinkSummaries).where(and22(eq27(backlinkSummaries.projectId, project.id), eq27(backlinkSummaries.source, source))).orderBy(asc4(backlinkSummaries.queriedAt)).all();
26573
+ const rows = app.db.select().from(backlinkSummaries).where(and23(eq27(backlinkSummaries.projectId, project.id), eq27(backlinkSummaries.source, source))).orderBy(asc4(backlinkSummaries.queriedAt)).all();
26534
26574
  const response = rows.map((r) => ({
26535
26575
  release: r.release,
26536
26576
  totalLinkingDomains: r.totalLinkingDomains,
@@ -26586,7 +26626,7 @@ async function backlinksRoutes(app, opts) {
26586
26626
  // ../api-routes/src/traffic.ts
26587
26627
  import crypto25 from "crypto";
26588
26628
  import { Agent as UndiciAgent } from "undici";
26589
- import { and as and23, desc as desc15, eq as eq28, gte as gte4, lte as lte3, sql as sql12 } from "drizzle-orm";
26629
+ import { and as and24, desc as desc15, eq as eq28, gte as gte4, lte as lte3, sql as sql12 } from "drizzle-orm";
26590
26630
 
26591
26631
  // ../integration-cloud-run/src/auth.ts
26592
26632
  import crypto24 from "crypto";
@@ -30445,28 +30485,28 @@ async function runBackfillTask(options) {
30445
30485
  try {
30446
30486
  app.db.transaction((tx) => {
30447
30487
  tx.delete(crawlerEventsHourly).where(
30448
- and23(
30488
+ and24(
30449
30489
  eq28(crawlerEventsHourly.sourceId, sourceRow.id),
30450
30490
  gte4(crawlerEventsHourly.tsHour, windowStartIso),
30451
30491
  lte3(crawlerEventsHourly.tsHour, windowEndIso)
30452
30492
  )
30453
30493
  ).run();
30454
30494
  tx.delete(aiUserFetchEventsHourly).where(
30455
- and23(
30495
+ and24(
30456
30496
  eq28(aiUserFetchEventsHourly.sourceId, sourceRow.id),
30457
30497
  gte4(aiUserFetchEventsHourly.tsHour, windowStartIso),
30458
30498
  lte3(aiUserFetchEventsHourly.tsHour, windowEndIso)
30459
30499
  )
30460
30500
  ).run();
30461
30501
  tx.delete(aiReferralEventsHourly).where(
30462
- and23(
30502
+ and24(
30463
30503
  eq28(aiReferralEventsHourly.sourceId, sourceRow.id),
30464
30504
  gte4(aiReferralEventsHourly.tsHour, windowStartIso),
30465
30505
  lte3(aiReferralEventsHourly.tsHour, windowEndIso)
30466
30506
  )
30467
30507
  ).run();
30468
30508
  tx.delete(rawEventSamples).where(
30469
- and23(
30509
+ and24(
30470
30510
  eq28(rawEventSamples.sourceId, sourceRow.id),
30471
30511
  gte4(rawEventSamples.ts, windowStartIso),
30472
30512
  lte3(rawEventSamples.ts, windowEndIso)
@@ -30849,7 +30889,7 @@ async function trafficRoutes(app, opts) {
30849
30889
  row = tx.select().from(trafficSources).where(eq28(trafficSources.id, newId)).get();
30850
30890
  }
30851
30891
  const existingSchedule = tx.select().from(schedules).where(
30852
- and23(
30892
+ and24(
30853
30893
  eq28(schedules.projectId, project.id),
30854
30894
  eq28(schedules.kind, SchedulableRunKinds["traffic-sync"])
30855
30895
  )
@@ -31571,7 +31611,7 @@ async function trafficRoutes(app, opts) {
31571
31611
  pathNormalized: crawlerEventsHourly.pathNormalized,
31572
31612
  hits: sql12`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
31573
31613
  }).from(crawlerEventsHourly).where(
31574
- and23(
31614
+ and24(
31575
31615
  eq28(crawlerEventsHourly.sourceId, row.id),
31576
31616
  gte4(crawlerEventsHourly.tsHour, since)
31577
31617
  )
@@ -31581,25 +31621,25 @@ async function trafficRoutes(app, opts) {
31581
31621
  );
31582
31622
  const crawlerTotal = crawlerSegments.content + crawlerSegments.sitemap + crawlerSegments.robots + crawlerSegments.asset + crawlerSegments.other;
31583
31623
  const aiUserFetchTotals = app.db.select({ total: sql12`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(
31584
- and23(
31624
+ and24(
31585
31625
  eq28(aiUserFetchEventsHourly.sourceId, row.id),
31586
31626
  gte4(aiUserFetchEventsHourly.tsHour, since)
31587
31627
  )
31588
31628
  ).get();
31589
31629
  const aiTotals = app.db.select({ total: sql12`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
31590
- and23(
31630
+ and24(
31591
31631
  eq28(aiReferralEventsHourly.sourceId, row.id),
31592
31632
  gte4(aiReferralEventsHourly.tsHour, since)
31593
31633
  )
31594
31634
  ).get();
31595
31635
  const sampleTotals = app.db.select({ total: sql12`COUNT(*)` }).from(rawEventSamples).where(
31596
- and23(
31636
+ and24(
31597
31637
  eq28(rawEventSamples.sourceId, row.id),
31598
31638
  gte4(rawEventSamples.ts, since)
31599
31639
  )
31600
31640
  ).get();
31601
31641
  const latestRun = app.db.select().from(runs).where(
31602
- and23(
31642
+ and24(
31603
31643
  eq28(runs.projectId, projectId),
31604
31644
  eq28(runs.kind, RunKinds["traffic-sync"]),
31605
31645
  eq28(runs.sourceId, row.id)
@@ -31633,7 +31673,7 @@ async function trafficRoutes(app, opts) {
31633
31673
  "`advanceToNow` must be `true`. There is no implicit reset."
31634
31674
  );
31635
31675
  }
31636
- const sourceRow = app.db.select().from(trafficSources).where(and23(eq28(trafficSources.projectId, project.id), eq28(trafficSources.id, request.params.id))).get();
31676
+ const sourceRow = app.db.select().from(trafficSources).where(and24(eq28(trafficSources.projectId, project.id), eq28(trafficSources.id, request.params.id))).get();
31637
31677
  if (!sourceRow) {
31638
31678
  throw notFound("traffic source", request.params.id);
31639
31679
  }
@@ -31738,7 +31778,7 @@ async function trafficRoutes(app, opts) {
31738
31778
  lte3(crawlerEventsHourly.tsHour, untilIso)
31739
31779
  ];
31740
31780
  if (sourceIdParam) crawlerFilters.push(eq28(crawlerEventsHourly.sourceId, sourceIdParam));
31741
- const crawlerWhere = and23(...crawlerFilters);
31781
+ const crawlerWhere = and24(...crawlerFilters);
31742
31782
  const pathTotals = app.db.select({
31743
31783
  pathNormalized: crawlerEventsHourly.pathNormalized,
31744
31784
  hits: sql12`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
@@ -31770,7 +31810,7 @@ async function trafficRoutes(app, opts) {
31770
31810
  lte3(aiUserFetchEventsHourly.tsHour, untilIso)
31771
31811
  ];
31772
31812
  if (sourceIdParam) userFetchFilters.push(eq28(aiUserFetchEventsHourly.sourceId, sourceIdParam));
31773
- const userFetchWhere = and23(...userFetchFilters);
31813
+ const userFetchWhere = and24(...userFetchFilters);
31774
31814
  const total = app.db.select({ total: sql12`COALESCE(SUM(${aiUserFetchEventsHourly.hits}), 0)` }).from(aiUserFetchEventsHourly).where(userFetchWhere).get();
31775
31815
  aiUserFetchTotal = Number(total?.total ?? 0);
31776
31816
  const rows = app.db.select().from(aiUserFetchEventsHourly).where(userFetchWhere).orderBy(desc15(aiUserFetchEventsHourly.tsHour)).limit(limit).all();
@@ -31795,7 +31835,7 @@ async function trafficRoutes(app, opts) {
31795
31835
  lte3(aiReferralEventsHourly.tsHour, untilIso)
31796
31836
  ];
31797
31837
  if (sourceIdParam) aiFilters.push(eq28(aiReferralEventsHourly.sourceId, sourceIdParam));
31798
- const aiWhere = and23(...aiFilters);
31838
+ const aiWhere = and24(...aiFilters);
31799
31839
  const total = app.db.select({ total: sql12`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(aiWhere).get();
31800
31840
  aiReferralTotal = Number(total?.total ?? 0);
31801
31841
  const rows = app.db.select().from(aiReferralEventsHourly).where(aiWhere).orderBy(desc15(aiReferralEventsHourly.tsHour)).limit(limit).all();
@@ -32002,7 +32042,7 @@ function readInstalledManifest(skillDir) {
32002
32042
  var AGENT_CHECKS = [skillsInstalledCheck, skillsCurrentCheck];
32003
32043
 
32004
32044
  // ../api-routes/src/doctor/checks/backlinks.ts
32005
- import { and as and24, eq as eq29 } from "drizzle-orm";
32045
+ import { and as and25, eq as eq29 } from "drizzle-orm";
32006
32046
  function skippedNoProject() {
32007
32047
  return {
32008
32048
  status: CheckStatuses.skipped,
@@ -32034,7 +32074,7 @@ var BACKLINKS_CHECKS = [
32034
32074
  details: { commoncrawl: ccConnected, bingWebmaster: bingConnected }
32035
32075
  };
32036
32076
  }
32037
- const ccHasData = ccConnected ? !!ctx.db.select({ id: backlinkSummaries.id }).from(backlinkSummaries).where(and24(
32077
+ const ccHasData = ccConnected ? !!ctx.db.select({ id: backlinkSummaries.id }).from(backlinkSummaries).where(and25(
32038
32078
  eq29(backlinkSummaries.projectId, ctx.project.id),
32039
32079
  eq29(backlinkSummaries.source, BacklinkSources.commoncrawl)
32040
32080
  )).limit(1).get() : false;
@@ -32559,7 +32599,7 @@ var ga4ConnectionCheck = {
32559
32599
  var GA_AUTH_CHECKS = [ga4ConnectionCheck];
32560
32600
 
32561
32601
  // ../api-routes/src/doctor/checks/gbp-auth.ts
32562
- import { and as and25, eq as eq32 } from "drizzle-orm";
32602
+ import { and as and26, eq as eq32 } from "drizzle-orm";
32563
32603
  var RECENT_SYNC_WARN_DAYS2 = 7;
32564
32604
  var RECENT_SYNC_FAIL_DAYS2 = 30;
32565
32605
  function skippedNoProject3() {
@@ -32792,7 +32832,7 @@ var recentSyncCheck = {
32792
32832
  title: "GBP recent sync",
32793
32833
  run: (ctx) => {
32794
32834
  if (!ctx.project) return skippedNoProject3();
32795
- const selected = ctx.db.select({ locationName: gbpLocations.locationName, syncedAt: gbpLocations.syncedAt }).from(gbpLocations).where(and25(eq32(gbpLocations.projectId, ctx.project.id), eq32(gbpLocations.selected, true))).all();
32835
+ const selected = ctx.db.select({ locationName: gbpLocations.locationName, syncedAt: gbpLocations.syncedAt }).from(gbpLocations).where(and26(eq32(gbpLocations.projectId, ctx.project.id), eq32(gbpLocations.selected, true))).all();
32796
32836
  if (selected.length === 0) {
32797
32837
  return {
32798
32838
  status: CheckStatuses.skipped,
@@ -33394,7 +33434,7 @@ var RUNTIME_STATE_CHECKS = [
33394
33434
  ];
33395
33435
 
33396
33436
  // ../api-routes/src/doctor/checks/traffic-source.ts
33397
- import { and as and26, eq as eq34, gte as gte5, ne as ne4, sql as sql13 } from "drizzle-orm";
33437
+ import { and as and27, eq as eq34, gte as gte5, ne as ne4, sql as sql13 } from "drizzle-orm";
33398
33438
  var RECENT_DATA_WARN_DAYS = 7;
33399
33439
  var RECENT_DATA_FAIL_DAYS = 30;
33400
33440
  function skippedNoProject5() {
@@ -33408,7 +33448,7 @@ function skippedNoProject5() {
33408
33448
  function loadProbes(ctx) {
33409
33449
  if (!ctx.project) return [];
33410
33450
  const rows = ctx.db.select().from(trafficSources).where(
33411
- and26(
33451
+ and27(
33412
33452
  eq34(trafficSources.projectId, ctx.project.id),
33413
33453
  ne4(trafficSources.status, TrafficSourceStatuses.archived)
33414
33454
  )
@@ -33489,7 +33529,7 @@ var recentDataCheck = {
33489
33529
  const failCutoff = new Date(now.getTime() - RECENT_DATA_FAIL_DAYS * 24 * 60 * 6e4).toISOString();
33490
33530
  const recentCrawlers = Number(
33491
33531
  ctx.db.select({ total: sql13`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
33492
- and26(
33532
+ and27(
33493
33533
  eq34(crawlerEventsHourly.projectId, ctx.project.id),
33494
33534
  gte5(crawlerEventsHourly.tsHour, warnCutoff)
33495
33535
  )
@@ -33497,7 +33537,7 @@ var recentDataCheck = {
33497
33537
  );
33498
33538
  const recentReferrals = Number(
33499
33539
  ctx.db.select({ total: sql13`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
33500
- and26(
33540
+ and27(
33501
33541
  eq34(aiReferralEventsHourly.projectId, ctx.project.id),
33502
33542
  gte5(aiReferralEventsHourly.tsHour, warnCutoff)
33503
33543
  )
@@ -33513,7 +33553,7 @@ var recentDataCheck = {
33513
33553
  }
33514
33554
  const olderCrawlers = Number(
33515
33555
  ctx.db.select({ total: sql13`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
33516
- and26(
33556
+ and27(
33517
33557
  eq34(crawlerEventsHourly.projectId, ctx.project.id),
33518
33558
  gte5(crawlerEventsHourly.tsHour, failCutoff)
33519
33559
  )
@@ -33521,7 +33561,7 @@ var recentDataCheck = {
33521
33561
  );
33522
33562
  const olderReferrals = Number(
33523
33563
  ctx.db.select({ total: sql13`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
33524
- and26(
33564
+ and27(
33525
33565
  eq34(aiReferralEventsHourly.projectId, ctx.project.id),
33526
33566
  gte5(aiReferralEventsHourly.tsHour, failCutoff)
33527
33567
  )
@@ -33938,7 +33978,7 @@ async function doctorRoutes(app, opts) {
33938
33978
 
33939
33979
  // ../api-routes/src/discovery/routes.ts
33940
33980
  import crypto27 from "crypto";
33941
- import { and as and27, desc as desc16, eq as eq35, gte as gte6, inArray as inArray12, isNull, or as or5 } from "drizzle-orm";
33981
+ import { and as and28, desc as desc16, eq as eq35, gte as gte6, inArray as inArray12, isNull, or as or5 } from "drizzle-orm";
33942
33982
  var MAX_INFLIGHT_DISCOVERY_AGE_MS = 2 * 60 * 60 * 1e3;
33943
33983
  async function discoveryRoutes(app, opts) {
33944
33984
  app.post("/projects/:name/discover/run", async (request, reply) => {
@@ -33972,7 +34012,7 @@ async function discoveryRoutes(app, opts) {
33972
34012
  const now = (/* @__PURE__ */ new Date()).toISOString();
33973
34013
  const ageFloorIso = new Date(Date.now() - MAX_INFLIGHT_DISCOVERY_AGE_MS).toISOString();
33974
34014
  const decision = app.db.transaction((tx) => {
33975
- const existing = tx.select({ id: discoverySessions.id, runId: discoverySessions.runId }).from(discoverySessions).where(and27(
34015
+ const existing = tx.select({ id: discoverySessions.id, runId: discoverySessions.runId }).from(discoverySessions).where(and28(
33976
34016
  eq35(discoverySessions.projectId, project.id),
33977
34017
  eq35(discoverySessions.icpDescription, icpDescription),
33978
34018
  // Buyer is part of session identity: it changes the seed prompt's
@@ -34618,7 +34658,7 @@ function dedupeStrings(input) {
34618
34658
 
34619
34659
  // ../api-routes/src/technical-aeo.ts
34620
34660
  import crypto29 from "crypto";
34621
- import { and as and28, asc as asc5, count, desc as desc17, eq as eq37, inArray as inArray13 } from "drizzle-orm";
34661
+ import { and as and29, asc as asc5, count, desc as desc17, eq as eq37, inArray as inArray13 } from "drizzle-orm";
34622
34662
  var SURFACEABLE_STATUSES = [RunStatuses.completed, RunStatuses.partial];
34623
34663
  function emptyScore(projectName) {
34624
34664
  return {
@@ -34650,7 +34690,7 @@ function parsePositiveInt(value, fallback, max) {
34650
34690
  async function technicalAeoRoutes(app, opts) {
34651
34691
  app.get("/projects/:name/technical-aeo", async (request) => {
34652
34692
  const project = resolveProject(app.db, request.params.name);
34653
- const rows = app.db.select({ snap: siteAuditSnapshots, runStatus: runs.status }).from(siteAuditSnapshots).innerJoin(runs, eq37(siteAuditSnapshots.runId, runs.id)).where(and28(
34693
+ const rows = app.db.select({ snap: siteAuditSnapshots, runStatus: runs.status }).from(siteAuditSnapshots).innerJoin(runs, eq37(siteAuditSnapshots.runId, runs.id)).where(and29(
34654
34694
  eq37(siteAuditSnapshots.projectId, project.id),
34655
34695
  eq37(runs.kind, RunKinds["site-audit"]),
34656
34696
  inArray13(runs.status, SURFACEABLE_STATUSES),
@@ -34685,7 +34725,7 @@ async function technicalAeoRoutes(app, opts) {
34685
34725
  });
34686
34726
  app.get("/projects/:name/technical-aeo/pages", async (request) => {
34687
34727
  const project = resolveProject(app.db, request.params.name);
34688
- const latest = app.db.select({ runId: siteAuditSnapshots.runId, auditedAt: siteAuditSnapshots.auditedAt }).from(siteAuditSnapshots).innerJoin(runs, eq37(siteAuditSnapshots.runId, runs.id)).where(and28(
34728
+ const latest = app.db.select({ runId: siteAuditSnapshots.runId, auditedAt: siteAuditSnapshots.auditedAt }).from(siteAuditSnapshots).innerJoin(runs, eq37(siteAuditSnapshots.runId, runs.id)).where(and29(
34689
34729
  eq37(siteAuditSnapshots.projectId, project.id),
34690
34730
  eq37(runs.kind, RunKinds["site-audit"]),
34691
34731
  inArray13(runs.status, SURFACEABLE_STATUSES),
@@ -34697,7 +34737,7 @@ async function technicalAeoRoutes(app, opts) {
34697
34737
  const statusFilter = request.query.status === "success" || request.query.status === "error" ? request.query.status : null;
34698
34738
  const conds = [eq37(siteAuditPages.runId, latest.runId)];
34699
34739
  if (statusFilter) conds.push(eq37(siteAuditPages.status, statusFilter));
34700
- const where = and28(...conds);
34740
+ const where = and29(...conds);
34701
34741
  const totalRow = app.db.select({ value: count() }).from(siteAuditPages).where(where).get();
34702
34742
  const total = totalRow?.value ?? 0;
34703
34743
  const limit = parsePositiveInt(request.query.limit, 100, 500);
@@ -34721,7 +34761,7 @@ async function technicalAeoRoutes(app, opts) {
34721
34761
  auditedAt: siteAuditSnapshots.auditedAt,
34722
34762
  aggregateScore: siteAuditSnapshots.aggregateScore,
34723
34763
  pagesAudited: siteAuditSnapshots.pagesAudited
34724
- }).from(siteAuditSnapshots).innerJoin(runs, eq37(siteAuditSnapshots.runId, runs.id)).where(and28(
34764
+ }).from(siteAuditSnapshots).innerJoin(runs, eq37(siteAuditSnapshots.runId, runs.id)).where(and29(
34725
34765
  eq37(siteAuditSnapshots.projectId, project.id),
34726
34766
  eq37(runs.kind, RunKinds["site-audit"]),
34727
34767
  inArray13(runs.status, SURFACEABLE_STATUSES),
@@ -34735,7 +34775,7 @@ async function technicalAeoRoutes(app, opts) {
34735
34775
  if (!parsed.success) {
34736
34776
  throw validationError(parsed.error.issues[0]?.message ?? "Invalid site-audit request");
34737
34777
  }
34738
- const existing = app.db.select({ id: runs.id, status: runs.status }).from(runs).where(and28(
34778
+ const existing = app.db.select({ id: runs.id, status: runs.status }).from(runs).where(and29(
34739
34779
  eq37(runs.projectId, project.id),
34740
34780
  eq37(runs.kind, RunKinds["site-audit"]),
34741
34781
  inArray13(runs.status, [RunStatuses.queued, RunStatuses.running])
@@ -35329,7 +35369,7 @@ var IntelligenceService = class {
35329
35369
  */
35330
35370
  analyzeAndPersist(runId, projectId) {
35331
35371
  const recentRuns = this.db.select().from(runs).where(
35332
- and29(
35372
+ and30(
35333
35373
  eq38(runs.projectId, projectId),
35334
35374
  or6(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35335
35375
  // Defensive: RunCoordinator already skips probes before this is
@@ -35421,7 +35461,7 @@ var IntelligenceService = class {
35421
35461
  }
35422
35462
  const windowStart = runRow.startedAt ?? runRow.createdAt;
35423
35463
  const windowEnd = runRow.finishedAt ?? (/* @__PURE__ */ new Date()).toISOString();
35424
- const selected = this.db.select().from(gbpLocations).where(and29(
35464
+ const selected = this.db.select().from(gbpLocations).where(and30(
35425
35465
  eq38(gbpLocations.projectId, projectId),
35426
35466
  eq38(gbpLocations.selected, true),
35427
35467
  gte7(gbpLocations.syncedAt, windowStart),
@@ -35458,12 +35498,12 @@ var IntelligenceService = class {
35458
35498
  }
35459
35499
  /** Build the per-location signal bundle the GBP analyzer consumes. */
35460
35500
  buildGbpLocationSignals(projectId, locationName, displayName, fallbackDate) {
35461
- const metricRows = this.db.select({ metric: gbpDailyMetrics.metric, date: gbpDailyMetrics.date, value: gbpDailyMetrics.value }).from(gbpDailyMetrics).where(and29(eq38(gbpDailyMetrics.projectId, projectId), eq38(gbpDailyMetrics.locationName, locationName))).all();
35462
- const placeActionRows = this.db.select({ placeActionType: gbpPlaceActions.placeActionType, providerType: gbpPlaceActions.providerType }).from(gbpPlaceActions).where(and29(eq38(gbpPlaceActions.projectId, projectId), eq38(gbpPlaceActions.locationName, locationName))).all();
35463
- const lodgingRow = this.db.select({ populatedGroupCount: gbpLodgingSnapshots.populatedGroupCount }).from(gbpLodgingSnapshots).where(and29(eq38(gbpLodgingSnapshots.projectId, projectId), eq38(gbpLodgingSnapshots.locationName, locationName))).orderBy(desc18(gbpLodgingSnapshots.syncedAt)).limit(1).get();
35464
- const ownerRow = this.db.select({ description: gbpLocations.description }).from(gbpLocations).where(and29(eq38(gbpLocations.projectId, projectId), eq38(gbpLocations.locationName, locationName))).get();
35501
+ const metricRows = this.db.select({ metric: gbpDailyMetrics.metric, date: gbpDailyMetrics.date, value: gbpDailyMetrics.value }).from(gbpDailyMetrics).where(and30(eq38(gbpDailyMetrics.projectId, projectId), eq38(gbpDailyMetrics.locationName, locationName))).all();
35502
+ const placeActionRows = this.db.select({ placeActionType: gbpPlaceActions.placeActionType, providerType: gbpPlaceActions.providerType }).from(gbpPlaceActions).where(and30(eq38(gbpPlaceActions.projectId, projectId), eq38(gbpPlaceActions.locationName, locationName))).all();
35503
+ const lodgingRow = this.db.select({ populatedGroupCount: gbpLodgingSnapshots.populatedGroupCount }).from(gbpLodgingSnapshots).where(and30(eq38(gbpLodgingSnapshots.projectId, projectId), eq38(gbpLodgingSnapshots.locationName, locationName))).orderBy(desc18(gbpLodgingSnapshots.syncedAt)).limit(1).get();
35504
+ const ownerRow = this.db.select({ description: gbpLocations.description }).from(gbpLocations).where(and30(eq38(gbpLocations.projectId, projectId), eq38(gbpLocations.locationName, locationName))).get();
35465
35505
  const descriptionMissing = !(ownerRow?.description ?? "").trim();
35466
- const placeRow = this.db.select({ attributes: gbpPlaceDetails.attributes }).from(gbpPlaceDetails).where(and29(eq38(gbpPlaceDetails.projectId, projectId), eq38(gbpPlaceDetails.locationName, locationName))).orderBy(desc18(gbpPlaceDetails.syncedAt)).limit(1).get();
35506
+ const placeRow = this.db.select({ attributes: gbpPlaceDetails.attributes }).from(gbpPlaceDetails).where(and30(eq38(gbpPlaceDetails.projectId, projectId), eq38(gbpPlaceDetails.locationName, locationName))).orderBy(desc18(gbpPlaceDetails.syncedAt)).limit(1).get();
35467
35507
  const placesAmenities = placeRow ? extractPlaceAmenities(placeRow.attributes) : [];
35468
35508
  const summary = buildGbpSummary({
35469
35509
  locationName,
@@ -35499,7 +35539,7 @@ var IntelligenceService = class {
35499
35539
  /** Build the month-over-month keyword series for a location from the
35500
35540
  * accumulating gbp_keyword_monthly table (latest complete month vs prior). */
35501
35541
  buildGbpKeywordTrend(projectId, locationName) {
35502
- const rows = this.db.select({ month: gbpKeywordMonthly.month, keyword: gbpKeywordMonthly.keyword, valueCount: gbpKeywordMonthly.valueCount }).from(gbpKeywordMonthly).where(and29(eq38(gbpKeywordMonthly.projectId, projectId), eq38(gbpKeywordMonthly.locationName, locationName))).all();
35542
+ const rows = this.db.select({ month: gbpKeywordMonthly.month, keyword: gbpKeywordMonthly.keyword, valueCount: gbpKeywordMonthly.valueCount }).from(gbpKeywordMonthly).where(and30(eq38(gbpKeywordMonthly.projectId, projectId), eq38(gbpKeywordMonthly.locationName, locationName))).all();
35503
35543
  if (rows.length === 0) return { recentMonth: null, priorMonth: null, points: [] };
35504
35544
  const months = [...new Set(rows.map((r) => r.month))].sort().reverse();
35505
35545
  const recentMonth = months[0] ?? null;
@@ -35530,7 +35570,7 @@ var IntelligenceService = class {
35530
35570
  */
35531
35571
  persistGbpInsights(runId, projectId, gbpInsights, coveredLocationNames) {
35532
35572
  const covered = new Set(coveredLocationNames);
35533
- const existing = this.db.select({ id: insights.id, dismissed: insights.dismissed }).from(insights).where(and29(eq38(insights.projectId, projectId), eq38(insights.provider, GBP_INSIGHT_PROVIDER))).all();
35573
+ const existing = this.db.select({ id: insights.id, dismissed: insights.dismissed }).from(insights).where(and30(eq38(insights.projectId, projectId), eq38(insights.provider, GBP_INSIGHT_PROVIDER))).all();
35534
35574
  const staleIds = [];
35535
35575
  const dismissedSlots = /* @__PURE__ */ new Set();
35536
35576
  for (const row of existing) {
@@ -35632,7 +35672,7 @@ var IntelligenceService = class {
35632
35672
  sinceTimestamp = parsed;
35633
35673
  }
35634
35674
  const allRuns = this.db.select().from(runs).where(
35635
- and29(
35675
+ and30(
35636
35676
  eq38(runs.projectId, project.id),
35637
35677
  or6(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
35638
35678
  // Backfill must not replay probe runs as if they were real sweeps.
@@ -35809,7 +35849,7 @@ var IntelligenceService = class {
35809
35849
  );
35810
35850
  const ROWS_PER_GROUP_BUDGET = Math.max(2, locationCount);
35811
35851
  const recentRunRows = this.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(
35812
- and29(
35852
+ and30(
35813
35853
  eq38(runs.projectId, projectId),
35814
35854
  eq38(runs.kind, RunKinds["answer-visibility"]),
35815
35855
  or6(eq38(runs.status, "completed"), eq38(runs.status, "partial")),
@@ -35832,7 +35872,7 @@ var IntelligenceService = class {
35832
35872
  const haveHistory = recentRunIds.length > 0;
35833
35873
  const priorRegressionsByPair = /* @__PURE__ */ new Map();
35834
35874
  if (haveHistory) {
35835
- const priorRows = this.db.select({ query: insights.query, provider: insights.provider, runId: insights.runId }).from(insights).where(and29(eq38(insights.type, "regression"), inArray14(insights.runId, recentRunIds))).all();
35875
+ const priorRows = this.db.select({ query: insights.query, provider: insights.provider, runId: insights.runId }).from(insights).where(and30(eq38(insights.type, "regression"), inArray14(insights.runId, recentRunIds))).all();
35836
35876
  const regressionGroups = /* @__PURE__ */ new Map();
35837
35877
  for (const row of priorRows) {
35838
35878
  if (!row.runId) continue;