@ainyc/canonry 4.47.0 → 4.50.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.
- package/assets/agent-workspace/skills/aero/SKILL.md +11 -0
- package/assets/agent-workspace/skills/aero/references/orchestration.md +8 -0
- package/assets/agent-workspace/skills/aero/soul.md +1 -1
- package/assets/agent-workspace/skills/canonry/SKILL.md +2 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +14 -1
- package/assets/assets/{index-BDMNXVHa.css → index-DOP3oQmw.css} +1 -1
- package/assets/assets/index-DVK0M62U.js +214 -0
- package/assets/assets/vendor-markdown-DN2199pt.js +14 -0
- package/assets/assets/vendor-radix-Bvy4KXTI.js +45 -0
- package/assets/assets/vendor-recharts-DPeiXMwW.js +36 -0
- package/assets/assets/vendor-tanstack-DPXTJtWt.js +1 -0
- package/assets/index.html +6 -2
- package/dist/{chunk-M7MSNUNQ.js → chunk-M4USKXJ4.js} +15 -5
- package/dist/chunk-MYDJ25GO.js +5744 -0
- package/dist/{chunk-4WXY57ET.js → chunk-QIG3TKL4.js} +1581 -753
- package/dist/{chunk-WYBKCDUH.js → chunk-YVP5CTSV.js} +840 -551
- package/dist/cli.js +15 -6
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-ADZRFCGO.js → intelligence-service-TY7IPRST.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -7
- package/assets/assets/index-CPUAzk7n.js +0 -302
- package/dist/chunk-ON545FBK.js +0 -2369
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
loadConfig,
|
|
6
6
|
loadConfigRaw,
|
|
7
7
|
saveConfigPatch
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MYDJ25GO.js";
|
|
9
9
|
import {
|
|
10
10
|
DEFAULT_RUN_HISTORY_LIMIT,
|
|
11
11
|
IntelligenceService,
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
smoothedRunDelta,
|
|
81
81
|
trafficSources,
|
|
82
82
|
usageCounters
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-M4USKXJ4.js";
|
|
84
84
|
import {
|
|
85
85
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
86
86
|
AGENT_PROVIDER_IDS,
|
|
@@ -120,18 +120,43 @@ import {
|
|
|
120
120
|
agentBusy,
|
|
121
121
|
agentMemoryDeleteRequestSchema,
|
|
122
122
|
agentMemoryUpsertRequestSchema,
|
|
123
|
+
agentProvidersResponseDtoSchema,
|
|
124
|
+
auditLogEntrySchema,
|
|
123
125
|
authInvalid,
|
|
124
126
|
authRequired,
|
|
127
|
+
backlinkHistoryEntrySchema,
|
|
128
|
+
backlinkListResponseSchema,
|
|
129
|
+
backlinkSummaryDtoSchema,
|
|
130
|
+
backlinksInstallResultDtoSchema,
|
|
131
|
+
backlinksInstallStatusDtoSchema,
|
|
132
|
+
bingConnectResponseDtoSchema,
|
|
133
|
+
bingCoverageSnapshotDtoSchema,
|
|
134
|
+
bingCoverageSummaryDtoSchema,
|
|
135
|
+
bingIndexingRequestResponseDtoSchema,
|
|
136
|
+
bingKeywordStatsDtoSchema,
|
|
137
|
+
bingSetSiteResponseDtoSchema,
|
|
138
|
+
bingSitesResponseDtoSchema,
|
|
139
|
+
bingStatusDtoSchema,
|
|
140
|
+
bingUrlInspectionDtoSchema,
|
|
125
141
|
brandKeyFromText,
|
|
126
142
|
brandLabelFromDomain,
|
|
127
143
|
buildRunErrorFromMessages,
|
|
128
144
|
categorizeSource,
|
|
129
145
|
categoryLabel,
|
|
146
|
+
ccAvailableReleaseSchema,
|
|
147
|
+
ccCachedReleaseSchema,
|
|
148
|
+
ccReleaseSyncDtoSchema,
|
|
149
|
+
cdpStatusDtoSchema,
|
|
130
150
|
citationStateSchema,
|
|
131
151
|
citationStateToCited,
|
|
152
|
+
citationVisibilityResponseSchema,
|
|
132
153
|
clusterByCosine,
|
|
133
154
|
competitorBatchRequestSchema,
|
|
155
|
+
competitorDtoSchema,
|
|
134
156
|
contentActionLabel,
|
|
157
|
+
contentGapsResponseDtoSchema,
|
|
158
|
+
contentSourcesResponseDtoSchema,
|
|
159
|
+
contentTargetsResponseDtoSchema,
|
|
135
160
|
dedupeReportActions,
|
|
136
161
|
dedupeReportOpportunities,
|
|
137
162
|
deliveryFailed,
|
|
@@ -139,8 +164,13 @@ import {
|
|
|
139
164
|
deltaTone,
|
|
140
165
|
determineAnswerMentioned,
|
|
141
166
|
discoveryBucketSchema,
|
|
167
|
+
discoveryPromotePreviewSchema,
|
|
142
168
|
discoveryPromoteRequestSchema,
|
|
169
|
+
discoveryPromoteResultSchema,
|
|
143
170
|
discoveryRunRequestSchema,
|
|
171
|
+
discoverySessionDetailDtoSchema,
|
|
172
|
+
discoverySessionDtoSchema,
|
|
173
|
+
doctorReportSchema,
|
|
144
174
|
effectiveBrandNames,
|
|
145
175
|
effectiveDomains,
|
|
146
176
|
emptyCitationVisibility,
|
|
@@ -152,12 +182,29 @@ import {
|
|
|
152
182
|
formatIsoDate,
|
|
153
183
|
formatNumber,
|
|
154
184
|
formatRatio,
|
|
185
|
+
ga4AiReferralHistoryEntrySchema,
|
|
186
|
+
ga4SessionHistoryEntrySchema,
|
|
187
|
+
ga4SocialReferralHistoryEntrySchema,
|
|
188
|
+
ga4StatusDtoSchema,
|
|
189
|
+
ga4SyncResponseDtoSchema,
|
|
155
190
|
getProviderLocationHandling,
|
|
191
|
+
googleConnectionDtoSchema,
|
|
192
|
+
gscCoverageSnapshotDtoSchema,
|
|
193
|
+
gscCoverageSummaryDtoSchema,
|
|
194
|
+
gscDeindexedRowSchema,
|
|
195
|
+
gscPerformanceDailyDtoSchema,
|
|
196
|
+
gscSearchDataDtoSchema,
|
|
197
|
+
gscSiteListResponseDtoSchema,
|
|
198
|
+
gscSitemapListResponseDtoSchema,
|
|
199
|
+
gscUrlInspectionDtoSchema,
|
|
156
200
|
hasLocationLabel,
|
|
201
|
+
indexingRequestResponseDtoSchema,
|
|
157
202
|
internalError,
|
|
158
203
|
isAgentProviderId,
|
|
159
204
|
isBrowserProvider,
|
|
205
|
+
keywordDtoSchema,
|
|
160
206
|
keywordGenerateRequestSchema,
|
|
207
|
+
latestProjectRunDtoSchema,
|
|
161
208
|
locationContextSchema,
|
|
162
209
|
mentionStateFromAnswerMentioned,
|
|
163
210
|
missingDependency,
|
|
@@ -166,12 +213,16 @@ import {
|
|
|
166
213
|
normalizeUrlPath,
|
|
167
214
|
notFound,
|
|
168
215
|
notImplemented,
|
|
216
|
+
notificationDtoSchema,
|
|
169
217
|
parseRunError,
|
|
170
218
|
parseWindow,
|
|
171
219
|
pickClusterRepresentative,
|
|
172
220
|
projectConfigSchema,
|
|
221
|
+
projectDtoSchema,
|
|
222
|
+
projectReportDtoSchema,
|
|
173
223
|
projectUpsertRequestSchema,
|
|
174
224
|
providerError,
|
|
225
|
+
queryDtoSchema,
|
|
175
226
|
queryGenerateRequestSchema,
|
|
176
227
|
registrableDomain,
|
|
177
228
|
reportActionCategoryLabel,
|
|
@@ -182,22 +233,47 @@ import {
|
|
|
182
233
|
resolveConfigSpecQueries,
|
|
183
234
|
resolveLocations,
|
|
184
235
|
resolveSnapshotRequestQueries,
|
|
236
|
+
runDetailDtoSchema,
|
|
237
|
+
runDtoSchema,
|
|
185
238
|
runInProgress,
|
|
186
239
|
runNotCancellable,
|
|
187
240
|
runTriggerRequestSchema,
|
|
188
241
|
schedulableRunKindSchema,
|
|
242
|
+
scheduleDtoSchema,
|
|
189
243
|
scheduleUpsertRequestSchema,
|
|
190
244
|
serializeRunError,
|
|
245
|
+
settingsDtoSchema,
|
|
246
|
+
snapshotDiffResponseSchema,
|
|
247
|
+
snapshotListResponseSchema,
|
|
248
|
+
snapshotReportSchema,
|
|
191
249
|
snapshotRequestSchema,
|
|
192
250
|
summarizeCheckResults,
|
|
251
|
+
trafficBackfillResponseSchema,
|
|
193
252
|
trafficConnectVercelRequestSchema,
|
|
194
253
|
trafficConnectWordpressRequestSchema,
|
|
254
|
+
trafficEventsResponseSchema,
|
|
255
|
+
trafficSourceDetailDtoSchema,
|
|
256
|
+
trafficSourceDtoSchema,
|
|
257
|
+
trafficSourceListResponseSchema,
|
|
258
|
+
trafficStatusResponseSchema,
|
|
259
|
+
trafficSyncResponseSchema,
|
|
195
260
|
unsupportedKind,
|
|
196
261
|
validationError,
|
|
197
262
|
visibilityStateFromAnswerMentioned,
|
|
198
263
|
windowCutoff,
|
|
199
|
-
|
|
200
|
-
|
|
264
|
+
wordpressAuditPageDtoSchema,
|
|
265
|
+
wordpressBulkMetaResultDtoSchema,
|
|
266
|
+
wordpressDiffDtoSchema,
|
|
267
|
+
wordpressEnvSchema,
|
|
268
|
+
wordpressManualAssistDtoSchema,
|
|
269
|
+
wordpressOnboardResultDtoSchema,
|
|
270
|
+
wordpressPageDetailDtoSchema,
|
|
271
|
+
wordpressPageSummaryDtoSchema,
|
|
272
|
+
wordpressSchemaBlockDtoSchema,
|
|
273
|
+
wordpressSchemaDeployResultDtoSchema,
|
|
274
|
+
wordpressSchemaStatusResultDtoSchema,
|
|
275
|
+
wordpressStatusDtoSchema
|
|
276
|
+
} from "./chunk-QIG3TKL4.js";
|
|
201
277
|
|
|
202
278
|
// src/telemetry.ts
|
|
203
279
|
import crypto from "crypto";
|
|
@@ -563,7 +639,10 @@ import { eq as eq3, sql as sql2 } from "drizzle-orm";
|
|
|
563
639
|
|
|
564
640
|
// ../api-routes/src/helpers.ts
|
|
565
641
|
import crypto3 from "crypto";
|
|
566
|
-
import { eq as eq2, sql } from "drizzle-orm";
|
|
642
|
+
import { eq as eq2, ne, sql } from "drizzle-orm";
|
|
643
|
+
function notProbeRun() {
|
|
644
|
+
return ne(runs.trigger, RunTriggers.probe);
|
|
645
|
+
}
|
|
567
646
|
function resolveProject(db, name) {
|
|
568
647
|
const project = db.select().from(projects).where(eq2(projects.name, name)).get();
|
|
569
648
|
if (!project) {
|
|
@@ -2266,7 +2345,7 @@ function normalizeCompetitorList2(domains) {
|
|
|
2266
2345
|
}
|
|
2267
2346
|
|
|
2268
2347
|
// ../api-routes/src/history.ts
|
|
2269
|
-
import { eq as eq9, desc as desc2, inArray as inArray2 } from "drizzle-orm";
|
|
2348
|
+
import { and as and4, eq as eq9, desc as desc2, inArray as inArray2 } from "drizzle-orm";
|
|
2270
2349
|
|
|
2271
2350
|
// ../api-routes/src/notification-redaction.ts
|
|
2272
2351
|
var REDACTED_URL = {
|
|
@@ -2323,7 +2402,7 @@ async function historyRoutes(app) {
|
|
|
2323
2402
|
const project = resolveProject(app.db, request.params.name);
|
|
2324
2403
|
const limit = parseInt(request.query.limit ?? "50", 10);
|
|
2325
2404
|
const offset = parseInt(request.query.offset ?? "0", 10);
|
|
2326
|
-
const projectRuns = app.db.select({ id: runs.id }).from(runs).where(eq9(runs.projectId, project.id)).all();
|
|
2405
|
+
const projectRuns = app.db.select({ id: runs.id }).from(runs).where(and4(eq9(runs.projectId, project.id), notProbeRun())).all();
|
|
2327
2406
|
if (projectRuns.length === 0) {
|
|
2328
2407
|
return reply.send({ snapshots: [], total: 0 });
|
|
2329
2408
|
}
|
|
@@ -2372,7 +2451,7 @@ async function historyRoutes(app) {
|
|
|
2372
2451
|
app.get("/projects/:name/timeline", async (request, reply) => {
|
|
2373
2452
|
const project = resolveProject(app.db, request.params.name);
|
|
2374
2453
|
const projectQueries = app.db.select().from(queries).where(eq9(queries.projectId, project.id)).all();
|
|
2375
|
-
const projectRuns = app.db.select().from(runs).where(eq9(runs.projectId, project.id)).orderBy(runs.createdAt).all();
|
|
2454
|
+
const projectRuns = app.db.select().from(runs).where(and4(eq9(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all();
|
|
2376
2455
|
if (projectRuns.length === 0 || projectQueries.length === 0) {
|
|
2377
2456
|
return reply.send([]);
|
|
2378
2457
|
}
|
|
@@ -2557,13 +2636,13 @@ function formatAuditEntry(row) {
|
|
|
2557
2636
|
}
|
|
2558
2637
|
|
|
2559
2638
|
// ../api-routes/src/analytics.ts
|
|
2560
|
-
import { eq as eq10, desc as desc3, inArray as inArray3 } from "drizzle-orm";
|
|
2639
|
+
import { and as and5, eq as eq10, desc as desc3, inArray as inArray3 } from "drizzle-orm";
|
|
2561
2640
|
async function analyticsRoutes(app) {
|
|
2562
2641
|
app.get("/projects/:name/analytics/metrics", async (request, reply) => {
|
|
2563
2642
|
const project = resolveProject(app.db, request.params.name);
|
|
2564
2643
|
const window = parseWindow(request.query.window);
|
|
2565
2644
|
const cutoff = windowCutoff(window);
|
|
2566
|
-
const projectRuns = app.db.select().from(runs).where(eq10(runs.projectId, project.id)).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
|
|
2645
|
+
const projectRuns = app.db.select().from(runs).where(and5(eq10(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
|
|
2567
2646
|
if (projectRuns.length === 0) {
|
|
2568
2647
|
return reply.send({
|
|
2569
2648
|
window,
|
|
@@ -2611,14 +2690,14 @@ async function analyticsRoutes(app) {
|
|
|
2611
2690
|
const project = resolveProject(app.db, request.params.name);
|
|
2612
2691
|
const window = parseWindow(request.query.window);
|
|
2613
2692
|
const cutoff = windowCutoff(window);
|
|
2614
|
-
const completedRuns = app.db.select().from(runs).where(eq10(runs.projectId, project.id)).orderBy(desc3(runs.createdAt), desc3(runs.id)).all().filter((r) => r.status === "completed" || r.status === "partial");
|
|
2693
|
+
const completedRuns = app.db.select().from(runs).where(and5(eq10(runs.projectId, project.id), notProbeRun())).orderBy(desc3(runs.createdAt), desc3(runs.id)).all().filter((r) => r.status === "completed" || r.status === "partial");
|
|
2615
2694
|
const latestGroup = groupRunsByCreatedAt(completedRuns)[0] ?? [];
|
|
2616
2695
|
const latestGroupRunIds = latestGroup.map((r) => r.id);
|
|
2617
2696
|
const latestRun = pickGroupRepresentative(latestGroup);
|
|
2618
2697
|
if (!latestRun) {
|
|
2619
2698
|
return reply.send({ cited: [], gap: [], uncited: [], mentionedQueries: [], mentionGap: [], notMentioned: [], runId: "", window });
|
|
2620
2699
|
}
|
|
2621
|
-
const windowRuns = app.db.select().from(runs).where(eq10(runs.projectId, project.id)).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
|
|
2700
|
+
const windowRuns = app.db.select().from(runs).where(and5(eq10(runs.projectId, project.id), notProbeRun())).orderBy(runs.createdAt).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
|
|
2622
2701
|
const windowRunIds = windowRuns.map((r) => r.id);
|
|
2623
2702
|
const runIdToCreatedAt = new Map(windowRuns.map((r) => [r.id, r.createdAt]));
|
|
2624
2703
|
const consistencyMap = /* @__PURE__ */ new Map();
|
|
@@ -2734,7 +2813,7 @@ async function analyticsRoutes(app) {
|
|
|
2734
2813
|
const project = resolveProject(app.db, request.params.name);
|
|
2735
2814
|
const window = parseWindow(request.query.window);
|
|
2736
2815
|
const cutoff = windowCutoff(window);
|
|
2737
|
-
const windowRuns = app.db.select().from(runs).where(eq10(runs.projectId, project.id)).orderBy(desc3(runs.createdAt), desc3(runs.id)).all().filter((r) => r.status === "completed" || r.status === "partial").filter((r) => !cutoff || r.createdAt >= cutoff);
|
|
2816
|
+
const windowRuns = app.db.select().from(runs).where(and5(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);
|
|
2738
2817
|
if (windowRuns.length === 0) {
|
|
2739
2818
|
return reply.send({ overall: [], byQuery: {}, runId: "", window });
|
|
2740
2819
|
}
|
|
@@ -2898,7 +2977,7 @@ function buildCategoryCounts(counts) {
|
|
|
2898
2977
|
}
|
|
2899
2978
|
|
|
2900
2979
|
// ../api-routes/src/intelligence.ts
|
|
2901
|
-
import { eq as eq11, desc as desc4, and as
|
|
2980
|
+
import { eq as eq11, desc as desc4, and as and6, inArray as inArray4 } from "drizzle-orm";
|
|
2902
2981
|
function emptyHealthSnapshot(projectId) {
|
|
2903
2982
|
return {
|
|
2904
2983
|
id: `no-data:${projectId}`,
|
|
@@ -2987,7 +3066,7 @@ async function intelligenceRoutes(app) {
|
|
|
2987
3066
|
if (request.query.runId) {
|
|
2988
3067
|
conditions.push(eq11(insights.runId, request.query.runId));
|
|
2989
3068
|
}
|
|
2990
|
-
const rows = app.db.select().from(insights).where(conditions.length === 1 ? conditions[0] :
|
|
3069
|
+
const rows = app.db.select().from(insights).where(conditions.length === 1 ? conditions[0] : and6(...conditions)).orderBy(desc4(insights.createdAt)).all();
|
|
2991
3070
|
const showDismissed = request.query.dismissed === "true";
|
|
2992
3071
|
const result = rows.filter((r) => showDismissed || !r.dismissed).map(mapInsightRow);
|
|
2993
3072
|
return reply.send(result);
|
|
@@ -3011,15 +3090,18 @@ async function intelligenceRoutes(app) {
|
|
|
3011
3090
|
});
|
|
3012
3091
|
app.get("/projects/:name/health/latest", async (request, reply) => {
|
|
3013
3092
|
const project = resolveProject(app.db, request.params.name);
|
|
3014
|
-
const projectVisRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(
|
|
3093
|
+
const projectVisRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(and6(
|
|
3015
3094
|
eq11(runs.projectId, project.id),
|
|
3016
3095
|
eq11(runs.kind, RunKinds["answer-visibility"]),
|
|
3017
|
-
inArray4(runs.status, [RunStatuses.completed, RunStatuses.partial])
|
|
3096
|
+
inArray4(runs.status, [RunStatuses.completed, RunStatuses.partial]),
|
|
3097
|
+
// Health-latest is the dashboard headline; probe runs must not
|
|
3098
|
+
// displace the most recent real visibility sweep.
|
|
3099
|
+
notProbeRun()
|
|
3018
3100
|
)).orderBy(desc4(runs.createdAt), desc4(runs.id)).all();
|
|
3019
3101
|
const latestGroup = groupRunsByCreatedAt(projectVisRuns)[0] ?? [];
|
|
3020
3102
|
const latestGroupRunIds = latestGroup.map((r) => r.id);
|
|
3021
3103
|
if (latestGroupRunIds.length > 0) {
|
|
3022
|
-
const groupRows = app.db.select().from(healthSnapshots).where(
|
|
3104
|
+
const groupRows = app.db.select().from(healthSnapshots).where(and6(
|
|
3023
3105
|
eq11(healthSnapshots.projectId, project.id),
|
|
3024
3106
|
inArray4(healthSnapshots.runId, latestGroupRunIds)
|
|
3025
3107
|
)).all();
|
|
@@ -3043,7 +3125,7 @@ async function intelligenceRoutes(app) {
|
|
|
3043
3125
|
}
|
|
3044
3126
|
|
|
3045
3127
|
// ../api-routes/src/report.ts
|
|
3046
|
-
import { and as
|
|
3128
|
+
import { and as and8, desc as desc6, eq as eq13, gte, inArray as inArray6, lt, lte, ne as ne2, or as or3, sql as sql5 } from "drizzle-orm";
|
|
3047
3129
|
|
|
3048
3130
|
// ../api-routes/src/report-renderer.ts
|
|
3049
3131
|
var COLORS = {
|
|
@@ -5283,7 +5365,7 @@ function renderReportHtml(report, opts = {}) {
|
|
|
5283
5365
|
}
|
|
5284
5366
|
|
|
5285
5367
|
// ../api-routes/src/content-data.ts
|
|
5286
|
-
import { and as
|
|
5368
|
+
import { and as and7, eq as eq12, desc as desc5, inArray as inArray5 } from "drizzle-orm";
|
|
5287
5369
|
var RECENT_RUNS_WINDOW = 5;
|
|
5288
5370
|
function loadOrchestratorInput(db, project, locationFilter = void 0) {
|
|
5289
5371
|
const projectId = project.id;
|
|
@@ -5407,13 +5489,16 @@ function listCompetitorDomains(db, projectId) {
|
|
|
5407
5489
|
}
|
|
5408
5490
|
function listRecentAnswerVisibilityRunIds(db, projectId, limit, locationFilter) {
|
|
5409
5491
|
const rows = db.select({ id: runs.id, location: runs.location }).from(runs).where(
|
|
5410
|
-
|
|
5492
|
+
and7(
|
|
5411
5493
|
eq12(runs.projectId, projectId),
|
|
5412
5494
|
eq12(runs.kind, RunKinds["answer-visibility"]),
|
|
5413
5495
|
// Queued/running/failed/cancelled runs may have partial or no
|
|
5414
5496
|
// snapshots; including them risks pointing latestRunId at a run with
|
|
5415
5497
|
// no usable evidence.
|
|
5416
|
-
inArray5(runs.status, [RunStatuses.completed, RunStatuses.partial])
|
|
5498
|
+
inArray5(runs.status, [RunStatuses.completed, RunStatuses.partial]),
|
|
5499
|
+
// Probe runs are operator/agent test runs; they must not poison the
|
|
5500
|
+
// recent-runs window the content engine uses to recommend actions.
|
|
5501
|
+
notProbeRun()
|
|
5417
5502
|
)
|
|
5418
5503
|
).orderBy(desc5(runs.createdAt)).all();
|
|
5419
5504
|
const filtered = locationFilter === void 0 ? rows : rows.filter((r) => (r.location ?? null) === locationFilter);
|
|
@@ -5774,7 +5859,7 @@ function buildGscSection(db, projectId, projectBrandNames, canonicalDomain, trac
|
|
|
5774
5859
|
}
|
|
5775
5860
|
function buildGaSection(db, projectId) {
|
|
5776
5861
|
const windowSummary = db.select().from(gaTrafficWindowSummaries).where(
|
|
5777
|
-
|
|
5862
|
+
and8(
|
|
5778
5863
|
eq13(gaTrafficWindowSummaries.projectId, projectId),
|
|
5779
5864
|
eq13(gaTrafficWindowSummaries.windowKey, "30d")
|
|
5780
5865
|
)
|
|
@@ -5952,9 +6037,9 @@ function nonSubresourceReferralPathCondition() {
|
|
|
5952
6037
|
}
|
|
5953
6038
|
function buildServerActivity(db, projectId) {
|
|
5954
6039
|
const sourceRows = db.select({ id: trafficSources.id }).from(trafficSources).where(
|
|
5955
|
-
|
|
6040
|
+
and8(
|
|
5956
6041
|
eq13(trafficSources.projectId, projectId),
|
|
5957
|
-
|
|
6042
|
+
ne2(trafficSources.status, TrafficSourceStatuses.archived)
|
|
5958
6043
|
)
|
|
5959
6044
|
).all();
|
|
5960
6045
|
if (sourceRows.length === 0) return null;
|
|
@@ -5968,7 +6053,7 @@ function buildServerActivity(db, projectId) {
|
|
|
5968
6053
|
const trendStart = new Date(trendStartMs).toISOString();
|
|
5969
6054
|
const sumVerifiedCrawlers = (windowStartIso, windowEndIso, exclusiveEnd = false) => Number(
|
|
5970
6055
|
db.select({ total: sql5`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
|
|
5971
|
-
|
|
6056
|
+
and8(
|
|
5972
6057
|
eq13(crawlerEventsHourly.projectId, projectId),
|
|
5973
6058
|
eq13(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
|
|
5974
6059
|
gte(crawlerEventsHourly.tsHour, windowStartIso),
|
|
@@ -5978,9 +6063,9 @@ function buildServerActivity(db, projectId) {
|
|
|
5978
6063
|
);
|
|
5979
6064
|
const sumUnverifiedCrawlers = (windowStartIso, windowEndIso, exclusiveEnd = false) => Number(
|
|
5980
6065
|
db.select({ total: sql5`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
|
|
5981
|
-
|
|
6066
|
+
and8(
|
|
5982
6067
|
eq13(crawlerEventsHourly.projectId, projectId),
|
|
5983
|
-
|
|
6068
|
+
ne2(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
|
|
5984
6069
|
gte(crawlerEventsHourly.tsHour, windowStartIso),
|
|
5985
6070
|
exclusiveEnd ? lt(crawlerEventsHourly.tsHour, windowEndIso) : lte(crawlerEventsHourly.tsHour, windowEndIso)
|
|
5986
6071
|
)
|
|
@@ -5988,7 +6073,7 @@ function buildServerActivity(db, projectId) {
|
|
|
5988
6073
|
);
|
|
5989
6074
|
const sumReferrals = (windowStartIso, windowEndIso, exclusiveEnd = false) => Number(
|
|
5990
6075
|
db.select({ total: sql5`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
|
|
5991
|
-
|
|
6076
|
+
and8(
|
|
5992
6077
|
eq13(aiReferralEventsHourly.projectId, projectId),
|
|
5993
6078
|
nonSubresourceReferralPathCondition(),
|
|
5994
6079
|
gte(aiReferralEventsHourly.tsHour, windowStartIso),
|
|
@@ -6007,7 +6092,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6007
6092
|
verificationStatus: crawlerEventsHourly.verificationStatus,
|
|
6008
6093
|
hits: sql5`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
|
|
6009
6094
|
}).from(crawlerEventsHourly).where(
|
|
6010
|
-
|
|
6095
|
+
and8(
|
|
6011
6096
|
eq13(crawlerEventsHourly.projectId, projectId),
|
|
6012
6097
|
gte(crawlerEventsHourly.tsHour, headlineStart),
|
|
6013
6098
|
lte(crawlerEventsHourly.tsHour, headlineEnd)
|
|
@@ -6017,7 +6102,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6017
6102
|
operator: crawlerEventsHourly.operator,
|
|
6018
6103
|
hits: sql5`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
|
|
6019
6104
|
}).from(crawlerEventsHourly).where(
|
|
6020
|
-
|
|
6105
|
+
and8(
|
|
6021
6106
|
eq13(crawlerEventsHourly.projectId, projectId),
|
|
6022
6107
|
eq13(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
|
|
6023
6108
|
gte(crawlerEventsHourly.tsHour, priorStart),
|
|
@@ -6028,7 +6113,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6028
6113
|
operator: aiReferralEventsHourly.operator,
|
|
6029
6114
|
hits: sql5`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`
|
|
6030
6115
|
}).from(aiReferralEventsHourly).where(
|
|
6031
|
-
|
|
6116
|
+
and8(
|
|
6032
6117
|
eq13(aiReferralEventsHourly.projectId, projectId),
|
|
6033
6118
|
nonSubresourceReferralPathCondition(),
|
|
6034
6119
|
gte(aiReferralEventsHourly.tsHour, headlineStart),
|
|
@@ -6069,7 +6154,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6069
6154
|
hits: sql5`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`,
|
|
6070
6155
|
operators: sql5`COUNT(DISTINCT ${crawlerEventsHourly.operator})`
|
|
6071
6156
|
}).from(crawlerEventsHourly).where(
|
|
6072
|
-
|
|
6157
|
+
and8(
|
|
6073
6158
|
eq13(crawlerEventsHourly.projectId, projectId),
|
|
6074
6159
|
eq13(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
|
|
6075
6160
|
gte(crawlerEventsHourly.tsHour, headlineStart),
|
|
@@ -6086,7 +6171,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6086
6171
|
arrivals: sql5`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
|
|
6087
6172
|
landingPaths: sql5`COUNT(DISTINCT ${aiReferralEventsHourly.landingPathNormalized})`
|
|
6088
6173
|
}).from(aiReferralEventsHourly).where(
|
|
6089
|
-
|
|
6174
|
+
and8(
|
|
6090
6175
|
eq13(aiReferralEventsHourly.projectId, projectId),
|
|
6091
6176
|
nonSubresourceReferralPathCondition(),
|
|
6092
6177
|
gte(aiReferralEventsHourly.tsHour, headlineStart),
|
|
@@ -6103,7 +6188,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6103
6188
|
arrivals: sql5`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`,
|
|
6104
6189
|
products: sql5`COUNT(DISTINCT ${aiReferralEventsHourly.product})`
|
|
6105
6190
|
}).from(aiReferralEventsHourly).where(
|
|
6106
|
-
|
|
6191
|
+
and8(
|
|
6107
6192
|
eq13(aiReferralEventsHourly.projectId, projectId),
|
|
6108
6193
|
nonSubresourceReferralPathCondition(),
|
|
6109
6194
|
gte(aiReferralEventsHourly.tsHour, headlineStart),
|
|
@@ -6119,7 +6204,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6119
6204
|
date: sql5`SUBSTR(${crawlerEventsHourly.tsHour}, 1, 10)`,
|
|
6120
6205
|
hits: sql5`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)`
|
|
6121
6206
|
}).from(crawlerEventsHourly).where(
|
|
6122
|
-
|
|
6207
|
+
and8(
|
|
6123
6208
|
eq13(crawlerEventsHourly.projectId, projectId),
|
|
6124
6209
|
eq13(crawlerEventsHourly.verificationStatus, VerificationStatuses.verified),
|
|
6125
6210
|
gte(crawlerEventsHourly.tsHour, trendStart),
|
|
@@ -6130,7 +6215,7 @@ function buildServerActivity(db, projectId) {
|
|
|
6130
6215
|
date: sql5`SUBSTR(${aiReferralEventsHourly.tsHour}, 1, 10)`,
|
|
6131
6216
|
hits: sql5`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)`
|
|
6132
6217
|
}).from(aiReferralEventsHourly).where(
|
|
6133
|
-
|
|
6218
|
+
and8(
|
|
6134
6219
|
eq13(aiReferralEventsHourly.projectId, projectId),
|
|
6135
6220
|
nonSubresourceReferralPathCondition(),
|
|
6136
6221
|
gte(aiReferralEventsHourly.tsHour, trendStart),
|
|
@@ -6205,7 +6290,7 @@ function buildIndexingHealth(db, projectId) {
|
|
|
6205
6290
|
return null;
|
|
6206
6291
|
}
|
|
6207
6292
|
function buildCitationsTrend(db, projectId, queryLookup, locationFilter) {
|
|
6208
|
-
const visibilityRuns = db.select().from(runs).where(
|
|
6293
|
+
const visibilityRuns = db.select().from(runs).where(and8(eq13(runs.projectId, projectId), eq13(runs.kind, RunKinds["answer-visibility"]), notProbeRun())).all().filter((r) => locationFilter === void 0 || (r.location ?? null) === locationFilter);
|
|
6209
6294
|
const totalQueries = queryLookup.byId.size;
|
|
6210
6295
|
const points = [];
|
|
6211
6296
|
for (const run of visibilityRuns) {
|
|
@@ -6251,14 +6336,15 @@ function buildCitationsTrend(db, projectId, queryLookup, locationFilter) {
|
|
|
6251
6336
|
}
|
|
6252
6337
|
function buildInsightList(db, projectId, locationFilter) {
|
|
6253
6338
|
const recentRunIds = db.select({ id: runs.id, location: runs.location }).from(runs).where(
|
|
6254
|
-
|
|
6339
|
+
and8(
|
|
6255
6340
|
eq13(runs.projectId, projectId),
|
|
6256
6341
|
eq13(runs.kind, RunKinds["answer-visibility"]),
|
|
6257
|
-
or3(eq13(runs.status, RunStatuses.completed), eq13(runs.status, RunStatuses.partial))
|
|
6342
|
+
or3(eq13(runs.status, RunStatuses.completed), eq13(runs.status, RunStatuses.partial)),
|
|
6343
|
+
notProbeRun()
|
|
6258
6344
|
)
|
|
6259
6345
|
).orderBy(desc6(runs.createdAt)).all().filter((r) => locationFilter === void 0 || (r.location ?? null) === locationFilter).slice(0, INSIGHT_LOOKBACK_RUNS).map((r) => r.id);
|
|
6260
6346
|
if (recentRunIds.length === 0) return [];
|
|
6261
|
-
const rows = db.select().from(insights).where(
|
|
6347
|
+
const rows = db.select().from(insights).where(and8(eq13(insights.projectId, projectId), inArray6(insights.runId, recentRunIds))).orderBy(desc6(insights.createdAt)).all();
|
|
6262
6348
|
const severityRank = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
6263
6349
|
const flat = rows.filter((r) => !r.dismissed).map((r) => {
|
|
6264
6350
|
const recommendation = parseJsonColumn(r.recommendation, null);
|
|
@@ -6803,7 +6889,7 @@ function buildWhatsChanged(input) {
|
|
|
6803
6889
|
function buildProjectReport(db, projectName) {
|
|
6804
6890
|
const project = resolveProject(db, projectName);
|
|
6805
6891
|
const queryLookup = loadQueryLookup(db, project.id);
|
|
6806
|
-
const allRuns = db.select().from(runs).where(eq13(runs.projectId, project.id)).orderBy(desc6(runs.createdAt), desc6(runs.id)).all();
|
|
6892
|
+
const allRuns = db.select().from(runs).where(and8(eq13(runs.projectId, project.id), notProbeRun())).orderBy(desc6(runs.createdAt), desc6(runs.id)).all();
|
|
6807
6893
|
const visibilityRuns = allRuns.filter((r) => r.kind === RunKinds["answer-visibility"]);
|
|
6808
6894
|
const completedVisRunGroups = groupRunsByCreatedAt(
|
|
6809
6895
|
visibilityRuns.filter((r) => r.status === RunStatuses.completed || r.status === RunStatuses.partial)
|
|
@@ -7031,7 +7117,7 @@ async function reportRoutes(app) {
|
|
|
7031
7117
|
}
|
|
7032
7118
|
|
|
7033
7119
|
// ../api-routes/src/citations.ts
|
|
7034
|
-
import { eq as eq14, inArray as inArray7 } from "drizzle-orm";
|
|
7120
|
+
import { and as and9, eq as eq14, inArray as inArray7 } from "drizzle-orm";
|
|
7035
7121
|
async function citationRoutes(app) {
|
|
7036
7122
|
app.get("/projects/:name/citations/visibility", async (request, reply) => {
|
|
7037
7123
|
const project = resolveProject(app.db, request.params.name);
|
|
@@ -7040,7 +7126,7 @@ async function citationRoutes(app) {
|
|
|
7040
7126
|
if (projectQueries.length === 0) {
|
|
7041
7127
|
return reply.send(emptyCitationVisibility("no-queries"));
|
|
7042
7128
|
}
|
|
7043
|
-
const projectRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(eq14(runs.projectId, project.id)).all();
|
|
7129
|
+
const projectRuns = app.db.select({ id: runs.id, createdAt: runs.createdAt }).from(runs).where(and9(eq14(runs.projectId, project.id), notProbeRun())).all();
|
|
7044
7130
|
if (projectRuns.length === 0) {
|
|
7045
7131
|
return reply.send(emptyCitationVisibility("no-runs-yet"));
|
|
7046
7132
|
}
|
|
@@ -7196,7 +7282,7 @@ function normalizeDomain2(domain) {
|
|
|
7196
7282
|
}
|
|
7197
7283
|
|
|
7198
7284
|
// ../api-routes/src/composites.ts
|
|
7199
|
-
import { eq as eq15, and as
|
|
7285
|
+
import { eq as eq15, and as and10, desc as desc7, sql as sql6, like, or as or4, inArray as inArray8 } from "drizzle-orm";
|
|
7200
7286
|
var TOP_INSIGHT_LIMIT = 5;
|
|
7201
7287
|
var SEARCH_HIT_HARD_LIMIT = 50;
|
|
7202
7288
|
var SEARCH_SNIPPET_RADIUS = 80;
|
|
@@ -7214,7 +7300,7 @@ async function compositeRoutes(app) {
|
|
|
7214
7300
|
const project = resolveProject(app.db, request.params.name);
|
|
7215
7301
|
const filterLocation = (request.query.location ?? "").trim() || null;
|
|
7216
7302
|
const sinceIso = parseSinceFilter(request.query.since);
|
|
7217
|
-
const allRunsRaw = app.db.select().from(runs).where(eq15(runs.projectId, project.id)).orderBy(desc7(runs.createdAt), desc7(runs.id)).all();
|
|
7303
|
+
const allRunsRaw = app.db.select().from(runs).where(and10(eq15(runs.projectId, project.id), notProbeRun())).orderBy(desc7(runs.createdAt), desc7(runs.id)).all();
|
|
7218
7304
|
const allRuns = allRunsRaw.filter((r) => runMatchesFilters(r, filterLocation, sinceIso));
|
|
7219
7305
|
const totalRuns = allRuns.length;
|
|
7220
7306
|
const visibilityRuns = allRuns.filter((r) => r.kind === RunKinds["answer-visibility"]);
|
|
@@ -7343,7 +7429,7 @@ async function compositeRoutes(app) {
|
|
|
7343
7429
|
rawResponse: querySnapshots.rawResponse,
|
|
7344
7430
|
createdAt: querySnapshots.createdAt
|
|
7345
7431
|
}).from(querySnapshots).innerJoin(queries, eq15(querySnapshots.queryId, queries.id)).where(
|
|
7346
|
-
|
|
7432
|
+
and10(
|
|
7347
7433
|
eq15(queries.projectId, project.id),
|
|
7348
7434
|
or4(
|
|
7349
7435
|
sql6`${querySnapshots.answerText} LIKE ${pattern} ESCAPE '\\'`,
|
|
@@ -7354,7 +7440,7 @@ async function compositeRoutes(app) {
|
|
|
7354
7440
|
)
|
|
7355
7441
|
).orderBy(desc7(querySnapshots.createdAt)).limit(limit + 1).all());
|
|
7356
7442
|
const insightMatches = app.db.select().from(insights).where(
|
|
7357
|
-
|
|
7443
|
+
and10(
|
|
7358
7444
|
eq15(insights.projectId, project.id),
|
|
7359
7445
|
or4(
|
|
7360
7446
|
like(insights.title, pattern),
|
|
@@ -7527,7 +7613,7 @@ function buildSuggestedQueriesFromGsc(app, projectId, trackedQueries) {
|
|
|
7527
7613
|
// NULLIF guards the degenerate impressions=0 case (SQLite returns NULL,
|
|
7528
7614
|
// which the JS coerces to 0 — caught by the impression floor anyway).
|
|
7529
7615
|
avgPosition: sql6`COALESCE(SUM(${gscSearchData.position} * ${gscSearchData.impressions}) * 1.0 / NULLIF(SUM(${gscSearchData.impressions}), 0), 0)`
|
|
7530
|
-
}).from(gscSearchData).where(
|
|
7616
|
+
}).from(gscSearchData).where(and10(
|
|
7531
7617
|
eq15(gscSearchData.projectId, projectId),
|
|
7532
7618
|
sql6`${gscSearchData.date} >= ${cutoff}`,
|
|
7533
7619
|
sql6`${gscSearchData.impressions} > 0`
|
|
@@ -7716,6 +7802,7 @@ function formatProject2(row) {
|
|
|
7716
7802
|
language: row.language,
|
|
7717
7803
|
tags: parseJsonColumn(row.tags, []),
|
|
7718
7804
|
labels: parseJsonColumn(row.labels, {}),
|
|
7805
|
+
providers: parseJsonColumn(row.providers, []),
|
|
7719
7806
|
locations: parseJsonColumn(row.locations, []),
|
|
7720
7807
|
defaultLocation: row.defaultLocation,
|
|
7721
7808
|
autoExtractBacklinks: row.autoExtractBacklinks === 1,
|
|
@@ -7862,6 +7949,141 @@ function parseLimitParam(raw) {
|
|
|
7862
7949
|
return parsed;
|
|
7863
7950
|
}
|
|
7864
7951
|
|
|
7952
|
+
// ../api-routes/src/openapi-schemas.ts
|
|
7953
|
+
import { z } from "zod";
|
|
7954
|
+
var SCHEMA_TABLE = {
|
|
7955
|
+
AgentProvidersResponseDto: agentProvidersResponseDtoSchema,
|
|
7956
|
+
AuditLogEntry: auditLogEntrySchema,
|
|
7957
|
+
BacklinkHistoryEntry: backlinkHistoryEntrySchema,
|
|
7958
|
+
BacklinkListResponse: backlinkListResponseSchema,
|
|
7959
|
+
BacklinkSummaryDto: backlinkSummaryDtoSchema,
|
|
7960
|
+
BacklinksInstallResultDto: backlinksInstallResultDtoSchema,
|
|
7961
|
+
BacklinksInstallStatusDto: backlinksInstallStatusDtoSchema,
|
|
7962
|
+
BingConnectResponseDto: bingConnectResponseDtoSchema,
|
|
7963
|
+
BingCoverageSnapshotDto: bingCoverageSnapshotDtoSchema,
|
|
7964
|
+
BingCoverageSummaryDto: bingCoverageSummaryDtoSchema,
|
|
7965
|
+
BingIndexingRequestResponseDto: bingIndexingRequestResponseDtoSchema,
|
|
7966
|
+
BingKeywordStatsDto: bingKeywordStatsDtoSchema,
|
|
7967
|
+
BingSetSiteResponseDto: bingSetSiteResponseDtoSchema,
|
|
7968
|
+
BingSitesResponseDto: bingSitesResponseDtoSchema,
|
|
7969
|
+
BingStatusDto: bingStatusDtoSchema,
|
|
7970
|
+
BingUrlInspectionDto: bingUrlInspectionDtoSchema,
|
|
7971
|
+
CcAvailableRelease: ccAvailableReleaseSchema,
|
|
7972
|
+
CcCachedRelease: ccCachedReleaseSchema,
|
|
7973
|
+
CcReleaseSyncDto: ccReleaseSyncDtoSchema,
|
|
7974
|
+
CdpStatusDto: cdpStatusDtoSchema,
|
|
7975
|
+
CitationVisibilityResponse: citationVisibilityResponseSchema,
|
|
7976
|
+
CompetitorDto: competitorDtoSchema,
|
|
7977
|
+
ContentGapsResponseDto: contentGapsResponseDtoSchema,
|
|
7978
|
+
ContentSourcesResponseDto: contentSourcesResponseDtoSchema,
|
|
7979
|
+
ContentTargetsResponseDto: contentTargetsResponseDtoSchema,
|
|
7980
|
+
DiscoveryPromotePreview: discoveryPromotePreviewSchema,
|
|
7981
|
+
DiscoveryPromoteResult: discoveryPromoteResultSchema,
|
|
7982
|
+
DiscoverySessionDetailDto: discoverySessionDetailDtoSchema,
|
|
7983
|
+
DiscoverySessionDto: discoverySessionDtoSchema,
|
|
7984
|
+
DoctorReportDto: doctorReportSchema,
|
|
7985
|
+
GA4AiReferralHistoryEntry: ga4AiReferralHistoryEntrySchema,
|
|
7986
|
+
GA4SessionHistoryEntry: ga4SessionHistoryEntrySchema,
|
|
7987
|
+
GA4SocialReferralHistoryEntry: ga4SocialReferralHistoryEntrySchema,
|
|
7988
|
+
GA4StatusDto: ga4StatusDtoSchema,
|
|
7989
|
+
GA4SyncResponseDto: ga4SyncResponseDtoSchema,
|
|
7990
|
+
GoogleConnectionDto: googleConnectionDtoSchema,
|
|
7991
|
+
GscCoverageSnapshotDto: gscCoverageSnapshotDtoSchema,
|
|
7992
|
+
GscCoverageSummaryDto: gscCoverageSummaryDtoSchema,
|
|
7993
|
+
GscDeindexedRowDto: gscDeindexedRowSchema,
|
|
7994
|
+
GscPerformanceDailyDto: gscPerformanceDailyDtoSchema,
|
|
7995
|
+
GscSearchDataDto: gscSearchDataDtoSchema,
|
|
7996
|
+
GscSiteListResponseDto: gscSiteListResponseDtoSchema,
|
|
7997
|
+
GscSitemapListResponseDto: gscSitemapListResponseDtoSchema,
|
|
7998
|
+
GscUrlInspectionDto: gscUrlInspectionDtoSchema,
|
|
7999
|
+
IndexingRequestResponseDto: indexingRequestResponseDtoSchema,
|
|
8000
|
+
KeywordDto: keywordDtoSchema,
|
|
8001
|
+
LatestProjectRunDto: latestProjectRunDtoSchema,
|
|
8002
|
+
LocationContext: locationContextSchema,
|
|
8003
|
+
NotificationDto: notificationDtoSchema,
|
|
8004
|
+
ProjectDto: projectDtoSchema,
|
|
8005
|
+
ProjectReportDto: projectReportDtoSchema,
|
|
8006
|
+
QueryDto: queryDtoSchema,
|
|
8007
|
+
RunDetailDto: runDetailDtoSchema,
|
|
8008
|
+
RunDto: runDtoSchema,
|
|
8009
|
+
ScheduleDto: scheduleDtoSchema,
|
|
8010
|
+
SettingsDto: settingsDtoSchema,
|
|
8011
|
+
SnapshotDiffResponse: snapshotDiffResponseSchema,
|
|
8012
|
+
SnapshotListResponse: snapshotListResponseSchema,
|
|
8013
|
+
SnapshotReportDto: snapshotReportSchema,
|
|
8014
|
+
TrafficBackfillResponse: trafficBackfillResponseSchema,
|
|
8015
|
+
TrafficEventsResponse: trafficEventsResponseSchema,
|
|
8016
|
+
TrafficSourceDetailDto: trafficSourceDetailDtoSchema,
|
|
8017
|
+
TrafficSourceDto: trafficSourceDtoSchema,
|
|
8018
|
+
TrafficSourceListResponse: trafficSourceListResponseSchema,
|
|
8019
|
+
TrafficStatusResponse: trafficStatusResponseSchema,
|
|
8020
|
+
TrafficSyncResponse: trafficSyncResponseSchema,
|
|
8021
|
+
WordpressAuditPageDto: wordpressAuditPageDtoSchema,
|
|
8022
|
+
WordpressBulkMetaResultDto: wordpressBulkMetaResultDtoSchema,
|
|
8023
|
+
WordpressDiffDto: wordpressDiffDtoSchema,
|
|
8024
|
+
WordpressManualAssistDto: wordpressManualAssistDtoSchema,
|
|
8025
|
+
WordpressOnboardResultDto: wordpressOnboardResultDtoSchema,
|
|
8026
|
+
WordpressPageDetailDto: wordpressPageDetailDtoSchema,
|
|
8027
|
+
WordpressPageSummaryDto: wordpressPageSummaryDtoSchema,
|
|
8028
|
+
WordpressSchemaBlockDto: wordpressSchemaBlockDtoSchema,
|
|
8029
|
+
WordpressSchemaDeployResultDto: wordpressSchemaDeployResultDtoSchema,
|
|
8030
|
+
WordpressSchemaStatusResultDto: wordpressSchemaStatusResultDtoSchema,
|
|
8031
|
+
WordpressStatusDto: wordpressStatusDtoSchema,
|
|
8032
|
+
// Shared envelope used by every 4xx/5xx response. Defined locally because
|
|
8033
|
+
// the API never returns this from a typed handler — it's emitted by the
|
|
8034
|
+
// global error handler. Codegen consumers reference it through the
|
|
8035
|
+
// ErrorEnvelope ref so error shape is part of the public contract.
|
|
8036
|
+
ErrorEnvelope: z.object({
|
|
8037
|
+
error: z.object({
|
|
8038
|
+
code: z.string(),
|
|
8039
|
+
message: z.string(),
|
|
8040
|
+
details: z.unknown().optional()
|
|
8041
|
+
})
|
|
8042
|
+
})
|
|
8043
|
+
};
|
|
8044
|
+
function buildComponentSchemas() {
|
|
8045
|
+
const out = {};
|
|
8046
|
+
for (const [name, schema] of Object.entries(SCHEMA_TABLE)) {
|
|
8047
|
+
out[name] = z.toJSONSchema(schema, { target: "openapi-3.0" });
|
|
8048
|
+
}
|
|
8049
|
+
return out;
|
|
8050
|
+
}
|
|
8051
|
+
function jsonResponse(description, schemaName) {
|
|
8052
|
+
return {
|
|
8053
|
+
description,
|
|
8054
|
+
content: {
|
|
8055
|
+
"application/json": {
|
|
8056
|
+
schema: { $ref: `#/components/schemas/${schemaName}` }
|
|
8057
|
+
}
|
|
8058
|
+
}
|
|
8059
|
+
};
|
|
8060
|
+
}
|
|
8061
|
+
function jsonArrayResponse(description, schemaName) {
|
|
8062
|
+
return {
|
|
8063
|
+
description,
|
|
8064
|
+
content: {
|
|
8065
|
+
"application/json": {
|
|
8066
|
+
schema: {
|
|
8067
|
+
type: "array",
|
|
8068
|
+
items: { $ref: `#/components/schemas/${schemaName}` }
|
|
8069
|
+
}
|
|
8070
|
+
}
|
|
8071
|
+
}
|
|
8072
|
+
};
|
|
8073
|
+
}
|
|
8074
|
+
function rawJsonResponse(description, schema) {
|
|
8075
|
+
return {
|
|
8076
|
+
description,
|
|
8077
|
+
content: {
|
|
8078
|
+
"application/json": { schema }
|
|
8079
|
+
}
|
|
8080
|
+
};
|
|
8081
|
+
}
|
|
8082
|
+
var looseObjectSchema = { type: "object", additionalProperties: true };
|
|
8083
|
+
function errorResponse(description) {
|
|
8084
|
+
return jsonResponse(description, "ErrorEnvelope");
|
|
8085
|
+
}
|
|
8086
|
+
|
|
7865
8087
|
// ../api-routes/src/openapi.ts
|
|
7866
8088
|
var stringSchema = { type: "string" };
|
|
7867
8089
|
var booleanSchema = { type: "boolean" };
|
|
@@ -7994,7 +8216,7 @@ var routeCatalog = [
|
|
|
7994
8216
|
tags: ["meta"],
|
|
7995
8217
|
auth: false,
|
|
7996
8218
|
responses: {
|
|
7997
|
-
200:
|
|
8219
|
+
200: rawJsonResponse("OpenAPI document.", looseObjectSchema)
|
|
7998
8220
|
}
|
|
7999
8221
|
},
|
|
8000
8222
|
{
|
|
@@ -8029,8 +8251,8 @@ var routeCatalog = [
|
|
|
8029
8251
|
}
|
|
8030
8252
|
},
|
|
8031
8253
|
responses: {
|
|
8032
|
-
200:
|
|
8033
|
-
201:
|
|
8254
|
+
200: jsonResponse("Project updated.", "ProjectDto"),
|
|
8255
|
+
201: jsonResponse("Project created.", "ProjectDto")
|
|
8034
8256
|
}
|
|
8035
8257
|
},
|
|
8036
8258
|
{
|
|
@@ -8039,7 +8261,7 @@ var routeCatalog = [
|
|
|
8039
8261
|
summary: "List projects",
|
|
8040
8262
|
tags: ["projects"],
|
|
8041
8263
|
responses: {
|
|
8042
|
-
200:
|
|
8264
|
+
200: jsonArrayResponse("Projects returned.", "ProjectDto")
|
|
8043
8265
|
}
|
|
8044
8266
|
},
|
|
8045
8267
|
{
|
|
@@ -8049,8 +8271,8 @@ var routeCatalog = [
|
|
|
8049
8271
|
tags: ["projects"],
|
|
8050
8272
|
parameters: [nameParameter],
|
|
8051
8273
|
responses: {
|
|
8052
|
-
200:
|
|
8053
|
-
404:
|
|
8274
|
+
200: jsonResponse("Project returned.", "ProjectDto"),
|
|
8275
|
+
404: errorResponse("Project not found.")
|
|
8054
8276
|
}
|
|
8055
8277
|
},
|
|
8056
8278
|
{
|
|
@@ -8061,7 +8283,7 @@ var routeCatalog = [
|
|
|
8061
8283
|
parameters: [nameParameter],
|
|
8062
8284
|
responses: {
|
|
8063
8285
|
204: { description: "Project deleted." },
|
|
8064
|
-
404:
|
|
8286
|
+
404: errorResponse("Project not found.")
|
|
8065
8287
|
}
|
|
8066
8288
|
},
|
|
8067
8289
|
{
|
|
@@ -8072,8 +8294,9 @@ var routeCatalog = [
|
|
|
8072
8294
|
tags: ["projects"],
|
|
8073
8295
|
parameters: [nameParameter],
|
|
8074
8296
|
responses: {
|
|
8075
|
-
|
|
8076
|
-
|
|
8297
|
+
// TODO: Define `ProjectDeletePreviewDto` Zod schema in contracts and reference here.
|
|
8298
|
+
200: rawJsonResponse("Preview of cascade impact.", looseObjectSchema),
|
|
8299
|
+
404: errorResponse("Project not found.")
|
|
8077
8300
|
}
|
|
8078
8301
|
},
|
|
8079
8302
|
{
|
|
@@ -8091,9 +8314,9 @@ var routeCatalog = [
|
|
|
8091
8314
|
}
|
|
8092
8315
|
},
|
|
8093
8316
|
responses: {
|
|
8094
|
-
201:
|
|
8095
|
-
400:
|
|
8096
|
-
404:
|
|
8317
|
+
201: jsonResponse("Location created.", "LocationContext"),
|
|
8318
|
+
400: errorResponse("Invalid location."),
|
|
8319
|
+
404: errorResponse("Project not found.")
|
|
8097
8320
|
}
|
|
8098
8321
|
},
|
|
8099
8322
|
{
|
|
@@ -8103,8 +8326,9 @@ var routeCatalog = [
|
|
|
8103
8326
|
tags: ["projects"],
|
|
8104
8327
|
parameters: [nameParameter],
|
|
8105
8328
|
responses: {
|
|
8106
|
-
|
|
8107
|
-
|
|
8329
|
+
// TODO: Define `ProjectLocationsResponse` Zod schema (`{ locations: LocationContext[]; defaultLocation: string | null }`) in contracts.
|
|
8330
|
+
200: rawJsonResponse("Locations returned.", looseObjectSchema),
|
|
8331
|
+
404: errorResponse("Project not found.")
|
|
8108
8332
|
}
|
|
8109
8333
|
},
|
|
8110
8334
|
{
|
|
@@ -8115,8 +8339,8 @@ var routeCatalog = [
|
|
|
8115
8339
|
parameters: [nameParameter, locationLabelParameter],
|
|
8116
8340
|
responses: {
|
|
8117
8341
|
204: { description: "Location removed." },
|
|
8118
|
-
400:
|
|
8119
|
-
404:
|
|
8342
|
+
400: errorResponse("Invalid location."),
|
|
8343
|
+
404: errorResponse("Project or location not found.")
|
|
8120
8344
|
}
|
|
8121
8345
|
},
|
|
8122
8346
|
{
|
|
@@ -8140,9 +8364,9 @@ var routeCatalog = [
|
|
|
8140
8364
|
}
|
|
8141
8365
|
},
|
|
8142
8366
|
responses: {
|
|
8143
|
-
200:
|
|
8144
|
-
400:
|
|
8145
|
-
404:
|
|
8367
|
+
200: jsonResponse("Default location updated.", "ProjectDto"),
|
|
8368
|
+
400: errorResponse("Invalid location."),
|
|
8369
|
+
404: errorResponse("Project not found.")
|
|
8146
8370
|
}
|
|
8147
8371
|
},
|
|
8148
8372
|
{
|
|
@@ -8152,8 +8376,9 @@ var routeCatalog = [
|
|
|
8152
8376
|
tags: ["projects"],
|
|
8153
8377
|
parameters: [nameParameter],
|
|
8154
8378
|
responses: {
|
|
8155
|
-
|
|
8156
|
-
|
|
8379
|
+
// TODO: Define an `ExportedProjectConfig` Zod schema in contracts (mirrors canonry.yaml shape).
|
|
8380
|
+
200: rawJsonResponse("Project configuration returned.", looseObjectSchema),
|
|
8381
|
+
404: errorResponse("Project not found.")
|
|
8157
8382
|
}
|
|
8158
8383
|
},
|
|
8159
8384
|
{
|
|
@@ -8163,7 +8388,7 @@ var routeCatalog = [
|
|
|
8163
8388
|
tags: ["queries"],
|
|
8164
8389
|
parameters: [nameParameter],
|
|
8165
8390
|
responses: {
|
|
8166
|
-
200:
|
|
8391
|
+
200: jsonArrayResponse("Queries returned.", "QueryDto")
|
|
8167
8392
|
}
|
|
8168
8393
|
},
|
|
8169
8394
|
{
|
|
@@ -8187,7 +8412,7 @@ var routeCatalog = [
|
|
|
8187
8412
|
}
|
|
8188
8413
|
},
|
|
8189
8414
|
responses: {
|
|
8190
|
-
200:
|
|
8415
|
+
200: jsonArrayResponse("Queries replaced.", "QueryDto")
|
|
8191
8416
|
}
|
|
8192
8417
|
},
|
|
8193
8418
|
{
|
|
@@ -8211,8 +8436,8 @@ var routeCatalog = [
|
|
|
8211
8436
|
}
|
|
8212
8437
|
},
|
|
8213
8438
|
responses: {
|
|
8214
|
-
200:
|
|
8215
|
-
400:
|
|
8439
|
+
200: jsonArrayResponse("Remaining queries returned.", "QueryDto"),
|
|
8440
|
+
400: errorResponse("Invalid query delete request.")
|
|
8216
8441
|
}
|
|
8217
8442
|
},
|
|
8218
8443
|
{
|
|
@@ -8236,7 +8461,7 @@ var routeCatalog = [
|
|
|
8236
8461
|
}
|
|
8237
8462
|
},
|
|
8238
8463
|
responses: {
|
|
8239
|
-
200:
|
|
8464
|
+
200: jsonArrayResponse("Queries appended.", "QueryDto")
|
|
8240
8465
|
}
|
|
8241
8466
|
},
|
|
8242
8467
|
{
|
|
@@ -8261,8 +8486,9 @@ var routeCatalog = [
|
|
|
8261
8486
|
}
|
|
8262
8487
|
},
|
|
8263
8488
|
responses: {
|
|
8264
|
-
|
|
8265
|
-
|
|
8489
|
+
// TODO: Add `QueriesReplacePreviewDto` Zod schema in contracts.
|
|
8490
|
+
200: rawJsonResponse("Replace preview returned.", looseObjectSchema),
|
|
8491
|
+
404: errorResponse("Project not found.")
|
|
8266
8492
|
}
|
|
8267
8493
|
},
|
|
8268
8494
|
{
|
|
@@ -8287,8 +8513,8 @@ var routeCatalog = [
|
|
|
8287
8513
|
}
|
|
8288
8514
|
},
|
|
8289
8515
|
responses: {
|
|
8290
|
-
200: {
|
|
8291
|
-
501:
|
|
8516
|
+
200: rawJsonResponse("Query suggestions returned.", { type: "object", properties: { suggestions: { type: "array", items: { type: "string" } } } }),
|
|
8517
|
+
501: errorResponse("Query generation is not available.")
|
|
8292
8518
|
}
|
|
8293
8519
|
},
|
|
8294
8520
|
{
|
|
@@ -8298,7 +8524,7 @@ var routeCatalog = [
|
|
|
8298
8524
|
tags: ["queries"],
|
|
8299
8525
|
parameters: [nameParameter],
|
|
8300
8526
|
responses: {
|
|
8301
|
-
200:
|
|
8527
|
+
200: jsonArrayResponse("Legacy keyword-shaped queries returned.", "KeywordDto")
|
|
8302
8528
|
}
|
|
8303
8529
|
},
|
|
8304
8530
|
{
|
|
@@ -8322,7 +8548,7 @@ var routeCatalog = [
|
|
|
8322
8548
|
}
|
|
8323
8549
|
},
|
|
8324
8550
|
responses: {
|
|
8325
|
-
200:
|
|
8551
|
+
200: jsonArrayResponse("Legacy keyword-shaped queries replaced.", "KeywordDto")
|
|
8326
8552
|
}
|
|
8327
8553
|
},
|
|
8328
8554
|
{
|
|
@@ -8346,8 +8572,8 @@ var routeCatalog = [
|
|
|
8346
8572
|
}
|
|
8347
8573
|
},
|
|
8348
8574
|
responses: {
|
|
8349
|
-
200:
|
|
8350
|
-
400:
|
|
8575
|
+
200: jsonArrayResponse("Remaining legacy keyword-shaped queries returned.", "KeywordDto"),
|
|
8576
|
+
400: errorResponse("Invalid legacy keyword delete request.")
|
|
8351
8577
|
}
|
|
8352
8578
|
},
|
|
8353
8579
|
{
|
|
@@ -8371,7 +8597,7 @@ var routeCatalog = [
|
|
|
8371
8597
|
}
|
|
8372
8598
|
},
|
|
8373
8599
|
responses: {
|
|
8374
|
-
200:
|
|
8600
|
+
200: jsonArrayResponse("Legacy keyword-shaped queries appended.", "KeywordDto")
|
|
8375
8601
|
}
|
|
8376
8602
|
},
|
|
8377
8603
|
{
|
|
@@ -8396,8 +8622,9 @@ var routeCatalog = [
|
|
|
8396
8622
|
}
|
|
8397
8623
|
},
|
|
8398
8624
|
responses: {
|
|
8399
|
-
|
|
8400
|
-
|
|
8625
|
+
// TODO: Add `KeywordGenerateResponse` Zod schema (`{ suggestions: string[] }`) in contracts.
|
|
8626
|
+
200: rawJsonResponse("Legacy keyword suggestions returned.", looseObjectSchema),
|
|
8627
|
+
501: errorResponse("Legacy keyword generation is not available.")
|
|
8401
8628
|
}
|
|
8402
8629
|
},
|
|
8403
8630
|
{
|
|
@@ -8407,7 +8634,7 @@ var routeCatalog = [
|
|
|
8407
8634
|
tags: ["competitors"],
|
|
8408
8635
|
parameters: [nameParameter],
|
|
8409
8636
|
responses: {
|
|
8410
|
-
200:
|
|
8637
|
+
200: jsonArrayResponse("Competitors returned.", "CompetitorDto")
|
|
8411
8638
|
}
|
|
8412
8639
|
},
|
|
8413
8640
|
{
|
|
@@ -8431,7 +8658,7 @@ var routeCatalog = [
|
|
|
8431
8658
|
}
|
|
8432
8659
|
},
|
|
8433
8660
|
responses: {
|
|
8434
|
-
200:
|
|
8661
|
+
200: jsonArrayResponse("Competitors replaced.", "CompetitorDto")
|
|
8435
8662
|
}
|
|
8436
8663
|
},
|
|
8437
8664
|
{
|
|
@@ -8455,8 +8682,8 @@ var routeCatalog = [
|
|
|
8455
8682
|
}
|
|
8456
8683
|
},
|
|
8457
8684
|
responses: {
|
|
8458
|
-
200:
|
|
8459
|
-
400:
|
|
8685
|
+
200: jsonArrayResponse("Competitors appended.", "CompetitorDto"),
|
|
8686
|
+
400: errorResponse("Invalid competitor append request.")
|
|
8460
8687
|
}
|
|
8461
8688
|
},
|
|
8462
8689
|
{
|
|
@@ -8480,8 +8707,8 @@ var routeCatalog = [
|
|
|
8480
8707
|
}
|
|
8481
8708
|
},
|
|
8482
8709
|
responses: {
|
|
8483
|
-
200:
|
|
8484
|
-
400:
|
|
8710
|
+
200: jsonArrayResponse("Remaining competitors returned.", "CompetitorDto"),
|
|
8711
|
+
400: errorResponse("Invalid competitor delete request.")
|
|
8485
8712
|
}
|
|
8486
8713
|
},
|
|
8487
8714
|
{
|
|
@@ -8509,8 +8736,8 @@ var routeCatalog = [
|
|
|
8509
8736
|
}
|
|
8510
8737
|
},
|
|
8511
8738
|
responses: {
|
|
8512
|
-
201:
|
|
8513
|
-
409:
|
|
8739
|
+
201: jsonResponse("Run queued.", "RunDto"),
|
|
8740
|
+
409: errorResponse("Run already in progress.")
|
|
8514
8741
|
}
|
|
8515
8742
|
},
|
|
8516
8743
|
{
|
|
@@ -8520,7 +8747,7 @@ var routeCatalog = [
|
|
|
8520
8747
|
tags: ["runs"],
|
|
8521
8748
|
parameters: [nameParameter, limitQueryParameter],
|
|
8522
8749
|
responses: {
|
|
8523
|
-
200:
|
|
8750
|
+
200: jsonArrayResponse("Runs returned.", "RunDto")
|
|
8524
8751
|
}
|
|
8525
8752
|
},
|
|
8526
8753
|
{
|
|
@@ -8530,7 +8757,7 @@ var routeCatalog = [
|
|
|
8530
8757
|
tags: ["runs"],
|
|
8531
8758
|
parameters: [nameParameter],
|
|
8532
8759
|
responses: {
|
|
8533
|
-
200:
|
|
8760
|
+
200: jsonResponse("Latest run returned.", "LatestProjectRunDto")
|
|
8534
8761
|
}
|
|
8535
8762
|
},
|
|
8536
8763
|
{
|
|
@@ -8539,7 +8766,7 @@ var routeCatalog = [
|
|
|
8539
8766
|
summary: "List all runs",
|
|
8540
8767
|
tags: ["runs"],
|
|
8541
8768
|
responses: {
|
|
8542
|
-
200:
|
|
8769
|
+
200: jsonArrayResponse("Runs returned.", "RunDto")
|
|
8543
8770
|
}
|
|
8544
8771
|
},
|
|
8545
8772
|
{
|
|
@@ -8561,7 +8788,8 @@ var routeCatalog = [
|
|
|
8561
8788
|
}
|
|
8562
8789
|
},
|
|
8563
8790
|
responses: {
|
|
8564
|
-
|
|
8791
|
+
// TODO: Add `TriggerAllRunsResponse` Zod schema in contracts.
|
|
8792
|
+
207: rawJsonResponse("Run results returned.", looseObjectSchema)
|
|
8565
8793
|
}
|
|
8566
8794
|
},
|
|
8567
8795
|
{
|
|
@@ -8571,8 +8799,8 @@ var routeCatalog = [
|
|
|
8571
8799
|
tags: ["runs"],
|
|
8572
8800
|
parameters: [runIdParameter],
|
|
8573
8801
|
responses: {
|
|
8574
|
-
200:
|
|
8575
|
-
404:
|
|
8802
|
+
200: jsonResponse("Run returned.", "RunDetailDto"),
|
|
8803
|
+
404: errorResponse("Run not found.")
|
|
8576
8804
|
}
|
|
8577
8805
|
},
|
|
8578
8806
|
{
|
|
@@ -8582,9 +8810,9 @@ var routeCatalog = [
|
|
|
8582
8810
|
tags: ["runs"],
|
|
8583
8811
|
parameters: [runIdParameter],
|
|
8584
8812
|
responses: {
|
|
8585
|
-
200:
|
|
8586
|
-
404:
|
|
8587
|
-
409:
|
|
8813
|
+
200: jsonResponse("Run cancelled.", "RunDto"),
|
|
8814
|
+
404: errorResponse("Run not found."),
|
|
8815
|
+
409: errorResponse("Run is not cancellable.")
|
|
8588
8816
|
}
|
|
8589
8817
|
},
|
|
8590
8818
|
{
|
|
@@ -8602,8 +8830,9 @@ var routeCatalog = [
|
|
|
8602
8830
|
}
|
|
8603
8831
|
},
|
|
8604
8832
|
responses: {
|
|
8605
|
-
|
|
8606
|
-
|
|
8833
|
+
// TODO: Add `ApplyResultDto` Zod schema in contracts (single-doc apply result).
|
|
8834
|
+
200: jsonResponse("Config applied.", "ProjectDto"),
|
|
8835
|
+
400: errorResponse("Invalid config.")
|
|
8607
8836
|
}
|
|
8608
8837
|
},
|
|
8609
8838
|
{
|
|
@@ -8613,7 +8842,7 @@ var routeCatalog = [
|
|
|
8613
8842
|
tags: ["history"],
|
|
8614
8843
|
parameters: [nameParameter],
|
|
8615
8844
|
responses: {
|
|
8616
|
-
200:
|
|
8845
|
+
200: jsonArrayResponse("Audit history returned.", "AuditLogEntry")
|
|
8617
8846
|
}
|
|
8618
8847
|
},
|
|
8619
8848
|
{
|
|
@@ -8622,7 +8851,7 @@ var routeCatalog = [
|
|
|
8622
8851
|
summary: "Get global audit history",
|
|
8623
8852
|
tags: ["history"],
|
|
8624
8853
|
responses: {
|
|
8625
|
-
200:
|
|
8854
|
+
200: jsonArrayResponse("Audit history returned.", "AuditLogEntry")
|
|
8626
8855
|
}
|
|
8627
8856
|
},
|
|
8628
8857
|
{
|
|
@@ -8637,7 +8866,7 @@ var routeCatalog = [
|
|
|
8637
8866
|
locationQueryParameter
|
|
8638
8867
|
],
|
|
8639
8868
|
responses: {
|
|
8640
|
-
200:
|
|
8869
|
+
200: jsonResponse("Snapshots returned.", "SnapshotListResponse")
|
|
8641
8870
|
}
|
|
8642
8871
|
},
|
|
8643
8872
|
{
|
|
@@ -8647,7 +8876,8 @@ var routeCatalog = [
|
|
|
8647
8876
|
tags: ["history"],
|
|
8648
8877
|
parameters: [nameParameter, locationQueryParameter],
|
|
8649
8878
|
responses: {
|
|
8650
|
-
|
|
8879
|
+
// TODO: Add `ProjectTimelineDto` Zod schema in contracts.
|
|
8880
|
+
200: rawJsonResponse("Timeline returned.", looseObjectSchema)
|
|
8651
8881
|
}
|
|
8652
8882
|
},
|
|
8653
8883
|
{
|
|
@@ -8657,8 +8887,9 @@ var routeCatalog = [
|
|
|
8657
8887
|
tags: ["analytics"],
|
|
8658
8888
|
parameters: [nameParameter, analyticsWindowParameter],
|
|
8659
8889
|
responses: {
|
|
8660
|
-
|
|
8661
|
-
|
|
8890
|
+
// TODO: Add `BrandMetricsDto` Zod schema in contracts.
|
|
8891
|
+
200: rawJsonResponse("Citation metrics returned.", looseObjectSchema),
|
|
8892
|
+
404: errorResponse("Project not found.")
|
|
8662
8893
|
}
|
|
8663
8894
|
},
|
|
8664
8895
|
{
|
|
@@ -8668,8 +8899,9 @@ var routeCatalog = [
|
|
|
8668
8899
|
tags: ["analytics"],
|
|
8669
8900
|
parameters: [nameParameter, analyticsWindowParameter],
|
|
8670
8901
|
responses: {
|
|
8671
|
-
|
|
8672
|
-
|
|
8902
|
+
// TODO: Add `GapAnalysisDto` Zod schema in contracts.
|
|
8903
|
+
200: rawJsonResponse("Gap analysis returned.", looseObjectSchema),
|
|
8904
|
+
404: errorResponse("Project not found.")
|
|
8673
8905
|
}
|
|
8674
8906
|
},
|
|
8675
8907
|
{
|
|
@@ -8679,8 +8911,9 @@ var routeCatalog = [
|
|
|
8679
8911
|
tags: ["analytics"],
|
|
8680
8912
|
parameters: [nameParameter, analyticsWindowParameter],
|
|
8681
8913
|
responses: {
|
|
8682
|
-
|
|
8683
|
-
|
|
8914
|
+
// TODO: Add `SourceBreakdownDto` Zod schema in contracts.
|
|
8915
|
+
200: rawJsonResponse("Source breakdown returned.", looseObjectSchema),
|
|
8916
|
+
404: errorResponse("Project not found.")
|
|
8684
8917
|
}
|
|
8685
8918
|
},
|
|
8686
8919
|
{
|
|
@@ -8706,8 +8939,8 @@ var routeCatalog = [
|
|
|
8706
8939
|
}
|
|
8707
8940
|
],
|
|
8708
8941
|
responses: {
|
|
8709
|
-
200:
|
|
8710
|
-
400:
|
|
8942
|
+
200: jsonResponse("Diff returned.", "SnapshotDiffResponse"),
|
|
8943
|
+
400: errorResponse("Missing run IDs.")
|
|
8711
8944
|
}
|
|
8712
8945
|
},
|
|
8713
8946
|
{
|
|
@@ -8716,7 +8949,7 @@ var routeCatalog = [
|
|
|
8716
8949
|
summary: "Get provider settings summary",
|
|
8717
8950
|
tags: ["settings"],
|
|
8718
8951
|
responses: {
|
|
8719
|
-
200:
|
|
8952
|
+
200: jsonResponse("Settings returned.", "SettingsDto")
|
|
8720
8953
|
}
|
|
8721
8954
|
},
|
|
8722
8955
|
{
|
|
@@ -8742,9 +8975,10 @@ var routeCatalog = [
|
|
|
8742
8975
|
}
|
|
8743
8976
|
},
|
|
8744
8977
|
responses: {
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8978
|
+
// TODO: Add `ProviderSettingsDto` Zod schema in contracts.
|
|
8979
|
+
200: rawJsonResponse("Provider updated.", looseObjectSchema),
|
|
8980
|
+
400: errorResponse("Invalid provider settings."),
|
|
8981
|
+
501: errorResponse("Provider updates are not supported.")
|
|
8748
8982
|
}
|
|
8749
8983
|
},
|
|
8750
8984
|
{
|
|
@@ -8768,9 +9002,10 @@ var routeCatalog = [
|
|
|
8768
9002
|
}
|
|
8769
9003
|
},
|
|
8770
9004
|
responses: {
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
9005
|
+
// TODO: Add `GoogleSettingsDto` Zod schema in contracts.
|
|
9006
|
+
200: rawJsonResponse("Google settings updated.", looseObjectSchema),
|
|
9007
|
+
400: errorResponse("Invalid Google settings."),
|
|
9008
|
+
501: errorResponse("Google settings updates are not supported.")
|
|
8774
9009
|
}
|
|
8775
9010
|
},
|
|
8776
9011
|
{
|
|
@@ -8796,9 +9031,9 @@ var routeCatalog = [
|
|
|
8796
9031
|
}
|
|
8797
9032
|
},
|
|
8798
9033
|
responses: {
|
|
8799
|
-
200:
|
|
8800
|
-
400:
|
|
8801
|
-
501:
|
|
9034
|
+
200: jsonResponse("Snapshot report returned.", "SnapshotReportDto"),
|
|
9035
|
+
400: errorResponse("Invalid snapshot input."),
|
|
9036
|
+
501: errorResponse("Snapshot reporting is not supported.")
|
|
8802
9037
|
}
|
|
8803
9038
|
},
|
|
8804
9039
|
{
|
|
@@ -8821,9 +9056,10 @@ var routeCatalog = [
|
|
|
8821
9056
|
}
|
|
8822
9057
|
},
|
|
8823
9058
|
responses: {
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
9059
|
+
// TODO: Add `BingSettingsDto` Zod schema in contracts.
|
|
9060
|
+
200: rawJsonResponse("Bing settings updated.", looseObjectSchema),
|
|
9061
|
+
400: errorResponse("Invalid Bing settings."),
|
|
9062
|
+
501: errorResponse("Bing settings updates are not supported.")
|
|
8827
9063
|
}
|
|
8828
9064
|
},
|
|
8829
9065
|
{
|
|
@@ -8847,9 +9083,10 @@ var routeCatalog = [
|
|
|
8847
9083
|
}
|
|
8848
9084
|
},
|
|
8849
9085
|
responses: {
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
9086
|
+
// TODO: Add `CdpEndpointConfigDto` Zod schema in contracts.
|
|
9087
|
+
200: rawJsonResponse("CDP endpoint updated.", looseObjectSchema),
|
|
9088
|
+
400: errorResponse("Invalid CDP settings."),
|
|
9089
|
+
501: errorResponse("CDP updates are not supported.")
|
|
8853
9090
|
}
|
|
8854
9091
|
},
|
|
8855
9092
|
{
|
|
@@ -8878,9 +9115,9 @@ var routeCatalog = [
|
|
|
8878
9115
|
}
|
|
8879
9116
|
},
|
|
8880
9117
|
responses: {
|
|
8881
|
-
200:
|
|
8882
|
-
201:
|
|
8883
|
-
400:
|
|
9118
|
+
200: jsonResponse("Schedule updated.", "ScheduleDto"),
|
|
9119
|
+
201: jsonResponse("Schedule created.", "ScheduleDto"),
|
|
9120
|
+
400: errorResponse("Invalid payload (e.g. sourceId missing for kind=traffic-sync, or providers set for kind=traffic-sync).")
|
|
8884
9121
|
}
|
|
8885
9122
|
},
|
|
8886
9123
|
{
|
|
@@ -8890,8 +9127,8 @@ var routeCatalog = [
|
|
|
8890
9127
|
tags: ["schedules"],
|
|
8891
9128
|
parameters: [nameParameter, scheduleKindQueryParameter],
|
|
8892
9129
|
responses: {
|
|
8893
|
-
200:
|
|
8894
|
-
404:
|
|
9130
|
+
200: jsonResponse("Schedule returned.", "ScheduleDto"),
|
|
9131
|
+
404: errorResponse("Schedule not found.")
|
|
8895
9132
|
}
|
|
8896
9133
|
},
|
|
8897
9134
|
{
|
|
@@ -8902,7 +9139,7 @@ var routeCatalog = [
|
|
|
8902
9139
|
parameters: [nameParameter, scheduleKindQueryParameter],
|
|
8903
9140
|
responses: {
|
|
8904
9141
|
204: { description: "Schedule deleted." },
|
|
8905
|
-
404:
|
|
9142
|
+
404: errorResponse("Schedule not found.")
|
|
8906
9143
|
}
|
|
8907
9144
|
},
|
|
8908
9145
|
{
|
|
@@ -8911,7 +9148,7 @@ var routeCatalog = [
|
|
|
8911
9148
|
summary: "List notification event types",
|
|
8912
9149
|
tags: ["notifications"],
|
|
8913
9150
|
responses: {
|
|
8914
|
-
200:
|
|
9151
|
+
200: rawJsonResponse("Events returned.", { type: "array", items: stringSchema })
|
|
8915
9152
|
}
|
|
8916
9153
|
},
|
|
8917
9154
|
{
|
|
@@ -8937,7 +9174,7 @@ var routeCatalog = [
|
|
|
8937
9174
|
}
|
|
8938
9175
|
},
|
|
8939
9176
|
responses: {
|
|
8940
|
-
201:
|
|
9177
|
+
201: jsonResponse("Notification created.", "NotificationDto")
|
|
8941
9178
|
}
|
|
8942
9179
|
},
|
|
8943
9180
|
{
|
|
@@ -8947,7 +9184,7 @@ var routeCatalog = [
|
|
|
8947
9184
|
tags: ["notifications"],
|
|
8948
9185
|
parameters: [nameParameter],
|
|
8949
9186
|
responses: {
|
|
8950
|
-
200:
|
|
9187
|
+
200: jsonArrayResponse("Notifications returned.", "NotificationDto")
|
|
8951
9188
|
}
|
|
8952
9189
|
},
|
|
8953
9190
|
{
|
|
@@ -8958,7 +9195,7 @@ var routeCatalog = [
|
|
|
8958
9195
|
parameters: [nameParameter, notificationIdParameter],
|
|
8959
9196
|
responses: {
|
|
8960
9197
|
204: { description: "Notification deleted." },
|
|
8961
|
-
404:
|
|
9198
|
+
404: errorResponse("Notification not found.")
|
|
8962
9199
|
}
|
|
8963
9200
|
},
|
|
8964
9201
|
{
|
|
@@ -8968,10 +9205,11 @@ var routeCatalog = [
|
|
|
8968
9205
|
tags: ["notifications"],
|
|
8969
9206
|
parameters: [nameParameter, notificationIdParameter],
|
|
8970
9207
|
responses: {
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
9208
|
+
// TODO: Add `NotificationTestResult` Zod schema in contracts.
|
|
9209
|
+
200: rawJsonResponse("Test notification sent.", looseObjectSchema),
|
|
9210
|
+
400: errorResponse("Stored notification config is invalid."),
|
|
9211
|
+
404: errorResponse("Notification not found."),
|
|
9212
|
+
502: errorResponse("Notification delivery failed.")
|
|
8975
9213
|
}
|
|
8976
9214
|
},
|
|
8977
9215
|
{
|
|
@@ -8980,8 +9218,9 @@ var routeCatalog = [
|
|
|
8980
9218
|
summary: "Get telemetry status",
|
|
8981
9219
|
tags: ["telemetry"],
|
|
8982
9220
|
responses: {
|
|
8983
|
-
|
|
8984
|
-
|
|
9221
|
+
// TODO: Add `TelemetryStatusDto` Zod schema in contracts.
|
|
9222
|
+
200: rawJsonResponse("Telemetry status returned.", looseObjectSchema),
|
|
9223
|
+
501: errorResponse("Telemetry status is not available.")
|
|
8985
9224
|
}
|
|
8986
9225
|
},
|
|
8987
9226
|
{
|
|
@@ -9004,9 +9243,10 @@ var routeCatalog = [
|
|
|
9004
9243
|
}
|
|
9005
9244
|
},
|
|
9006
9245
|
responses: {
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9246
|
+
// TODO: Add `TelemetryStatusDto` Zod schema in contracts.
|
|
9247
|
+
200: rawJsonResponse("Telemetry updated.", looseObjectSchema),
|
|
9248
|
+
400: errorResponse("Invalid telemetry request."),
|
|
9249
|
+
501: errorResponse("Telemetry configuration is not available.")
|
|
9010
9250
|
}
|
|
9011
9251
|
},
|
|
9012
9252
|
{
|
|
@@ -9016,8 +9256,9 @@ var routeCatalog = [
|
|
|
9016
9256
|
tags: ["cdp"],
|
|
9017
9257
|
parameters: [snapshotIdParameter],
|
|
9018
9258
|
responses: {
|
|
9019
|
-
|
|
9020
|
-
|
|
9259
|
+
// Returns image bytes, not JSON. Codegen consumers should treat this as a binary stream.
|
|
9260
|
+
200: { description: "Screenshot returned.", content: { "image/png": { schema: { type: "string", format: "binary" } } } },
|
|
9261
|
+
404: errorResponse("Screenshot not found.")
|
|
9021
9262
|
}
|
|
9022
9263
|
},
|
|
9023
9264
|
{
|
|
@@ -9026,8 +9267,8 @@ var routeCatalog = [
|
|
|
9026
9267
|
summary: "Get CDP connection status",
|
|
9027
9268
|
tags: ["cdp"],
|
|
9028
9269
|
responses: {
|
|
9029
|
-
200:
|
|
9030
|
-
501:
|
|
9270
|
+
200: jsonResponse("CDP status returned.", "CdpStatusDto"),
|
|
9271
|
+
501: errorResponse("CDP is not configured.")
|
|
9031
9272
|
}
|
|
9032
9273
|
},
|
|
9033
9274
|
{
|
|
@@ -9051,9 +9292,10 @@ var routeCatalog = [
|
|
|
9051
9292
|
}
|
|
9052
9293
|
},
|
|
9053
9294
|
responses: {
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9295
|
+
// TODO: Add `CdpScreenshotResultDto` Zod schema in contracts.
|
|
9296
|
+
200: rawJsonResponse("CDP screenshot results returned.", looseObjectSchema),
|
|
9297
|
+
400: errorResponse("Invalid CDP screenshot request."),
|
|
9298
|
+
501: errorResponse("CDP screenshot support is not available.")
|
|
9057
9299
|
}
|
|
9058
9300
|
},
|
|
9059
9301
|
{
|
|
@@ -9063,8 +9305,9 @@ var routeCatalog = [
|
|
|
9063
9305
|
tags: ["cdp", "runs"],
|
|
9064
9306
|
parameters: [nameParameter, projectRunIdParameter],
|
|
9065
9307
|
responses: {
|
|
9066
|
-
|
|
9067
|
-
|
|
9308
|
+
// TODO: Add `BrowserDiffDto` Zod schema in contracts.
|
|
9309
|
+
200: rawJsonResponse("Browser diff returned.", looseObjectSchema),
|
|
9310
|
+
404: errorResponse("Project or run not found.")
|
|
9068
9311
|
}
|
|
9069
9312
|
},
|
|
9070
9313
|
{
|
|
@@ -9079,9 +9322,9 @@ var routeCatalog = [
|
|
|
9079
9322
|
{ name: "error", in: "query", description: "OAuth error code.", schema: stringSchema }
|
|
9080
9323
|
],
|
|
9081
9324
|
responses: {
|
|
9082
|
-
200:
|
|
9083
|
-
400:
|
|
9084
|
-
500:
|
|
9325
|
+
200: rawJsonResponse("OAuth callback handled.", { type: "object", properties: { status: { type: "string" } } }),
|
|
9326
|
+
400: errorResponse("Invalid callback request."),
|
|
9327
|
+
500: errorResponse("OAuth configuration is incomplete.")
|
|
9085
9328
|
}
|
|
9086
9329
|
},
|
|
9087
9330
|
{
|
|
@@ -9097,9 +9340,9 @@ var routeCatalog = [
|
|
|
9097
9340
|
{ name: "error", in: "query", description: "OAuth error code.", schema: stringSchema }
|
|
9098
9341
|
],
|
|
9099
9342
|
responses: {
|
|
9100
|
-
200:
|
|
9101
|
-
400:
|
|
9102
|
-
500:
|
|
9343
|
+
200: rawJsonResponse("OAuth callback handled.", { type: "object", properties: { status: { type: "string" } } }),
|
|
9344
|
+
400: errorResponse("Invalid callback request."),
|
|
9345
|
+
500: errorResponse("OAuth configuration is incomplete.")
|
|
9103
9346
|
}
|
|
9104
9347
|
},
|
|
9105
9348
|
{
|
|
@@ -9109,8 +9352,8 @@ var routeCatalog = [
|
|
|
9109
9352
|
tags: ["google"],
|
|
9110
9353
|
parameters: [nameParameter],
|
|
9111
9354
|
responses: {
|
|
9112
|
-
200:
|
|
9113
|
-
404:
|
|
9355
|
+
200: jsonArrayResponse("Google connections returned.", "GoogleConnectionDto"),
|
|
9356
|
+
404: errorResponse("Project not found.")
|
|
9114
9357
|
}
|
|
9115
9358
|
},
|
|
9116
9359
|
{
|
|
@@ -9136,8 +9379,8 @@ var routeCatalog = [
|
|
|
9136
9379
|
}
|
|
9137
9380
|
},
|
|
9138
9381
|
responses: {
|
|
9139
|
-
200:
|
|
9140
|
-
400:
|
|
9382
|
+
200: rawJsonResponse("Google auth URL returned.", { type: "object", properties: { url: { type: "string" } } }),
|
|
9383
|
+
400: errorResponse("Invalid Google connection request.")
|
|
9141
9384
|
}
|
|
9142
9385
|
},
|
|
9143
9386
|
{
|
|
@@ -9148,7 +9391,7 @@ var routeCatalog = [
|
|
|
9148
9391
|
parameters: [nameParameter, googleTypeParameter],
|
|
9149
9392
|
responses: {
|
|
9150
9393
|
204: { description: "Google connection deleted." },
|
|
9151
|
-
404:
|
|
9394
|
+
404: errorResponse("Project or connection not found.")
|
|
9152
9395
|
}
|
|
9153
9396
|
},
|
|
9154
9397
|
{
|
|
@@ -9158,9 +9401,9 @@ var routeCatalog = [
|
|
|
9158
9401
|
tags: ["google"],
|
|
9159
9402
|
parameters: [nameParameter],
|
|
9160
9403
|
responses: {
|
|
9161
|
-
200:
|
|
9162
|
-
400:
|
|
9163
|
-
404:
|
|
9404
|
+
200: jsonResponse("Google properties returned.", "GscSiteListResponseDto"),
|
|
9405
|
+
400: errorResponse("Google OAuth is not configured."),
|
|
9406
|
+
404: errorResponse("Project not found.")
|
|
9164
9407
|
}
|
|
9165
9408
|
},
|
|
9166
9409
|
{
|
|
@@ -9184,9 +9427,9 @@ var routeCatalog = [
|
|
|
9184
9427
|
}
|
|
9185
9428
|
},
|
|
9186
9429
|
responses: {
|
|
9187
|
-
200:
|
|
9188
|
-
400:
|
|
9189
|
-
404:
|
|
9430
|
+
200: jsonResponse("Google property updated.", "GoogleConnectionDto"),
|
|
9431
|
+
400: errorResponse("Invalid property request."),
|
|
9432
|
+
404: errorResponse("Project or connection not found.")
|
|
9190
9433
|
}
|
|
9191
9434
|
},
|
|
9192
9435
|
{
|
|
@@ -9210,9 +9453,9 @@ var routeCatalog = [
|
|
|
9210
9453
|
}
|
|
9211
9454
|
},
|
|
9212
9455
|
responses: {
|
|
9213
|
-
200:
|
|
9214
|
-
400:
|
|
9215
|
-
404:
|
|
9456
|
+
200: jsonResponse("Google sitemap updated.", "GoogleConnectionDto"),
|
|
9457
|
+
400: errorResponse("Invalid sitemap request."),
|
|
9458
|
+
404: errorResponse("Project or connection not found.")
|
|
9216
9459
|
}
|
|
9217
9460
|
},
|
|
9218
9461
|
{
|
|
@@ -9235,9 +9478,9 @@ var routeCatalog = [
|
|
|
9235
9478
|
}
|
|
9236
9479
|
},
|
|
9237
9480
|
responses: {
|
|
9238
|
-
200:
|
|
9239
|
-
400:
|
|
9240
|
-
404:
|
|
9481
|
+
200: jsonResponse("GSC sync run returned.", "RunDto"),
|
|
9482
|
+
400: errorResponse("Invalid GSC sync request."),
|
|
9483
|
+
404: errorResponse("Project or connection not found.")
|
|
9241
9484
|
}
|
|
9242
9485
|
},
|
|
9243
9486
|
{
|
|
@@ -9256,8 +9499,11 @@ var routeCatalog = [
|
|
|
9256
9499
|
analyticsWindowParameter
|
|
9257
9500
|
],
|
|
9258
9501
|
responses: {
|
|
9259
|
-
|
|
9260
|
-
|
|
9502
|
+
// Handler returns an array of GscSearchDataDto rows (web's
|
|
9503
|
+
// ApiGscPerformanceRow[] confirms). Was incorrectly spec'd as a
|
|
9504
|
+
// single object, which silently truncated client types to one row.
|
|
9505
|
+
200: jsonArrayResponse("GSC performance rows returned.", "GscSearchDataDto"),
|
|
9506
|
+
404: errorResponse("Project not found.")
|
|
9261
9507
|
}
|
|
9262
9508
|
},
|
|
9263
9509
|
{
|
|
@@ -9272,8 +9518,8 @@ var routeCatalog = [
|
|
|
9272
9518
|
analyticsWindowParameter
|
|
9273
9519
|
],
|
|
9274
9520
|
responses: {
|
|
9275
|
-
200:
|
|
9276
|
-
404:
|
|
9521
|
+
200: jsonResponse("Daily aggregate (date \u2192 clicks/impressions/ctr) plus window totals.", "GscPerformanceDailyDto"),
|
|
9522
|
+
404: errorResponse("Project not found.")
|
|
9277
9523
|
}
|
|
9278
9524
|
},
|
|
9279
9525
|
{
|
|
@@ -9297,9 +9543,9 @@ var routeCatalog = [
|
|
|
9297
9543
|
}
|
|
9298
9544
|
},
|
|
9299
9545
|
responses: {
|
|
9300
|
-
200:
|
|
9301
|
-
400:
|
|
9302
|
-
404:
|
|
9546
|
+
200: jsonResponse("GSC inspection result returned.", "GscUrlInspectionDto"),
|
|
9547
|
+
400: errorResponse("Invalid inspection request."),
|
|
9548
|
+
404: errorResponse("Project or connection not found.")
|
|
9303
9549
|
}
|
|
9304
9550
|
},
|
|
9305
9551
|
{
|
|
@@ -9309,8 +9555,8 @@ var routeCatalog = [
|
|
|
9309
9555
|
tags: ["google"],
|
|
9310
9556
|
parameters: [nameParameter, { name: "url", in: "query", description: "Filter by URL.", schema: stringSchema }, limitQueryParameter],
|
|
9311
9557
|
responses: {
|
|
9312
|
-
200:
|
|
9313
|
-
404:
|
|
9558
|
+
200: jsonArrayResponse("GSC inspections returned.", "GscUrlInspectionDto"),
|
|
9559
|
+
404: errorResponse("Project not found.")
|
|
9314
9560
|
}
|
|
9315
9561
|
},
|
|
9316
9562
|
{
|
|
@@ -9320,8 +9566,8 @@ var routeCatalog = [
|
|
|
9320
9566
|
tags: ["google"],
|
|
9321
9567
|
parameters: [nameParameter],
|
|
9322
9568
|
responses: {
|
|
9323
|
-
200:
|
|
9324
|
-
404:
|
|
9569
|
+
200: jsonArrayResponse("Deindexed pages returned.", "GscDeindexedRowDto"),
|
|
9570
|
+
404: errorResponse("Project not found.")
|
|
9325
9571
|
}
|
|
9326
9572
|
},
|
|
9327
9573
|
{
|
|
@@ -9331,8 +9577,8 @@ var routeCatalog = [
|
|
|
9331
9577
|
tags: ["google"],
|
|
9332
9578
|
parameters: [nameParameter],
|
|
9333
9579
|
responses: {
|
|
9334
|
-
200:
|
|
9335
|
-
404:
|
|
9580
|
+
200: jsonResponse("GSC coverage returned.", "GscCoverageSummaryDto"),
|
|
9581
|
+
404: errorResponse("Project not found.")
|
|
9336
9582
|
}
|
|
9337
9583
|
},
|
|
9338
9584
|
{
|
|
@@ -9342,8 +9588,8 @@ var routeCatalog = [
|
|
|
9342
9588
|
tags: ["google"],
|
|
9343
9589
|
parameters: [nameParameter, limitQueryParameter],
|
|
9344
9590
|
responses: {
|
|
9345
|
-
200:
|
|
9346
|
-
404:
|
|
9591
|
+
200: jsonArrayResponse("GSC coverage history returned.", "GscCoverageSnapshotDto"),
|
|
9592
|
+
404: errorResponse("Project not found.")
|
|
9347
9593
|
}
|
|
9348
9594
|
},
|
|
9349
9595
|
{
|
|
@@ -9353,9 +9599,9 @@ var routeCatalog = [
|
|
|
9353
9599
|
tags: ["google"],
|
|
9354
9600
|
parameters: [nameParameter],
|
|
9355
9601
|
responses: {
|
|
9356
|
-
200:
|
|
9357
|
-
400:
|
|
9358
|
-
404:
|
|
9602
|
+
200: jsonResponse("GSC sitemaps returned.", "GscSitemapListResponseDto"),
|
|
9603
|
+
400: errorResponse("Invalid sitemap request."),
|
|
9604
|
+
404: errorResponse("Project or connection not found.")
|
|
9359
9605
|
}
|
|
9360
9606
|
},
|
|
9361
9607
|
{
|
|
@@ -9365,9 +9611,10 @@ var routeCatalog = [
|
|
|
9365
9611
|
tags: ["google"],
|
|
9366
9612
|
parameters: [nameParameter],
|
|
9367
9613
|
responses: {
|
|
9368
|
-
|
|
9369
|
-
|
|
9370
|
-
|
|
9614
|
+
// TODO: Add `DiscoverSitemapsResponse` Zod schema in contracts.
|
|
9615
|
+
200: rawJsonResponse("Discovered sitemaps and queued run returned.", looseObjectSchema),
|
|
9616
|
+
400: errorResponse("Invalid sitemap discovery request."),
|
|
9617
|
+
404: errorResponse("Project or connection not found.")
|
|
9371
9618
|
}
|
|
9372
9619
|
},
|
|
9373
9620
|
{
|
|
@@ -9389,9 +9636,9 @@ var routeCatalog = [
|
|
|
9389
9636
|
}
|
|
9390
9637
|
},
|
|
9391
9638
|
responses: {
|
|
9392
|
-
200:
|
|
9393
|
-
400:
|
|
9394
|
-
404:
|
|
9639
|
+
200: jsonResponse("Sitemap inspection run returned.", "RunDto"),
|
|
9640
|
+
400: errorResponse("Invalid sitemap inspection request."),
|
|
9641
|
+
404: errorResponse("Project or connection not found.")
|
|
9395
9642
|
}
|
|
9396
9643
|
},
|
|
9397
9644
|
{
|
|
@@ -9415,9 +9662,9 @@ var routeCatalog = [
|
|
|
9415
9662
|
}
|
|
9416
9663
|
},
|
|
9417
9664
|
responses: {
|
|
9418
|
-
200:
|
|
9419
|
-
400:
|
|
9420
|
-
404:
|
|
9665
|
+
200: jsonResponse("Indexing request results returned.", "IndexingRequestResponseDto"),
|
|
9666
|
+
400: errorResponse("Invalid indexing request."),
|
|
9667
|
+
404: errorResponse("Project or connection not found.")
|
|
9421
9668
|
}
|
|
9422
9669
|
},
|
|
9423
9670
|
{
|
|
@@ -9441,9 +9688,9 @@ var routeCatalog = [
|
|
|
9441
9688
|
}
|
|
9442
9689
|
},
|
|
9443
9690
|
responses: {
|
|
9444
|
-
200:
|
|
9445
|
-
400:
|
|
9446
|
-
404:
|
|
9691
|
+
200: jsonResponse("Bing connection returned.", "BingConnectResponseDto"),
|
|
9692
|
+
400: errorResponse("Invalid Bing connection request."),
|
|
9693
|
+
404: errorResponse("Project not found.")
|
|
9447
9694
|
}
|
|
9448
9695
|
},
|
|
9449
9696
|
{
|
|
@@ -9454,7 +9701,7 @@ var routeCatalog = [
|
|
|
9454
9701
|
parameters: [nameParameter],
|
|
9455
9702
|
responses: {
|
|
9456
9703
|
204: { description: "Bing connection deleted." },
|
|
9457
|
-
404:
|
|
9704
|
+
404: errorResponse("Project or connection not found.")
|
|
9458
9705
|
}
|
|
9459
9706
|
},
|
|
9460
9707
|
{
|
|
@@ -9464,8 +9711,8 @@ var routeCatalog = [
|
|
|
9464
9711
|
tags: ["bing"],
|
|
9465
9712
|
parameters: [nameParameter],
|
|
9466
9713
|
responses: {
|
|
9467
|
-
200:
|
|
9468
|
-
404:
|
|
9714
|
+
200: jsonResponse("Bing status returned.", "BingStatusDto"),
|
|
9715
|
+
404: errorResponse("Project not found.")
|
|
9469
9716
|
}
|
|
9470
9717
|
},
|
|
9471
9718
|
{
|
|
@@ -9475,9 +9722,9 @@ var routeCatalog = [
|
|
|
9475
9722
|
tags: ["bing"],
|
|
9476
9723
|
parameters: [nameParameter],
|
|
9477
9724
|
responses: {
|
|
9478
|
-
200:
|
|
9479
|
-
400:
|
|
9480
|
-
404:
|
|
9725
|
+
200: jsonResponse("Bing sites returned.", "BingSitesResponseDto"),
|
|
9726
|
+
400: errorResponse("Bing is not configured for this project."),
|
|
9727
|
+
404: errorResponse("Project not found.")
|
|
9481
9728
|
}
|
|
9482
9729
|
},
|
|
9483
9730
|
{
|
|
@@ -9501,9 +9748,9 @@ var routeCatalog = [
|
|
|
9501
9748
|
}
|
|
9502
9749
|
},
|
|
9503
9750
|
responses: {
|
|
9504
|
-
200:
|
|
9505
|
-
400:
|
|
9506
|
-
404:
|
|
9751
|
+
200: jsonResponse("Active Bing site updated.", "BingSetSiteResponseDto"),
|
|
9752
|
+
400: errorResponse("Invalid Bing site request."),
|
|
9753
|
+
404: errorResponse("Project or connection not found.")
|
|
9507
9754
|
}
|
|
9508
9755
|
},
|
|
9509
9756
|
{
|
|
@@ -9513,9 +9760,13 @@ var routeCatalog = [
|
|
|
9513
9760
|
tags: ["bing"],
|
|
9514
9761
|
parameters: [nameParameter],
|
|
9515
9762
|
responses: {
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9763
|
+
// Was incorrectly mapped to `BingCoverageSnapshotDto` (the daily
|
|
9764
|
+
// history snapshot — 4 fields). The /coverage handler actually
|
|
9765
|
+
// returns the nested summary shape with indexed/notIndexed/unknown
|
|
9766
|
+
// arrays. `BingCoverageSummaryDto` is the right ref.
|
|
9767
|
+
200: jsonResponse("Bing coverage returned.", "BingCoverageSummaryDto"),
|
|
9768
|
+
400: errorResponse("Bing is not configured for this project."),
|
|
9769
|
+
404: errorResponse("Project not found.")
|
|
9519
9770
|
}
|
|
9520
9771
|
},
|
|
9521
9772
|
{
|
|
@@ -9525,9 +9776,9 @@ var routeCatalog = [
|
|
|
9525
9776
|
tags: ["bing"],
|
|
9526
9777
|
parameters: [nameParameter, limitQueryParameter],
|
|
9527
9778
|
responses: {
|
|
9528
|
-
200:
|
|
9529
|
-
400:
|
|
9530
|
-
404:
|
|
9779
|
+
200: jsonArrayResponse("Bing coverage history returned.", "BingCoverageSnapshotDto"),
|
|
9780
|
+
400: errorResponse("Bing is not configured for this project."),
|
|
9781
|
+
404: errorResponse("Project not found.")
|
|
9531
9782
|
}
|
|
9532
9783
|
},
|
|
9533
9784
|
{
|
|
@@ -9537,9 +9788,9 @@ var routeCatalog = [
|
|
|
9537
9788
|
tags: ["bing"],
|
|
9538
9789
|
parameters: [nameParameter, { name: "url", in: "query", description: "Filter by URL.", schema: stringSchema }, limitQueryParameter],
|
|
9539
9790
|
responses: {
|
|
9540
|
-
200:
|
|
9541
|
-
400:
|
|
9542
|
-
404:
|
|
9791
|
+
200: jsonArrayResponse("Bing inspections returned.", "BingUrlInspectionDto"),
|
|
9792
|
+
400: errorResponse("Bing is not configured for this project."),
|
|
9793
|
+
404: errorResponse("Project not found.")
|
|
9543
9794
|
}
|
|
9544
9795
|
},
|
|
9545
9796
|
{
|
|
@@ -9563,9 +9814,9 @@ var routeCatalog = [
|
|
|
9563
9814
|
}
|
|
9564
9815
|
},
|
|
9565
9816
|
responses: {
|
|
9566
|
-
200:
|
|
9567
|
-
400:
|
|
9568
|
-
404:
|
|
9817
|
+
200: jsonResponse("Bing inspection result returned.", "BingUrlInspectionDto"),
|
|
9818
|
+
400: errorResponse("Invalid inspection request."),
|
|
9819
|
+
404: errorResponse("Project or connection not found.")
|
|
9569
9820
|
}
|
|
9570
9821
|
},
|
|
9571
9822
|
{
|
|
@@ -9588,9 +9839,9 @@ var routeCatalog = [
|
|
|
9588
9839
|
}
|
|
9589
9840
|
},
|
|
9590
9841
|
responses: {
|
|
9591
|
-
200:
|
|
9592
|
-
400:
|
|
9593
|
-
404:
|
|
9842
|
+
200: jsonResponse("Sitemap inspection run queued.", "RunDto"),
|
|
9843
|
+
400: errorResponse("Bing is not configured for this project."),
|
|
9844
|
+
404: errorResponse("Project not found.")
|
|
9594
9845
|
}
|
|
9595
9846
|
},
|
|
9596
9847
|
{
|
|
@@ -9614,9 +9865,9 @@ var routeCatalog = [
|
|
|
9614
9865
|
}
|
|
9615
9866
|
},
|
|
9616
9867
|
responses: {
|
|
9617
|
-
200:
|
|
9618
|
-
400:
|
|
9619
|
-
404:
|
|
9868
|
+
200: jsonResponse("Bing indexing request results returned.", "BingIndexingRequestResponseDto"),
|
|
9869
|
+
400: errorResponse("Invalid indexing request."),
|
|
9870
|
+
404: errorResponse("Project or connection not found.")
|
|
9620
9871
|
}
|
|
9621
9872
|
},
|
|
9622
9873
|
{
|
|
@@ -9626,9 +9877,9 @@ var routeCatalog = [
|
|
|
9626
9877
|
tags: ["bing"],
|
|
9627
9878
|
parameters: [nameParameter, limitQueryParameter],
|
|
9628
9879
|
responses: {
|
|
9629
|
-
200:
|
|
9630
|
-
400:
|
|
9631
|
-
404:
|
|
9880
|
+
200: jsonArrayResponse("Bing performance returned.", "BingKeywordStatsDto"),
|
|
9881
|
+
400: errorResponse("Bing is not configured for this project."),
|
|
9882
|
+
404: errorResponse("Project not found.")
|
|
9632
9883
|
}
|
|
9633
9884
|
},
|
|
9634
9885
|
{
|
|
@@ -9656,9 +9907,9 @@ var routeCatalog = [
|
|
|
9656
9907
|
}
|
|
9657
9908
|
},
|
|
9658
9909
|
responses: {
|
|
9659
|
-
200:
|
|
9660
|
-
400:
|
|
9661
|
-
404:
|
|
9910
|
+
200: jsonResponse("WordPress connection status returned.", "WordpressStatusDto"),
|
|
9911
|
+
400: errorResponse("Invalid WordPress connection request."),
|
|
9912
|
+
404: errorResponse("Project not found.")
|
|
9662
9913
|
}
|
|
9663
9914
|
},
|
|
9664
9915
|
{
|
|
@@ -9669,7 +9920,7 @@ var routeCatalog = [
|
|
|
9669
9920
|
parameters: [nameParameter],
|
|
9670
9921
|
responses: {
|
|
9671
9922
|
204: { description: "WordPress connection deleted." },
|
|
9672
|
-
404:
|
|
9923
|
+
404: errorResponse("Project or connection not found.")
|
|
9673
9924
|
}
|
|
9674
9925
|
},
|
|
9675
9926
|
{
|
|
@@ -9679,8 +9930,8 @@ var routeCatalog = [
|
|
|
9679
9930
|
tags: ["wordpress"],
|
|
9680
9931
|
parameters: [nameParameter],
|
|
9681
9932
|
responses: {
|
|
9682
|
-
200:
|
|
9683
|
-
404:
|
|
9933
|
+
200: jsonResponse("WordPress status returned.", "WordpressStatusDto"),
|
|
9934
|
+
404: errorResponse("Project not found.")
|
|
9684
9935
|
}
|
|
9685
9936
|
},
|
|
9686
9937
|
{
|
|
@@ -9690,9 +9941,9 @@ var routeCatalog = [
|
|
|
9690
9941
|
tags: ["wordpress"],
|
|
9691
9942
|
parameters: [nameParameter, wordpressEnvQueryParameter],
|
|
9692
9943
|
responses: {
|
|
9693
|
-
200:
|
|
9694
|
-
400:
|
|
9695
|
-
404:
|
|
9944
|
+
200: jsonArrayResponse("WordPress pages returned.", "WordpressPageSummaryDto"),
|
|
9945
|
+
400: errorResponse("Invalid environment or missing connection."),
|
|
9946
|
+
404: errorResponse("Project not found.")
|
|
9696
9947
|
}
|
|
9697
9948
|
},
|
|
9698
9949
|
{
|
|
@@ -9702,9 +9953,9 @@ var routeCatalog = [
|
|
|
9702
9953
|
tags: ["wordpress"],
|
|
9703
9954
|
parameters: [nameParameter, wordpressSlugQueryParameter, wordpressEnvQueryParameter],
|
|
9704
9955
|
responses: {
|
|
9705
|
-
200:
|
|
9706
|
-
400:
|
|
9707
|
-
404:
|
|
9956
|
+
200: jsonResponse("WordPress page returned.", "WordpressPageDetailDto"),
|
|
9957
|
+
400: errorResponse("Invalid slug or environment."),
|
|
9958
|
+
404: errorResponse("Project, connection, or page not found.")
|
|
9708
9959
|
}
|
|
9709
9960
|
},
|
|
9710
9961
|
{
|
|
@@ -9732,9 +9983,9 @@ var routeCatalog = [
|
|
|
9732
9983
|
}
|
|
9733
9984
|
},
|
|
9734
9985
|
responses: {
|
|
9735
|
-
200:
|
|
9736
|
-
400:
|
|
9737
|
-
404:
|
|
9986
|
+
200: jsonResponse("WordPress page created.", "WordpressPageDetailDto"),
|
|
9987
|
+
400: errorResponse("Invalid page creation request."),
|
|
9988
|
+
404: errorResponse("Project or connection not found.")
|
|
9738
9989
|
}
|
|
9739
9990
|
},
|
|
9740
9991
|
{
|
|
@@ -9763,9 +10014,9 @@ var routeCatalog = [
|
|
|
9763
10014
|
}
|
|
9764
10015
|
},
|
|
9765
10016
|
responses: {
|
|
9766
|
-
200:
|
|
9767
|
-
400:
|
|
9768
|
-
404:
|
|
10017
|
+
200: jsonResponse("WordPress page updated.", "WordpressPageDetailDto"),
|
|
10018
|
+
400: errorResponse("Invalid page update request."),
|
|
10019
|
+
404: errorResponse("Project, connection, or page not found.")
|
|
9769
10020
|
}
|
|
9770
10021
|
},
|
|
9771
10022
|
{
|
|
@@ -9793,9 +10044,10 @@ var routeCatalog = [
|
|
|
9793
10044
|
}
|
|
9794
10045
|
},
|
|
9795
10046
|
responses: {
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
10047
|
+
// TODO: Add `WordpressSeoStateDto` to the schema table (already in contracts).
|
|
10048
|
+
200: rawJsonResponse("WordPress SEO meta updated.", looseObjectSchema),
|
|
10049
|
+
400: errorResponse("SEO meta is unsupported or the request is invalid."),
|
|
10050
|
+
404: errorResponse("Project, connection, or page not found.")
|
|
9799
10051
|
}
|
|
9800
10052
|
},
|
|
9801
10053
|
{
|
|
@@ -9832,9 +10084,9 @@ var routeCatalog = [
|
|
|
9832
10084
|
}
|
|
9833
10085
|
},
|
|
9834
10086
|
responses: {
|
|
9835
|
-
200:
|
|
9836
|
-
400:
|
|
9837
|
-
404:
|
|
10087
|
+
200: jsonResponse("Bulk SEO meta update results returned.", "WordpressBulkMetaResultDto"),
|
|
10088
|
+
400: errorResponse("Invalid entries or environment."),
|
|
10089
|
+
404: errorResponse("Project or connection not found.")
|
|
9838
10090
|
}
|
|
9839
10091
|
},
|
|
9840
10092
|
{
|
|
@@ -9844,9 +10096,9 @@ var routeCatalog = [
|
|
|
9844
10096
|
tags: ["wordpress"],
|
|
9845
10097
|
parameters: [nameParameter, wordpressSlugQueryParameter, wordpressEnvQueryParameter],
|
|
9846
10098
|
responses: {
|
|
9847
|
-
200:
|
|
9848
|
-
400:
|
|
9849
|
-
404:
|
|
10099
|
+
200: jsonArrayResponse("WordPress schema blocks returned.", "WordpressSchemaBlockDto"),
|
|
10100
|
+
400: errorResponse("Invalid slug or environment."),
|
|
10101
|
+
404: errorResponse("Project, connection, or page not found.")
|
|
9850
10102
|
}
|
|
9851
10103
|
},
|
|
9852
10104
|
{
|
|
@@ -9873,9 +10125,9 @@ var routeCatalog = [
|
|
|
9873
10125
|
}
|
|
9874
10126
|
},
|
|
9875
10127
|
responses: {
|
|
9876
|
-
200:
|
|
9877
|
-
400:
|
|
9878
|
-
404:
|
|
10128
|
+
200: jsonResponse("Manual schema instructions returned.", "WordpressManualAssistDto"),
|
|
10129
|
+
400: errorResponse("Invalid schema request."),
|
|
10130
|
+
404: errorResponse("Project, connection, or page not found.")
|
|
9879
10131
|
}
|
|
9880
10132
|
},
|
|
9881
10133
|
{
|
|
@@ -9903,9 +10155,9 @@ var routeCatalog = [
|
|
|
9903
10155
|
}
|
|
9904
10156
|
},
|
|
9905
10157
|
responses: {
|
|
9906
|
-
200:
|
|
9907
|
-
400:
|
|
9908
|
-
404:
|
|
10158
|
+
200: jsonResponse("Schema deployment results returned.", "WordpressSchemaDeployResultDto"),
|
|
10159
|
+
400: errorResponse("Invalid profile or environment."),
|
|
10160
|
+
404: errorResponse("Project or connection not found.")
|
|
9909
10161
|
}
|
|
9910
10162
|
},
|
|
9911
10163
|
{
|
|
@@ -9915,9 +10167,9 @@ var routeCatalog = [
|
|
|
9915
10167
|
tags: ["wordpress"],
|
|
9916
10168
|
parameters: [nameParameter, wordpressEnvQueryParameter],
|
|
9917
10169
|
responses: {
|
|
9918
|
-
200:
|
|
9919
|
-
400:
|
|
9920
|
-
404:
|
|
10170
|
+
200: jsonResponse("Schema status per page returned.", "WordpressSchemaStatusResultDto"),
|
|
10171
|
+
400: errorResponse("Invalid environment."),
|
|
10172
|
+
404: errorResponse("Project or connection not found.")
|
|
9921
10173
|
}
|
|
9922
10174
|
},
|
|
9923
10175
|
{
|
|
@@ -9927,9 +10179,10 @@ var routeCatalog = [
|
|
|
9927
10179
|
tags: ["wordpress"],
|
|
9928
10180
|
parameters: [nameParameter, wordpressEnvQueryParameter],
|
|
9929
10181
|
responses: {
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
|
|
10182
|
+
// Returns raw text/plain content of llms.txt.
|
|
10183
|
+
200: { description: "llms.txt returned.", content: { "text/plain": { schema: { type: "string" } } } },
|
|
10184
|
+
400: errorResponse("Invalid environment or missing connection."),
|
|
10185
|
+
404: errorResponse("Project not found.")
|
|
9933
10186
|
}
|
|
9934
10187
|
},
|
|
9935
10188
|
{
|
|
@@ -9954,9 +10207,9 @@ var routeCatalog = [
|
|
|
9954
10207
|
}
|
|
9955
10208
|
},
|
|
9956
10209
|
responses: {
|
|
9957
|
-
200:
|
|
9958
|
-
400:
|
|
9959
|
-
404:
|
|
10210
|
+
200: jsonResponse("Manual llms.txt instructions returned.", "WordpressManualAssistDto"),
|
|
10211
|
+
400: errorResponse("Invalid llms.txt request."),
|
|
10212
|
+
404: errorResponse("Project or connection not found.")
|
|
9960
10213
|
}
|
|
9961
10214
|
},
|
|
9962
10215
|
{
|
|
@@ -9966,9 +10219,9 @@ var routeCatalog = [
|
|
|
9966
10219
|
tags: ["wordpress"],
|
|
9967
10220
|
parameters: [nameParameter, wordpressEnvQueryParameter],
|
|
9968
10221
|
responses: {
|
|
9969
|
-
200:
|
|
9970
|
-
400:
|
|
9971
|
-
404:
|
|
10222
|
+
200: jsonArrayResponse("WordPress audit returned.", "WordpressAuditPageDto"),
|
|
10223
|
+
400: errorResponse("Invalid environment or missing connection."),
|
|
10224
|
+
404: errorResponse("Project not found.")
|
|
9972
10225
|
}
|
|
9973
10226
|
},
|
|
9974
10227
|
{
|
|
@@ -9978,9 +10231,9 @@ var routeCatalog = [
|
|
|
9978
10231
|
tags: ["wordpress"],
|
|
9979
10232
|
parameters: [nameParameter, wordpressSlugQueryParameter],
|
|
9980
10233
|
responses: {
|
|
9981
|
-
200:
|
|
9982
|
-
400:
|
|
9983
|
-
404:
|
|
10234
|
+
200: jsonResponse("WordPress diff returned.", "WordpressDiffDto"),
|
|
10235
|
+
400: errorResponse("Invalid slug or missing staging configuration."),
|
|
10236
|
+
404: errorResponse("Project, connection, or page not found.")
|
|
9984
10237
|
}
|
|
9985
10238
|
},
|
|
9986
10239
|
{
|
|
@@ -9990,9 +10243,10 @@ var routeCatalog = [
|
|
|
9990
10243
|
tags: ["wordpress"],
|
|
9991
10244
|
parameters: [nameParameter],
|
|
9992
10245
|
responses: {
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
10246
|
+
// TODO: Add `WordpressSiteStatusDto` to the schema table (already in contracts).
|
|
10247
|
+
200: rawJsonResponse("WordPress staging status returned.", looseObjectSchema),
|
|
10248
|
+
400: errorResponse("WordPress is not configured for this project."),
|
|
10249
|
+
404: errorResponse("Project not found.")
|
|
9996
10250
|
}
|
|
9997
10251
|
},
|
|
9998
10252
|
{
|
|
@@ -10002,9 +10256,9 @@ var routeCatalog = [
|
|
|
10002
10256
|
tags: ["wordpress"],
|
|
10003
10257
|
parameters: [nameParameter],
|
|
10004
10258
|
responses: {
|
|
10005
|
-
200:
|
|
10006
|
-
400:
|
|
10007
|
-
404:
|
|
10259
|
+
200: jsonResponse("Manual staging push instructions returned.", "WordpressManualAssistDto"),
|
|
10260
|
+
400: errorResponse("Missing staging configuration."),
|
|
10261
|
+
404: errorResponse("Project or connection not found.")
|
|
10008
10262
|
}
|
|
10009
10263
|
},
|
|
10010
10264
|
{
|
|
@@ -10035,9 +10289,9 @@ var routeCatalog = [
|
|
|
10035
10289
|
}
|
|
10036
10290
|
},
|
|
10037
10291
|
responses: {
|
|
10038
|
-
200:
|
|
10039
|
-
400:
|
|
10040
|
-
404:
|
|
10292
|
+
200: jsonResponse("Onboarding result with step-by-step status.", "WordpressOnboardResultDto"),
|
|
10293
|
+
400: errorResponse("Invalid onboarding request."),
|
|
10294
|
+
404: errorResponse("Project not found.")
|
|
10041
10295
|
}
|
|
10042
10296
|
},
|
|
10043
10297
|
// GA4 routes
|
|
@@ -10063,9 +10317,10 @@ var routeCatalog = [
|
|
|
10063
10317
|
}
|
|
10064
10318
|
},
|
|
10065
10319
|
responses: {
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
|
|
10320
|
+
// TODO: Add `GaConnectResponse` Zod schema in contracts.
|
|
10321
|
+
200: rawJsonResponse("GA4 connection established.", looseObjectSchema),
|
|
10322
|
+
400: errorResponse("Invalid GA4 connection request."),
|
|
10323
|
+
404: errorResponse("Project not found.")
|
|
10069
10324
|
}
|
|
10070
10325
|
},
|
|
10071
10326
|
{
|
|
@@ -10076,7 +10331,7 @@ var routeCatalog = [
|
|
|
10076
10331
|
parameters: [nameParameter],
|
|
10077
10332
|
responses: {
|
|
10078
10333
|
204: { description: "GA4 connection deleted." },
|
|
10079
|
-
404:
|
|
10334
|
+
404: errorResponse("Project or connection not found.")
|
|
10080
10335
|
}
|
|
10081
10336
|
},
|
|
10082
10337
|
{
|
|
@@ -10086,8 +10341,8 @@ var routeCatalog = [
|
|
|
10086
10341
|
tags: ["ga4"],
|
|
10087
10342
|
parameters: [nameParameter],
|
|
10088
10343
|
responses: {
|
|
10089
|
-
200:
|
|
10090
|
-
404:
|
|
10344
|
+
200: jsonResponse("GA4 status returned.", "GA4StatusDto"),
|
|
10345
|
+
404: errorResponse("Project not found.")
|
|
10091
10346
|
}
|
|
10092
10347
|
},
|
|
10093
10348
|
{
|
|
@@ -10110,9 +10365,9 @@ var routeCatalog = [
|
|
|
10110
10365
|
}
|
|
10111
10366
|
},
|
|
10112
10367
|
responses: {
|
|
10113
|
-
200:
|
|
10114
|
-
400:
|
|
10115
|
-
404:
|
|
10368
|
+
200: jsonResponse("GA4 sync completed.", "GA4SyncResponseDto"),
|
|
10369
|
+
400: errorResponse("GA4 is not connected."),
|
|
10370
|
+
404: errorResponse("Project not found.")
|
|
10116
10371
|
}
|
|
10117
10372
|
},
|
|
10118
10373
|
{
|
|
@@ -10122,9 +10377,10 @@ var routeCatalog = [
|
|
|
10122
10377
|
tags: ["ga4"],
|
|
10123
10378
|
parameters: [nameParameter, limitQueryParameter, analyticsWindowParameter],
|
|
10124
10379
|
responses: {
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10380
|
+
// TODO: Add `GaTrafficResponse` Zod schema in contracts.
|
|
10381
|
+
200: rawJsonResponse("GA4 traffic data returned.", looseObjectSchema),
|
|
10382
|
+
400: errorResponse("GA4 is not connected."),
|
|
10383
|
+
404: errorResponse("Project not found.")
|
|
10128
10384
|
}
|
|
10129
10385
|
},
|
|
10130
10386
|
{
|
|
@@ -10134,9 +10390,9 @@ var routeCatalog = [
|
|
|
10134
10390
|
tags: ["ga4"],
|
|
10135
10391
|
parameters: [nameParameter, analyticsWindowParameter],
|
|
10136
10392
|
responses: {
|
|
10137
|
-
200:
|
|
10138
|
-
400:
|
|
10139
|
-
404:
|
|
10393
|
+
200: jsonArrayResponse("AI referral history returned.", "GA4AiReferralHistoryEntry"),
|
|
10394
|
+
400: errorResponse("GA4 is not connected."),
|
|
10395
|
+
404: errorResponse("Project not found.")
|
|
10140
10396
|
}
|
|
10141
10397
|
},
|
|
10142
10398
|
{
|
|
@@ -10146,9 +10402,9 @@ var routeCatalog = [
|
|
|
10146
10402
|
tags: ["ga4"],
|
|
10147
10403
|
parameters: [nameParameter, analyticsWindowParameter],
|
|
10148
10404
|
responses: {
|
|
10149
|
-
200:
|
|
10150
|
-
400:
|
|
10151
|
-
404:
|
|
10405
|
+
200: jsonArrayResponse("Social referral history returned.", "GA4SocialReferralHistoryEntry"),
|
|
10406
|
+
400: errorResponse("GA4 is not connected."),
|
|
10407
|
+
404: errorResponse("Project not found.")
|
|
10152
10408
|
}
|
|
10153
10409
|
},
|
|
10154
10410
|
{
|
|
@@ -10158,9 +10414,10 @@ var routeCatalog = [
|
|
|
10158
10414
|
tags: ["ga4"],
|
|
10159
10415
|
parameters: [nameParameter],
|
|
10160
10416
|
responses: {
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
|
|
10417
|
+
// TODO: Add `GaSocialReferralTrendResponse` Zod schema in contracts.
|
|
10418
|
+
200: rawJsonResponse("Social referral trend returned.", looseObjectSchema),
|
|
10419
|
+
400: errorResponse("GA4 is not connected."),
|
|
10420
|
+
404: errorResponse("Project not found.")
|
|
10164
10421
|
}
|
|
10165
10422
|
},
|
|
10166
10423
|
{
|
|
@@ -10170,9 +10427,10 @@ var routeCatalog = [
|
|
|
10170
10427
|
tags: ["ga4"],
|
|
10171
10428
|
parameters: [nameParameter],
|
|
10172
10429
|
responses: {
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
|
|
10430
|
+
// TODO: Add `GaAttributionTrendResponse` Zod schema in contracts.
|
|
10431
|
+
200: rawJsonResponse("Attribution trend returned.", looseObjectSchema),
|
|
10432
|
+
400: errorResponse("GA4 is not connected."),
|
|
10433
|
+
404: errorResponse("Project not found.")
|
|
10176
10434
|
}
|
|
10177
10435
|
},
|
|
10178
10436
|
{
|
|
@@ -10182,9 +10440,9 @@ var routeCatalog = [
|
|
|
10182
10440
|
tags: ["ga4"],
|
|
10183
10441
|
parameters: [nameParameter, analyticsWindowParameter],
|
|
10184
10442
|
responses: {
|
|
10185
|
-
200:
|
|
10186
|
-
400:
|
|
10187
|
-
404:
|
|
10443
|
+
200: jsonArrayResponse("Session history returned.", "GA4SessionHistoryEntry"),
|
|
10444
|
+
400: errorResponse("GA4 is not connected."),
|
|
10445
|
+
404: errorResponse("Project not found.")
|
|
10188
10446
|
}
|
|
10189
10447
|
},
|
|
10190
10448
|
{
|
|
@@ -10194,9 +10452,10 @@ var routeCatalog = [
|
|
|
10194
10452
|
tags: ["ga4"],
|
|
10195
10453
|
parameters: [nameParameter],
|
|
10196
10454
|
responses: {
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10455
|
+
// TODO: Add `GaCoverageResponse` Zod schema in contracts.
|
|
10456
|
+
200: rawJsonResponse("GA4 coverage data returned.", looseObjectSchema),
|
|
10457
|
+
400: errorResponse("GA4 is not connected."),
|
|
10458
|
+
404: errorResponse("Project not found.")
|
|
10200
10459
|
}
|
|
10201
10460
|
},
|
|
10202
10461
|
// Intelligence
|
|
@@ -10211,8 +10470,9 @@ var routeCatalog = [
|
|
|
10211
10470
|
{ name: "runId", in: "query", description: "Filter by run ID.", schema: stringSchema }
|
|
10212
10471
|
],
|
|
10213
10472
|
responses: {
|
|
10214
|
-
|
|
10215
|
-
|
|
10473
|
+
// TODO: Add `InsightDto` Zod schema in contracts.
|
|
10474
|
+
200: rawJsonResponse("Insights returned.", { type: "array", items: looseObjectSchema }),
|
|
10475
|
+
404: errorResponse("Project not found.")
|
|
10216
10476
|
}
|
|
10217
10477
|
},
|
|
10218
10478
|
{
|
|
@@ -10225,8 +10485,9 @@ var routeCatalog = [
|
|
|
10225
10485
|
{ name: "id", in: "path", required: true, description: "Insight ID.", schema: stringSchema }
|
|
10226
10486
|
],
|
|
10227
10487
|
responses: {
|
|
10228
|
-
|
|
10229
|
-
|
|
10488
|
+
// TODO: Add `InsightDto` Zod schema in contracts.
|
|
10489
|
+
200: rawJsonResponse("Insight returned.", looseObjectSchema),
|
|
10490
|
+
404: errorResponse("Insight not found.")
|
|
10230
10491
|
}
|
|
10231
10492
|
},
|
|
10232
10493
|
{
|
|
@@ -10239,8 +10500,9 @@ var routeCatalog = [
|
|
|
10239
10500
|
{ name: "id", in: "path", required: true, description: "Insight ID.", schema: stringSchema }
|
|
10240
10501
|
],
|
|
10241
10502
|
responses: {
|
|
10242
|
-
|
|
10243
|
-
|
|
10503
|
+
// TODO: Add `InsightDto` Zod schema in contracts.
|
|
10504
|
+
200: rawJsonResponse("Insight dismissed.", looseObjectSchema),
|
|
10505
|
+
404: errorResponse("Insight not found.")
|
|
10244
10506
|
}
|
|
10245
10507
|
},
|
|
10246
10508
|
{
|
|
@@ -10251,8 +10513,8 @@ var routeCatalog = [
|
|
|
10251
10513
|
description: "Bundles every section the canonry-report HTML output needs (executive summary, client summary, agency diagnostics, action plan, citation scorecard, competitor landscape \u2014 citation + mention landscapes, AI citation sources, GSC, GA4, social/AI referrals, indexing health, citations trend, insights, and recommended next steps) into a single canonical JSON payload. Backs `canonry report <project>` and MCP report reads.",
|
|
10252
10514
|
parameters: [nameParameter],
|
|
10253
10515
|
responses: {
|
|
10254
|
-
200:
|
|
10255
|
-
404:
|
|
10516
|
+
200: jsonResponse("Report returned.", "ProjectReportDto"),
|
|
10517
|
+
404: errorResponse("Project not found.")
|
|
10256
10518
|
}
|
|
10257
10519
|
},
|
|
10258
10520
|
{
|
|
@@ -10263,8 +10525,8 @@ var routeCatalog = [
|
|
|
10263
10525
|
description: "Server-rendered self-contained HTML version of the project report. Same data as `/projects/{name}/report` (JSON), rendered through the canonry HTML report renderer in agency or client mode. Returns `text/html` with `Content-Disposition: attachment` so browsers download it as `canonry-report-<project>-<audience>-YYYY-MM-DD.html`. Open in a browser and Print \u2192 Save as PDF for a PDF copy.",
|
|
10264
10526
|
parameters: [nameParameter, reportAudienceQueryParameter],
|
|
10265
10527
|
responses: {
|
|
10266
|
-
200: { description: "HTML report returned." },
|
|
10267
|
-
404:
|
|
10528
|
+
200: { description: "HTML report returned.", content: { "text/html": { schema: { type: "string" } } } },
|
|
10529
|
+
404: errorResponse("Project not found.")
|
|
10268
10530
|
}
|
|
10269
10531
|
},
|
|
10270
10532
|
{
|
|
@@ -10275,8 +10537,9 @@ var routeCatalog = [
|
|
|
10275
10537
|
tags: ["intelligence"],
|
|
10276
10538
|
parameters: [nameParameter],
|
|
10277
10539
|
responses: {
|
|
10278
|
-
|
|
10279
|
-
|
|
10540
|
+
// TODO: Add `HealthSnapshotDto` Zod schema in contracts.
|
|
10541
|
+
200: rawJsonResponse("Health snapshot or no-data sentinel returned.", looseObjectSchema),
|
|
10542
|
+
404: errorResponse("Project not found.")
|
|
10280
10543
|
}
|
|
10281
10544
|
},
|
|
10282
10545
|
{
|
|
@@ -10289,8 +10552,9 @@ var routeCatalog = [
|
|
|
10289
10552
|
{ name: "limit", in: "query", description: "Max results.", schema: stringSchema }
|
|
10290
10553
|
],
|
|
10291
10554
|
responses: {
|
|
10292
|
-
|
|
10293
|
-
|
|
10555
|
+
// TODO: Add `HealthSnapshotDto` Zod schema in contracts.
|
|
10556
|
+
200: rawJsonResponse("Health history returned.", { type: "array", items: looseObjectSchema }),
|
|
10557
|
+
404: errorResponse("Project not found.")
|
|
10294
10558
|
}
|
|
10295
10559
|
},
|
|
10296
10560
|
{
|
|
@@ -10301,8 +10565,8 @@ var routeCatalog = [
|
|
|
10301
10565
|
tags: ["intelligence"],
|
|
10302
10566
|
parameters: [nameParameter],
|
|
10303
10567
|
responses: {
|
|
10304
|
-
200:
|
|
10305
|
-
404:
|
|
10568
|
+
200: jsonResponse("Citation visibility report or no-data sentinel returned.", "CitationVisibilityResponse"),
|
|
10569
|
+
404: errorResponse("Project not found.")
|
|
10306
10570
|
}
|
|
10307
10571
|
},
|
|
10308
10572
|
// Content opportunity engine
|
|
@@ -10318,9 +10582,9 @@ var routeCatalog = [
|
|
|
10318
10582
|
{ name: "include-in-progress", in: "query", description: "Include rows with in-flight tracked actions.", schema: stringSchema }
|
|
10319
10583
|
],
|
|
10320
10584
|
responses: {
|
|
10321
|
-
200:
|
|
10322
|
-
400:
|
|
10323
|
-
404:
|
|
10585
|
+
200: jsonResponse("Targets returned.", "ContentTargetsResponseDto"),
|
|
10586
|
+
400: errorResponse("Invalid limit."),
|
|
10587
|
+
404: errorResponse("Project not found.")
|
|
10324
10588
|
}
|
|
10325
10589
|
},
|
|
10326
10590
|
{
|
|
@@ -10331,8 +10595,8 @@ var routeCatalog = [
|
|
|
10331
10595
|
tags: ["content"],
|
|
10332
10596
|
parameters: [nameParameter],
|
|
10333
10597
|
responses: {
|
|
10334
|
-
200:
|
|
10335
|
-
404:
|
|
10598
|
+
200: jsonResponse("Sources returned.", "ContentSourcesResponseDto"),
|
|
10599
|
+
404: errorResponse("Project not found.")
|
|
10336
10600
|
}
|
|
10337
10601
|
},
|
|
10338
10602
|
{
|
|
@@ -10343,8 +10607,8 @@ var routeCatalog = [
|
|
|
10343
10607
|
tags: ["content"],
|
|
10344
10608
|
parameters: [nameParameter],
|
|
10345
10609
|
responses: {
|
|
10346
|
-
200:
|
|
10347
|
-
404:
|
|
10610
|
+
200: jsonResponse("Gaps returned.", "ContentGapsResponseDto"),
|
|
10611
|
+
404: errorResponse("Project not found.")
|
|
10348
10612
|
}
|
|
10349
10613
|
},
|
|
10350
10614
|
{
|
|
@@ -10355,8 +10619,9 @@ var routeCatalog = [
|
|
|
10355
10619
|
tags: ["intelligence"],
|
|
10356
10620
|
parameters: [nameParameter],
|
|
10357
10621
|
responses: {
|
|
10358
|
-
|
|
10359
|
-
|
|
10622
|
+
// TODO: Add `ProjectOverviewDto` Zod schema in contracts.
|
|
10623
|
+
200: rawJsonResponse("Overview returned.", looseObjectSchema),
|
|
10624
|
+
404: errorResponse("Project not found.")
|
|
10360
10625
|
}
|
|
10361
10626
|
},
|
|
10362
10627
|
{
|
|
@@ -10371,9 +10636,10 @@ var routeCatalog = [
|
|
|
10371
10636
|
{ name: "limit", in: "query", description: "Max combined hits (1-50, default 25).", schema: stringSchema }
|
|
10372
10637
|
],
|
|
10373
10638
|
responses: {
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10639
|
+
// TODO: Add `ProjectSearchResponseDto` Zod schema in contracts (projectSearchResponseSchema exists).
|
|
10640
|
+
200: rawJsonResponse("Search hits returned.", looseObjectSchema),
|
|
10641
|
+
400: errorResponse("Query string missing or too short."),
|
|
10642
|
+
404: errorResponse("Project not found.")
|
|
10377
10643
|
}
|
|
10378
10644
|
},
|
|
10379
10645
|
{
|
|
@@ -10391,7 +10657,7 @@ var routeCatalog = [
|
|
|
10391
10657
|
}
|
|
10392
10658
|
],
|
|
10393
10659
|
responses: {
|
|
10394
|
-
200:
|
|
10660
|
+
200: jsonResponse("Doctor report returned.", "DoctorReportDto")
|
|
10395
10661
|
}
|
|
10396
10662
|
},
|
|
10397
10663
|
{
|
|
@@ -10410,8 +10676,8 @@ var routeCatalog = [
|
|
|
10410
10676
|
}
|
|
10411
10677
|
],
|
|
10412
10678
|
responses: {
|
|
10413
|
-
200:
|
|
10414
|
-
404:
|
|
10679
|
+
200: jsonResponse("Doctor report returned.", "DoctorReportDto"),
|
|
10680
|
+
404: errorResponse("Project not found.")
|
|
10415
10681
|
}
|
|
10416
10682
|
},
|
|
10417
10683
|
{
|
|
@@ -10421,8 +10687,8 @@ var routeCatalog = [
|
|
|
10421
10687
|
description: "Reports whether @duckdb/node-api is installed in the local plugin dir. Returns MISSING_DEPENDENCY (422) on deployments that cannot host the plugin (e.g. the cloud API).",
|
|
10422
10688
|
tags: ["backlinks"],
|
|
10423
10689
|
responses: {
|
|
10424
|
-
200:
|
|
10425
|
-
422:
|
|
10690
|
+
200: jsonResponse("Install status returned.", "BacklinksInstallStatusDto"),
|
|
10691
|
+
422: errorResponse("Backlinks feature is not available on this deployment.")
|
|
10426
10692
|
}
|
|
10427
10693
|
},
|
|
10428
10694
|
{
|
|
@@ -10432,8 +10698,8 @@ var routeCatalog = [
|
|
|
10432
10698
|
description: "Idempotently installs DuckDB into the canonry plugin dir. Returns MISSING_DEPENDENCY (422) when the host cannot perform the install.",
|
|
10433
10699
|
tags: ["backlinks"],
|
|
10434
10700
|
responses: {
|
|
10435
|
-
200:
|
|
10436
|
-
422:
|
|
10701
|
+
200: jsonResponse("Installed (or already present).", "BacklinksInstallResultDto"),
|
|
10702
|
+
422: errorResponse("Backlinks feature is not available on this deployment.")
|
|
10437
10703
|
}
|
|
10438
10704
|
},
|
|
10439
10705
|
{
|
|
@@ -10456,10 +10722,10 @@ var routeCatalog = [
|
|
|
10456
10722
|
}
|
|
10457
10723
|
},
|
|
10458
10724
|
responses: {
|
|
10459
|
-
200:
|
|
10460
|
-
201:
|
|
10461
|
-
400:
|
|
10462
|
-
422:
|
|
10725
|
+
200: jsonResponse("Existing in-flight sync returned.", "CcReleaseSyncDto"),
|
|
10726
|
+
201: jsonResponse("Sync queued.", "CcReleaseSyncDto"),
|
|
10727
|
+
400: errorResponse("Invalid release id."),
|
|
10728
|
+
422: errorResponse("Backlinks feature is not available on this deployment.")
|
|
10463
10729
|
}
|
|
10464
10730
|
},
|
|
10465
10731
|
{
|
|
@@ -10469,7 +10735,7 @@ var routeCatalog = [
|
|
|
10469
10735
|
description: "Returns syncs ordered by updatedAt DESC \u2014 re-queued rows surface ahead of untouched newer rows.",
|
|
10470
10736
|
tags: ["backlinks"],
|
|
10471
10737
|
responses: {
|
|
10472
|
-
200:
|
|
10738
|
+
200: jsonArrayResponse("Sync history returned.", "CcReleaseSyncDto")
|
|
10473
10739
|
}
|
|
10474
10740
|
},
|
|
10475
10741
|
{
|
|
@@ -10478,7 +10744,10 @@ var routeCatalog = [
|
|
|
10478
10744
|
summary: "Get the most recently-updated Common Crawl release sync",
|
|
10479
10745
|
tags: ["backlinks"],
|
|
10480
10746
|
responses: {
|
|
10481
|
-
|
|
10747
|
+
// Returns CcReleaseSyncDto | null
|
|
10748
|
+
200: rawJsonResponse("Latest sync returned, or null when no sync exists.", {
|
|
10749
|
+
oneOf: [{ $ref: "#/components/schemas/CcReleaseSyncDto" }, { type: "null" }]
|
|
10750
|
+
})
|
|
10482
10751
|
}
|
|
10483
10752
|
},
|
|
10484
10753
|
{
|
|
@@ -10487,7 +10756,7 @@ var routeCatalog = [
|
|
|
10487
10756
|
summary: "List cached Common Crawl releases on the local filesystem",
|
|
10488
10757
|
tags: ["backlinks"],
|
|
10489
10758
|
responses: {
|
|
10490
|
-
200:
|
|
10759
|
+
200: jsonArrayResponse("Cached release metadata returned.", "CcCachedRelease")
|
|
10491
10760
|
}
|
|
10492
10761
|
},
|
|
10493
10762
|
{
|
|
@@ -10497,8 +10766,10 @@ var routeCatalog = [
|
|
|
10497
10766
|
description: "Probes Common Crawl by HEAD-checking quarterly release slugs and returns the newest one published. The local server caches the result for ~5 minutes so repeated calls do not hammer Common Crawl.",
|
|
10498
10767
|
tags: ["backlinks"],
|
|
10499
10768
|
responses: {
|
|
10500
|
-
200:
|
|
10501
|
-
|
|
10769
|
+
200: rawJsonResponse("Latest available release, or null when no candidate slug responded.", {
|
|
10770
|
+
oneOf: [{ $ref: "#/components/schemas/CcAvailableRelease" }, { type: "null" }]
|
|
10771
|
+
}),
|
|
10772
|
+
422: errorResponse("Backlinks feature is not available on this deployment.")
|
|
10502
10773
|
}
|
|
10503
10774
|
},
|
|
10504
10775
|
{
|
|
@@ -10516,9 +10787,10 @@ var routeCatalog = [
|
|
|
10516
10787
|
}
|
|
10517
10788
|
],
|
|
10518
10789
|
responses: {
|
|
10519
|
-
|
|
10520
|
-
|
|
10521
|
-
|
|
10790
|
+
// TODO: Add `BacklinksCachePruneResultDto` Zod schema in contracts.
|
|
10791
|
+
200: rawJsonResponse("Cache pruned.", looseObjectSchema),
|
|
10792
|
+
400: errorResponse("Invalid release id."),
|
|
10793
|
+
422: errorResponse("Backlinks feature is not available on this deployment.")
|
|
10522
10794
|
}
|
|
10523
10795
|
},
|
|
10524
10796
|
{
|
|
@@ -10542,10 +10814,10 @@ var routeCatalog = [
|
|
|
10542
10814
|
}
|
|
10543
10815
|
},
|
|
10544
10816
|
responses: {
|
|
10545
|
-
201:
|
|
10546
|
-
400:
|
|
10547
|
-
404:
|
|
10548
|
-
422:
|
|
10817
|
+
201: jsonResponse("Extract run queued.", "RunDto"),
|
|
10818
|
+
400: errorResponse("Invalid release id."),
|
|
10819
|
+
404: errorResponse("Project not found."),
|
|
10820
|
+
422: errorResponse("Backlinks feature is not available on this deployment.")
|
|
10549
10821
|
}
|
|
10550
10822
|
},
|
|
10551
10823
|
{
|
|
@@ -10558,8 +10830,10 @@ var routeCatalog = [
|
|
|
10558
10830
|
{ name: "release", in: "query", description: "Release id filter.", schema: stringSchema }
|
|
10559
10831
|
],
|
|
10560
10832
|
responses: {
|
|
10561
|
-
200:
|
|
10562
|
-
|
|
10833
|
+
200: rawJsonResponse("Summary returned, or null when no backlinks exist.", {
|
|
10834
|
+
oneOf: [{ $ref: "#/components/schemas/BacklinkSummaryDto" }, { type: "null" }]
|
|
10835
|
+
}),
|
|
10836
|
+
404: errorResponse("Project not found.")
|
|
10563
10837
|
}
|
|
10564
10838
|
},
|
|
10565
10839
|
{
|
|
@@ -10574,8 +10848,8 @@ var routeCatalog = [
|
|
|
10574
10848
|
{ name: "offset", in: "query", description: "Pagination offset.", schema: stringSchema }
|
|
10575
10849
|
],
|
|
10576
10850
|
responses: {
|
|
10577
|
-
200:
|
|
10578
|
-
404:
|
|
10851
|
+
200: jsonResponse("Domain list returned.", "BacklinkListResponse"),
|
|
10852
|
+
404: errorResponse("Project not found.")
|
|
10579
10853
|
}
|
|
10580
10854
|
},
|
|
10581
10855
|
{
|
|
@@ -10585,8 +10859,8 @@ var routeCatalog = [
|
|
|
10585
10859
|
tags: ["backlinks"],
|
|
10586
10860
|
parameters: [nameParameter],
|
|
10587
10861
|
responses: {
|
|
10588
|
-
200:
|
|
10589
|
-
404:
|
|
10862
|
+
200: jsonArrayResponse("History returned oldest-first by queriedAt.", "BacklinkHistoryEntry"),
|
|
10863
|
+
404: errorResponse("Project not found.")
|
|
10590
10864
|
}
|
|
10591
10865
|
},
|
|
10592
10866
|
{
|
|
@@ -10615,9 +10889,9 @@ var routeCatalog = [
|
|
|
10615
10889
|
}
|
|
10616
10890
|
},
|
|
10617
10891
|
responses: {
|
|
10618
|
-
200:
|
|
10619
|
-
400:
|
|
10620
|
-
404:
|
|
10892
|
+
200: jsonResponse("Traffic source DTO returned.", "TrafficSourceDto"),
|
|
10893
|
+
400: errorResponse("Invalid Cloud Run connection request."),
|
|
10894
|
+
404: errorResponse("Project not found.")
|
|
10621
10895
|
}
|
|
10622
10896
|
},
|
|
10623
10897
|
{
|
|
@@ -10645,10 +10919,10 @@ var routeCatalog = [
|
|
|
10645
10919
|
}
|
|
10646
10920
|
},
|
|
10647
10921
|
responses: {
|
|
10648
|
-
200:
|
|
10649
|
-
400:
|
|
10650
|
-
404:
|
|
10651
|
-
502:
|
|
10922
|
+
200: jsonResponse("Traffic source DTO returned.", "TrafficSourceDto"),
|
|
10923
|
+
400: errorResponse("Invalid WordPress connection request."),
|
|
10924
|
+
404: errorResponse("Project not found."),
|
|
10925
|
+
502: errorResponse("WordPress plugin endpoint probe failed (bad credentials, unreachable host, etc.).")
|
|
10652
10926
|
}
|
|
10653
10927
|
},
|
|
10654
10928
|
{
|
|
@@ -10677,10 +10951,10 @@ var routeCatalog = [
|
|
|
10677
10951
|
}
|
|
10678
10952
|
},
|
|
10679
10953
|
responses: {
|
|
10680
|
-
200:
|
|
10681
|
-
400:
|
|
10682
|
-
404:
|
|
10683
|
-
502:
|
|
10954
|
+
200: jsonResponse("Traffic source DTO returned.", "TrafficSourceDto"),
|
|
10955
|
+
400: errorResponse("Invalid Vercel connection request."),
|
|
10956
|
+
404: errorResponse("Project not found."),
|
|
10957
|
+
502: errorResponse("Vercel request-logs endpoint probe failed (bad token, wrong project / team id, unreachable host, etc.).")
|
|
10684
10958
|
}
|
|
10685
10959
|
},
|
|
10686
10960
|
{
|
|
@@ -10707,10 +10981,10 @@ var routeCatalog = [
|
|
|
10707
10981
|
}
|
|
10708
10982
|
},
|
|
10709
10983
|
responses: {
|
|
10710
|
-
200:
|
|
10711
|
-
400:
|
|
10712
|
-
404:
|
|
10713
|
-
502:
|
|
10984
|
+
200: jsonResponse("Sync summary returned.", "TrafficSyncResponse"),
|
|
10985
|
+
400: errorResponse("Invalid sync request or missing credentials."),
|
|
10986
|
+
404: errorResponse("Project or traffic source not found."),
|
|
10987
|
+
502: errorResponse("Upstream Cloud Run pull or auth-token resolution failed.")
|
|
10714
10988
|
}
|
|
10715
10989
|
},
|
|
10716
10990
|
{
|
|
@@ -10737,9 +11011,9 @@ var routeCatalog = [
|
|
|
10737
11011
|
}
|
|
10738
11012
|
},
|
|
10739
11013
|
responses: {
|
|
10740
|
-
200:
|
|
10741
|
-
400:
|
|
10742
|
-
404:
|
|
11014
|
+
200: jsonResponse("Backfill submitted; poll the returned runId for completion.", "TrafficBackfillResponse"),
|
|
11015
|
+
400: errorResponse("Invalid backfill request or missing credentials."),
|
|
11016
|
+
404: errorResponse("Project or traffic source not found.")
|
|
10743
11017
|
}
|
|
10744
11018
|
},
|
|
10745
11019
|
{
|
|
@@ -10749,8 +11023,8 @@ var routeCatalog = [
|
|
|
10749
11023
|
tags: ["traffic"],
|
|
10750
11024
|
parameters: [nameParameter],
|
|
10751
11025
|
responses: {
|
|
10752
|
-
200:
|
|
10753
|
-
404:
|
|
11026
|
+
200: jsonResponse("Source list returned.", "TrafficSourceListResponse"),
|
|
11027
|
+
404: errorResponse("Project not found.")
|
|
10754
11028
|
}
|
|
10755
11029
|
},
|
|
10756
11030
|
{
|
|
@@ -10761,8 +11035,8 @@ var routeCatalog = [
|
|
|
10761
11035
|
tags: ["traffic"],
|
|
10762
11036
|
parameters: [nameParameter],
|
|
10763
11037
|
responses: {
|
|
10764
|
-
200:
|
|
10765
|
-
404:
|
|
11038
|
+
200: jsonResponse("Status returned.", "TrafficStatusResponse"),
|
|
11039
|
+
404: errorResponse("Project not found.")
|
|
10766
11040
|
}
|
|
10767
11041
|
},
|
|
10768
11042
|
{
|
|
@@ -10775,8 +11049,8 @@ var routeCatalog = [
|
|
|
10775
11049
|
{ name: "id", in: "path", required: true, description: "Traffic source ID.", schema: stringSchema }
|
|
10776
11050
|
],
|
|
10777
11051
|
responses: {
|
|
10778
|
-
200:
|
|
10779
|
-
404:
|
|
11052
|
+
200: jsonResponse("Source detail returned.", "TrafficSourceDetailDto"),
|
|
11053
|
+
404: errorResponse("Project or source not found.")
|
|
10780
11054
|
}
|
|
10781
11055
|
},
|
|
10782
11056
|
{
|
|
@@ -10794,9 +11068,9 @@ var routeCatalog = [
|
|
|
10794
11068
|
{ name: "sourceId", in: "query", description: "Restrict to a single traffic source.", schema: stringSchema }
|
|
10795
11069
|
],
|
|
10796
11070
|
responses: {
|
|
10797
|
-
200:
|
|
10798
|
-
400:
|
|
10799
|
-
404:
|
|
11071
|
+
200: jsonResponse("Events returned with windowed totals.", "TrafficEventsResponse"),
|
|
11072
|
+
400: errorResponse("Invalid query parameters."),
|
|
11073
|
+
404: errorResponse("Project not found.")
|
|
10800
11074
|
}
|
|
10801
11075
|
},
|
|
10802
11076
|
{
|
|
@@ -10827,10 +11101,11 @@ var routeCatalog = [
|
|
|
10827
11101
|
}
|
|
10828
11102
|
},
|
|
10829
11103
|
responses: {
|
|
10830
|
-
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
|
|
11104
|
+
// TODO: Add `DiscoveryRunResponse` Zod schema in contracts (`{ runId, sessionId, status, consolidated }`).
|
|
11105
|
+
200: rawJsonResponse("An in-flight session with the same project + ICP was reused; returns { runId, sessionId, status, consolidated: true }. The request's dedupThreshold / maxProbes are ignored.", looseObjectSchema),
|
|
11106
|
+
201: rawJsonResponse("New discovery session enqueued; returns { runId, sessionId, status, consolidated: false }.", looseObjectSchema),
|
|
11107
|
+
400: errorResponse("Missing or invalid ICP / parameters."),
|
|
11108
|
+
404: errorResponse("Project not found.")
|
|
10834
11109
|
}
|
|
10835
11110
|
},
|
|
10836
11111
|
{
|
|
@@ -10844,8 +11119,8 @@ var routeCatalog = [
|
|
|
10844
11119
|
{ name: "limit", in: "query", description: "Max sessions returned. Default 50.", schema: stringSchema }
|
|
10845
11120
|
],
|
|
10846
11121
|
responses: {
|
|
10847
|
-
200:
|
|
10848
|
-
404:
|
|
11122
|
+
200: jsonArrayResponse("Sessions returned.", "DiscoverySessionDto"),
|
|
11123
|
+
404: errorResponse("Project not found.")
|
|
10849
11124
|
}
|
|
10850
11125
|
},
|
|
10851
11126
|
{
|
|
@@ -10859,8 +11134,8 @@ var routeCatalog = [
|
|
|
10859
11134
|
{ name: "id", in: "path", required: true, description: "Discovery session ID.", schema: stringSchema }
|
|
10860
11135
|
],
|
|
10861
11136
|
responses: {
|
|
10862
|
-
200:
|
|
10863
|
-
404:
|
|
11137
|
+
200: jsonResponse("Session detail returned.", "DiscoverySessionDetailDto"),
|
|
11138
|
+
404: errorResponse("Project or session not found.")
|
|
10864
11139
|
}
|
|
10865
11140
|
},
|
|
10866
11141
|
{
|
|
@@ -10874,8 +11149,8 @@ var routeCatalog = [
|
|
|
10874
11149
|
{ name: "id", in: "path", required: true, description: "Discovery session ID.", schema: stringSchema }
|
|
10875
11150
|
],
|
|
10876
11151
|
responses: {
|
|
10877
|
-
200:
|
|
10878
|
-
404:
|
|
11152
|
+
200: jsonResponse("Promote preview returned.", "DiscoveryPromotePreview"),
|
|
11153
|
+
404: errorResponse("Project or session not found.")
|
|
10879
11154
|
}
|
|
10880
11155
|
},
|
|
10881
11156
|
{
|
|
@@ -10918,9 +11193,9 @@ var routeCatalog = [
|
|
|
10918
11193
|
}
|
|
10919
11194
|
},
|
|
10920
11195
|
responses: {
|
|
10921
|
-
200:
|
|
10922
|
-
400:
|
|
10923
|
-
404:
|
|
11196
|
+
200: jsonResponse("Promotion applied; returns promoted + skipped query/competitor lists.", "DiscoveryPromoteResult"),
|
|
11197
|
+
400: errorResponse("Session is not completed, or invalid request body."),
|
|
11198
|
+
404: errorResponse("Project or session not found.")
|
|
10924
11199
|
}
|
|
10925
11200
|
}
|
|
10926
11201
|
];
|
|
@@ -10933,8 +11208,9 @@ var canonryLocalRouteCatalog = [
|
|
|
10933
11208
|
tags: ["agent"],
|
|
10934
11209
|
parameters: [nameParameter],
|
|
10935
11210
|
responses: {
|
|
10936
|
-
|
|
10937
|
-
|
|
11211
|
+
// TODO: Add `AgentTranscriptDto` Zod schema in contracts.
|
|
11212
|
+
200: rawJsonResponse("Transcript returned.", looseObjectSchema),
|
|
11213
|
+
404: errorResponse("Project not found.")
|
|
10938
11214
|
}
|
|
10939
11215
|
},
|
|
10940
11216
|
{
|
|
@@ -10945,8 +11221,9 @@ var canonryLocalRouteCatalog = [
|
|
|
10945
11221
|
tags: ["agent"],
|
|
10946
11222
|
parameters: [nameParameter],
|
|
10947
11223
|
responses: {
|
|
10948
|
-
|
|
10949
|
-
|
|
11224
|
+
// Returns { status: 'reset' } sentinel.
|
|
11225
|
+
200: rawJsonResponse("Session reset.", { type: "object", properties: { status: { type: "string", enum: ["reset"] } } }),
|
|
11226
|
+
404: errorResponse("Project not found.")
|
|
10950
11227
|
}
|
|
10951
11228
|
},
|
|
10952
11229
|
{
|
|
@@ -10957,8 +11234,9 @@ var canonryLocalRouteCatalog = [
|
|
|
10957
11234
|
tags: ["agent"],
|
|
10958
11235
|
parameters: [nameParameter],
|
|
10959
11236
|
responses: {
|
|
10960
|
-
|
|
10961
|
-
|
|
11237
|
+
// TODO: Add `AgentMemoryListResponse` Zod schema in contracts.
|
|
11238
|
+
200: rawJsonResponse("Memory entries returned.", looseObjectSchema),
|
|
11239
|
+
404: errorResponse("Project not found.")
|
|
10962
11240
|
}
|
|
10963
11241
|
},
|
|
10964
11242
|
{
|
|
@@ -10984,9 +11262,10 @@ var canonryLocalRouteCatalog = [
|
|
|
10984
11262
|
}
|
|
10985
11263
|
},
|
|
10986
11264
|
responses: {
|
|
10987
|
-
|
|
10988
|
-
|
|
10989
|
-
|
|
11265
|
+
// TODO: Add `AgentMemoryEntryDto` Zod schema in contracts.
|
|
11266
|
+
200: rawJsonResponse("Entry upserted.", looseObjectSchema),
|
|
11267
|
+
400: errorResponse("Validation failed (key length, value size, reserved prefix)."),
|
|
11268
|
+
404: errorResponse("Project not found.")
|
|
10990
11269
|
}
|
|
10991
11270
|
},
|
|
10992
11271
|
{
|
|
@@ -11011,9 +11290,10 @@ var canonryLocalRouteCatalog = [
|
|
|
11011
11290
|
}
|
|
11012
11291
|
},
|
|
11013
11292
|
responses: {
|
|
11014
|
-
|
|
11015
|
-
|
|
11016
|
-
|
|
11293
|
+
// Returns { status: 'removed' | 'missing' } sentinel.
|
|
11294
|
+
200: rawJsonResponse("Entry removed or already absent.", { type: "object", properties: { status: { type: "string", enum: ["removed", "missing"] } } }),
|
|
11295
|
+
400: errorResponse("Validation failed (reserved prefix)."),
|
|
11296
|
+
404: errorResponse("Project not found.")
|
|
11017
11297
|
}
|
|
11018
11298
|
},
|
|
11019
11299
|
{
|
|
@@ -11024,8 +11304,8 @@ var canonryLocalRouteCatalog = [
|
|
|
11024
11304
|
tags: ["agent"],
|
|
11025
11305
|
parameters: [nameParameter],
|
|
11026
11306
|
responses: {
|
|
11027
|
-
200:
|
|
11028
|
-
404:
|
|
11307
|
+
200: jsonResponse("Providers returned.", "AgentProvidersResponseDto"),
|
|
11308
|
+
404: errorResponse("Project not found.")
|
|
11029
11309
|
}
|
|
11030
11310
|
},
|
|
11031
11311
|
{
|
|
@@ -11064,10 +11344,11 @@ var canonryLocalRouteCatalog = [
|
|
|
11064
11344
|
}
|
|
11065
11345
|
},
|
|
11066
11346
|
responses: {
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11347
|
+
// Returns text/event-stream — codegen consumers should treat as a stream.
|
|
11348
|
+
200: { description: "SSE stream of AgentEvent frames.", content: { "text/event-stream": { schema: { type: "string" } } } },
|
|
11349
|
+
400: errorResponse("Missing or empty prompt."),
|
|
11350
|
+
404: errorResponse("Project not found."),
|
|
11351
|
+
409: errorResponse("Another Aero turn is already in flight.")
|
|
11071
11352
|
}
|
|
11072
11353
|
}
|
|
11073
11354
|
];
|
|
@@ -11093,8 +11374,14 @@ function buildOpenApiDocument(info = {}) {
|
|
|
11093
11374
|
acc[fullPath] = pathItem;
|
|
11094
11375
|
return acc;
|
|
11095
11376
|
}, {});
|
|
11377
|
+
const schemas = buildComponentSchemas();
|
|
11096
11378
|
return {
|
|
11097
|
-
|
|
11379
|
+
// OpenAPI 3.0 (not 3.1) so `nullable: true` on emitted schemas is the
|
|
11380
|
+
// canonical nullability marker. `z.toJSONSchema(..., { target: 'openapi-3.0' })`
|
|
11381
|
+
// outputs `nullable: true`; declaring 3.1 would tell consumers (and the
|
|
11382
|
+
// hey-api codegen) to expect 3.1-style `type: ["string", "null"]` instead,
|
|
11383
|
+
// and they'd silently strip the `null` from optional fields.
|
|
11384
|
+
openapi: "3.0.0",
|
|
11098
11385
|
info: {
|
|
11099
11386
|
title: info.title ?? "Canonry API",
|
|
11100
11387
|
version: info.version ?? "0.0.0",
|
|
@@ -11113,7 +11400,8 @@ function buildOpenApiDocument(info = {}) {
|
|
|
11113
11400
|
scheme: "bearer",
|
|
11114
11401
|
bearerFormat: "API key"
|
|
11115
11402
|
}
|
|
11116
|
-
}
|
|
11403
|
+
},
|
|
11404
|
+
schemas
|
|
11117
11405
|
},
|
|
11118
11406
|
paths
|
|
11119
11407
|
};
|
|
@@ -11288,7 +11576,7 @@ async function telemetryRoutes(app, opts) {
|
|
|
11288
11576
|
|
|
11289
11577
|
// ../api-routes/src/schedules.ts
|
|
11290
11578
|
import crypto11 from "crypto";
|
|
11291
|
-
import { and as
|
|
11579
|
+
import { and as and11, eq as eq16 } from "drizzle-orm";
|
|
11292
11580
|
function parseKindParam(raw) {
|
|
11293
11581
|
if (raw === void 0 || raw === null || raw === "") return SchedulableRunKinds["answer-visibility"];
|
|
11294
11582
|
const parsed = schedulableRunKindSchema.safeParse(raw);
|
|
@@ -11354,7 +11642,7 @@ async function scheduleRoutes(app, opts) {
|
|
|
11354
11642
|
}
|
|
11355
11643
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11356
11644
|
const enabledInt = enabled === false ? 0 : 1;
|
|
11357
|
-
const existing = app.db.select().from(schedules).where(
|
|
11645
|
+
const existing = app.db.select().from(schedules).where(and11(eq16(schedules.projectId, project.id), eq16(schedules.kind, kind))).get();
|
|
11358
11646
|
if (existing) {
|
|
11359
11647
|
app.db.update(schedules).set({
|
|
11360
11648
|
cronExpr,
|
|
@@ -11388,13 +11676,13 @@ async function scheduleRoutes(app, opts) {
|
|
|
11388
11676
|
diff: { kind, cronExpr, preset, timezone, providers, sourceId }
|
|
11389
11677
|
});
|
|
11390
11678
|
opts.onScheduleUpdated?.("upsert", project.id, kind);
|
|
11391
|
-
const schedule = app.db.select().from(schedules).where(
|
|
11679
|
+
const schedule = app.db.select().from(schedules).where(and11(eq16(schedules.projectId, project.id), eq16(schedules.kind, kind))).get();
|
|
11392
11680
|
return reply.status(existing ? 200 : 201).send(formatSchedule(schedule));
|
|
11393
11681
|
});
|
|
11394
11682
|
app.get("/projects/:name/schedule", async (request, reply) => {
|
|
11395
11683
|
const project = resolveProject(app.db, request.params.name);
|
|
11396
11684
|
const kind = parseKindParam(request.query?.kind);
|
|
11397
|
-
const schedule = app.db.select().from(schedules).where(
|
|
11685
|
+
const schedule = app.db.select().from(schedules).where(and11(eq16(schedules.projectId, project.id), eq16(schedules.kind, kind))).get();
|
|
11398
11686
|
if (!schedule) {
|
|
11399
11687
|
throw notFound("Schedule", `${request.params.name} (kind=${kind})`);
|
|
11400
11688
|
}
|
|
@@ -11403,7 +11691,7 @@ async function scheduleRoutes(app, opts) {
|
|
|
11403
11691
|
app.delete("/projects/:name/schedule", async (request, reply) => {
|
|
11404
11692
|
const project = resolveProject(app.db, request.params.name);
|
|
11405
11693
|
const kind = parseKindParam(request.query?.kind);
|
|
11406
|
-
const schedule = app.db.select().from(schedules).where(
|
|
11694
|
+
const schedule = app.db.select().from(schedules).where(and11(eq16(schedules.projectId, project.id), eq16(schedules.kind, kind))).get();
|
|
11407
11695
|
if (!schedule) {
|
|
11408
11696
|
throw notFound("Schedule", `${request.params.name} (kind=${kind})`);
|
|
11409
11697
|
}
|
|
@@ -11560,7 +11848,7 @@ function formatNotification(row) {
|
|
|
11560
11848
|
|
|
11561
11849
|
// ../api-routes/src/google.ts
|
|
11562
11850
|
import crypto14 from "crypto";
|
|
11563
|
-
import { eq as eq18, and as
|
|
11851
|
+
import { eq as eq18, and as and12, desc as desc8, sql as sql7 } from "drizzle-orm";
|
|
11564
11852
|
|
|
11565
11853
|
// ../integration-google/src/constants.ts
|
|
11566
11854
|
var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
@@ -12814,7 +13102,7 @@ async function googleRoutes(app, opts) {
|
|
|
12814
13102
|
if (page) conditions.push(sql7`${gscSearchData.page} LIKE ${"%" + page + "%"}`);
|
|
12815
13103
|
const limitVal = Math.max(parseInt(limit ?? "500", 10) || 0, 1);
|
|
12816
13104
|
const offsetVal = Math.max(parseInt(offset ?? "0", 10) || 0, 0);
|
|
12817
|
-
const rows = app.db.select().from(gscSearchData).where(
|
|
13105
|
+
const rows = app.db.select().from(gscSearchData).where(and12(...conditions)).orderBy(desc8(gscSearchData.date)).limit(limitVal).offset(offsetVal).all();
|
|
12818
13106
|
return rows.map((r) => ({
|
|
12819
13107
|
date: r.date,
|
|
12820
13108
|
query: r.query,
|
|
@@ -12839,7 +13127,7 @@ async function googleRoutes(app, opts) {
|
|
|
12839
13127
|
date: gscSearchData.date,
|
|
12840
13128
|
clicks: sql7`COALESCE(SUM(${gscSearchData.clicks}), 0)`,
|
|
12841
13129
|
impressions: sql7`COALESCE(SUM(${gscSearchData.impressions}), 0)`
|
|
12842
|
-
}).from(gscSearchData).where(
|
|
13130
|
+
}).from(gscSearchData).where(and12(...conditions)).groupBy(gscSearchData.date).orderBy(gscSearchData.date).all();
|
|
12843
13131
|
const daily = rows.map((r) => ({
|
|
12844
13132
|
date: r.date,
|
|
12845
13133
|
clicks: r.clicks,
|
|
@@ -12919,7 +13207,7 @@ async function googleRoutes(app, opts) {
|
|
|
12919
13207
|
const { url, limit } = request.query;
|
|
12920
13208
|
const conditions = [eq18(gscUrlInspections.projectId, project.id)];
|
|
12921
13209
|
if (url) conditions.push(eq18(gscUrlInspections.url, url));
|
|
12922
|
-
const rows = app.db.select().from(gscUrlInspections).where(
|
|
13210
|
+
const rows = app.db.select().from(gscUrlInspections).where(and12(...conditions)).orderBy(desc8(gscUrlInspections.inspectedAt)).limit(parseInt(limit ?? "100", 10)).all();
|
|
12923
13211
|
return rows.map((r) => ({
|
|
12924
13212
|
id: r.id,
|
|
12925
13213
|
url: r.url,
|
|
@@ -13271,7 +13559,7 @@ async function googleRoutes(app, opts) {
|
|
|
13271
13559
|
|
|
13272
13560
|
// ../api-routes/src/bing.ts
|
|
13273
13561
|
import crypto15 from "crypto";
|
|
13274
|
-
import { eq as eq19, and as
|
|
13562
|
+
import { eq as eq19, and as and13, desc as desc9 } from "drizzle-orm";
|
|
13275
13563
|
|
|
13276
13564
|
// ../integration-bing/src/constants.ts
|
|
13277
13565
|
var BING_WMT_API_BASE = "https://ssl.bing.com/webmaster/api.svc/json";
|
|
@@ -13685,7 +13973,7 @@ async function bingRoutes(app, opts) {
|
|
|
13685
13973
|
requireConnectionStore();
|
|
13686
13974
|
const project = resolveProject(app.db, request.params.name);
|
|
13687
13975
|
const { url, limit } = request.query;
|
|
13688
|
-
const whereClause = url ?
|
|
13976
|
+
const whereClause = url ? and13(eq19(bingUrlInspections.projectId, project.id), eq19(bingUrlInspections.url, url)) : eq19(bingUrlInspections.projectId, project.id);
|
|
13689
13977
|
const filtered = app.db.select().from(bingUrlInspections).where(whereClause).orderBy(desc9(bingUrlInspections.inspectedAt)).limit(Math.max(1, Math.min(parseInt(limit ?? "100", 10) || 100, 1e3))).all();
|
|
13690
13978
|
return filtered.map((r) => ({
|
|
13691
13979
|
id: r.id,
|
|
@@ -13917,7 +14205,7 @@ async function bingRoutes(app, opts) {
|
|
|
13917
14205
|
import fs from "fs";
|
|
13918
14206
|
import path from "path";
|
|
13919
14207
|
import os2 from "os";
|
|
13920
|
-
import { eq as eq20, and as
|
|
14208
|
+
import { eq as eq20, and as and14 } from "drizzle-orm";
|
|
13921
14209
|
function getScreenshotDir() {
|
|
13922
14210
|
return path.join(os2.homedir(), ".canonry", "screenshots");
|
|
13923
14211
|
}
|
|
@@ -13990,7 +14278,7 @@ async function cdpRoutes(app, opts) {
|
|
|
13990
14278
|
async (request, reply) => {
|
|
13991
14279
|
const project = resolveProject(app.db, request.params.name);
|
|
13992
14280
|
const { runId } = request.params;
|
|
13993
|
-
const run = app.db.select().from(runs).where(
|
|
14281
|
+
const run = app.db.select().from(runs).where(and14(eq20(runs.id, runId), eq20(runs.projectId, project.id))).get();
|
|
13994
14282
|
if (!run) {
|
|
13995
14283
|
const err = notFound("Run", runId);
|
|
13996
14284
|
return reply.code(err.statusCode).send(err.toJSON());
|
|
@@ -14087,7 +14375,7 @@ async function cdpRoutes(app, opts) {
|
|
|
14087
14375
|
|
|
14088
14376
|
// ../api-routes/src/ga.ts
|
|
14089
14377
|
import crypto16 from "crypto";
|
|
14090
|
-
import { eq as eq21, desc as desc10, and as
|
|
14378
|
+
import { eq as eq21, desc as desc10, and as and15, sql as sql8 } from "drizzle-orm";
|
|
14091
14379
|
function gaLog(level, action, ctx) {
|
|
14092
14380
|
const entry = { ts: (/* @__PURE__ */ new Date()).toISOString(), level, module: "GA4Routes", action, ...ctx };
|
|
14093
14381
|
const stream = level === "error" ? process.stderr : process.stdout;
|
|
@@ -14382,7 +14670,7 @@ async function ga4Routes(app, opts) {
|
|
|
14382
14670
|
app.db.transaction((tx) => {
|
|
14383
14671
|
if (syncTraffic) {
|
|
14384
14672
|
tx.delete(gaTrafficSnapshots).where(
|
|
14385
|
-
|
|
14673
|
+
and15(
|
|
14386
14674
|
eq21(gaTrafficSnapshots.projectId, project.id),
|
|
14387
14675
|
sql8`${gaTrafficSnapshots.date} >= ${summary.periodStart}`,
|
|
14388
14676
|
sql8`${gaTrafficSnapshots.date} <= ${summary.periodEnd}`
|
|
@@ -14406,7 +14694,7 @@ async function ga4Routes(app, opts) {
|
|
|
14406
14694
|
}
|
|
14407
14695
|
if (syncAi) {
|
|
14408
14696
|
tx.delete(gaAiReferrals).where(
|
|
14409
|
-
|
|
14697
|
+
and15(
|
|
14410
14698
|
eq21(gaAiReferrals.projectId, project.id),
|
|
14411
14699
|
sql8`${gaAiReferrals.date} >= ${summary.periodStart}`,
|
|
14412
14700
|
sql8`${gaAiReferrals.date} <= ${summary.periodEnd}`
|
|
@@ -14432,7 +14720,7 @@ async function ga4Routes(app, opts) {
|
|
|
14432
14720
|
}
|
|
14433
14721
|
if (syncSocial) {
|
|
14434
14722
|
tx.delete(gaSocialReferrals).where(
|
|
14435
|
-
|
|
14723
|
+
and15(
|
|
14436
14724
|
eq21(gaSocialReferrals.projectId, project.id),
|
|
14437
14725
|
sql8`${gaSocialReferrals.date} >= ${summary.periodStart}`,
|
|
14438
14726
|
sql8`${gaSocialReferrals.date} <= ${summary.periodEnd}`
|
|
@@ -14536,7 +14824,7 @@ async function ga4Routes(app, opts) {
|
|
|
14536
14824
|
totalDirectSessions: gaTrafficWindowSummaries.totalDirectSessions,
|
|
14537
14825
|
totalUsers: gaTrafficWindowSummaries.totalUsers
|
|
14538
14826
|
}).from(gaTrafficWindowSummaries).where(
|
|
14539
|
-
|
|
14827
|
+
and15(
|
|
14540
14828
|
eq21(gaTrafficWindowSummaries.projectId, project.id),
|
|
14541
14829
|
eq21(gaTrafficWindowSummaries.windowKey, window)
|
|
14542
14830
|
)
|
|
@@ -14545,7 +14833,7 @@ async function ga4Routes(app, opts) {
|
|
|
14545
14833
|
totalSessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)`,
|
|
14546
14834
|
totalOrganicSessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)`,
|
|
14547
14835
|
totalUsers: sql8`COALESCE(SUM(${gaTrafficSnapshots.users}), 0)`
|
|
14548
|
-
}).from(gaTrafficSnapshots).where(
|
|
14836
|
+
}).from(gaTrafficSnapshots).where(and15(...snapshotConditions)).get() : null;
|
|
14549
14837
|
const summaryRow = cutoffDate ? windowSummaryRow ?? snapshotTotalsRow : app.db.select({
|
|
14550
14838
|
totalSessions: gaTrafficSummaries.totalSessions,
|
|
14551
14839
|
totalOrganicSessions: gaTrafficSummaries.totalOrganicSessions,
|
|
@@ -14553,7 +14841,7 @@ async function ga4Routes(app, opts) {
|
|
|
14553
14841
|
}).from(gaTrafficSummaries).where(eq21(gaTrafficSummaries.projectId, project.id)).get();
|
|
14554
14842
|
const directTotalRow = windowSummaryRow ? { totalDirectSessions: windowSummaryRow.totalDirectSessions } : app.db.select({
|
|
14555
14843
|
totalDirectSessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`
|
|
14556
|
-
}).from(gaTrafficSnapshots).where(
|
|
14844
|
+
}).from(gaTrafficSnapshots).where(and15(...snapshotConditions)).get();
|
|
14557
14845
|
const summaryMeta = app.db.select({
|
|
14558
14846
|
periodStart: gaTrafficSummaries.periodStart,
|
|
14559
14847
|
periodEnd: gaTrafficSummaries.periodEnd
|
|
@@ -14564,14 +14852,14 @@ async function ga4Routes(app, opts) {
|
|
|
14564
14852
|
organicSessions: sql8`SUM(${gaTrafficSnapshots.organicSessions})`,
|
|
14565
14853
|
directSessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)`,
|
|
14566
14854
|
users: sql8`SUM(${gaTrafficSnapshots.users})`
|
|
14567
|
-
}).from(gaTrafficSnapshots).where(
|
|
14855
|
+
}).from(gaTrafficSnapshots).where(and15(...snapshotConditions)).groupBy(sql8`COALESCE(${gaTrafficSnapshots.landingPageNormalized}, ${gaTrafficSnapshots.landingPage})`).orderBy(sql8`SUM(${gaTrafficSnapshots.sessions}) DESC`).limit(limit).all();
|
|
14568
14856
|
const aiReferralRows = app.db.select({
|
|
14569
14857
|
source: gaAiReferrals.source,
|
|
14570
14858
|
medium: gaAiReferrals.medium,
|
|
14571
14859
|
sourceDimension: gaAiReferrals.sourceDimension,
|
|
14572
14860
|
sessions: sql8`SUM(${gaAiReferrals.sessions})`,
|
|
14573
14861
|
users: sql8`SUM(${gaAiReferrals.users})`
|
|
14574
|
-
}).from(gaAiReferrals).where(
|
|
14862
|
+
}).from(gaAiReferrals).where(and15(...aiConditions)).groupBy(gaAiReferrals.source, gaAiReferrals.medium, gaAiReferrals.sourceDimension).all();
|
|
14575
14863
|
const aiReferralLandingPageRows = app.db.select({
|
|
14576
14864
|
source: gaAiReferrals.source,
|
|
14577
14865
|
medium: gaAiReferrals.medium,
|
|
@@ -14579,7 +14867,7 @@ async function ga4Routes(app, opts) {
|
|
|
14579
14867
|
landingPage: sql8`COALESCE(${gaAiReferrals.landingPageNormalized}, ${gaAiReferrals.landingPage})`,
|
|
14580
14868
|
sessions: sql8`SUM(${gaAiReferrals.sessions})`,
|
|
14581
14869
|
users: sql8`SUM(${gaAiReferrals.users})`
|
|
14582
|
-
}).from(gaAiReferrals).where(
|
|
14870
|
+
}).from(gaAiReferrals).where(and15(...aiConditions)).groupBy(
|
|
14583
14871
|
gaAiReferrals.source,
|
|
14584
14872
|
gaAiReferrals.medium,
|
|
14585
14873
|
gaAiReferrals.sourceDimension,
|
|
@@ -14616,7 +14904,7 @@ async function ga4Routes(app, opts) {
|
|
|
14616
14904
|
channelGroup: gaAiReferrals.channelGroup,
|
|
14617
14905
|
sessions: sql8`COALESCE(SUM(${gaAiReferrals.sessions}), 0)`,
|
|
14618
14906
|
users: sql8`COALESCE(SUM(${gaAiReferrals.users}), 0)`
|
|
14619
|
-
}).from(gaAiReferrals).where(
|
|
14907
|
+
}).from(gaAiReferrals).where(and15(...aiConditions, eq21(gaAiReferrals.sourceDimension, "session"))).groupBy(gaAiReferrals.channelGroup).all();
|
|
14620
14908
|
const aiSessionsByChannelGroup = /* @__PURE__ */ new Map();
|
|
14621
14909
|
let aiBySessionUsers = 0;
|
|
14622
14910
|
for (const row of aiBySessionRows) {
|
|
@@ -14630,11 +14918,11 @@ async function ga4Routes(app, opts) {
|
|
|
14630
14918
|
channelGroup: gaSocialReferrals.channelGroup,
|
|
14631
14919
|
sessions: sql8`SUM(${gaSocialReferrals.sessions})`,
|
|
14632
14920
|
users: sql8`SUM(${gaSocialReferrals.users})`
|
|
14633
|
-
}).from(gaSocialReferrals).where(
|
|
14921
|
+
}).from(gaSocialReferrals).where(and15(...socialConditions)).groupBy(gaSocialReferrals.source, gaSocialReferrals.medium, gaSocialReferrals.channelGroup).orderBy(sql8`SUM(${gaSocialReferrals.sessions}) DESC`).all();
|
|
14634
14922
|
const socialTotals = app.db.select({
|
|
14635
14923
|
sessions: sql8`SUM(${gaSocialReferrals.sessions})`,
|
|
14636
14924
|
users: sql8`SUM(${gaSocialReferrals.users})`
|
|
14637
|
-
}).from(gaSocialReferrals).where(
|
|
14925
|
+
}).from(gaSocialReferrals).where(and15(...socialConditions)).get();
|
|
14638
14926
|
const latestSync = app.db.select({ syncedAt: gaTrafficSummaries.syncedAt }).from(gaTrafficSummaries).where(eq21(gaTrafficSummaries.projectId, project.id)).orderBy(desc10(gaTrafficSummaries.syncedAt)).limit(1).get();
|
|
14639
14927
|
const total = summaryRow?.totalSessions ?? 0;
|
|
14640
14928
|
const totalDirectSessions = directTotalRow?.totalDirectSessions ?? 0;
|
|
@@ -14725,7 +15013,7 @@ async function ga4Routes(app, opts) {
|
|
|
14725
15013
|
sourceDimension: gaAiReferrals.sourceDimension,
|
|
14726
15014
|
sessions: sql8`SUM(${gaAiReferrals.sessions})`,
|
|
14727
15015
|
users: sql8`SUM(${gaAiReferrals.users})`
|
|
14728
|
-
}).from(gaAiReferrals).where(
|
|
15016
|
+
}).from(gaAiReferrals).where(and15(...conditions)).groupBy(
|
|
14729
15017
|
gaAiReferrals.date,
|
|
14730
15018
|
gaAiReferrals.source,
|
|
14731
15019
|
gaAiReferrals.medium,
|
|
@@ -14747,7 +15035,7 @@ async function ga4Routes(app, opts) {
|
|
|
14747
15035
|
channelGroup: gaSocialReferrals.channelGroup,
|
|
14748
15036
|
sessions: gaSocialReferrals.sessions,
|
|
14749
15037
|
users: gaSocialReferrals.users
|
|
14750
|
-
}).from(gaSocialReferrals).where(
|
|
15038
|
+
}).from(gaSocialReferrals).where(and15(...conditions)).orderBy(gaSocialReferrals.date).all();
|
|
14751
15039
|
return rows;
|
|
14752
15040
|
});
|
|
14753
15041
|
app.get("/projects/:name/ga/social-referral-trend", async (request, _reply) => {
|
|
@@ -14760,7 +15048,7 @@ async function ga4Routes(app, opts) {
|
|
|
14760
15048
|
d.setDate(d.getDate() - n);
|
|
14761
15049
|
return fmt(d);
|
|
14762
15050
|
};
|
|
14763
|
-
const sumSocial = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(
|
|
15051
|
+
const sumSocial = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and15(
|
|
14764
15052
|
eq21(gaSocialReferrals.projectId, project.id),
|
|
14765
15053
|
sql8`${gaSocialReferrals.date} >= ${from}`,
|
|
14766
15054
|
sql8`${gaSocialReferrals.date} < ${to}`
|
|
@@ -14773,7 +15061,7 @@ async function ga4Routes(app, opts) {
|
|
|
14773
15061
|
const sourceCurrent = app.db.select({
|
|
14774
15062
|
source: gaSocialReferrals.source,
|
|
14775
15063
|
sessions: sql8`SUM(${gaSocialReferrals.sessions})`
|
|
14776
|
-
}).from(gaSocialReferrals).where(
|
|
15064
|
+
}).from(gaSocialReferrals).where(and15(
|
|
14777
15065
|
eq21(gaSocialReferrals.projectId, project.id),
|
|
14778
15066
|
sql8`${gaSocialReferrals.date} >= ${daysAgo2(7)}`,
|
|
14779
15067
|
sql8`${gaSocialReferrals.date} < ${fmt(today)}`
|
|
@@ -14781,7 +15069,7 @@ async function ga4Routes(app, opts) {
|
|
|
14781
15069
|
const sourcePrev = app.db.select({
|
|
14782
15070
|
source: gaSocialReferrals.source,
|
|
14783
15071
|
sessions: sql8`SUM(${gaSocialReferrals.sessions})`
|
|
14784
|
-
}).from(gaSocialReferrals).where(
|
|
15072
|
+
}).from(gaSocialReferrals).where(and15(
|
|
14785
15073
|
eq21(gaSocialReferrals.projectId, project.id),
|
|
14786
15074
|
sql8`${gaSocialReferrals.date} >= ${daysAgo2(14)}`,
|
|
14787
15075
|
sql8`${gaSocialReferrals.date} < ${daysAgo2(7)}`
|
|
@@ -14823,16 +15111,16 @@ async function ga4Routes(app, opts) {
|
|
|
14823
15111
|
return fmt(d);
|
|
14824
15112
|
};
|
|
14825
15113
|
const pct = (cur, prev) => prev === 0 ? null : Math.round((cur - prev) / prev * 100);
|
|
14826
|
-
const sumTotal = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)` }).from(gaTrafficSnapshots).where(
|
|
14827
|
-
const sumOrganic = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)` }).from(gaTrafficSnapshots).where(
|
|
14828
|
-
const sumDirect = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)` }).from(gaTrafficSnapshots).where(
|
|
14829
|
-
const sumAi = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(
|
|
15114
|
+
const sumTotal = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.sessions}), 0)` }).from(gaTrafficSnapshots).where(and15(eq21(gaTrafficSnapshots.projectId, project.id), sql8`${gaTrafficSnapshots.date} >= ${from}`, sql8`${gaTrafficSnapshots.date} < ${to}`)).get();
|
|
15115
|
+
const sumOrganic = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.organicSessions}), 0)` }).from(gaTrafficSnapshots).where(and15(eq21(gaTrafficSnapshots.projectId, project.id), sql8`${gaTrafficSnapshots.date} >= ${from}`, sql8`${gaTrafficSnapshots.date} < ${to}`)).get();
|
|
15116
|
+
const sumDirect = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaTrafficSnapshots.directSessions}), 0)` }).from(gaTrafficSnapshots).where(and15(eq21(gaTrafficSnapshots.projectId, project.id), sql8`${gaTrafficSnapshots.date} >= ${from}`, sql8`${gaTrafficSnapshots.date} < ${to}`)).get();
|
|
15117
|
+
const sumAi = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and15(
|
|
14830
15118
|
eq21(gaAiReferrals.projectId, project.id),
|
|
14831
15119
|
sql8`${gaAiReferrals.date} >= ${from}`,
|
|
14832
15120
|
sql8`${gaAiReferrals.date} < ${to}`,
|
|
14833
15121
|
eq21(gaAiReferrals.sourceDimension, "session")
|
|
14834
15122
|
)).get();
|
|
14835
|
-
const sumSocial = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(
|
|
15123
|
+
const sumSocial = (from, to) => app.db.select({ sessions: sql8`COALESCE(SUM(${gaSocialReferrals.sessions}), 0)` }).from(gaSocialReferrals).where(and15(eq21(gaSocialReferrals.projectId, project.id), sql8`${gaSocialReferrals.date} >= ${from}`, sql8`${gaSocialReferrals.date} < ${to}`)).get();
|
|
14836
15124
|
const todayStr = fmt(today);
|
|
14837
15125
|
const buildTrend = (sum) => {
|
|
14838
15126
|
const c7 = sum(daysAgo2(7), todayStr)?.sessions ?? 0;
|
|
@@ -14841,13 +15129,13 @@ async function ga4Routes(app, opts) {
|
|
|
14841
15129
|
const p30 = sum(daysAgo2(60), daysAgo2(30))?.sessions ?? 0;
|
|
14842
15130
|
return { sessions7d: c7, sessionsPrev7d: p7, trend7dPct: pct(c7, p7), sessions30d: c30, sessionsPrev30d: p30, trend30dPct: pct(c30, p30) };
|
|
14843
15131
|
};
|
|
14844
|
-
const aiSourceCurrent = app.db.select({ source: gaAiReferrals.source, sessions: sql8`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(
|
|
15132
|
+
const aiSourceCurrent = app.db.select({ source: gaAiReferrals.source, sessions: sql8`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and15(
|
|
14845
15133
|
eq21(gaAiReferrals.projectId, project.id),
|
|
14846
15134
|
sql8`${gaAiReferrals.date} >= ${daysAgo2(7)}`,
|
|
14847
15135
|
sql8`${gaAiReferrals.date} < ${todayStr}`,
|
|
14848
15136
|
eq21(gaAiReferrals.sourceDimension, "session")
|
|
14849
15137
|
)).groupBy(gaAiReferrals.source).all();
|
|
14850
|
-
const aiSourcePrev = app.db.select({ source: gaAiReferrals.source, sessions: sql8`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(
|
|
15138
|
+
const aiSourcePrev = app.db.select({ source: gaAiReferrals.source, sessions: sql8`COALESCE(SUM(${gaAiReferrals.sessions}), 0)` }).from(gaAiReferrals).where(and15(
|
|
14851
15139
|
eq21(gaAiReferrals.projectId, project.id),
|
|
14852
15140
|
sql8`${gaAiReferrals.date} >= ${daysAgo2(14)}`,
|
|
14853
15141
|
sql8`${gaAiReferrals.date} < ${daysAgo2(7)}`,
|
|
@@ -14867,8 +15155,8 @@ async function ga4Routes(app, opts) {
|
|
|
14867
15155
|
}
|
|
14868
15156
|
return mover;
|
|
14869
15157
|
};
|
|
14870
|
-
const socialSourceCurrent = app.db.select({ source: gaSocialReferrals.source, sessions: sql8`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(
|
|
14871
|
-
const socialSourcePrev = app.db.select({ source: gaSocialReferrals.source, sessions: sql8`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(
|
|
15158
|
+
const socialSourceCurrent = app.db.select({ source: gaSocialReferrals.source, sessions: sql8`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and15(eq21(gaSocialReferrals.projectId, project.id), sql8`${gaSocialReferrals.date} >= ${daysAgo2(7)}`, sql8`${gaSocialReferrals.date} < ${todayStr}`)).groupBy(gaSocialReferrals.source).all();
|
|
15159
|
+
const socialSourcePrev = app.db.select({ source: gaSocialReferrals.source, sessions: sql8`SUM(${gaSocialReferrals.sessions})` }).from(gaSocialReferrals).where(and15(eq21(gaSocialReferrals.projectId, project.id), sql8`${gaSocialReferrals.date} >= ${daysAgo2(14)}`, sql8`${gaSocialReferrals.date} < ${daysAgo2(7)}`)).groupBy(gaSocialReferrals.source).all();
|
|
14872
15160
|
return {
|
|
14873
15161
|
total: buildTrend(sumTotal),
|
|
14874
15162
|
organic: buildTrend(sumOrganic),
|
|
@@ -14890,7 +15178,7 @@ async function ga4Routes(app, opts) {
|
|
|
14890
15178
|
sessions: sql8`SUM(${gaTrafficSnapshots.sessions})`,
|
|
14891
15179
|
organicSessions: sql8`SUM(${gaTrafficSnapshots.organicSessions})`,
|
|
14892
15180
|
users: sql8`SUM(${gaTrafficSnapshots.users})`
|
|
14893
|
-
}).from(gaTrafficSnapshots).where(
|
|
15181
|
+
}).from(gaTrafficSnapshots).where(and15(...conditions)).groupBy(gaTrafficSnapshots.date).orderBy(gaTrafficSnapshots.date).all();
|
|
14894
15182
|
return rows.map((r) => ({
|
|
14895
15183
|
date: r.date,
|
|
14896
15184
|
sessions: r.sessions ?? 0,
|
|
@@ -16543,7 +16831,7 @@ async function wordpressRoutes(app, opts) {
|
|
|
16543
16831
|
|
|
16544
16832
|
// ../api-routes/src/backlinks.ts
|
|
16545
16833
|
import crypto18 from "crypto";
|
|
16546
|
-
import { and as
|
|
16834
|
+
import { and as and17, asc as asc2, desc as desc11, eq as eq22, sql as sql9 } from "drizzle-orm";
|
|
16547
16835
|
|
|
16548
16836
|
// ../integration-commoncrawl/src/constants.ts
|
|
16549
16837
|
import os3 from "os";
|
|
@@ -16940,7 +17228,7 @@ function pruneCachedRelease(release, opts = {}) {
|
|
|
16940
17228
|
}
|
|
16941
17229
|
|
|
16942
17230
|
// ../api-routes/src/backlinks-filter.ts
|
|
16943
|
-
import { and as
|
|
17231
|
+
import { and as and16, ne as ne3, notLike } from "drizzle-orm";
|
|
16944
17232
|
var BACKLINK_FILTER_PATTERNS = [
|
|
16945
17233
|
"*.google.com",
|
|
16946
17234
|
"*.googleusercontent.com",
|
|
@@ -16957,13 +17245,13 @@ function backlinkCrawlerExclusionClause() {
|
|
|
16957
17245
|
for (const pattern of BACKLINK_FILTER_PATTERNS) {
|
|
16958
17246
|
if (pattern.startsWith("*.")) {
|
|
16959
17247
|
const suffix = pattern.slice(2);
|
|
16960
|
-
conditions.push(
|
|
17248
|
+
conditions.push(ne3(backlinkDomains.linkingDomain, suffix));
|
|
16961
17249
|
conditions.push(notLike(backlinkDomains.linkingDomain, `%.${suffix}`));
|
|
16962
17250
|
} else {
|
|
16963
|
-
conditions.push(
|
|
17251
|
+
conditions.push(ne3(backlinkDomains.linkingDomain, pattern));
|
|
16964
17252
|
}
|
|
16965
17253
|
}
|
|
16966
|
-
const combined =
|
|
17254
|
+
const combined = and16(...conditions);
|
|
16967
17255
|
if (!combined) throw new Error("BACKLINK_FILTER_PATTERNS is unexpectedly empty");
|
|
16968
17256
|
return combined;
|
|
16969
17257
|
}
|
|
@@ -17024,7 +17312,7 @@ function mapRunRow(row) {
|
|
|
17024
17312
|
};
|
|
17025
17313
|
}
|
|
17026
17314
|
function latestSummaryForProject(db, projectId, release) {
|
|
17027
|
-
const condition = release ?
|
|
17315
|
+
const condition = release ? and17(eq22(backlinkSummaries.projectId, projectId), eq22(backlinkSummaries.release, release)) : eq22(backlinkSummaries.projectId, projectId);
|
|
17028
17316
|
return db.select().from(backlinkSummaries).where(condition).orderBy(desc11(backlinkSummaries.queriedAt)).limit(1).get();
|
|
17029
17317
|
}
|
|
17030
17318
|
function parseExcludeCrawlers(value) {
|
|
@@ -17033,11 +17321,11 @@ function parseExcludeCrawlers(value) {
|
|
|
17033
17321
|
return lower === "1" || lower === "true" || lower === "yes";
|
|
17034
17322
|
}
|
|
17035
17323
|
function computeFilteredSummary(db, base) {
|
|
17036
|
-
const baseDomainCondition =
|
|
17324
|
+
const baseDomainCondition = and17(
|
|
17037
17325
|
eq22(backlinkDomains.projectId, base.projectId),
|
|
17038
17326
|
eq22(backlinkDomains.release, base.release)
|
|
17039
17327
|
);
|
|
17040
|
-
const filteredCondition =
|
|
17328
|
+
const filteredCondition = and17(baseDomainCondition, backlinkCrawlerExclusionClause());
|
|
17041
17329
|
const unfilteredAgg = db.select({
|
|
17042
17330
|
count: sql9`count(*)`,
|
|
17043
17331
|
total: sql9`coalesce(sum(${backlinkDomains.numHosts}), 0)`
|
|
@@ -17213,11 +17501,11 @@ async function backlinksRoutes(app, opts) {
|
|
|
17213
17501
|
const limit = Math.min(Math.max(parseInt(request.query.limit ?? "50", 10) || 50, 1), 500);
|
|
17214
17502
|
const offset = Math.max(parseInt(request.query.offset ?? "0", 10) || 0, 0);
|
|
17215
17503
|
const excludeCrawlers = parseExcludeCrawlers(request.query.excludeCrawlers);
|
|
17216
|
-
const baseDomainCondition =
|
|
17504
|
+
const baseDomainCondition = and17(
|
|
17217
17505
|
eq22(backlinkDomains.projectId, project.id),
|
|
17218
17506
|
eq22(backlinkDomains.release, targetRelease)
|
|
17219
17507
|
);
|
|
17220
|
-
const domainCondition = excludeCrawlers ?
|
|
17508
|
+
const domainCondition = excludeCrawlers ? and17(baseDomainCondition, backlinkCrawlerExclusionClause()) : baseDomainCondition;
|
|
17221
17509
|
const totalRow = app.db.select({ count: sql9`count(*)` }).from(backlinkDomains).where(domainCondition).get();
|
|
17222
17510
|
const rows = app.db.select({
|
|
17223
17511
|
linkingDomain: backlinkDomains.linkingDomain,
|
|
@@ -17253,7 +17541,7 @@ async function backlinksRoutes(app, opts) {
|
|
|
17253
17541
|
|
|
17254
17542
|
// ../api-routes/src/traffic.ts
|
|
17255
17543
|
import crypto20 from "crypto";
|
|
17256
|
-
import { and as
|
|
17544
|
+
import { and as and18, desc as desc12, eq as eq23, gte as gte2, lte as lte2, sql as sql10 } from "drizzle-orm";
|
|
17257
17545
|
|
|
17258
17546
|
// ../integration-cloud-run/src/auth.ts
|
|
17259
17547
|
import crypto19 from "crypto";
|
|
@@ -18402,21 +18690,21 @@ async function runBackfillTask(options) {
|
|
|
18402
18690
|
try {
|
|
18403
18691
|
app.db.transaction((tx) => {
|
|
18404
18692
|
tx.delete(crawlerEventsHourly).where(
|
|
18405
|
-
|
|
18693
|
+
and18(
|
|
18406
18694
|
eq23(crawlerEventsHourly.sourceId, sourceRow.id),
|
|
18407
18695
|
gte2(crawlerEventsHourly.tsHour, windowStartIso),
|
|
18408
18696
|
lte2(crawlerEventsHourly.tsHour, windowEndIso)
|
|
18409
18697
|
)
|
|
18410
18698
|
).run();
|
|
18411
18699
|
tx.delete(aiReferralEventsHourly).where(
|
|
18412
|
-
|
|
18700
|
+
and18(
|
|
18413
18701
|
eq23(aiReferralEventsHourly.sourceId, sourceRow.id),
|
|
18414
18702
|
gte2(aiReferralEventsHourly.tsHour, windowStartIso),
|
|
18415
18703
|
lte2(aiReferralEventsHourly.tsHour, windowEndIso)
|
|
18416
18704
|
)
|
|
18417
18705
|
).run();
|
|
18418
18706
|
tx.delete(rawEventSamples).where(
|
|
18419
|
-
|
|
18707
|
+
and18(
|
|
18420
18708
|
eq23(rawEventSamples.sourceId, sourceRow.id),
|
|
18421
18709
|
gte2(rawEventSamples.ts, windowStartIso),
|
|
18422
18710
|
lte2(rawEventSamples.ts, windowEndIso)
|
|
@@ -19280,25 +19568,25 @@ async function trafficRoutes(app, opts) {
|
|
|
19280
19568
|
});
|
|
19281
19569
|
function buildSourceDetail(projectId, row, since) {
|
|
19282
19570
|
const crawlerTotals = app.db.select({ total: sql10`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
|
|
19283
|
-
|
|
19571
|
+
and18(
|
|
19284
19572
|
eq23(crawlerEventsHourly.sourceId, row.id),
|
|
19285
19573
|
gte2(crawlerEventsHourly.tsHour, since)
|
|
19286
19574
|
)
|
|
19287
19575
|
).get();
|
|
19288
19576
|
const aiTotals = app.db.select({ total: sql10`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
|
|
19289
|
-
|
|
19577
|
+
and18(
|
|
19290
19578
|
eq23(aiReferralEventsHourly.sourceId, row.id),
|
|
19291
19579
|
gte2(aiReferralEventsHourly.tsHour, since)
|
|
19292
19580
|
)
|
|
19293
19581
|
).get();
|
|
19294
19582
|
const sampleTotals = app.db.select({ total: sql10`COUNT(*)` }).from(rawEventSamples).where(
|
|
19295
|
-
|
|
19583
|
+
and18(
|
|
19296
19584
|
eq23(rawEventSamples.sourceId, row.id),
|
|
19297
19585
|
gte2(rawEventSamples.ts, since)
|
|
19298
19586
|
)
|
|
19299
19587
|
).get();
|
|
19300
19588
|
const latestRun = app.db.select().from(runs).where(
|
|
19301
|
-
|
|
19589
|
+
and18(
|
|
19302
19590
|
eq23(runs.projectId, projectId),
|
|
19303
19591
|
eq23(runs.kind, RunKinds["traffic-sync"]),
|
|
19304
19592
|
eq23(runs.sourceId, row.id)
|
|
@@ -19392,7 +19680,7 @@ async function trafficRoutes(app, opts) {
|
|
|
19392
19680
|
lte2(crawlerEventsHourly.tsHour, untilIso)
|
|
19393
19681
|
];
|
|
19394
19682
|
if (sourceIdParam) crawlerFilters.push(eq23(crawlerEventsHourly.sourceId, sourceIdParam));
|
|
19395
|
-
const crawlerWhere =
|
|
19683
|
+
const crawlerWhere = and18(...crawlerFilters);
|
|
19396
19684
|
const total = app.db.select({ total: sql10`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(crawlerWhere).get();
|
|
19397
19685
|
crawlerTotal = Number(total?.total ?? 0);
|
|
19398
19686
|
const rows = app.db.select().from(crawlerEventsHourly).where(crawlerWhere).orderBy(desc12(crawlerEventsHourly.tsHour)).limit(limit).all();
|
|
@@ -19417,7 +19705,7 @@ async function trafficRoutes(app, opts) {
|
|
|
19417
19705
|
lte2(aiReferralEventsHourly.tsHour, untilIso)
|
|
19418
19706
|
];
|
|
19419
19707
|
if (sourceIdParam) aiFilters.push(eq23(aiReferralEventsHourly.sourceId, sourceIdParam));
|
|
19420
|
-
const aiWhere =
|
|
19708
|
+
const aiWhere = and18(...aiFilters);
|
|
19421
19709
|
const total = app.db.select({ total: sql10`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(aiWhere).get();
|
|
19422
19710
|
aiReferralTotal = Number(total?.total ?? 0);
|
|
19423
19711
|
const rows = app.db.select().from(aiReferralEventsHourly).where(aiWhere).orderBy(desc12(aiReferralEventsHourly.tsHour)).limit(limit).all();
|
|
@@ -20141,7 +20429,7 @@ var providersConfiguredCheck = {
|
|
|
20141
20429
|
var PROVIDERS_CHECKS = [providersConfiguredCheck];
|
|
20142
20430
|
|
|
20143
20431
|
// ../api-routes/src/doctor/checks/traffic-source.ts
|
|
20144
|
-
import { and as
|
|
20432
|
+
import { and as and19, eq as eq24, gte as gte3, ne as ne4, sql as sql11 } from "drizzle-orm";
|
|
20145
20433
|
var RECENT_DATA_WARN_DAYS = 7;
|
|
20146
20434
|
var RECENT_DATA_FAIL_DAYS = 30;
|
|
20147
20435
|
function skippedNoProject2() {
|
|
@@ -20155,9 +20443,9 @@ function skippedNoProject2() {
|
|
|
20155
20443
|
function loadProbes(ctx) {
|
|
20156
20444
|
if (!ctx.project) return [];
|
|
20157
20445
|
const rows = ctx.db.select().from(trafficSources).where(
|
|
20158
|
-
|
|
20446
|
+
and19(
|
|
20159
20447
|
eq24(trafficSources.projectId, ctx.project.id),
|
|
20160
|
-
|
|
20448
|
+
ne4(trafficSources.status, TrafficSourceStatuses.archived)
|
|
20161
20449
|
)
|
|
20162
20450
|
).all();
|
|
20163
20451
|
return rows.map((r) => ({
|
|
@@ -20236,7 +20524,7 @@ var recentDataCheck = {
|
|
|
20236
20524
|
const failCutoff = new Date(now.getTime() - RECENT_DATA_FAIL_DAYS * 24 * 60 * 6e4).toISOString();
|
|
20237
20525
|
const recentCrawlers = Number(
|
|
20238
20526
|
ctx.db.select({ total: sql11`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
|
|
20239
|
-
|
|
20527
|
+
and19(
|
|
20240
20528
|
eq24(crawlerEventsHourly.projectId, ctx.project.id),
|
|
20241
20529
|
gte3(crawlerEventsHourly.tsHour, warnCutoff)
|
|
20242
20530
|
)
|
|
@@ -20244,7 +20532,7 @@ var recentDataCheck = {
|
|
|
20244
20532
|
);
|
|
20245
20533
|
const recentReferrals = Number(
|
|
20246
20534
|
ctx.db.select({ total: sql11`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
|
|
20247
|
-
|
|
20535
|
+
and19(
|
|
20248
20536
|
eq24(aiReferralEventsHourly.projectId, ctx.project.id),
|
|
20249
20537
|
gte3(aiReferralEventsHourly.tsHour, warnCutoff)
|
|
20250
20538
|
)
|
|
@@ -20260,7 +20548,7 @@ var recentDataCheck = {
|
|
|
20260
20548
|
}
|
|
20261
20549
|
const olderCrawlers = Number(
|
|
20262
20550
|
ctx.db.select({ total: sql11`COALESCE(SUM(${crawlerEventsHourly.hits}), 0)` }).from(crawlerEventsHourly).where(
|
|
20263
|
-
|
|
20551
|
+
and19(
|
|
20264
20552
|
eq24(crawlerEventsHourly.projectId, ctx.project.id),
|
|
20265
20553
|
gte3(crawlerEventsHourly.tsHour, failCutoff)
|
|
20266
20554
|
)
|
|
@@ -20268,7 +20556,7 @@ var recentDataCheck = {
|
|
|
20268
20556
|
);
|
|
20269
20557
|
const olderReferrals = Number(
|
|
20270
20558
|
ctx.db.select({ total: sql11`COALESCE(SUM(${aiReferralEventsHourly.sessionsOrHits}), 0)` }).from(aiReferralEventsHourly).where(
|
|
20271
|
-
|
|
20559
|
+
and19(
|
|
20272
20560
|
eq24(aiReferralEventsHourly.projectId, ctx.project.id),
|
|
20273
20561
|
gte3(aiReferralEventsHourly.tsHour, failCutoff)
|
|
20274
20562
|
)
|
|
@@ -20452,9 +20740,6 @@ var ALL_CHECKS = [
|
|
|
20452
20740
|
...TRAFFIC_SOURCE_CHECKS,
|
|
20453
20741
|
...AGENT_CHECKS
|
|
20454
20742
|
];
|
|
20455
|
-
var CHECK_BY_ID = Object.fromEntries(
|
|
20456
|
-
ALL_CHECKS.map((check) => [check.id, check])
|
|
20457
|
-
);
|
|
20458
20743
|
|
|
20459
20744
|
// ../api-routes/src/doctor/runner.ts
|
|
20460
20745
|
function matchesCheckId(checkId, filters) {
|
|
@@ -20567,7 +20852,7 @@ async function doctorRoutes(app, opts) {
|
|
|
20567
20852
|
|
|
20568
20853
|
// ../api-routes/src/discovery/routes.ts
|
|
20569
20854
|
import crypto21 from "crypto";
|
|
20570
|
-
import { and as
|
|
20855
|
+
import { and as and20, desc as desc13, eq as eq25, gte as gte4, inArray as inArray9 } from "drizzle-orm";
|
|
20571
20856
|
var MAX_INFLIGHT_DISCOVERY_AGE_MS = 2 * 60 * 60 * 1e3;
|
|
20572
20857
|
async function discoveryRoutes(app, opts) {
|
|
20573
20858
|
app.post("/projects/:name/discover/run", async (request, reply) => {
|
|
@@ -20599,7 +20884,7 @@ async function discoveryRoutes(app, opts) {
|
|
|
20599
20884
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20600
20885
|
const ageFloorIso = new Date(Date.now() - MAX_INFLIGHT_DISCOVERY_AGE_MS).toISOString();
|
|
20601
20886
|
const decision = app.db.transaction((tx) => {
|
|
20602
|
-
const existing = tx.select({ id: discoverySessions.id, runId: discoverySessions.runId }).from(discoverySessions).where(
|
|
20887
|
+
const existing = tx.select({ id: discoverySessions.id, runId: discoverySessions.runId }).from(discoverySessions).where(and20(
|
|
20603
20888
|
eq25(discoverySessions.projectId, project.id),
|
|
20604
20889
|
eq25(discoverySessions.icpDescription, icpDescription),
|
|
20605
20890
|
inArray9(discoverySessions.status, [
|
|
@@ -21847,7 +22132,7 @@ async function healthcheck2(config) {
|
|
|
21847
22132
|
async function executeTrackedQuery2(input) {
|
|
21848
22133
|
const model = input.config.model ?? DEFAULT_MODEL2;
|
|
21849
22134
|
const client = new OpenAI({ apiKey: input.config.apiKey });
|
|
21850
|
-
const webSearchTool = { type: "
|
|
22135
|
+
const webSearchTool = { type: "web_search" };
|
|
21851
22136
|
if (input.location) {
|
|
21852
22137
|
webSearchTool.user_location = {
|
|
21853
22138
|
type: "approximate",
|
|
@@ -23922,7 +24207,7 @@ import crypto24 from "crypto";
|
|
|
23922
24207
|
import fs8 from "fs";
|
|
23923
24208
|
import path10 from "path";
|
|
23924
24209
|
import os5 from "os";
|
|
23925
|
-
import { and as
|
|
24210
|
+
import { and as and21, eq as eq27, inArray as inArray10, sql as sql12 } from "drizzle-orm";
|
|
23926
24211
|
|
|
23927
24212
|
// src/run-telemetry.ts
|
|
23928
24213
|
import crypto23 from "crypto";
|
|
@@ -24305,7 +24590,7 @@ var JobRunner = class {
|
|
|
24305
24590
|
throw new Error(`Run ${runId} is not executable from status '${existingRun.status}'`);
|
|
24306
24591
|
}
|
|
24307
24592
|
if (existingRun.status === "queued") {
|
|
24308
|
-
this.db.update(runs).set({ status: "running", startedAt: now }).where(
|
|
24593
|
+
this.db.update(runs).set({ status: "running", startedAt: now }).where(and21(eq27(runs.id, runId), eq27(runs.status, "queued"))).run();
|
|
24309
24594
|
}
|
|
24310
24595
|
this.throwIfRunCancelled(runId);
|
|
24311
24596
|
const project = this.db.select().from(projects).where(eq27(projects.id, projectId)).get();
|
|
@@ -24330,7 +24615,7 @@ var JobRunner = class {
|
|
|
24330
24615
|
}
|
|
24331
24616
|
log.info("run.dispatch", { runId, providerCount: activeProviders.length, providers: activeProviders.map((p) => p.adapter.name) });
|
|
24332
24617
|
const scopedQueryNames = parseJsonColumn(existingRun.queries, null);
|
|
24333
|
-
projectQueries = scopedQueryNames ? this.db.select().from(queries).where(
|
|
24618
|
+
projectQueries = scopedQueryNames ? this.db.select().from(queries).where(and21(eq27(queries.projectId, projectId), inArray10(queries.query, scopedQueryNames))).all() : this.db.select().from(queries).where(eq27(queries.projectId, projectId)).all();
|
|
24334
24619
|
const projectCompetitors = this.db.select().from(competitors).where(eq27(competitors.projectId, projectId)).all();
|
|
24335
24620
|
const competitorDomains = projectCompetitors.map((c) => c.domain);
|
|
24336
24621
|
const allDomains = effectiveDomains({
|
|
@@ -24673,7 +24958,7 @@ function buildPhases(input) {
|
|
|
24673
24958
|
|
|
24674
24959
|
// src/gsc-sync.ts
|
|
24675
24960
|
import crypto25 from "crypto";
|
|
24676
|
-
import { eq as eq28, and as
|
|
24961
|
+
import { eq as eq28, and as and22, sql as sql13 } from "drizzle-orm";
|
|
24677
24962
|
var log2 = createLogger("GscSync");
|
|
24678
24963
|
function formatDate3(d) {
|
|
24679
24964
|
return d.toISOString().split("T")[0];
|
|
@@ -24725,7 +25010,7 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
24725
25010
|
});
|
|
24726
25011
|
log2.info("fetch.complete", { runId, projectId, rowCount: rows.length });
|
|
24727
25012
|
db.delete(gscSearchData).where(
|
|
24728
|
-
|
|
25013
|
+
and22(
|
|
24729
25014
|
eq28(gscSearchData.projectId, projectId),
|
|
24730
25015
|
sql13`${gscSearchData.date} >= ${startDate}`,
|
|
24731
25016
|
sql13`${gscSearchData.date} <= ${endDate}`
|
|
@@ -24814,7 +25099,7 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
24814
25099
|
}
|
|
24815
25100
|
}
|
|
24816
25101
|
const snapshotDate = formatDate3(/* @__PURE__ */ new Date());
|
|
24817
|
-
db.delete(gscCoverageSnapshots).where(
|
|
25102
|
+
db.delete(gscCoverageSnapshots).where(and22(eq28(gscCoverageSnapshots.projectId, projectId), eq28(gscCoverageSnapshots.date, snapshotDate))).run();
|
|
24818
25103
|
db.insert(gscCoverageSnapshots).values({
|
|
24819
25104
|
id: crypto25.randomUUID(),
|
|
24820
25105
|
projectId,
|
|
@@ -24837,7 +25122,7 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
24837
25122
|
|
|
24838
25123
|
// src/gsc-inspect-sitemap.ts
|
|
24839
25124
|
import crypto26 from "crypto";
|
|
24840
|
-
import { eq as eq29, and as
|
|
25125
|
+
import { eq as eq29, and as and23 } from "drizzle-orm";
|
|
24841
25126
|
|
|
24842
25127
|
// src/sitemap-parser.ts
|
|
24843
25128
|
var log3 = createLogger("SitemapParser");
|
|
@@ -25055,7 +25340,7 @@ async function executeInspectSitemap(db, runId, projectId, opts) {
|
|
|
25055
25340
|
}
|
|
25056
25341
|
}
|
|
25057
25342
|
const snapshotDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
25058
|
-
db.delete(gscCoverageSnapshots).where(
|
|
25343
|
+
db.delete(gscCoverageSnapshots).where(and23(eq29(gscCoverageSnapshots.projectId, projectId), eq29(gscCoverageSnapshots.date, snapshotDate))).run();
|
|
25059
25344
|
db.insert(gscCoverageSnapshots).values({
|
|
25060
25345
|
id: crypto26.randomUUID(),
|
|
25061
25346
|
projectId,
|
|
@@ -25266,7 +25551,7 @@ async function executeBingInspectSitemap(db, runId, projectId, opts) {
|
|
|
25266
25551
|
// src/commoncrawl-sync.ts
|
|
25267
25552
|
import crypto28 from "crypto";
|
|
25268
25553
|
import path11 from "path";
|
|
25269
|
-
import { and as
|
|
25554
|
+
import { and as and24, eq as eq31, sql as sql14 } from "drizzle-orm";
|
|
25270
25555
|
var log6 = createLogger("CommonCrawlSync");
|
|
25271
25556
|
var INSERT_CHUNK_SIZE = 1e4;
|
|
25272
25557
|
function defaultDeps() {
|
|
@@ -25457,7 +25742,7 @@ function computeSummary(rows) {
|
|
|
25457
25742
|
// src/backlink-extract.ts
|
|
25458
25743
|
import crypto29 from "crypto";
|
|
25459
25744
|
import fs9 from "fs";
|
|
25460
|
-
import { and as
|
|
25745
|
+
import { and as and25, desc as desc15, eq as eq32 } from "drizzle-orm";
|
|
25461
25746
|
var log7 = createLogger("BacklinkExtract");
|
|
25462
25747
|
function defaultDeps2() {
|
|
25463
25748
|
return {
|
|
@@ -25503,7 +25788,7 @@ async function executeBacklinkExtract(db, runId, projectId, opts = {}) {
|
|
|
25503
25788
|
const targetDomain = project.canonicalDomain;
|
|
25504
25789
|
db.transaction((tx) => {
|
|
25505
25790
|
tx.delete(backlinkDomains).where(
|
|
25506
|
-
|
|
25791
|
+
and25(eq32(backlinkDomains.projectId, projectId), eq32(backlinkDomains.release, release))
|
|
25507
25792
|
).run();
|
|
25508
25793
|
if (rows.length > 0) {
|
|
25509
25794
|
const values = rows.map((r) => ({
|
|
@@ -25574,7 +25859,7 @@ function computeSummary2(rows) {
|
|
|
25574
25859
|
|
|
25575
25860
|
// src/discovery-run.ts
|
|
25576
25861
|
import crypto30 from "crypto";
|
|
25577
|
-
import { and as
|
|
25862
|
+
import { and as and26, eq as eq33 } from "drizzle-orm";
|
|
25578
25863
|
var log8 = createLogger("DiscoveryRun");
|
|
25579
25864
|
var DEFAULT_SEED_COUNT = 30;
|
|
25580
25865
|
var QUERIES_PER_INTENT_BUCKET = 6;
|
|
@@ -25834,7 +26119,7 @@ function writeDiscoveryInsight(db, input) {
|
|
|
25834
26119
|
totalProbes
|
|
25835
26120
|
});
|
|
25836
26121
|
db.transaction((tx) => {
|
|
25837
|
-
tx.update(insights).set({ dismissed: true }).where(
|
|
26122
|
+
tx.update(insights).set({ dismissed: true }).where(and26(
|
|
25838
26123
|
eq33(insights.projectId, input.projectId),
|
|
25839
26124
|
eq33(insights.type, "discovery.basket-divergence"),
|
|
25840
26125
|
eq33(insights.dismissed, false)
|
|
@@ -25878,7 +26163,7 @@ function buildDiscoveryInsightTitle(input) {
|
|
|
25878
26163
|
}
|
|
25879
26164
|
|
|
25880
26165
|
// src/commands/backfill.ts
|
|
25881
|
-
import { and as
|
|
26166
|
+
import { and as and27, eq as eq34, inArray as inArray11 } from "drizzle-orm";
|
|
25882
26167
|
var SNAPSHOT_BATCH_SIZE = 500;
|
|
25883
26168
|
async function backfillAnswerVisibilityCommand(opts) {
|
|
25884
26169
|
const config = loadConfig();
|
|
@@ -25894,7 +26179,7 @@ async function backfillAnswerVisibilityCommand(opts) {
|
|
|
25894
26179
|
let reparsed = 0;
|
|
25895
26180
|
let providerErrors = 0;
|
|
25896
26181
|
if (scopedProjects.length > 0) {
|
|
25897
|
-
const runRows = projectFilter ? db.select({ id: runs.id, projectId: runs.projectId }).from(runs).where(
|
|
26182
|
+
const runRows = projectFilter ? db.select({ id: runs.id, projectId: runs.projectId }).from(runs).where(and27(
|
|
25898
26183
|
eq34(runs.kind, RunKinds["answer-visibility"]),
|
|
25899
26184
|
inArray11(runs.projectId, scopedProjects.map((project) => project.id))
|
|
25900
26185
|
)).all() : db.select({ id: runs.id, projectId: runs.projectId }).from(runs).where(eq34(runs.kind, RunKinds["answer-visibility"])).all();
|
|
@@ -26052,7 +26337,7 @@ function backfillNormalizedPaths(db, opts) {
|
|
|
26052
26337
|
id: gaTrafficSnapshots.id,
|
|
26053
26338
|
landingPage: gaTrafficSnapshots.landingPage,
|
|
26054
26339
|
landingPageNormalized: gaTrafficSnapshots.landingPageNormalized
|
|
26055
|
-
}).from(gaTrafficSnapshots).where(baseConditions.length > 0 ?
|
|
26340
|
+
}).from(gaTrafficSnapshots).where(baseConditions.length > 0 ? and27(...baseConditions) : void 0).all();
|
|
26056
26341
|
let updated = 0;
|
|
26057
26342
|
let unchanged = 0;
|
|
26058
26343
|
if (rows.length > 0) {
|
|
@@ -26124,7 +26409,7 @@ function backfillAiReferralPaths(db, opts) {
|
|
|
26124
26409
|
id: gaAiReferrals.id,
|
|
26125
26410
|
landingPage: gaAiReferrals.landingPage,
|
|
26126
26411
|
landingPageNormalized: gaAiReferrals.landingPageNormalized
|
|
26127
|
-
}).from(gaAiReferrals).where(baseConditions.length > 0 ?
|
|
26412
|
+
}).from(gaAiReferrals).where(baseConditions.length > 0 ? and27(...baseConditions) : void 0).all();
|
|
26128
26413
|
let updated = 0;
|
|
26129
26414
|
let unchanged = 0;
|
|
26130
26415
|
if (rows.length > 0) {
|
|
@@ -26192,7 +26477,7 @@ function backfillProjectAnswerMentions(db, projectId, opts) {
|
|
|
26192
26477
|
const project = db.select().from(projects).where(eq34(projects.id, projectId)).get();
|
|
26193
26478
|
if (!project) return { examined: 0, updated: 0, mentioned: 0 };
|
|
26194
26479
|
const competitorDomains = db.select({ domain: competitors.domain }).from(competitors).where(eq34(competitors.projectId, projectId)).all().map((row) => row.domain);
|
|
26195
|
-
const runRows = db.select({ id: runs.id }).from(runs).where(
|
|
26480
|
+
const runRows = db.select({ id: runs.id }).from(runs).where(and27(eq34(runs.kind, RunKinds["answer-visibility"]), eq34(runs.projectId, projectId))).all();
|
|
26196
26481
|
const runIds = runRows.map((r) => r.id);
|
|
26197
26482
|
let examined = 0;
|
|
26198
26483
|
let updated = 0;
|
|
@@ -26343,7 +26628,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
26343
26628
|
return result;
|
|
26344
26629
|
}
|
|
26345
26630
|
async function backfillInsightsCommand(project, opts) {
|
|
26346
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
26631
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-TY7IPRST.js");
|
|
26347
26632
|
const config = loadConfig();
|
|
26348
26633
|
const db = createClient(config.database);
|
|
26349
26634
|
migrate(db);
|
|
@@ -26492,7 +26777,7 @@ var ProviderRegistry = class {
|
|
|
26492
26777
|
|
|
26493
26778
|
// src/scheduler.ts
|
|
26494
26779
|
import cron from "node-cron";
|
|
26495
|
-
import { and as
|
|
26780
|
+
import { and as and28, eq as eq35 } from "drizzle-orm";
|
|
26496
26781
|
var log9 = createLogger("Scheduler");
|
|
26497
26782
|
function taskKey(projectId, kind) {
|
|
26498
26783
|
return `${projectId}::${kind}`;
|
|
@@ -26537,7 +26822,7 @@ var Scheduler = class {
|
|
|
26537
26822
|
this.stopTask(key, existing, "Stopped");
|
|
26538
26823
|
this.tasks.delete(key);
|
|
26539
26824
|
}
|
|
26540
|
-
const schedule = this.db.select().from(schedules).where(
|
|
26825
|
+
const schedule = this.db.select().from(schedules).where(and28(eq35(schedules.projectId, projectId), eq35(schedules.kind, kind))).get();
|
|
26541
26826
|
if (schedule && schedule.enabled === 1) {
|
|
26542
26827
|
this.registerCronTask(schedule);
|
|
26543
26828
|
}
|
|
@@ -26661,7 +26946,7 @@ var Scheduler = class {
|
|
|
26661
26946
|
};
|
|
26662
26947
|
|
|
26663
26948
|
// src/notifier.ts
|
|
26664
|
-
import { eq as eq36, desc as desc16, and as
|
|
26949
|
+
import { eq as eq36, desc as desc16, and as and29, inArray as inArray12, or as or5 } from "drizzle-orm";
|
|
26665
26950
|
import crypto31 from "crypto";
|
|
26666
26951
|
var log10 = createLogger("Notifier");
|
|
26667
26952
|
var Notifier = class {
|
|
@@ -26768,7 +27053,7 @@ var Notifier = class {
|
|
|
26768
27053
|
computeTransitions(runId, projectId) {
|
|
26769
27054
|
const thisRun = this.db.select().from(runs).where(eq36(runs.id, runId)).get();
|
|
26770
27055
|
if (!thisRun) return [];
|
|
26771
|
-
const groupSiblings = this.db.select().from(runs).where(
|
|
27056
|
+
const groupSiblings = this.db.select().from(runs).where(and29(
|
|
26772
27057
|
eq36(runs.projectId, projectId),
|
|
26773
27058
|
eq36(runs.kind, thisRun.kind),
|
|
26774
27059
|
eq36(runs.createdAt, thisRun.createdAt)
|
|
@@ -26794,7 +27079,7 @@ var Notifier = class {
|
|
|
26794
27079
|
);
|
|
26795
27080
|
const RECENT_FETCH_LIMIT = Math.max(8, locationCount * 4);
|
|
26796
27081
|
const recentRuns = this.db.select().from(runs).where(
|
|
26797
|
-
|
|
27082
|
+
and29(
|
|
26798
27083
|
eq36(runs.projectId, projectId),
|
|
26799
27084
|
eq36(runs.kind, thisRun.kind),
|
|
26800
27085
|
or5(eq36(runs.status, "completed"), eq36(runs.status, "partial"))
|
|
@@ -26907,6 +27192,10 @@ var RunCoordinator = class {
|
|
|
26907
27192
|
async onRunCompleted(runId, projectId) {
|
|
26908
27193
|
const runRow = this.db.select().from(runs).where(eq37(runs.id, runId)).get();
|
|
26909
27194
|
const kind = runRow?.kind ?? RunKinds["answer-visibility"];
|
|
27195
|
+
if (runRow?.trigger === RunTriggers.probe) {
|
|
27196
|
+
log11.info("probe.skip-side-effects", { runId, projectId, kind });
|
|
27197
|
+
return;
|
|
27198
|
+
}
|
|
26910
27199
|
let insightCount = 0;
|
|
26911
27200
|
let criticalOrHigh = 0;
|
|
26912
27201
|
if (kind === RunKinds["answer-visibility"]) {
|
|
@@ -27333,7 +27622,7 @@ function resolveSessionProviderAndModel(config, opts) {
|
|
|
27333
27622
|
|
|
27334
27623
|
// src/agent/memory-store.ts
|
|
27335
27624
|
import crypto32 from "crypto";
|
|
27336
|
-
import { and as
|
|
27625
|
+
import { and as and30, desc as desc17, eq as eq38, like as like2, sql as sql15 } from "drizzle-orm";
|
|
27337
27626
|
var COMPACTION_KEY_PREFIX = "compaction:";
|
|
27338
27627
|
var COMPACTION_NOTES_PER_SESSION = 3;
|
|
27339
27628
|
function rowToDto2(row) {
|
|
@@ -27378,12 +27667,12 @@ function upsertMemoryEntry(db, args) {
|
|
|
27378
27667
|
updatedAt: now
|
|
27379
27668
|
}
|
|
27380
27669
|
}).run();
|
|
27381
|
-
const row = db.select().from(agentMemory).where(
|
|
27670
|
+
const row = db.select().from(agentMemory).where(and30(eq38(agentMemory.projectId, args.projectId), eq38(agentMemory.key, args.key))).get();
|
|
27382
27671
|
if (!row) throw new Error("memory upsert produced no row");
|
|
27383
27672
|
return rowToDto2(row);
|
|
27384
27673
|
}
|
|
27385
27674
|
function deleteMemoryEntry(db, projectId, key) {
|
|
27386
|
-
const result = db.delete(agentMemory).where(
|
|
27675
|
+
const result = db.delete(agentMemory).where(and30(eq38(agentMemory.projectId, projectId), eq38(agentMemory.key, key))).run();
|
|
27387
27676
|
const changes = result.changes ?? 0;
|
|
27388
27677
|
return changes > 0;
|
|
27389
27678
|
}
|
|
@@ -27412,7 +27701,7 @@ function writeCompactionNote(db, args) {
|
|
|
27412
27701
|
}).run();
|
|
27413
27702
|
const sessionPrefix = `${COMPACTION_KEY_PREFIX}${args.sessionId}:`;
|
|
27414
27703
|
const existing = tx.select({ id: agentMemory.id, updatedAt: agentMemory.updatedAt }).from(agentMemory).where(
|
|
27415
|
-
|
|
27704
|
+
and30(
|
|
27416
27705
|
eq38(agentMemory.projectId, args.projectId),
|
|
27417
27706
|
like2(agentMemory.key, `${sessionPrefix}%`)
|
|
27418
27707
|
)
|
|
@@ -27421,7 +27710,7 @@ function writeCompactionNote(db, args) {
|
|
|
27421
27710
|
if (stale.length > 0) {
|
|
27422
27711
|
tx.delete(agentMemory).where(sql15`${agentMemory.id} IN (${sql15.join(stale.map((s) => sql15`${s}`), sql15`, `)})`).run();
|
|
27423
27712
|
}
|
|
27424
|
-
const row = tx.select().from(agentMemory).where(
|
|
27713
|
+
const row = tx.select().from(agentMemory).where(and30(eq38(agentMemory.projectId, args.projectId), eq38(agentMemory.key, key))).get();
|
|
27425
27714
|
if (row) inserted = rowToDto2(row);
|
|
27426
27715
|
});
|
|
27427
27716
|
if (!inserted) throw new Error("compaction note write produced no row");
|