@canonry/canonry 4.117.2 → 4.118.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/canonry/references/canonry-cli.md +53 -1
- package/assets/assets/AuditHistoryPanel-Yh7VEe4P.js +1 -0
- package/assets/assets/{BacklinksPage-CschVQxC.js → BacklinksPage-BmO77kMs.js} +1 -1
- package/assets/assets/{ChartPrimitives-D4782Ifx.js → ChartPrimitives-H0ICVpw_.js} +1 -1
- package/assets/assets/HistoryPage-DkLV_iRc.js +1 -0
- package/assets/assets/ProjectPage-R3odr_eA.js +7 -0
- package/assets/assets/{RunRow-ggNGlwdN.js → RunRow-BDH9agxQ.js} +1 -1
- package/assets/assets/RunsPage-D9YsEeT3.js +1 -0
- package/assets/assets/{SettingsPage-Cy9SlBJX.js → SettingsPage-o5as3Ixw.js} +1 -1
- package/assets/assets/{TrafficPage-1S2PzSHB.js → TrafficPage-BCK203aQ.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CqXCoaod.js → TrafficSourceDetailPage-DsVMAZvS.js} +1 -1
- package/assets/assets/{arrow-left-kCK5M8Bp.js → arrow-left-B7ZR6VC9.js} +1 -1
- package/assets/assets/{extract-error-message-C82LAW6q.js → extract-error-message-DeYDUpew.js} +1 -1
- package/assets/assets/index-Bot6YiD6.css +1 -0
- package/assets/assets/index-QCFQv0xh.js +210 -0
- package/assets/assets/{trash-2-8Pe4v1T0.js → trash-2-xxHTqWbF.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-4PMMEFME.js → chunk-75UBTCKS.js} +499 -16
- package/dist/{chunk-BMPIV35C.js → chunk-CMZIPFNQ.js} +937 -104
- package/dist/{chunk-F2SRZJMY.js → chunk-HGNY5GL4.js} +384 -15
- package/dist/{chunk-EZME2J2G.js → chunk-KEZWLP4O.js} +1196 -1012
- package/dist/cli.js +319 -86
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-GNOE4J35.js → intelligence-service-FWPXMAVK.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -8
- package/assets/assets/ProjectPage-BSGTpBUJ.js +0 -7
- package/assets/assets/RunsPage-Bfp0K6Ry.js +0 -1
- package/assets/assets/index-DrDNyUhv.css +0 -1
- package/assets/assets/index-i-t64RXw.js +0 -210
|
@@ -32,6 +32,9 @@ var AppError = class extends Error {
|
|
|
32
32
|
function notFound(entity, id) {
|
|
33
33
|
return new AppError("NOT_FOUND", `${entity} '${id}' not found`, 404);
|
|
34
34
|
}
|
|
35
|
+
function alreadyExists(entity, id) {
|
|
36
|
+
return new AppError("ALREADY_EXISTS", `${entity} '${id}' already exists`, 409);
|
|
37
|
+
}
|
|
35
38
|
function validationError(message, details) {
|
|
36
39
|
return new AppError("VALIDATION_ERROR", message, 400, details);
|
|
37
40
|
}
|
|
@@ -574,12 +577,17 @@ var auditLogEntrySchema = z3.object({
|
|
|
574
577
|
entityType: z3.string(),
|
|
575
578
|
entityId: z3.string().nullable().optional(),
|
|
576
579
|
diff: z3.unknown().optional(),
|
|
580
|
+
/** Originating HTTP client, when available (dashboard browser, CLI, MCP, or external script). */
|
|
581
|
+
userAgent: z3.string().nullable().optional(),
|
|
582
|
+
/** Optional caller-supplied correlation key for grouping related mutations. */
|
|
583
|
+
actorSession: z3.string().nullable().optional(),
|
|
577
584
|
createdAt: z3.string()
|
|
578
585
|
});
|
|
579
586
|
|
|
580
587
|
// ../contracts/src/scopes.ts
|
|
581
588
|
var READ_ONLY_SCOPE = "read";
|
|
582
589
|
var WILDCARD_SCOPE = "*";
|
|
590
|
+
var ADS_WRITE_SCOPE = "ads.write";
|
|
583
591
|
function grantsWrite(scope) {
|
|
584
592
|
return scope === WILDCARD_SCOPE || scope === "write" || scope.endsWith(".write");
|
|
585
593
|
}
|
|
@@ -3621,51 +3629,88 @@ function escapeRegExp(value) {
|
|
|
3621
3629
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3622
3630
|
}
|
|
3623
3631
|
|
|
3624
|
-
// ../contracts/src/
|
|
3632
|
+
// ../contracts/src/intelligence.ts
|
|
3625
3633
|
import { z as z24 } from "zod";
|
|
3626
|
-
var
|
|
3627
|
-
|
|
3634
|
+
var healthSnapshotDtoSchema = z24.object({
|
|
3635
|
+
id: z24.string(),
|
|
3636
|
+
projectId: z24.string(),
|
|
3637
|
+
runId: z24.string().nullable(),
|
|
3638
|
+
overallCitedRate: z24.number(),
|
|
3639
|
+
/**
|
|
3640
|
+
* Share of (query × provider) pairs where the project was MENTIONED in the
|
|
3641
|
+
* answer text. Independent of `overallCitedRate` — never derived from it.
|
|
3642
|
+
* Legacy snapshots persisted before the mention columns existed read back
|
|
3643
|
+
* as 0 (the API coalesces NULL→0).
|
|
3644
|
+
*/
|
|
3645
|
+
overallMentionRate: z24.number(),
|
|
3646
|
+
totalPairs: z24.number().int().nonnegative(),
|
|
3647
|
+
citedPairs: z24.number().int().nonnegative(),
|
|
3648
|
+
/** Count of pairs mentioned in the answer text. Legacy rows read back as 0. */
|
|
3649
|
+
mentionedPairs: z24.number().int().nonnegative(),
|
|
3650
|
+
providerBreakdown: z24.record(z24.string(), z24.object({
|
|
3651
|
+
citedRate: z24.number(),
|
|
3652
|
+
mentionRate: z24.number(),
|
|
3653
|
+
cited: z24.number().int().nonnegative(),
|
|
3654
|
+
mentioned: z24.number().int().nonnegative(),
|
|
3655
|
+
total: z24.number().int().nonnegative()
|
|
3656
|
+
})),
|
|
3657
|
+
createdAt: z24.string(),
|
|
3658
|
+
/**
|
|
3659
|
+
* `'ready'` when the snapshot reflects real data; `'no-data'` for the
|
|
3660
|
+
* sentinel returned by `/health/latest` when a project has no health
|
|
3661
|
+
* snapshots yet (newly created, or only failed runs). Numeric fields are
|
|
3662
|
+
* zero and `providerBreakdown` is `{}` in the no-data case.
|
|
3663
|
+
*/
|
|
3664
|
+
status: z24.enum(["ready", "no-data"]),
|
|
3665
|
+
/** Reason for `status === 'no-data'`. Absent when `status === 'ready'`. */
|
|
3666
|
+
reason: z24.literal("no-runs-yet").optional()
|
|
3667
|
+
});
|
|
3668
|
+
|
|
3669
|
+
// ../contracts/src/agent.ts
|
|
3670
|
+
import { z as z25 } from "zod";
|
|
3671
|
+
var agentProviderIdSchema = z25.enum(["claude", "openai", "gemini", "zai", "deepinfra"]);
|
|
3672
|
+
var agentProviderOptionDtoSchema = z25.object({
|
|
3628
3673
|
/** Stable identifier — what clients pass back as `provider` on the prompt endpoint. */
|
|
3629
3674
|
id: agentProviderIdSchema,
|
|
3630
3675
|
/** Human-readable label for UI pickers, e.g. "Anthropic (Claude)". */
|
|
3631
|
-
label:
|
|
3676
|
+
label: z25.string(),
|
|
3632
3677
|
/** Default model if the caller doesn't pick one. */
|
|
3633
|
-
defaultModel:
|
|
3678
|
+
defaultModel: z25.string(),
|
|
3634
3679
|
/** Whether a usable API key was found (config.yaml or provider env var). */
|
|
3635
|
-
configured:
|
|
3680
|
+
configured: z25.boolean(),
|
|
3636
3681
|
/**
|
|
3637
3682
|
* Where the key resolved from, if any. `null` when `configured === false`.
|
|
3638
3683
|
* Surfaced so the UI can nudge users toward their preferred source of truth.
|
|
3639
3684
|
*/
|
|
3640
|
-
keySource:
|
|
3685
|
+
keySource: z25.enum(["config", "env"]).nullable()
|
|
3641
3686
|
});
|
|
3642
|
-
var agentProvidersResponseDtoSchema =
|
|
3687
|
+
var agentProvidersResponseDtoSchema = z25.object({
|
|
3643
3688
|
/**
|
|
3644
3689
|
* Every provider Aero knows about. `configured === false` entries are
|
|
3645
3690
|
* included so the UI can render them disabled with an onboarding hint.
|
|
3646
3691
|
*/
|
|
3647
|
-
providers:
|
|
3692
|
+
providers: z25.array(agentProviderOptionDtoSchema).default([]),
|
|
3648
3693
|
/**
|
|
3649
3694
|
* Provider Aero auto-picks when no explicit override is passed. Null if
|
|
3650
3695
|
* nothing is configured (install never exchanged a key).
|
|
3651
3696
|
*/
|
|
3652
3697
|
defaultProvider: agentProviderIdSchema.nullable()
|
|
3653
3698
|
});
|
|
3654
|
-
var memorySourceSchema =
|
|
3699
|
+
var memorySourceSchema = z25.enum(["aero", "user", "compaction"]);
|
|
3655
3700
|
var MemorySources = memorySourceSchema.enum;
|
|
3656
3701
|
var AGENT_MEMORY_VALUE_MAX_BYTES = 2 * 1024;
|
|
3657
3702
|
var AGENT_MEMORY_KEY_MAX_LENGTH = 128;
|
|
3658
|
-
var agentMemoryUpsertRequestSchema =
|
|
3659
|
-
key:
|
|
3660
|
-
value:
|
|
3703
|
+
var agentMemoryUpsertRequestSchema = z25.object({
|
|
3704
|
+
key: z25.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH),
|
|
3705
|
+
value: z25.string().min(1)
|
|
3661
3706
|
});
|
|
3662
|
-
var agentMemoryDeleteRequestSchema =
|
|
3663
|
-
key:
|
|
3707
|
+
var agentMemoryDeleteRequestSchema = z25.object({
|
|
3708
|
+
key: z25.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH)
|
|
3664
3709
|
});
|
|
3665
3710
|
|
|
3666
3711
|
// ../contracts/src/backlinks.ts
|
|
3667
|
-
import { z as
|
|
3668
|
-
var backlinkSourceSchema =
|
|
3712
|
+
import { z as z26 } from "zod";
|
|
3713
|
+
var backlinkSourceSchema = z26.enum(["commoncrawl", "bing-webmaster"]);
|
|
3669
3714
|
var BacklinkSources = backlinkSourceSchema.enum;
|
|
3670
3715
|
function computeBacklinkSummaryMetrics(rows) {
|
|
3671
3716
|
if (rows.length === 0) {
|
|
@@ -3681,181 +3726,181 @@ function computeBacklinkSummaryMetrics(rows) {
|
|
|
3681
3726
|
top10HostsShare: share.toFixed(6)
|
|
3682
3727
|
};
|
|
3683
3728
|
}
|
|
3684
|
-
var ccReleaseSyncStatusSchema =
|
|
3729
|
+
var ccReleaseSyncStatusSchema = z26.enum(["queued", "downloading", "querying", "ready", "failed"]);
|
|
3685
3730
|
var CcReleaseSyncStatuses = ccReleaseSyncStatusSchema.enum;
|
|
3686
|
-
var ccReleaseSyncDtoSchema =
|
|
3687
|
-
id:
|
|
3688
|
-
release:
|
|
3731
|
+
var ccReleaseSyncDtoSchema = z26.object({
|
|
3732
|
+
id: z26.string(),
|
|
3733
|
+
release: z26.string(),
|
|
3689
3734
|
status: ccReleaseSyncStatusSchema,
|
|
3690
|
-
phaseDetail:
|
|
3691
|
-
vertexPath:
|
|
3692
|
-
edgesPath:
|
|
3693
|
-
vertexSha256:
|
|
3694
|
-
edgesSha256:
|
|
3695
|
-
vertexBytes:
|
|
3696
|
-
edgesBytes:
|
|
3697
|
-
projectsProcessed:
|
|
3698
|
-
domainsDiscovered:
|
|
3699
|
-
downloadStartedAt:
|
|
3700
|
-
downloadFinishedAt:
|
|
3701
|
-
queryStartedAt:
|
|
3702
|
-
queryFinishedAt:
|
|
3703
|
-
error:
|
|
3704
|
-
createdAt:
|
|
3705
|
-
updatedAt:
|
|
3706
|
-
});
|
|
3707
|
-
var backlinkDomainDtoSchema =
|
|
3708
|
-
linkingDomain:
|
|
3735
|
+
phaseDetail: z26.string().nullable().optional(),
|
|
3736
|
+
vertexPath: z26.string().nullable().optional(),
|
|
3737
|
+
edgesPath: z26.string().nullable().optional(),
|
|
3738
|
+
vertexSha256: z26.string().nullable().optional(),
|
|
3739
|
+
edgesSha256: z26.string().nullable().optional(),
|
|
3740
|
+
vertexBytes: z26.number().int().nullable().optional(),
|
|
3741
|
+
edgesBytes: z26.number().int().nullable().optional(),
|
|
3742
|
+
projectsProcessed: z26.number().int().nullable().optional(),
|
|
3743
|
+
domainsDiscovered: z26.number().int().nullable().optional(),
|
|
3744
|
+
downloadStartedAt: z26.string().nullable().optional(),
|
|
3745
|
+
downloadFinishedAt: z26.string().nullable().optional(),
|
|
3746
|
+
queryStartedAt: z26.string().nullable().optional(),
|
|
3747
|
+
queryFinishedAt: z26.string().nullable().optional(),
|
|
3748
|
+
error: z26.string().nullable().optional(),
|
|
3749
|
+
createdAt: z26.string(),
|
|
3750
|
+
updatedAt: z26.string()
|
|
3751
|
+
});
|
|
3752
|
+
var backlinkDomainDtoSchema = z26.object({
|
|
3753
|
+
linkingDomain: z26.string(),
|
|
3709
3754
|
// For Common Crawl this is the count of distinct hosts within the linking
|
|
3710
3755
|
// domain; for Bing Webmaster it is the count of distinct linking pages (URLs)
|
|
3711
3756
|
// from that linking host. Read alongside `source` — the unit differs per source.
|
|
3712
|
-
numHosts:
|
|
3757
|
+
numHosts: z26.number().int(),
|
|
3713
3758
|
source: backlinkSourceSchema
|
|
3714
3759
|
});
|
|
3715
|
-
var backlinkSummaryDtoSchema =
|
|
3716
|
-
projectId:
|
|
3760
|
+
var backlinkSummaryDtoSchema = z26.object({
|
|
3761
|
+
projectId: z26.string(),
|
|
3717
3762
|
// Window identifier. Common Crawl uses the release slug
|
|
3718
3763
|
// (`cc-main-YYYY-<mon>-<mon>-<mon>`); Bing Webmaster uses a synthetic
|
|
3719
3764
|
// per-sync-day window (`bing-YYYY-MM-DD`).
|
|
3720
|
-
release:
|
|
3721
|
-
targetDomain:
|
|
3722
|
-
totalLinkingDomains:
|
|
3723
|
-
totalHosts:
|
|
3724
|
-
top10HostsShare:
|
|
3725
|
-
queriedAt:
|
|
3765
|
+
release: z26.string(),
|
|
3766
|
+
targetDomain: z26.string(),
|
|
3767
|
+
totalLinkingDomains: z26.number().int(),
|
|
3768
|
+
totalHosts: z26.number().int(),
|
|
3769
|
+
top10HostsShare: z26.string(),
|
|
3770
|
+
queriedAt: z26.string(),
|
|
3726
3771
|
source: backlinkSourceSchema,
|
|
3727
3772
|
// Populated when the response is filtered (e.g. ?excludeCrawlers=1).
|
|
3728
3773
|
// Counts the rows omitted from totalLinkingDomains/totalHosts so callers
|
|
3729
3774
|
// can show "N hidden" hints without re-deriving them.
|
|
3730
|
-
excludedLinkingDomains:
|
|
3731
|
-
excludedHosts:
|
|
3775
|
+
excludedLinkingDomains: z26.number().int().optional(),
|
|
3776
|
+
excludedHosts: z26.number().int().optional()
|
|
3732
3777
|
});
|
|
3733
|
-
var backlinkListResponseSchema =
|
|
3778
|
+
var backlinkListResponseSchema = z26.object({
|
|
3734
3779
|
// The source this response was filtered to (defaults to commoncrawl when the
|
|
3735
3780
|
// caller omits `?source`).
|
|
3736
3781
|
source: backlinkSourceSchema,
|
|
3737
3782
|
summary: backlinkSummaryDtoSchema.nullable(),
|
|
3738
|
-
total:
|
|
3739
|
-
rows:
|
|
3740
|
-
});
|
|
3741
|
-
var backlinkHistoryEntrySchema =
|
|
3742
|
-
release:
|
|
3743
|
-
totalLinkingDomains:
|
|
3744
|
-
totalHosts:
|
|
3745
|
-
top10HostsShare:
|
|
3746
|
-
queriedAt:
|
|
3783
|
+
total: z26.number().int(),
|
|
3784
|
+
rows: z26.array(backlinkDomainDtoSchema)
|
|
3785
|
+
});
|
|
3786
|
+
var backlinkHistoryEntrySchema = z26.object({
|
|
3787
|
+
release: z26.string(),
|
|
3788
|
+
totalLinkingDomains: z26.number().int(),
|
|
3789
|
+
totalHosts: z26.number().int(),
|
|
3790
|
+
top10HostsShare: z26.string(),
|
|
3791
|
+
queriedAt: z26.string(),
|
|
3747
3792
|
source: backlinkSourceSchema
|
|
3748
3793
|
});
|
|
3749
|
-
var backlinkSourceAvailabilityDtoSchema =
|
|
3794
|
+
var backlinkSourceAvailabilityDtoSchema = z26.object({
|
|
3750
3795
|
source: backlinkSourceSchema,
|
|
3751
3796
|
/**
|
|
3752
3797
|
* The source is set up for this project:
|
|
3753
3798
|
* - commoncrawl: `autoExtractBacklinks` enabled AND a `ready` release sync exists.
|
|
3754
3799
|
* - bing-webmaster: a Bing Webmaster connection exists for the project domain.
|
|
3755
3800
|
*/
|
|
3756
|
-
connected:
|
|
3801
|
+
connected: z26.boolean(),
|
|
3757
3802
|
/** Backlink rows exist for this project + source. */
|
|
3758
|
-
hasData:
|
|
3803
|
+
hasData: z26.boolean(),
|
|
3759
3804
|
/** Latest window id with data for this source, null when none. */
|
|
3760
|
-
latestRelease:
|
|
3805
|
+
latestRelease: z26.string().nullable(),
|
|
3761
3806
|
/**
|
|
3762
3807
|
* Linking-domain count in the latest window. Excludes crawler/proxy hosts only
|
|
3763
3808
|
* when the request sets `?excludeCrawlers=1` (default off, matching the summary
|
|
3764
3809
|
* and domains endpoints); the dashboard passes it so the switcher pill matches
|
|
3765
3810
|
* the metric card.
|
|
3766
3811
|
*/
|
|
3767
|
-
totalLinkingDomains:
|
|
3812
|
+
totalLinkingDomains: z26.number().int(),
|
|
3768
3813
|
/** Freshness: `queriedAt` of the latest summary for this source, null when none. */
|
|
3769
|
-
lastSyncedAt:
|
|
3814
|
+
lastSyncedAt: z26.string().nullable()
|
|
3770
3815
|
});
|
|
3771
|
-
var backlinkSourcesResponseSchema =
|
|
3772
|
-
projectId:
|
|
3773
|
-
targetDomain:
|
|
3816
|
+
var backlinkSourcesResponseSchema = z26.object({
|
|
3817
|
+
projectId: z26.string(),
|
|
3818
|
+
targetDomain: z26.string(),
|
|
3774
3819
|
/** Availability for every known source, in a stable order. */
|
|
3775
|
-
sources:
|
|
3776
|
-
anyConnected:
|
|
3777
|
-
anyData:
|
|
3778
|
-
});
|
|
3779
|
-
var backlinksInstallStatusDtoSchema =
|
|
3780
|
-
duckdbInstalled:
|
|
3781
|
-
duckdbVersion:
|
|
3782
|
-
duckdbSpec:
|
|
3783
|
-
pluginDir:
|
|
3784
|
-
});
|
|
3785
|
-
var backlinksInstallResultDtoSchema =
|
|
3786
|
-
installed:
|
|
3787
|
-
version:
|
|
3788
|
-
path:
|
|
3789
|
-
alreadyPresent:
|
|
3790
|
-
});
|
|
3791
|
-
var ccAvailableReleaseSchema =
|
|
3792
|
-
release:
|
|
3793
|
-
vertexUrl:
|
|
3794
|
-
edgesUrl:
|
|
3795
|
-
vertexBytes:
|
|
3796
|
-
edgesBytes:
|
|
3797
|
-
lastModified:
|
|
3798
|
-
});
|
|
3799
|
-
var ccCachedReleaseSchema =
|
|
3800
|
-
release:
|
|
3820
|
+
sources: z26.array(backlinkSourceAvailabilityDtoSchema),
|
|
3821
|
+
anyConnected: z26.boolean(),
|
|
3822
|
+
anyData: z26.boolean()
|
|
3823
|
+
});
|
|
3824
|
+
var backlinksInstallStatusDtoSchema = z26.object({
|
|
3825
|
+
duckdbInstalled: z26.boolean(),
|
|
3826
|
+
duckdbVersion: z26.string().nullable().optional(),
|
|
3827
|
+
duckdbSpec: z26.string(),
|
|
3828
|
+
pluginDir: z26.string()
|
|
3829
|
+
});
|
|
3830
|
+
var backlinksInstallResultDtoSchema = z26.object({
|
|
3831
|
+
installed: z26.boolean(),
|
|
3832
|
+
version: z26.string(),
|
|
3833
|
+
path: z26.string(),
|
|
3834
|
+
alreadyPresent: z26.boolean()
|
|
3835
|
+
});
|
|
3836
|
+
var ccAvailableReleaseSchema = z26.object({
|
|
3837
|
+
release: z26.string(),
|
|
3838
|
+
vertexUrl: z26.string(),
|
|
3839
|
+
edgesUrl: z26.string(),
|
|
3840
|
+
vertexBytes: z26.number().int().nullable(),
|
|
3841
|
+
edgesBytes: z26.number().int().nullable(),
|
|
3842
|
+
lastModified: z26.string().nullable()
|
|
3843
|
+
});
|
|
3844
|
+
var ccCachedReleaseSchema = z26.object({
|
|
3845
|
+
release: z26.string(),
|
|
3801
3846
|
syncStatus: ccReleaseSyncStatusSchema.nullable(),
|
|
3802
|
-
bytes:
|
|
3803
|
-
lastUsedAt:
|
|
3847
|
+
bytes: z26.number().int(),
|
|
3848
|
+
lastUsedAt: z26.string().nullable()
|
|
3804
3849
|
});
|
|
3805
3850
|
|
|
3806
3851
|
// ../contracts/src/composites.ts
|
|
3807
|
-
import { z as
|
|
3808
|
-
var metricToneSchema =
|
|
3809
|
-
var scoreSummarySchema =
|
|
3810
|
-
label:
|
|
3811
|
-
value:
|
|
3812
|
-
delta:
|
|
3852
|
+
import { z as z27 } from "zod";
|
|
3853
|
+
var metricToneSchema = z27.enum(["positive", "caution", "negative", "neutral"]);
|
|
3854
|
+
var scoreSummarySchema = z27.object({
|
|
3855
|
+
label: z27.string(),
|
|
3856
|
+
value: z27.string(),
|
|
3857
|
+
delta: z27.string(),
|
|
3813
3858
|
tone: metricToneSchema,
|
|
3814
|
-
description:
|
|
3815
|
-
tooltip:
|
|
3816
|
-
trend:
|
|
3817
|
-
progress:
|
|
3818
|
-
providerCoverage:
|
|
3859
|
+
description: z27.string(),
|
|
3860
|
+
tooltip: z27.string().optional(),
|
|
3861
|
+
trend: z27.array(z27.number()),
|
|
3862
|
+
progress: z27.number().optional(),
|
|
3863
|
+
providerCoverage: z27.string().optional()
|
|
3819
3864
|
});
|
|
3820
3865
|
var mentionShareSchema = scoreSummarySchema.extend({
|
|
3821
|
-
breakdown:
|
|
3822
|
-
projectMentionSnapshots:
|
|
3823
|
-
competitorMentionSnapshots:
|
|
3824
|
-
perCompetitor:
|
|
3825
|
-
domain:
|
|
3826
|
-
mentionSnapshots:
|
|
3827
|
-
shareOfCompetitiveTotal:
|
|
3866
|
+
breakdown: z27.object({
|
|
3867
|
+
projectMentionSnapshots: z27.number().int().nonnegative(),
|
|
3868
|
+
competitorMentionSnapshots: z27.number().int().nonnegative(),
|
|
3869
|
+
perCompetitor: z27.array(z27.object({
|
|
3870
|
+
domain: z27.string(),
|
|
3871
|
+
mentionSnapshots: z27.number().int().nonnegative(),
|
|
3872
|
+
shareOfCompetitiveTotal: z27.number()
|
|
3828
3873
|
})),
|
|
3829
|
-
snapshotsWithAnswerText:
|
|
3830
|
-
snapshotsTotal:
|
|
3874
|
+
snapshotsWithAnswerText: z27.number().int().nonnegative(),
|
|
3875
|
+
snapshotsTotal: z27.number().int().nonnegative()
|
|
3831
3876
|
})
|
|
3832
3877
|
});
|
|
3833
|
-
var movementSummarySchema =
|
|
3834
|
-
gained:
|
|
3835
|
-
lost:
|
|
3878
|
+
var movementSummarySchema = z27.object({
|
|
3879
|
+
gained: z27.number().int().nonnegative(),
|
|
3880
|
+
lost: z27.number().int().nonnegative(),
|
|
3836
3881
|
tone: metricToneSchema,
|
|
3837
|
-
hasPreviousRun:
|
|
3838
|
-
gainedQueries:
|
|
3839
|
-
lostQueries:
|
|
3840
|
-
});
|
|
3841
|
-
var movementComparisonSchema =
|
|
3842
|
-
hasPreviousRun:
|
|
3843
|
-
comparable:
|
|
3844
|
-
querySetChanged:
|
|
3845
|
-
previousRunAt:
|
|
3846
|
-
currentQueryCount:
|
|
3847
|
-
previousQueryCount:
|
|
3848
|
-
comparableQueryCount:
|
|
3849
|
-
addedQueryCount:
|
|
3850
|
-
removedQueryCount:
|
|
3851
|
-
addedQueries:
|
|
3852
|
-
removedQueries:
|
|
3853
|
-
});
|
|
3854
|
-
var projectOverviewInsightSchema =
|
|
3855
|
-
id:
|
|
3856
|
-
projectId:
|
|
3857
|
-
runId:
|
|
3858
|
-
type:
|
|
3882
|
+
hasPreviousRun: z27.boolean(),
|
|
3883
|
+
gainedQueries: z27.array(z27.string()).optional(),
|
|
3884
|
+
lostQueries: z27.array(z27.string()).optional()
|
|
3885
|
+
});
|
|
3886
|
+
var movementComparisonSchema = z27.object({
|
|
3887
|
+
hasPreviousRun: z27.boolean(),
|
|
3888
|
+
comparable: z27.boolean(),
|
|
3889
|
+
querySetChanged: z27.boolean(),
|
|
3890
|
+
previousRunAt: z27.string().nullable(),
|
|
3891
|
+
currentQueryCount: z27.number().int().nonnegative(),
|
|
3892
|
+
previousQueryCount: z27.number().int().nonnegative(),
|
|
3893
|
+
comparableQueryCount: z27.number().int().nonnegative(),
|
|
3894
|
+
addedQueryCount: z27.number().int().nonnegative(),
|
|
3895
|
+
removedQueryCount: z27.number().int().nonnegative(),
|
|
3896
|
+
addedQueries: z27.array(z27.string()),
|
|
3897
|
+
removedQueries: z27.array(z27.string())
|
|
3898
|
+
});
|
|
3899
|
+
var projectOverviewInsightSchema = z27.object({
|
|
3900
|
+
id: z27.string(),
|
|
3901
|
+
projectId: z27.string(),
|
|
3902
|
+
runId: z27.string().nullable(),
|
|
3903
|
+
type: z27.enum([
|
|
3859
3904
|
"regression",
|
|
3860
3905
|
"gain",
|
|
3861
3906
|
"opportunity",
|
|
@@ -3871,70 +3916,70 @@ var projectOverviewInsightSchema = z26.object({
|
|
|
3871
3916
|
"gbp-metric-drop",
|
|
3872
3917
|
"gbp-keyword-drop"
|
|
3873
3918
|
]),
|
|
3874
|
-
severity:
|
|
3875
|
-
title:
|
|
3876
|
-
query:
|
|
3877
|
-
provider:
|
|
3878
|
-
recommendation:
|
|
3879
|
-
action:
|
|
3880
|
-
target:
|
|
3881
|
-
reason:
|
|
3919
|
+
severity: z27.enum(["critical", "high", "medium", "low"]),
|
|
3920
|
+
title: z27.string(),
|
|
3921
|
+
query: z27.string(),
|
|
3922
|
+
provider: z27.string(),
|
|
3923
|
+
recommendation: z27.object({
|
|
3924
|
+
action: z27.string(),
|
|
3925
|
+
target: z27.string().optional(),
|
|
3926
|
+
reason: z27.string()
|
|
3882
3927
|
}).optional(),
|
|
3883
|
-
cause:
|
|
3884
|
-
cause:
|
|
3885
|
-
competitorDomain:
|
|
3886
|
-
details:
|
|
3928
|
+
cause: z27.object({
|
|
3929
|
+
cause: z27.string(),
|
|
3930
|
+
competitorDomain: z27.string().optional(),
|
|
3931
|
+
details: z27.string().optional()
|
|
3887
3932
|
}).optional(),
|
|
3888
|
-
dismissed:
|
|
3889
|
-
createdAt:
|
|
3890
|
-
});
|
|
3891
|
-
var projectOverviewHealthSchema =
|
|
3892
|
-
id:
|
|
3893
|
-
projectId:
|
|
3894
|
-
runId:
|
|
3895
|
-
overallCitedRate:
|
|
3896
|
-
overallMentionRate:
|
|
3897
|
-
totalPairs:
|
|
3898
|
-
citedPairs:
|
|
3899
|
-
mentionedPairs:
|
|
3900
|
-
providerBreakdown:
|
|
3901
|
-
citedRate:
|
|
3902
|
-
mentionRate:
|
|
3903
|
-
cited:
|
|
3904
|
-
mentioned:
|
|
3905
|
-
total:
|
|
3933
|
+
dismissed: z27.boolean(),
|
|
3934
|
+
createdAt: z27.string()
|
|
3935
|
+
});
|
|
3936
|
+
var projectOverviewHealthSchema = z27.object({
|
|
3937
|
+
id: z27.string(),
|
|
3938
|
+
projectId: z27.string(),
|
|
3939
|
+
runId: z27.string().nullable(),
|
|
3940
|
+
overallCitedRate: z27.number(),
|
|
3941
|
+
overallMentionRate: z27.number(),
|
|
3942
|
+
totalPairs: z27.number().int().nonnegative(),
|
|
3943
|
+
citedPairs: z27.number().int().nonnegative(),
|
|
3944
|
+
mentionedPairs: z27.number().int().nonnegative(),
|
|
3945
|
+
providerBreakdown: z27.record(z27.string(), z27.object({
|
|
3946
|
+
citedRate: z27.number(),
|
|
3947
|
+
mentionRate: z27.number(),
|
|
3948
|
+
cited: z27.number().int().nonnegative(),
|
|
3949
|
+
mentioned: z27.number().int().nonnegative(),
|
|
3950
|
+
total: z27.number().int().nonnegative()
|
|
3906
3951
|
})),
|
|
3907
|
-
createdAt:
|
|
3908
|
-
status:
|
|
3909
|
-
reason:
|
|
3952
|
+
createdAt: z27.string(),
|
|
3953
|
+
status: z27.enum(["ready", "no-data"]),
|
|
3954
|
+
reason: z27.literal("no-runs-yet").optional()
|
|
3910
3955
|
});
|
|
3911
|
-
var projectOverviewDtoSchema =
|
|
3956
|
+
var projectOverviewDtoSchema = z27.object({
|
|
3912
3957
|
project: projectDtoSchema,
|
|
3913
3958
|
latestRun: latestProjectRunDtoSchema,
|
|
3914
3959
|
health: projectOverviewHealthSchema.nullable(),
|
|
3915
|
-
topInsights:
|
|
3916
|
-
queryCounts:
|
|
3917
|
-
totalQueries:
|
|
3918
|
-
citedQueries:
|
|
3919
|
-
notCitedQueries:
|
|
3920
|
-
citedRate:
|
|
3921
|
-
mentionedQueries:
|
|
3922
|
-
notMentionedQueries:
|
|
3923
|
-
mentionRate:
|
|
3960
|
+
topInsights: z27.array(projectOverviewInsightSchema),
|
|
3961
|
+
queryCounts: z27.object({
|
|
3962
|
+
totalQueries: z27.number().int().nonnegative(),
|
|
3963
|
+
citedQueries: z27.number().int().nonnegative(),
|
|
3964
|
+
notCitedQueries: z27.number().int().nonnegative(),
|
|
3965
|
+
citedRate: z27.number(),
|
|
3966
|
+
mentionedQueries: z27.number().int().nonnegative(),
|
|
3967
|
+
notMentionedQueries: z27.number().int().nonnegative(),
|
|
3968
|
+
mentionRate: z27.number()
|
|
3924
3969
|
}),
|
|
3925
|
-
providers:
|
|
3926
|
-
provider:
|
|
3927
|
-
citedRate:
|
|
3928
|
-
cited:
|
|
3929
|
-
total:
|
|
3970
|
+
providers: z27.array(z27.object({
|
|
3971
|
+
provider: z27.string(),
|
|
3972
|
+
citedRate: z27.number(),
|
|
3973
|
+
cited: z27.number().int().nonnegative(),
|
|
3974
|
+
total: z27.number().int().nonnegative()
|
|
3930
3975
|
})),
|
|
3931
|
-
transitions:
|
|
3932
|
-
since:
|
|
3933
|
-
gained:
|
|
3934
|
-
lost:
|
|
3935
|
-
emerging:
|
|
3976
|
+
transitions: z27.object({
|
|
3977
|
+
since: z27.string().nullable(),
|
|
3978
|
+
gained: z27.number().int().nonnegative(),
|
|
3979
|
+
lost: z27.number().int().nonnegative(),
|
|
3980
|
+
emerging: z27.number().int().nonnegative()
|
|
3936
3981
|
}),
|
|
3937
|
-
scores:
|
|
3982
|
+
scores: z27.object({
|
|
3938
3983
|
mention: scoreSummarySchema,
|
|
3939
3984
|
visibility: scoreSummarySchema,
|
|
3940
3985
|
mentionShare: mentionShareSchema,
|
|
@@ -3948,72 +3993,72 @@ var projectOverviewDtoSchema = z26.object({
|
|
|
3948
3993
|
citationMovement: movementSummarySchema,
|
|
3949
3994
|
mentionMovement: movementSummarySchema,
|
|
3950
3995
|
movementComparison: movementComparisonSchema,
|
|
3951
|
-
competitors:
|
|
3952
|
-
id:
|
|
3953
|
-
domain:
|
|
3954
|
-
citationCount:
|
|
3955
|
-
totalQueries:
|
|
3956
|
-
pressureLabel:
|
|
3957
|
-
citedQueries:
|
|
3996
|
+
competitors: z27.array(z27.object({
|
|
3997
|
+
id: z27.string(),
|
|
3998
|
+
domain: z27.string(),
|
|
3999
|
+
citationCount: z27.number().int().nonnegative(),
|
|
4000
|
+
totalQueries: z27.number().int().nonnegative(),
|
|
4001
|
+
pressureLabel: z27.enum(["None", "Low", "Moderate", "High"]),
|
|
4002
|
+
citedQueries: z27.array(z27.string())
|
|
3958
4003
|
})),
|
|
3959
|
-
providerScores:
|
|
3960
|
-
provider:
|
|
3961
|
-
model:
|
|
3962
|
-
score:
|
|
3963
|
-
cited:
|
|
3964
|
-
total:
|
|
3965
|
-
trend:
|
|
4004
|
+
providerScores: z27.array(z27.object({
|
|
4005
|
+
provider: z27.string(),
|
|
4006
|
+
model: z27.string().nullable(),
|
|
4007
|
+
score: z27.number(),
|
|
4008
|
+
cited: z27.number().int().nonnegative(),
|
|
4009
|
+
total: z27.number().int().nonnegative(),
|
|
4010
|
+
trend: z27.array(z27.number()).optional()
|
|
3966
4011
|
})),
|
|
3967
|
-
attentionItems:
|
|
3968
|
-
id:
|
|
4012
|
+
attentionItems: z27.array(z27.object({
|
|
4013
|
+
id: z27.string(),
|
|
3969
4014
|
tone: metricToneSchema,
|
|
3970
|
-
title:
|
|
3971
|
-
detail:
|
|
3972
|
-
actionLabel:
|
|
3973
|
-
href:
|
|
4015
|
+
title: z27.string(),
|
|
4016
|
+
detail: z27.string(),
|
|
4017
|
+
actionLabel: z27.string(),
|
|
4018
|
+
href: z27.string()
|
|
3974
4019
|
})),
|
|
3975
|
-
runHistory:
|
|
3976
|
-
runId:
|
|
3977
|
-
createdAt:
|
|
3978
|
-
citedCount:
|
|
3979
|
-
totalCount:
|
|
3980
|
-
citationRate:
|
|
3981
|
-
mentionedCount:
|
|
3982
|
-
mentionRate:
|
|
3983
|
-
status:
|
|
4020
|
+
runHistory: z27.array(z27.object({
|
|
4021
|
+
runId: z27.string(),
|
|
4022
|
+
createdAt: z27.string(),
|
|
4023
|
+
citedCount: z27.number().int().nonnegative(),
|
|
4024
|
+
totalCount: z27.number().int().nonnegative(),
|
|
4025
|
+
citationRate: z27.number(),
|
|
4026
|
+
mentionedCount: z27.number().int().nonnegative(),
|
|
4027
|
+
mentionRate: z27.number(),
|
|
4028
|
+
status: z27.string()
|
|
3984
4029
|
})),
|
|
3985
|
-
suggestedQueries:
|
|
3986
|
-
rows:
|
|
3987
|
-
query:
|
|
3988
|
-
impressions:
|
|
3989
|
-
clicks:
|
|
3990
|
-
avgPosition:
|
|
3991
|
-
reason:
|
|
4030
|
+
suggestedQueries: z27.object({
|
|
4031
|
+
rows: z27.array(z27.object({
|
|
4032
|
+
query: z27.string(),
|
|
4033
|
+
impressions: z27.number(),
|
|
4034
|
+
clicks: z27.number(),
|
|
4035
|
+
avgPosition: z27.number(),
|
|
4036
|
+
reason: z27.string()
|
|
3992
4037
|
})),
|
|
3993
|
-
totalCandidates:
|
|
3994
|
-
skippedAlreadyTracked:
|
|
4038
|
+
totalCandidates: z27.number().int().nonnegative(),
|
|
4039
|
+
skippedAlreadyTracked: z27.number().int().nonnegative()
|
|
3995
4040
|
}),
|
|
3996
|
-
dateRangeLabel:
|
|
3997
|
-
contextLabel:
|
|
3998
|
-
});
|
|
3999
|
-
var searchHitKindSchema =
|
|
4000
|
-
var projectSearchSnapshotHitSchema =
|
|
4001
|
-
kind:
|
|
4002
|
-
id:
|
|
4003
|
-
runId:
|
|
4004
|
-
query:
|
|
4005
|
-
provider:
|
|
4006
|
-
model:
|
|
4041
|
+
dateRangeLabel: z27.string(),
|
|
4042
|
+
contextLabel: z27.string()
|
|
4043
|
+
});
|
|
4044
|
+
var searchHitKindSchema = z27.enum(["snapshot", "insight"]);
|
|
4045
|
+
var projectSearchSnapshotHitSchema = z27.object({
|
|
4046
|
+
kind: z27.literal("snapshot"),
|
|
4047
|
+
id: z27.string(),
|
|
4048
|
+
runId: z27.string(),
|
|
4049
|
+
query: z27.string(),
|
|
4050
|
+
provider: z27.string(),
|
|
4051
|
+
model: z27.string().nullable(),
|
|
4007
4052
|
citationState: citationStateSchema,
|
|
4008
|
-
matchedField:
|
|
4009
|
-
snippet:
|
|
4010
|
-
createdAt:
|
|
4011
|
-
});
|
|
4012
|
-
var projectSearchInsightHitSchema =
|
|
4013
|
-
kind:
|
|
4014
|
-
id:
|
|
4015
|
-
runId:
|
|
4016
|
-
type:
|
|
4053
|
+
matchedField: z27.enum(["answerText", "citedDomains", "searchQueries", "query"]),
|
|
4054
|
+
snippet: z27.string(),
|
|
4055
|
+
createdAt: z27.string()
|
|
4056
|
+
});
|
|
4057
|
+
var projectSearchInsightHitSchema = z27.object({
|
|
4058
|
+
kind: z27.literal("insight"),
|
|
4059
|
+
id: z27.string(),
|
|
4060
|
+
runId: z27.string().nullable(),
|
|
4061
|
+
type: z27.enum([
|
|
4017
4062
|
"regression",
|
|
4018
4063
|
"gain",
|
|
4019
4064
|
"opportunity",
|
|
@@ -4030,29 +4075,29 @@ var projectSearchInsightHitSchema = z26.object({
|
|
|
4030
4075
|
"gbp-metric-drop",
|
|
4031
4076
|
"gbp-keyword-drop"
|
|
4032
4077
|
]),
|
|
4033
|
-
severity:
|
|
4034
|
-
title:
|
|
4035
|
-
query:
|
|
4036
|
-
provider:
|
|
4037
|
-
matchedField:
|
|
4038
|
-
snippet:
|
|
4039
|
-
dismissed:
|
|
4040
|
-
createdAt:
|
|
4041
|
-
});
|
|
4042
|
-
var projectSearchHitSchema =
|
|
4078
|
+
severity: z27.enum(["critical", "high", "medium", "low"]),
|
|
4079
|
+
title: z27.string(),
|
|
4080
|
+
query: z27.string(),
|
|
4081
|
+
provider: z27.string(),
|
|
4082
|
+
matchedField: z27.enum(["title", "query", "recommendation", "cause"]),
|
|
4083
|
+
snippet: z27.string(),
|
|
4084
|
+
dismissed: z27.boolean(),
|
|
4085
|
+
createdAt: z27.string()
|
|
4086
|
+
});
|
|
4087
|
+
var projectSearchHitSchema = z27.discriminatedUnion("kind", [
|
|
4043
4088
|
projectSearchSnapshotHitSchema,
|
|
4044
4089
|
projectSearchInsightHitSchema
|
|
4045
4090
|
]);
|
|
4046
|
-
var projectSearchResponseSchema =
|
|
4047
|
-
query:
|
|
4048
|
-
totalHits:
|
|
4049
|
-
truncated:
|
|
4050
|
-
hits:
|
|
4091
|
+
var projectSearchResponseSchema = z27.object({
|
|
4092
|
+
query: z27.string(),
|
|
4093
|
+
totalHits: z27.number().int().nonnegative(),
|
|
4094
|
+
truncated: z27.boolean(),
|
|
4095
|
+
hits: z27.array(projectSearchHitSchema)
|
|
4051
4096
|
});
|
|
4052
4097
|
|
|
4053
4098
|
// ../contracts/src/content.ts
|
|
4054
|
-
import { z as
|
|
4055
|
-
var contentActionSchema =
|
|
4099
|
+
import { z as z28 } from "zod";
|
|
4100
|
+
var contentActionSchema = z28.enum(["create", "expand", "refresh", "add-schema"]);
|
|
4056
4101
|
var ContentActions = contentActionSchema.enum;
|
|
4057
4102
|
function contentActionLabel(action) {
|
|
4058
4103
|
switch (action) {
|
|
@@ -4066,9 +4111,9 @@ function contentActionLabel(action) {
|
|
|
4066
4111
|
return "Add schema";
|
|
4067
4112
|
}
|
|
4068
4113
|
}
|
|
4069
|
-
var demandSourceSchema =
|
|
4114
|
+
var demandSourceSchema = z28.enum(["gsc", "competitor-evidence", "both"]);
|
|
4070
4115
|
var DemandSources = demandSourceSchema.enum;
|
|
4071
|
-
var actionConfidenceSchema =
|
|
4116
|
+
var actionConfidenceSchema = z28.enum(["high", "medium", "low"]);
|
|
4072
4117
|
var ActionConfidences = actionConfidenceSchema.enum;
|
|
4073
4118
|
function actionConfidenceLabel(confidence) {
|
|
4074
4119
|
switch (confidence) {
|
|
@@ -4080,7 +4125,7 @@ function actionConfidenceLabel(confidence) {
|
|
|
4080
4125
|
return "Low";
|
|
4081
4126
|
}
|
|
4082
4127
|
}
|
|
4083
|
-
var pageTypeSchema =
|
|
4128
|
+
var pageTypeSchema = z28.enum([
|
|
4084
4129
|
"blog-post",
|
|
4085
4130
|
"comparison",
|
|
4086
4131
|
"listicle",
|
|
@@ -4089,7 +4134,7 @@ var pageTypeSchema = z27.enum([
|
|
|
4089
4134
|
"glossary"
|
|
4090
4135
|
]);
|
|
4091
4136
|
var PageTypes = pageTypeSchema.enum;
|
|
4092
|
-
var contentActionStateSchema =
|
|
4137
|
+
var contentActionStateSchema = z28.enum([
|
|
4093
4138
|
"proposed",
|
|
4094
4139
|
"briefed",
|
|
4095
4140
|
"payload-generated",
|
|
@@ -4099,7 +4144,7 @@ var contentActionStateSchema = z27.enum([
|
|
|
4099
4144
|
"dismissed"
|
|
4100
4145
|
]);
|
|
4101
4146
|
var ContentActionStates = contentActionStateSchema.enum;
|
|
4102
|
-
var winnabilityClassSchema =
|
|
4147
|
+
var winnabilityClassSchema = z28.enum(["ownable", "ceded"]);
|
|
4103
4148
|
var WinnabilityClasses = winnabilityClassSchema.enum;
|
|
4104
4149
|
function winnabilityClassLabel(winnabilityClass) {
|
|
4105
4150
|
switch (winnabilityClass) {
|
|
@@ -4134,40 +4179,40 @@ function deriveWinnabilityClass(citedSurfaceDomains, surfaceClasses, threshold =
|
|
|
4134
4179
|
winnability
|
|
4135
4180
|
};
|
|
4136
4181
|
}
|
|
4137
|
-
var ourBestPageSchema =
|
|
4138
|
-
url:
|
|
4139
|
-
gscImpressions:
|
|
4140
|
-
gscClicks:
|
|
4182
|
+
var ourBestPageSchema = z28.object({
|
|
4183
|
+
url: z28.string(),
|
|
4184
|
+
gscImpressions: z28.number().nonnegative(),
|
|
4185
|
+
gscClicks: z28.number().nonnegative(),
|
|
4141
4186
|
// Null when the page came from the inventory fallback (no GSC ranking data).
|
|
4142
|
-
gscAvgPosition:
|
|
4143
|
-
organicSessions:
|
|
4187
|
+
gscAvgPosition: z28.number().nonnegative().nullable(),
|
|
4188
|
+
organicSessions: z28.number().nonnegative()
|
|
4144
4189
|
});
|
|
4145
|
-
var winningCompetitorSchema =
|
|
4146
|
-
domain:
|
|
4147
|
-
url:
|
|
4148
|
-
title:
|
|
4149
|
-
citationCount:
|
|
4190
|
+
var winningCompetitorSchema = z28.object({
|
|
4191
|
+
domain: z28.string(),
|
|
4192
|
+
url: z28.string(),
|
|
4193
|
+
title: z28.string(),
|
|
4194
|
+
citationCount: z28.number().int().nonnegative()
|
|
4150
4195
|
});
|
|
4151
|
-
var scoreBreakdownSchema =
|
|
4152
|
-
demand:
|
|
4153
|
-
competitor:
|
|
4154
|
-
absence:
|
|
4155
|
-
gapSeverity:
|
|
4196
|
+
var scoreBreakdownSchema = z28.object({
|
|
4197
|
+
demand: z28.number(),
|
|
4198
|
+
competitor: z28.number(),
|
|
4199
|
+
absence: z28.number(),
|
|
4200
|
+
gapSeverity: z28.number()
|
|
4156
4201
|
});
|
|
4157
|
-
var existingActionRefSchema =
|
|
4158
|
-
actionId:
|
|
4202
|
+
var existingActionRefSchema = z28.object({
|
|
4203
|
+
actionId: z28.string(),
|
|
4159
4204
|
state: contentActionStateSchema,
|
|
4160
|
-
lastUpdated:
|
|
4205
|
+
lastUpdated: z28.string()
|
|
4161
4206
|
});
|
|
4162
|
-
var contentTargetRowDtoSchema =
|
|
4163
|
-
targetRef:
|
|
4164
|
-
query:
|
|
4207
|
+
var contentTargetRowDtoSchema = z28.object({
|
|
4208
|
+
targetRef: z28.string(),
|
|
4209
|
+
query: z28.string(),
|
|
4165
4210
|
action: contentActionSchema,
|
|
4166
4211
|
ourBestPage: ourBestPageSchema.nullable(),
|
|
4167
4212
|
winningCompetitor: winningCompetitorSchema.nullable(),
|
|
4168
|
-
score:
|
|
4213
|
+
score: z28.number(),
|
|
4169
4214
|
scoreBreakdown: scoreBreakdownSchema,
|
|
4170
|
-
drivers:
|
|
4215
|
+
drivers: z28.array(z28.string()),
|
|
4171
4216
|
demandSource: demandSourceSchema,
|
|
4172
4217
|
actionConfidence: actionConfidenceSchema,
|
|
4173
4218
|
existingAction: existingActionRefSchema.nullable(),
|
|
@@ -4182,134 +4227,134 @@ var contentTargetRowDtoSchema = z27.object({
|
|
|
4182
4227
|
* `[0, 1]`. `null` when the gate failed open (no classification coverage for
|
|
4183
4228
|
* the cited surface) — distinct from a computed `1.0`.
|
|
4184
4229
|
*/
|
|
4185
|
-
winnability:
|
|
4186
|
-
});
|
|
4187
|
-
var contentTargetsResponseDtoSchema =
|
|
4188
|
-
targets:
|
|
4189
|
-
contextMetrics:
|
|
4190
|
-
totalAiReferralSessions:
|
|
4191
|
-
latestRunId:
|
|
4192
|
-
runTimestamp:
|
|
4230
|
+
winnability: z28.number().min(0).max(1).nullable()
|
|
4231
|
+
});
|
|
4232
|
+
var contentTargetsResponseDtoSchema = z28.object({
|
|
4233
|
+
targets: z28.array(contentTargetRowDtoSchema),
|
|
4234
|
+
contextMetrics: z28.object({
|
|
4235
|
+
totalAiReferralSessions: z28.number().int().nonnegative(),
|
|
4236
|
+
latestRunId: z28.string(),
|
|
4237
|
+
runTimestamp: z28.string()
|
|
4193
4238
|
})
|
|
4194
4239
|
});
|
|
4195
|
-
var contentTargetDismissalDtoSchema =
|
|
4196
|
-
targetRef:
|
|
4197
|
-
addressedUrl:
|
|
4198
|
-
note:
|
|
4199
|
-
dismissedAt:
|
|
4240
|
+
var contentTargetDismissalDtoSchema = z28.object({
|
|
4241
|
+
targetRef: z28.string(),
|
|
4242
|
+
addressedUrl: z28.string().nullable(),
|
|
4243
|
+
note: z28.string().nullable(),
|
|
4244
|
+
dismissedAt: z28.string()
|
|
4200
4245
|
});
|
|
4201
|
-
var contentTargetDismissalsResponseDtoSchema =
|
|
4202
|
-
dismissals:
|
|
4246
|
+
var contentTargetDismissalsResponseDtoSchema = z28.object({
|
|
4247
|
+
dismissals: z28.array(contentTargetDismissalDtoSchema)
|
|
4203
4248
|
});
|
|
4204
|
-
var contentTargetDismissRequestSchema =
|
|
4205
|
-
targetRef:
|
|
4249
|
+
var contentTargetDismissRequestSchema = z28.object({
|
|
4250
|
+
targetRef: z28.string().min(1),
|
|
4206
4251
|
/** URL of the page the user wrote that addresses this recommendation. Stored verbatim for the audit trail; not currently used to suppress the slug-token matcher. */
|
|
4207
|
-
addressedUrl:
|
|
4252
|
+
addressedUrl: z28.string().url().optional(),
|
|
4208
4253
|
/** Free-form note (e.g. "covered in our Q1 content sprint"). 500 char cap is the API surface limit; the DB column is unbounded. */
|
|
4209
|
-
note:
|
|
4254
|
+
note: z28.string().max(500).optional()
|
|
4210
4255
|
});
|
|
4211
|
-
var recommendationExplanationDtoSchema =
|
|
4212
|
-
targetRef:
|
|
4256
|
+
var recommendationExplanationDtoSchema = z28.object({
|
|
4257
|
+
targetRef: z28.string(),
|
|
4213
4258
|
/** Version of the prompt template used. Bumping the version invalidates the cache forward without touching the table. */
|
|
4214
|
-
promptVersion:
|
|
4259
|
+
promptVersion: z28.string(),
|
|
4215
4260
|
/** Provider that produced the explanation (e.g. "claude", "gemini"). */
|
|
4216
|
-
provider:
|
|
4261
|
+
provider: z28.string(),
|
|
4217
4262
|
/** Model id within that provider (e.g. "claude-sonnet-4-6"). */
|
|
4218
|
-
model:
|
|
4263
|
+
model: z28.string(),
|
|
4219
4264
|
/** Markdown-formatted rationale + recommended next steps. */
|
|
4220
|
-
responseText:
|
|
4265
|
+
responseText: z28.string(),
|
|
4221
4266
|
/** Estimated cost in millicents (1/100 of a cent). 0 when unknown. */
|
|
4222
|
-
costMillicents:
|
|
4223
|
-
generatedAt:
|
|
4267
|
+
costMillicents: z28.number().int().nonnegative(),
|
|
4268
|
+
generatedAt: z28.string()
|
|
4224
4269
|
});
|
|
4225
|
-
var recommendationExplainRequestSchema =
|
|
4270
|
+
var recommendationExplainRequestSchema = z28.object({
|
|
4226
4271
|
/**
|
|
4227
4272
|
* Optional provider override (e.g. "claude" to force Claude even if
|
|
4228
4273
|
* the project's default is Gemini). Falls through to project default
|
|
4229
4274
|
* → auto-detect when omitted.
|
|
4230
4275
|
*/
|
|
4231
|
-
provider:
|
|
4276
|
+
provider: z28.string().optional(),
|
|
4232
4277
|
/**
|
|
4233
4278
|
* Optional model override within the chosen provider. Falls through to
|
|
4234
4279
|
* the `analyze`-tier default model when omitted.
|
|
4235
4280
|
*/
|
|
4236
|
-
model:
|
|
4281
|
+
model: z28.string().optional(),
|
|
4237
4282
|
/**
|
|
4238
4283
|
* Force a fresh LLM call even if a cached explanation exists for the
|
|
4239
4284
|
* current prompt version. Use sparingly — defeats the cache.
|
|
4240
4285
|
*/
|
|
4241
|
-
forceRefresh:
|
|
4286
|
+
forceRefresh: z28.boolean().optional()
|
|
4242
4287
|
});
|
|
4243
|
-
var contentBriefDtoSchema =
|
|
4288
|
+
var contentBriefDtoSchema = z28.object({
|
|
4244
4289
|
/** The query the brief is for (echoed from the recommendation). */
|
|
4245
|
-
targetQuery:
|
|
4290
|
+
targetQuery: z28.string().trim().min(1),
|
|
4246
4291
|
/** Always `ownable` in practice — the gate rejects `ceded` before synthesis. */
|
|
4247
4292
|
winnabilityClass: winnabilityClassSchema,
|
|
4248
4293
|
/** The differentiated content angle to take. */
|
|
4249
|
-
angle:
|
|
4294
|
+
angle: z28.string().trim().min(1),
|
|
4250
4295
|
/** Why this query is winnable, citing the cited-surface signal. */
|
|
4251
|
-
whyWinnable:
|
|
4296
|
+
whyWinnable: z28.string().trim().min(1),
|
|
4252
4297
|
/** The schema.org type or markup to add or extend. */
|
|
4253
|
-
schemaHookup:
|
|
4298
|
+
schemaHookup: z28.string().trim().min(1),
|
|
4254
4299
|
/** Why the cited surface is controllable (the ownable-vs-ceded reasoning). */
|
|
4255
|
-
controllableSurfaceRationale:
|
|
4300
|
+
controllableSurfaceRationale: z28.string().trim().min(1)
|
|
4256
4301
|
});
|
|
4257
|
-
var recommendationBriefDtoSchema =
|
|
4258
|
-
targetRef:
|
|
4302
|
+
var recommendationBriefDtoSchema = z28.object({
|
|
4303
|
+
targetRef: z28.string(),
|
|
4259
4304
|
/** Version of the brief prompt template; bumping invalidates the cache forward. */
|
|
4260
|
-
promptVersion:
|
|
4261
|
-
provider:
|
|
4262
|
-
model:
|
|
4305
|
+
promptVersion: z28.string(),
|
|
4306
|
+
provider: z28.string(),
|
|
4307
|
+
model: z28.string(),
|
|
4263
4308
|
brief: contentBriefDtoSchema,
|
|
4264
4309
|
/** Estimated cost in millicents (1/100 of a cent). 0 when unknown. */
|
|
4265
|
-
costMillicents:
|
|
4266
|
-
generatedAt:
|
|
4310
|
+
costMillicents: z28.number().int().nonnegative(),
|
|
4311
|
+
generatedAt: z28.string()
|
|
4267
4312
|
});
|
|
4268
|
-
var domainClassificationDtoSchema =
|
|
4269
|
-
domain:
|
|
4313
|
+
var domainClassificationDtoSchema = z28.object({
|
|
4314
|
+
domain: z28.string(),
|
|
4270
4315
|
competitorType: discoveryCompetitorTypeSchema,
|
|
4271
|
-
hits:
|
|
4272
|
-
updatedAt:
|
|
4273
|
-
});
|
|
4274
|
-
var domainClassificationsResponseDtoSchema = z27.object({
|
|
4275
|
-
classifications: z27.array(domainClassificationDtoSchema)
|
|
4316
|
+
hits: z28.number().int().nonnegative(),
|
|
4317
|
+
updatedAt: z28.string()
|
|
4276
4318
|
});
|
|
4277
|
-
var
|
|
4278
|
-
|
|
4279
|
-
title: z27.string(),
|
|
4280
|
-
domain: z27.string(),
|
|
4281
|
-
isOurDomain: z27.boolean(),
|
|
4282
|
-
isCompetitor: z27.boolean(),
|
|
4283
|
-
citationCount: z27.number().int().nonnegative(),
|
|
4284
|
-
providers: z27.array(providerNameSchema)
|
|
4285
|
-
});
|
|
4286
|
-
var contentSourceRowDtoSchema = z27.object({
|
|
4287
|
-
query: z27.string(),
|
|
4288
|
-
groundingSources: z27.array(contentGroundingSourceSchema)
|
|
4319
|
+
var domainClassificationsResponseDtoSchema = z28.object({
|
|
4320
|
+
classifications: z28.array(domainClassificationDtoSchema)
|
|
4289
4321
|
});
|
|
4290
|
-
var
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4322
|
+
var contentGroundingSourceSchema = z28.object({
|
|
4323
|
+
uri: z28.string(),
|
|
4324
|
+
title: z28.string(),
|
|
4325
|
+
domain: z28.string(),
|
|
4326
|
+
isOurDomain: z28.boolean(),
|
|
4327
|
+
isCompetitor: z28.boolean(),
|
|
4328
|
+
citationCount: z28.number().int().nonnegative(),
|
|
4329
|
+
providers: z28.array(providerNameSchema)
|
|
4330
|
+
});
|
|
4331
|
+
var contentSourceRowDtoSchema = z28.object({
|
|
4332
|
+
query: z28.string(),
|
|
4333
|
+
groundingSources: z28.array(contentGroundingSourceSchema)
|
|
4334
|
+
});
|
|
4335
|
+
var contentSourcesResponseDtoSchema = z28.object({
|
|
4336
|
+
sources: z28.array(contentSourceRowDtoSchema),
|
|
4337
|
+
latestRunId: z28.string()
|
|
4338
|
+
});
|
|
4339
|
+
var contentGapRowDtoSchema = z28.object({
|
|
4340
|
+
query: z28.string(),
|
|
4341
|
+
competitorDomains: z28.array(z28.string()),
|
|
4342
|
+
competitorCount: z28.number().int().nonnegative(),
|
|
4343
|
+
missRate: z28.number().min(0).max(1),
|
|
4344
|
+
lastSeenInRunId: z28.string()
|
|
4345
|
+
});
|
|
4346
|
+
var contentGapsResponseDtoSchema = z28.object({
|
|
4347
|
+
gaps: z28.array(contentGapRowDtoSchema),
|
|
4348
|
+
latestRunId: z28.string()
|
|
4304
4349
|
});
|
|
4305
4350
|
|
|
4306
4351
|
// ../contracts/src/doctor.ts
|
|
4307
|
-
import { z as
|
|
4308
|
-
var checkStatusSchema =
|
|
4352
|
+
import { z as z29 } from "zod";
|
|
4353
|
+
var checkStatusSchema = z29.enum(["ok", "warn", "fail", "skipped"]);
|
|
4309
4354
|
var CheckStatuses = checkStatusSchema.enum;
|
|
4310
|
-
var checkScopeSchema =
|
|
4355
|
+
var checkScopeSchema = z29.enum(["global", "project"]);
|
|
4311
4356
|
var CheckScopes = checkScopeSchema.enum;
|
|
4312
|
-
var checkCategorySchema =
|
|
4357
|
+
var checkCategorySchema = z29.enum([
|
|
4313
4358
|
"auth",
|
|
4314
4359
|
"config",
|
|
4315
4360
|
"providers",
|
|
@@ -4320,31 +4365,31 @@ var checkCategorySchema = z28.enum([
|
|
|
4320
4365
|
"agent"
|
|
4321
4366
|
]);
|
|
4322
4367
|
var CheckCategories = checkCategorySchema.enum;
|
|
4323
|
-
var checkResultSchema =
|
|
4324
|
-
id:
|
|
4368
|
+
var checkResultSchema = z29.object({
|
|
4369
|
+
id: z29.string(),
|
|
4325
4370
|
category: checkCategorySchema,
|
|
4326
4371
|
scope: checkScopeSchema,
|
|
4327
|
-
title:
|
|
4372
|
+
title: z29.string(),
|
|
4328
4373
|
status: checkStatusSchema,
|
|
4329
|
-
code:
|
|
4330
|
-
summary:
|
|
4331
|
-
remediation:
|
|
4332
|
-
details:
|
|
4333
|
-
durationMs:
|
|
4374
|
+
code: z29.string().describe('Stable machine-readable code (e.g. "google.token.refresh-failed"). Use this for filtering and remediation logic.'),
|
|
4375
|
+
summary: z29.string(),
|
|
4376
|
+
remediation: z29.string().nullable().optional().describe('Operator-facing next step. Null when status is "ok" or no specific remediation applies.'),
|
|
4377
|
+
details: z29.record(z29.string(), z29.unknown()).optional().describe("Structured context \u2014 principal email, redirect URI, missing scopes, etc. Stable per check id."),
|
|
4378
|
+
durationMs: z29.number().int().nonnegative().describe("How long the check took to execute.")
|
|
4334
4379
|
});
|
|
4335
|
-
var doctorReportSchema =
|
|
4380
|
+
var doctorReportSchema = z29.object({
|
|
4336
4381
|
scope: checkScopeSchema,
|
|
4337
|
-
project:
|
|
4338
|
-
generatedAt:
|
|
4339
|
-
durationMs:
|
|
4340
|
-
summary:
|
|
4341
|
-
total:
|
|
4342
|
-
ok:
|
|
4343
|
-
warn:
|
|
4344
|
-
fail:
|
|
4345
|
-
skipped:
|
|
4382
|
+
project: z29.string().nullable().describe('Project name when scope is "project", null otherwise.'),
|
|
4383
|
+
generatedAt: z29.string().describe("ISO-8601 timestamp when this doctor run started."),
|
|
4384
|
+
durationMs: z29.number().int().nonnegative(),
|
|
4385
|
+
summary: z29.object({
|
|
4386
|
+
total: z29.number().int().nonnegative(),
|
|
4387
|
+
ok: z29.number().int().nonnegative(),
|
|
4388
|
+
warn: z29.number().int().nonnegative(),
|
|
4389
|
+
fail: z29.number().int().nonnegative(),
|
|
4390
|
+
skipped: z29.number().int().nonnegative()
|
|
4346
4391
|
}),
|
|
4347
|
-
checks:
|
|
4392
|
+
checks: z29.array(checkResultSchema)
|
|
4348
4393
|
});
|
|
4349
4394
|
function summarizeCheckResults(results) {
|
|
4350
4395
|
const summary = { total: results.length, ok: 0, warn: 0, fail: 0, skipped: 0 };
|
|
@@ -4373,52 +4418,52 @@ function normalizeQueryText(value) {
|
|
|
4373
4418
|
}
|
|
4374
4419
|
|
|
4375
4420
|
// ../contracts/src/citations.ts
|
|
4376
|
-
import { z as
|
|
4377
|
-
var citationCoverageProviderSchema =
|
|
4378
|
-
provider:
|
|
4421
|
+
import { z as z30 } from "zod";
|
|
4422
|
+
var citationCoverageProviderSchema = z30.object({
|
|
4423
|
+
provider: z30.string(),
|
|
4379
4424
|
citationState: citationStateSchema,
|
|
4380
|
-
cited:
|
|
4381
|
-
mentioned:
|
|
4382
|
-
runId:
|
|
4383
|
-
runCreatedAt:
|
|
4384
|
-
});
|
|
4385
|
-
var citationCoverageRowSchema =
|
|
4386
|
-
queryId:
|
|
4387
|
-
query:
|
|
4388
|
-
providers:
|
|
4389
|
-
citedCount:
|
|
4390
|
-
mentionedCount:
|
|
4391
|
-
totalProviders:
|
|
4392
|
-
});
|
|
4393
|
-
var competitorGapRowSchema =
|
|
4394
|
-
queryId:
|
|
4395
|
-
query:
|
|
4396
|
-
provider:
|
|
4397
|
-
citingCompetitors:
|
|
4398
|
-
runId:
|
|
4399
|
-
runCreatedAt:
|
|
4400
|
-
});
|
|
4401
|
-
var citationVisibilitySummarySchema =
|
|
4402
|
-
providersConfigured:
|
|
4403
|
-
providersCiting:
|
|
4404
|
-
providersMentioning:
|
|
4405
|
-
totalQueries:
|
|
4425
|
+
cited: z30.boolean(),
|
|
4426
|
+
mentioned: z30.boolean(),
|
|
4427
|
+
runId: z30.string(),
|
|
4428
|
+
runCreatedAt: z30.string()
|
|
4429
|
+
});
|
|
4430
|
+
var citationCoverageRowSchema = z30.object({
|
|
4431
|
+
queryId: z30.string(),
|
|
4432
|
+
query: z30.string(),
|
|
4433
|
+
providers: z30.array(citationCoverageProviderSchema),
|
|
4434
|
+
citedCount: z30.number().int().nonnegative(),
|
|
4435
|
+
mentionedCount: z30.number().int().nonnegative(),
|
|
4436
|
+
totalProviders: z30.number().int().nonnegative()
|
|
4437
|
+
});
|
|
4438
|
+
var competitorGapRowSchema = z30.object({
|
|
4439
|
+
queryId: z30.string(),
|
|
4440
|
+
query: z30.string(),
|
|
4441
|
+
provider: z30.string(),
|
|
4442
|
+
citingCompetitors: z30.array(z30.string()),
|
|
4443
|
+
runId: z30.string(),
|
|
4444
|
+
runCreatedAt: z30.string()
|
|
4445
|
+
});
|
|
4446
|
+
var citationVisibilitySummarySchema = z30.object({
|
|
4447
|
+
providersConfigured: z30.number().int().nonnegative(),
|
|
4448
|
+
providersCiting: z30.number().int().nonnegative(),
|
|
4449
|
+
providersMentioning: z30.number().int().nonnegative(),
|
|
4450
|
+
totalQueries: z30.number().int().nonnegative(),
|
|
4406
4451
|
// Cross-tab buckets — each tracked query with at least one snapshot lands
|
|
4407
4452
|
// in exactly one of these. Queries with zero snapshots are not counted in
|
|
4408
4453
|
// any bucket; (sum of buckets) ≤ totalQueries.
|
|
4409
|
-
queriesCitedAndMentioned:
|
|
4410
|
-
queriesCitedOnly:
|
|
4411
|
-
queriesMentionedOnly:
|
|
4412
|
-
queriesInvisible:
|
|
4413
|
-
latestRunId:
|
|
4414
|
-
latestRunAt:
|
|
4415
|
-
});
|
|
4416
|
-
var citationVisibilityResponseSchema =
|
|
4454
|
+
queriesCitedAndMentioned: z30.number().int().nonnegative(),
|
|
4455
|
+
queriesCitedOnly: z30.number().int().nonnegative(),
|
|
4456
|
+
queriesMentionedOnly: z30.number().int().nonnegative(),
|
|
4457
|
+
queriesInvisible: z30.number().int().nonnegative(),
|
|
4458
|
+
latestRunId: z30.string().nullable(),
|
|
4459
|
+
latestRunAt: z30.string().nullable()
|
|
4460
|
+
});
|
|
4461
|
+
var citationVisibilityResponseSchema = z30.object({
|
|
4417
4462
|
summary: citationVisibilitySummarySchema,
|
|
4418
|
-
byQuery:
|
|
4419
|
-
competitorGaps:
|
|
4420
|
-
status:
|
|
4421
|
-
reason:
|
|
4463
|
+
byQuery: z30.array(citationCoverageRowSchema),
|
|
4464
|
+
competitorGaps: z30.array(competitorGapRowSchema),
|
|
4465
|
+
status: z30.enum(["ready", "no-data"]),
|
|
4466
|
+
reason: z30.enum(["no-runs-yet", "no-queries"]).optional()
|
|
4422
4467
|
});
|
|
4423
4468
|
function emptyCitationVisibility(reason) {
|
|
4424
4469
|
return {
|
|
@@ -4445,10 +4490,10 @@ function citationStateToCited(state) {
|
|
|
4445
4490
|
}
|
|
4446
4491
|
|
|
4447
4492
|
// ../contracts/src/report.ts
|
|
4448
|
-
import { z as
|
|
4493
|
+
import { z as z31 } from "zod";
|
|
4449
4494
|
var REPORT_PERIOD_OPTIONS = [7, 14, 30, 90];
|
|
4450
4495
|
var REPORT_DEFAULT_PERIOD_DAYS = 30;
|
|
4451
|
-
var reportPeriodSchema =
|
|
4496
|
+
var reportPeriodSchema = z31.union([z31.literal(7), z31.literal(14), z31.literal(30), z31.literal(90)]).describe("Report window in days (7, 14, 30, or 90). Defaults to 30 when omitted.");
|
|
4452
4497
|
function isReportPeriodDays(n) {
|
|
4453
4498
|
return REPORT_PERIOD_OPTIONS.includes(n);
|
|
4454
4499
|
}
|
|
@@ -4463,45 +4508,45 @@ function parseReportPeriodDays(value) {
|
|
|
4463
4508
|
function reportComparisonWindowDays(periodDays) {
|
|
4464
4509
|
return Math.max(1, Math.floor(periodDays / 2));
|
|
4465
4510
|
}
|
|
4466
|
-
var providerLocationTreatmentSchema =
|
|
4511
|
+
var providerLocationTreatmentSchema = z31.enum([
|
|
4467
4512
|
"prompt",
|
|
4468
4513
|
"request-param",
|
|
4469
4514
|
"browser-geo",
|
|
4470
4515
|
"ignored"
|
|
4471
4516
|
]);
|
|
4472
|
-
var reportMetaLocationSchema =
|
|
4517
|
+
var reportMetaLocationSchema = z31.object({
|
|
4473
4518
|
/** Human-readable label as configured on the project (e.g. "michigan"). */
|
|
4474
|
-
label:
|
|
4519
|
+
label: z31.string(),
|
|
4475
4520
|
/** Resolved city/region/country from the project's `LocationContext`. */
|
|
4476
|
-
city:
|
|
4477
|
-
region:
|
|
4478
|
-
country:
|
|
4521
|
+
city: z31.string(),
|
|
4522
|
+
region: z31.string(),
|
|
4523
|
+
country: z31.string(),
|
|
4479
4524
|
/**
|
|
4480
4525
|
* Other locations configured on the project that did NOT power this report.
|
|
4481
4526
|
* When non-empty, callers should make clear that the report is location-scoped:
|
|
4482
4527
|
* a separate sweep is needed to see how AI engines respond from each one.
|
|
4483
4528
|
*/
|
|
4484
|
-
otherConfiguredLabels:
|
|
4529
|
+
otherConfiguredLabels: z31.array(z31.string())
|
|
4485
4530
|
});
|
|
4486
|
-
var reportProviderLocationHandlingSchema =
|
|
4531
|
+
var reportProviderLocationHandlingSchema = z31.object({
|
|
4487
4532
|
/** Provider name (matches `query_snapshots.provider`). */
|
|
4488
|
-
provider:
|
|
4533
|
+
provider: z31.string(),
|
|
4489
4534
|
/** How this provider applied the configured location during this run. */
|
|
4490
4535
|
treatment: providerLocationTreatmentSchema,
|
|
4491
4536
|
/** One-sentence explanation suitable for the report. */
|
|
4492
|
-
description:
|
|
4537
|
+
description: z31.string()
|
|
4493
4538
|
});
|
|
4494
|
-
var reportMetaSchema =
|
|
4539
|
+
var reportMetaSchema = z31.object({
|
|
4495
4540
|
/** ISO timestamp the report was generated (server clock). */
|
|
4496
|
-
generatedAt:
|
|
4541
|
+
generatedAt: z31.string(),
|
|
4497
4542
|
/** Project the report covers. */
|
|
4498
|
-
project:
|
|
4499
|
-
id:
|
|
4500
|
-
name:
|
|
4501
|
-
displayName:
|
|
4502
|
-
canonicalDomain:
|
|
4503
|
-
country:
|
|
4504
|
-
language:
|
|
4543
|
+
project: z31.object({
|
|
4544
|
+
id: z31.string(),
|
|
4545
|
+
name: z31.string(),
|
|
4546
|
+
displayName: z31.string(),
|
|
4547
|
+
canonicalDomain: z31.string(),
|
|
4548
|
+
country: z31.string(),
|
|
4549
|
+
language: z31.string()
|
|
4505
4550
|
}),
|
|
4506
4551
|
/**
|
|
4507
4552
|
* The location that powered the latest visibility run, when one was set.
|
|
@@ -4516,31 +4561,31 @@ var reportMetaSchema = z30.object({
|
|
|
4516
4561
|
* each provider's answer — some providers append it to the prompt, some
|
|
4517
4562
|
* pass it as a structured request field, and some (CDP) ignore it.
|
|
4518
4563
|
*/
|
|
4519
|
-
providerLocationHandling:
|
|
4564
|
+
providerLocationHandling: z31.array(reportProviderLocationHandlingSchema),
|
|
4520
4565
|
/** Earliest data point referenced by the report (ISO date). */
|
|
4521
|
-
periodStart:
|
|
4566
|
+
periodStart: z31.string().nullable(),
|
|
4522
4567
|
/** Latest data point referenced by the report (ISO date). */
|
|
4523
|
-
periodEnd:
|
|
4568
|
+
periodEnd: z31.string().nullable(),
|
|
4524
4569
|
/**
|
|
4525
4570
|
* The selected report window, in days (one of `REPORT_PERIOD_OPTIONS`).
|
|
4526
4571
|
* Every time-windowed section scopes to this many days; renderers read it to
|
|
4527
4572
|
* label the window ("Last 30 days", "(30d)"). Defaults to
|
|
4528
4573
|
* `REPORT_DEFAULT_PERIOD_DAYS` when no `period` is requested.
|
|
4529
4574
|
*/
|
|
4530
|
-
periodDays:
|
|
4575
|
+
periodDays: z31.number().int().positive()
|
|
4531
4576
|
});
|
|
4532
|
-
var reportExecutiveSummarySchema =
|
|
4577
|
+
var reportExecutiveSummarySchema = z31.object({
|
|
4533
4578
|
/**
|
|
4534
4579
|
* 0..100 — share of tracked queries that were cited by at least one
|
|
4535
4580
|
* provider in the latest run. "Cited" means the project's domain appeared
|
|
4536
4581
|
* in the source list / grounding the AI used to answer. Computed per-query
|
|
4537
4582
|
* (not per-(query × provider)) so the rate is invariant to provider count.
|
|
4538
4583
|
*/
|
|
4539
|
-
citationRate:
|
|
4584
|
+
citationRate: z31.number(),
|
|
4540
4585
|
/** Numerator of `citationRate` — distinct tracked queries cited by ≥1 provider in the latest run. */
|
|
4541
|
-
citedQueryCount:
|
|
4586
|
+
citedQueryCount: z31.number(),
|
|
4542
4587
|
/** Denominator of `citationRate` — total tracked queries. */
|
|
4543
|
-
totalQueryCount:
|
|
4588
|
+
totalQueryCount: z31.number(),
|
|
4544
4589
|
/**
|
|
4545
4590
|
* 0..100 — share of tracked queries where the project's brand or domain
|
|
4546
4591
|
* appeared in at least one provider's answer text in the latest run.
|
|
@@ -4548,71 +4593,71 @@ var reportExecutiveSummarySchema = z30.object({
|
|
|
4548
4593
|
* the prose without citing your domain in its sources, and vice versa.
|
|
4549
4594
|
* Same per-query denominator as `citationRate` for consistency.
|
|
4550
4595
|
*/
|
|
4551
|
-
mentionRate:
|
|
4596
|
+
mentionRate: z31.number(),
|
|
4552
4597
|
/** Numerator of `mentionRate` — distinct tracked queries mentioned in ≥1 provider's answer text. */
|
|
4553
|
-
mentionedQueryCount:
|
|
4598
|
+
mentionedQueryCount: z31.number(),
|
|
4554
4599
|
/** Compared to the previous run: 'up' | 'down' | 'flat' | 'unknown' (no prior run). */
|
|
4555
|
-
trend:
|
|
4600
|
+
trend: z31.enum(["up", "down", "flat", "unknown"]),
|
|
4556
4601
|
/** Total tracked queries. */
|
|
4557
|
-
queryCount:
|
|
4602
|
+
queryCount: z31.number(),
|
|
4558
4603
|
/** Total tracked competitors. */
|
|
4559
|
-
competitorCount:
|
|
4604
|
+
competitorCount: z31.number(),
|
|
4560
4605
|
/** Number of providers in the latest run. */
|
|
4561
|
-
providerCount:
|
|
4606
|
+
providerCount: z31.number(),
|
|
4562
4607
|
/** GSC totals across the most-recent sync window. Null when GSC is not connected. */
|
|
4563
|
-
gsc:
|
|
4564
|
-
clicks:
|
|
4565
|
-
impressions:
|
|
4566
|
-
ctr:
|
|
4567
|
-
avgPosition:
|
|
4568
|
-
periodStart:
|
|
4569
|
-
periodEnd:
|
|
4608
|
+
gsc: z31.object({
|
|
4609
|
+
clicks: z31.number(),
|
|
4610
|
+
impressions: z31.number(),
|
|
4611
|
+
ctr: z31.number(),
|
|
4612
|
+
avgPosition: z31.number(),
|
|
4613
|
+
periodStart: z31.string(),
|
|
4614
|
+
periodEnd: z31.string()
|
|
4570
4615
|
}).nullable(),
|
|
4571
4616
|
/** GA4 totals across the most-recent sync period. Null when GA4 is not connected. */
|
|
4572
|
-
ga:
|
|
4573
|
-
sessions:
|
|
4574
|
-
users:
|
|
4575
|
-
periodStart:
|
|
4576
|
-
periodEnd:
|
|
4617
|
+
ga: z31.object({
|
|
4618
|
+
sessions: z31.number(),
|
|
4619
|
+
users: z31.number(),
|
|
4620
|
+
periodStart: z31.string(),
|
|
4621
|
+
periodEnd: z31.string()
|
|
4577
4622
|
}).nullable(),
|
|
4578
4623
|
/** Top 3-5 findings, each rendered as a single-sentence narrative. */
|
|
4579
|
-
findings:
|
|
4580
|
-
title:
|
|
4581
|
-
detail:
|
|
4582
|
-
tone:
|
|
4624
|
+
findings: z31.array(z31.object({
|
|
4625
|
+
title: z31.string(),
|
|
4626
|
+
detail: z31.string(),
|
|
4627
|
+
tone: z31.enum(["positive", "caution", "negative", "neutral"])
|
|
4583
4628
|
}))
|
|
4584
4629
|
});
|
|
4585
|
-
var citationCellSchema =
|
|
4586
|
-
citationState:
|
|
4587
|
-
answerMentioned:
|
|
4588
|
-
model:
|
|
4630
|
+
var citationCellSchema = z31.object({
|
|
4631
|
+
citationState: z31.enum(["cited", "not-cited", "pending"]),
|
|
4632
|
+
answerMentioned: z31.boolean().nullable(),
|
|
4633
|
+
model: z31.string().nullable()
|
|
4589
4634
|
});
|
|
4590
|
-
var citationScorecardSchema =
|
|
4591
|
-
queries:
|
|
4592
|
-
providers:
|
|
4635
|
+
var citationScorecardSchema = z31.object({
|
|
4636
|
+
queries: z31.array(z31.string()),
|
|
4637
|
+
providers: z31.array(z31.string()),
|
|
4593
4638
|
/** matrix[queryIndex][providerIndex] — null when no snapshot exists for the pair. */
|
|
4594
|
-
matrix:
|
|
4639
|
+
matrix: z31.array(z31.array(citationCellSchema.nullable())),
|
|
4595
4640
|
/** Per-provider citation + mention rates (0..100). */
|
|
4596
|
-
providerRates:
|
|
4597
|
-
provider:
|
|
4598
|
-
citedCount:
|
|
4641
|
+
providerRates: z31.array(z31.object({
|
|
4642
|
+
provider: z31.string(),
|
|
4643
|
+
citedCount: z31.number(),
|
|
4599
4644
|
/** Number of snapshots for this provider where the answer text mentioned the project. */
|
|
4600
|
-
mentionedCount:
|
|
4601
|
-
totalCount:
|
|
4602
|
-
citationRate:
|
|
4603
|
-
mentionRate:
|
|
4645
|
+
mentionedCount: z31.number(),
|
|
4646
|
+
totalCount: z31.number(),
|
|
4647
|
+
citationRate: z31.number(),
|
|
4648
|
+
mentionRate: z31.number()
|
|
4604
4649
|
}))
|
|
4605
4650
|
});
|
|
4606
|
-
var competitorRowSchema =
|
|
4607
|
-
domain:
|
|
4651
|
+
var competitorRowSchema = z31.object({
|
|
4652
|
+
domain: z31.string(),
|
|
4608
4653
|
/** Number of (query × provider) pairs that cited this competitor. */
|
|
4609
|
-
citationCount:
|
|
4654
|
+
citationCount: z31.number(),
|
|
4610
4655
|
/** Out-of count for the same denominator. */
|
|
4611
|
-
totalCount:
|
|
4656
|
+
totalCount: z31.number(),
|
|
4612
4657
|
/** 'High' | 'Moderate' | 'Low' | 'None' — from buildPortfolioProject pressure logic. */
|
|
4613
|
-
pressureLabel:
|
|
4658
|
+
pressureLabel: z31.enum(["High", "Moderate", "Low", "None"]),
|
|
4614
4659
|
/** Distinct queries on which this competitor was cited. */
|
|
4615
|
-
citedQueries:
|
|
4660
|
+
citedQueries: z31.array(z31.string()),
|
|
4616
4661
|
/**
|
|
4617
4662
|
* Citation share 0..100. Numerator = this competitor's `citationCount`.
|
|
4618
4663
|
* Denominator = sum of `citationCount` across all competitors plus the
|
|
@@ -4620,30 +4665,30 @@ var competitorRowSchema = z30.object({
|
|
|
4620
4665
|
* slots in the snapshot. Distinct from the project-level Mention Share
|
|
4621
4666
|
* gauge — that one is brand-in-answer-text, this one is domain-in-source-list.
|
|
4622
4667
|
*/
|
|
4623
|
-
sharePct:
|
|
4668
|
+
sharePct: z31.number(),
|
|
4624
4669
|
/**
|
|
4625
4670
|
* URLs from the latest run's grounding sources whose host matches this
|
|
4626
4671
|
* competitor's domain, with the queries each URL was cited for. Empty
|
|
4627
4672
|
* when no grounding-source data is available (e.g. no `rawResponse` JSON
|
|
4628
4673
|
* stored for the snapshots).
|
|
4629
4674
|
*/
|
|
4630
|
-
theirCitedPages:
|
|
4675
|
+
theirCitedPages: z31.array(z31.object({ url: z31.string(), citedFor: z31.array(z31.string()) }))
|
|
4631
4676
|
});
|
|
4632
|
-
var competitorLandscapeSchema =
|
|
4677
|
+
var competitorLandscapeSchema = z31.object({
|
|
4633
4678
|
/** Project's own citation count (for the bar chart comparing project vs competitors). */
|
|
4634
|
-
projectCitationCount:
|
|
4635
|
-
competitors:
|
|
4679
|
+
projectCitationCount: z31.number(),
|
|
4680
|
+
competitors: z31.array(competitorRowSchema)
|
|
4636
4681
|
});
|
|
4637
|
-
var mentionRowSchema =
|
|
4638
|
-
domain:
|
|
4682
|
+
var mentionRowSchema = z31.object({
|
|
4683
|
+
domain: z31.string(),
|
|
4639
4684
|
/** Number of (query × provider) pairs whose answer text mentioned this competitor's brand or domain. */
|
|
4640
|
-
mentionCount:
|
|
4685
|
+
mentionCount: z31.number(),
|
|
4641
4686
|
/** Out-of count for the same denominator (snapshots that had answer text). */
|
|
4642
|
-
totalCount:
|
|
4687
|
+
totalCount: z31.number(),
|
|
4643
4688
|
/** 'High' | 'Moderate' | 'Low' | 'None' — mention frequency tier (mirrors CompetitorRow.pressureLabel). */
|
|
4644
|
-
pressureLabel:
|
|
4689
|
+
pressureLabel: z31.enum(["High", "Moderate", "Low", "None"]),
|
|
4645
4690
|
/** Distinct queries on which this competitor was mentioned. */
|
|
4646
|
-
mentionedQueries:
|
|
4691
|
+
mentionedQueries: z31.array(z31.string()),
|
|
4647
4692
|
/**
|
|
4648
4693
|
* Mention share 0..100. Numerator = this competitor's `mentionCount`.
|
|
4649
4694
|
* Denominator = sum of `mentionCount` across all competitors plus the
|
|
@@ -4651,135 +4696,135 @@ var mentionRowSchema = z30.object({
|
|
|
4651
4696
|
* mention. Per-competitor split of the same head-to-head measure the
|
|
4652
4697
|
* project's hero `MentionShareDto` gauge headlines.
|
|
4653
4698
|
*/
|
|
4654
|
-
sharePct:
|
|
4699
|
+
sharePct: z31.number()
|
|
4655
4700
|
});
|
|
4656
|
-
var mentionLandscapeSchema =
|
|
4701
|
+
var mentionLandscapeSchema = z31.object({
|
|
4657
4702
|
/** Project's own mention count (for the bar chart comparing project vs competitors). */
|
|
4658
|
-
projectMentionCount:
|
|
4703
|
+
projectMentionCount: z31.number(),
|
|
4659
4704
|
/** Snapshots considered — those with non-empty answerText. Drives the totalCount denominator. */
|
|
4660
|
-
totalAnswerSnapshots:
|
|
4661
|
-
competitors:
|
|
4705
|
+
totalAnswerSnapshots: z31.number(),
|
|
4706
|
+
competitors: z31.array(mentionRowSchema)
|
|
4662
4707
|
});
|
|
4663
|
-
var aiSourceCategoryBucketSchema =
|
|
4708
|
+
var aiSourceCategoryBucketSchema = z31.object({
|
|
4664
4709
|
/** Category slug from packages/contracts/src/source-categories. */
|
|
4665
|
-
category:
|
|
4710
|
+
category: z31.string(),
|
|
4666
4711
|
/** Display label. */
|
|
4667
|
-
label:
|
|
4712
|
+
label: z31.string(),
|
|
4668
4713
|
/** Number of citations falling in this category. */
|
|
4669
|
-
count:
|
|
4714
|
+
count: z31.number(),
|
|
4670
4715
|
/** 0..100 share of total citations. */
|
|
4671
|
-
sharePct:
|
|
4716
|
+
sharePct: z31.number()
|
|
4672
4717
|
});
|
|
4673
|
-
var aiSourceOriginSchema =
|
|
4674
|
-
categories:
|
|
4718
|
+
var aiSourceOriginSchema = z31.object({
|
|
4719
|
+
categories: z31.array(aiSourceCategoryBucketSchema),
|
|
4675
4720
|
/** Top 20 source domains by citation count (excluding the project's own domain). */
|
|
4676
|
-
topDomains:
|
|
4677
|
-
domain:
|
|
4678
|
-
count:
|
|
4721
|
+
topDomains: z31.array(z31.object({
|
|
4722
|
+
domain: z31.string(),
|
|
4723
|
+
count: z31.number(),
|
|
4679
4724
|
/** True when the domain is one of the project's tracked competitors. */
|
|
4680
|
-
isCompetitor:
|
|
4725
|
+
isCompetitor: z31.boolean()
|
|
4681
4726
|
}))
|
|
4682
4727
|
});
|
|
4683
|
-
var gscQueryRowSchema =
|
|
4684
|
-
query:
|
|
4685
|
-
clicks:
|
|
4686
|
-
impressions:
|
|
4687
|
-
ctr:
|
|
4688
|
-
avgPosition:
|
|
4728
|
+
var gscQueryRowSchema = z31.object({
|
|
4729
|
+
query: z31.string(),
|
|
4730
|
+
clicks: z31.number(),
|
|
4731
|
+
impressions: z31.number(),
|
|
4732
|
+
ctr: z31.number(),
|
|
4733
|
+
avgPosition: z31.number(),
|
|
4689
4734
|
/** Heuristic categorization: 'brand' | 'lead-gen' | 'industry' | 'other'. */
|
|
4690
|
-
category:
|
|
4691
|
-
});
|
|
4692
|
-
var gscSectionSchema =
|
|
4693
|
-
periodStart:
|
|
4694
|
-
periodEnd:
|
|
4695
|
-
totalClicks:
|
|
4696
|
-
totalImpressions:
|
|
4697
|
-
ctr:
|
|
4698
|
-
avgPosition:
|
|
4699
|
-
topQueries:
|
|
4700
|
-
categoryBreakdown:
|
|
4701
|
-
category:
|
|
4702
|
-
clicks:
|
|
4703
|
-
impressions:
|
|
4704
|
-
sharePct:
|
|
4735
|
+
category: z31.enum(["brand", "lead-gen", "industry", "other"])
|
|
4736
|
+
});
|
|
4737
|
+
var gscSectionSchema = z31.object({
|
|
4738
|
+
periodStart: z31.string(),
|
|
4739
|
+
periodEnd: z31.string(),
|
|
4740
|
+
totalClicks: z31.number(),
|
|
4741
|
+
totalImpressions: z31.number(),
|
|
4742
|
+
ctr: z31.number(),
|
|
4743
|
+
avgPosition: z31.number(),
|
|
4744
|
+
topQueries: z31.array(gscQueryRowSchema),
|
|
4745
|
+
categoryBreakdown: z31.array(z31.object({
|
|
4746
|
+
category: z31.enum(["brand", "lead-gen", "industry", "other"]),
|
|
4747
|
+
clicks: z31.number(),
|
|
4748
|
+
impressions: z31.number(),
|
|
4749
|
+
sharePct: z31.number()
|
|
4705
4750
|
})),
|
|
4706
|
-
trend:
|
|
4751
|
+
trend: z31.array(z31.object({ date: z31.string(), clicks: z31.number(), impressions: z31.number() })),
|
|
4707
4752
|
/**
|
|
4708
4753
|
* Tracked AEO queries that have no GSC impressions in the report window.
|
|
4709
4754
|
* Surfaces queries that may not represent real search demand.
|
|
4710
4755
|
*/
|
|
4711
|
-
trackedButNoGsc:
|
|
4756
|
+
trackedButNoGsc: z31.array(z31.string()),
|
|
4712
4757
|
/**
|
|
4713
4758
|
* GSC top queries (sorted by impressions desc) that are not tracked as
|
|
4714
4759
|
* AEO queries — the candidate set for adding to the AEO project.
|
|
4715
4760
|
*/
|
|
4716
|
-
gscButNotTracked:
|
|
4717
|
-
});
|
|
4718
|
-
var gaTrafficSectionSchema =
|
|
4719
|
-
totalSessions:
|
|
4720
|
-
totalUsers:
|
|
4721
|
-
totalOrganicSessions:
|
|
4722
|
-
periodStart:
|
|
4723
|
-
periodEnd:
|
|
4724
|
-
topLandingPages:
|
|
4725
|
-
page:
|
|
4726
|
-
sessions:
|
|
4727
|
-
users:
|
|
4728
|
-
organicSessions:
|
|
4761
|
+
gscButNotTracked: z31.array(z31.string())
|
|
4762
|
+
});
|
|
4763
|
+
var gaTrafficSectionSchema = z31.object({
|
|
4764
|
+
totalSessions: z31.number(),
|
|
4765
|
+
totalUsers: z31.number(),
|
|
4766
|
+
totalOrganicSessions: z31.number(),
|
|
4767
|
+
periodStart: z31.string(),
|
|
4768
|
+
periodEnd: z31.string(),
|
|
4769
|
+
topLandingPages: z31.array(z31.object({
|
|
4770
|
+
page: z31.string(),
|
|
4771
|
+
sessions: z31.number(),
|
|
4772
|
+
users: z31.number(),
|
|
4773
|
+
organicSessions: z31.number()
|
|
4729
4774
|
})),
|
|
4730
|
-
channelBreakdown:
|
|
4731
|
-
channel:
|
|
4732
|
-
sessions:
|
|
4733
|
-
sharePct:
|
|
4775
|
+
channelBreakdown: z31.array(z31.object({
|
|
4776
|
+
channel: z31.string(),
|
|
4777
|
+
sessions: z31.number(),
|
|
4778
|
+
sharePct: z31.number()
|
|
4734
4779
|
}))
|
|
4735
4780
|
});
|
|
4736
|
-
var socialReferralSectionSchema =
|
|
4737
|
-
totalSessions:
|
|
4738
|
-
organicSessions:
|
|
4739
|
-
paidSessions:
|
|
4740
|
-
channels:
|
|
4741
|
-
channelGroup:
|
|
4742
|
-
sessions:
|
|
4743
|
-
sharePct:
|
|
4781
|
+
var socialReferralSectionSchema = z31.object({
|
|
4782
|
+
totalSessions: z31.number(),
|
|
4783
|
+
organicSessions: z31.number(),
|
|
4784
|
+
paidSessions: z31.number(),
|
|
4785
|
+
channels: z31.array(z31.object({
|
|
4786
|
+
channelGroup: z31.string(),
|
|
4787
|
+
sessions: z31.number(),
|
|
4788
|
+
sharePct: z31.number()
|
|
4744
4789
|
})),
|
|
4745
|
-
topCampaigns:
|
|
4746
|
-
source:
|
|
4747
|
-
medium:
|
|
4748
|
-
sessions:
|
|
4790
|
+
topCampaigns: z31.array(z31.object({
|
|
4791
|
+
source: z31.string(),
|
|
4792
|
+
medium: z31.string(),
|
|
4793
|
+
sessions: z31.number()
|
|
4749
4794
|
}))
|
|
4750
4795
|
});
|
|
4751
|
-
var aiReferralSectionSchema =
|
|
4752
|
-
totalSessions:
|
|
4753
|
-
totalUsers:
|
|
4754
|
-
paidSessions:
|
|
4755
|
-
paidUsers:
|
|
4756
|
-
organicSessions:
|
|
4757
|
-
organicUsers:
|
|
4758
|
-
bySource:
|
|
4759
|
-
source:
|
|
4760
|
-
sessions:
|
|
4761
|
-
users:
|
|
4762
|
-
paidSessions:
|
|
4763
|
-
organicSessions:
|
|
4764
|
-
sharePct:
|
|
4796
|
+
var aiReferralSectionSchema = z31.object({
|
|
4797
|
+
totalSessions: z31.number(),
|
|
4798
|
+
totalUsers: z31.number(),
|
|
4799
|
+
paidSessions: z31.number(),
|
|
4800
|
+
paidUsers: z31.number(),
|
|
4801
|
+
organicSessions: z31.number(),
|
|
4802
|
+
organicUsers: z31.number(),
|
|
4803
|
+
bySource: z31.array(z31.object({
|
|
4804
|
+
source: z31.string(),
|
|
4805
|
+
sessions: z31.number(),
|
|
4806
|
+
users: z31.number(),
|
|
4807
|
+
paidSessions: z31.number(),
|
|
4808
|
+
organicSessions: z31.number(),
|
|
4809
|
+
sharePct: z31.number()
|
|
4765
4810
|
})),
|
|
4766
|
-
trend:
|
|
4767
|
-
topLandingPages:
|
|
4768
|
-
page:
|
|
4769
|
-
sessions:
|
|
4770
|
-
users:
|
|
4811
|
+
trend: z31.array(z31.object({ date: z31.string(), sessions: z31.number() })),
|
|
4812
|
+
topLandingPages: z31.array(z31.object({
|
|
4813
|
+
page: z31.string(),
|
|
4814
|
+
sessions: z31.number(),
|
|
4815
|
+
users: z31.number()
|
|
4771
4816
|
}))
|
|
4772
4817
|
});
|
|
4773
|
-
var serverActivitySectionSchema =
|
|
4818
|
+
var serverActivitySectionSchema = z31.object({
|
|
4774
4819
|
/** ISO8601 inclusive lower bound of the report window (default: 7 days). */
|
|
4775
|
-
windowStart:
|
|
4820
|
+
windowStart: z31.string(),
|
|
4776
4821
|
/** ISO8601 inclusive upper bound. */
|
|
4777
|
-
windowEnd:
|
|
4778
|
-
hasData:
|
|
4822
|
+
windowEnd: z31.string(),
|
|
4823
|
+
hasData: z31.boolean(),
|
|
4779
4824
|
/** Last-7d total verified crawler hits, with prior 7d for delta. */
|
|
4780
|
-
verifiedCrawlerHits:
|
|
4825
|
+
verifiedCrawlerHits: z31.object({ current: z31.number(), prior: z31.number(), deltaPct: z31.number().nullable() }),
|
|
4781
4826
|
/** Last-7d total unverified crawler hits, separated from verified trust metrics. */
|
|
4782
|
-
unverifiedCrawlerHits:
|
|
4827
|
+
unverifiedCrawlerHits: z31.object({ current: z31.number(), prior: z31.number(), deltaPct: z31.number().nullable() }),
|
|
4783
4828
|
/**
|
|
4784
4829
|
* Last-7d on-demand per-user fetches from AI surfaces (ChatGPT-User,
|
|
4785
4830
|
* Perplexity-User, MistralAI-User). Disjoint from `verifiedCrawlerHits` /
|
|
@@ -4788,9 +4833,9 @@ var serverActivitySectionSchema = z30.object({
|
|
|
4788
4833
|
* because the operational question for user-fetch is "is this happening?"
|
|
4789
4834
|
* not "is this a confirmed bot identity?"
|
|
4790
4835
|
*/
|
|
4791
|
-
aiUserFetchHits:
|
|
4836
|
+
aiUserFetchHits: z31.object({ current: z31.number(), prior: z31.number(), deltaPct: z31.number().nullable() }),
|
|
4792
4837
|
/** Last-7d AI-referral sessions (sessionized from server-side request evidence). Paid + organic + unclassified. */
|
|
4793
|
-
referralArrivals:
|
|
4838
|
+
referralArrivals: z31.object({ current: z31.number(), prior: z31.number(), deltaPct: z31.number().nullable() }),
|
|
4794
4839
|
/**
|
|
4795
4840
|
* `referralArrivals` split by traffic class. The three buckets sum to it.
|
|
4796
4841
|
*
|
|
@@ -4799,23 +4844,23 @@ var serverActivitySectionSchema = z30.object({
|
|
|
4799
4844
|
* never be resolved. Reporting them as organic would overstate earned AI
|
|
4800
4845
|
* traffic by exactly a client's ad volume.
|
|
4801
4846
|
*/
|
|
4802
|
-
referralArrivalsByClass:
|
|
4803
|
-
paid:
|
|
4804
|
-
organic:
|
|
4805
|
-
unclassified:
|
|
4847
|
+
referralArrivalsByClass: z31.object({
|
|
4848
|
+
paid: z31.object({ current: z31.number(), prior: z31.number(), deltaPct: z31.number().nullable() }),
|
|
4849
|
+
organic: z31.object({ current: z31.number(), prior: z31.number(), deltaPct: z31.number().nullable() }),
|
|
4850
|
+
unclassified: z31.object({ current: z31.number(), prior: z31.number(), deltaPct: z31.number().nullable() })
|
|
4806
4851
|
}),
|
|
4807
4852
|
/** Pre-rendered one-line breakdown, e.g. "Paid 1,200 · Organic 24". Empty when there is nothing to split. */
|
|
4808
|
-
referralArrivalsClassSummary:
|
|
4853
|
+
referralArrivalsClassSummary: z31.string(),
|
|
4809
4854
|
/** Per-AI-operator breakdown (OpenAI, Anthropic, Google AI, Perplexity, …). */
|
|
4810
|
-
byOperator:
|
|
4811
|
-
operator:
|
|
4812
|
-
verifiedHits:
|
|
4855
|
+
byOperator: z31.array(z31.object({
|
|
4856
|
+
operator: z31.string(),
|
|
4857
|
+
verifiedHits: z31.number(),
|
|
4813
4858
|
/** Shown to agency audience only: claimed-bot UA, source IP not in a published range. */
|
|
4814
|
-
unverifiedHits:
|
|
4859
|
+
unverifiedHits: z31.number(),
|
|
4815
4860
|
/** Per-user fetches from this operator's AI surface (ChatGPT-User, …). */
|
|
4816
|
-
userFetchHits:
|
|
4817
|
-
referralArrivals:
|
|
4818
|
-
deltaPct:
|
|
4861
|
+
userFetchHits: z31.number(),
|
|
4862
|
+
referralArrivals: z31.number(),
|
|
4863
|
+
deltaPct: z31.number().nullable()
|
|
4819
4864
|
})),
|
|
4820
4865
|
/**
|
|
4821
4866
|
* Top crawled paths (verified only, last-7d). Path-level citation cross-reference
|
|
@@ -4825,88 +4870,88 @@ var serverActivitySectionSchema = z30.object({
|
|
|
4825
4870
|
* citation evidence can extend this entry with a `citationState` field without
|
|
4826
4871
|
* breaking the contract.
|
|
4827
4872
|
*/
|
|
4828
|
-
topCrawledPaths:
|
|
4829
|
-
path:
|
|
4830
|
-
verifiedHits:
|
|
4873
|
+
topCrawledPaths: z31.array(z31.object({
|
|
4874
|
+
path: z31.string(),
|
|
4875
|
+
verifiedHits: z31.number(),
|
|
4831
4876
|
/** How many distinct AI operators crawled this path in the window. */
|
|
4832
|
-
distinctOperators:
|
|
4877
|
+
distinctOperators: z31.number()
|
|
4833
4878
|
})),
|
|
4834
4879
|
/** AI products that sent ≥1 session in the window (referral by destination). */
|
|
4835
|
-
referralProducts:
|
|
4836
|
-
product:
|
|
4837
|
-
arrivals:
|
|
4838
|
-
distinctLandingPaths:
|
|
4880
|
+
referralProducts: z31.array(z31.object({
|
|
4881
|
+
product: z31.string(),
|
|
4882
|
+
arrivals: z31.number(),
|
|
4883
|
+
distinctLandingPaths: z31.number()
|
|
4839
4884
|
})),
|
|
4840
4885
|
/** Daily trend, last 14d for sparkline / chart rendering. */
|
|
4841
|
-
dailyTrend:
|
|
4842
|
-
date:
|
|
4843
|
-
verifiedCrawlerHits:
|
|
4844
|
-
userFetchHits:
|
|
4845
|
-
referralArrivals:
|
|
4886
|
+
dailyTrend: z31.array(z31.object({
|
|
4887
|
+
date: z31.string(),
|
|
4888
|
+
verifiedCrawlerHits: z31.number(),
|
|
4889
|
+
userFetchHits: z31.number(),
|
|
4890
|
+
referralArrivals: z31.number()
|
|
4846
4891
|
})),
|
|
4847
4892
|
/**
|
|
4848
4893
|
* Top landing paths for AI-referral sessions (last-7d).
|
|
4849
4894
|
* Complements `topCrawledPaths` (what bots fetch) with what humans actually land on.
|
|
4850
4895
|
*/
|
|
4851
|
-
topReferralLandingPaths:
|
|
4852
|
-
path:
|
|
4853
|
-
arrivals:
|
|
4854
|
-
distinctProducts:
|
|
4896
|
+
topReferralLandingPaths: z31.array(z31.object({
|
|
4897
|
+
path: z31.string(),
|
|
4898
|
+
arrivals: z31.number(),
|
|
4899
|
+
distinctProducts: z31.number()
|
|
4855
4900
|
}))
|
|
4856
4901
|
});
|
|
4857
|
-
var indexingHealthSectionSchema =
|
|
4902
|
+
var indexingHealthSectionSchema = z31.object({
|
|
4858
4903
|
/** Source: 'google' | 'bing' | null when neither is connected. */
|
|
4859
|
-
provider:
|
|
4860
|
-
total:
|
|
4861
|
-
indexed:
|
|
4862
|
-
notIndexed:
|
|
4904
|
+
provider: z31.enum(["google", "bing"]).nullable(),
|
|
4905
|
+
total: z31.number(),
|
|
4906
|
+
indexed: z31.number(),
|
|
4907
|
+
notIndexed: z31.number(),
|
|
4863
4908
|
/** Google-only — pages explicitly marked as deindexed. Bing reports 'unknown' instead. */
|
|
4864
|
-
deindexed:
|
|
4909
|
+
deindexed: z31.number(),
|
|
4865
4910
|
/** Bing-only — pages with no inspection data yet. */
|
|
4866
|
-
unknown:
|
|
4911
|
+
unknown: z31.number(),
|
|
4867
4912
|
/** 0..100. */
|
|
4868
|
-
indexedPct:
|
|
4913
|
+
indexedPct: z31.number()
|
|
4869
4914
|
});
|
|
4870
|
-
var citationsTrendPointSchema =
|
|
4915
|
+
var citationsTrendPointSchema = z31.object({
|
|
4871
4916
|
/** Run ID — anchor for cross-section linking. */
|
|
4872
|
-
runId:
|
|
4917
|
+
runId: z31.string(),
|
|
4873
4918
|
/** ISO timestamp when the run finished (or createdAt fallback). */
|
|
4874
|
-
date:
|
|
4919
|
+
date: z31.string(),
|
|
4875
4920
|
/**
|
|
4876
4921
|
* 0..100 — same per-query unique-cited definition as
|
|
4877
4922
|
* `ReportExecutiveSummary.citationRate`. Stable across runs with different
|
|
4878
4923
|
* provider counts so the trend line measures real movement rather than
|
|
4879
4924
|
* provider-count variance.
|
|
4880
4925
|
*/
|
|
4881
|
-
citationRate:
|
|
4926
|
+
citationRate: z31.number(),
|
|
4882
4927
|
/** Numerator of `citationRate` for this run. */
|
|
4883
|
-
citedQueryCount:
|
|
4928
|
+
citedQueryCount: z31.number(),
|
|
4884
4929
|
/** Denominator of `citationRate` for this run. */
|
|
4885
|
-
totalQueryCount:
|
|
4930
|
+
totalQueryCount: z31.number(),
|
|
4886
4931
|
/** 0..100 — same per-query unique-mentioned definition as `ReportExecutiveSummary.mentionRate`. */
|
|
4887
|
-
mentionRate:
|
|
4932
|
+
mentionRate: z31.number(),
|
|
4888
4933
|
/** Numerator of `mentionRate` for this run. */
|
|
4889
|
-
mentionedQueryCount:
|
|
4934
|
+
mentionedQueryCount: z31.number(),
|
|
4890
4935
|
/**
|
|
4891
4936
|
* Per-provider rates for the same run. Each provider's rate is per-pair
|
|
4892
4937
|
* within that provider (`cited / scanned`), so it remains comparable
|
|
4893
4938
|
* between providers in the same run.
|
|
4894
4939
|
*/
|
|
4895
|
-
providerRates:
|
|
4896
|
-
provider:
|
|
4897
|
-
citationRate:
|
|
4898
|
-
mentionRate:
|
|
4940
|
+
providerRates: z31.array(z31.object({
|
|
4941
|
+
provider: z31.string(),
|
|
4942
|
+
citationRate: z31.number(),
|
|
4943
|
+
mentionRate: z31.number()
|
|
4899
4944
|
}))
|
|
4900
4945
|
});
|
|
4901
|
-
var reportInsightSchema =
|
|
4902
|
-
id:
|
|
4903
|
-
type:
|
|
4904
|
-
severity:
|
|
4905
|
-
title:
|
|
4906
|
-
query:
|
|
4907
|
-
provider:
|
|
4908
|
-
recommendation:
|
|
4909
|
-
createdAt:
|
|
4946
|
+
var reportInsightSchema = z31.object({
|
|
4947
|
+
id: z31.string(),
|
|
4948
|
+
type: z31.enum(["regression", "gain", "opportunity"]),
|
|
4949
|
+
severity: z31.enum(["critical", "high", "medium", "low"]),
|
|
4950
|
+
title: z31.string(),
|
|
4951
|
+
query: z31.string(),
|
|
4952
|
+
provider: z31.string(),
|
|
4953
|
+
recommendation: z31.string().nullable(),
|
|
4954
|
+
createdAt: z31.string(),
|
|
4910
4955
|
/**
|
|
4911
4956
|
* How many times this insight fired across recent runs for the same
|
|
4912
4957
|
* `(query, provider, type)` tuple. Always ≥ 1. Insights returned by the
|
|
@@ -4914,64 +4959,64 @@ var reportInsightSchema = z30.object({
|
|
|
4914
4959
|
* surfacing the multiplicity. Use it directly instead of grouping again
|
|
4915
4960
|
* client-side — counts derived from raw insight rows will overcount.
|
|
4916
4961
|
*/
|
|
4917
|
-
instanceCount:
|
|
4962
|
+
instanceCount: z31.number()
|
|
4918
4963
|
});
|
|
4919
|
-
var recommendedNextStepSchema =
|
|
4964
|
+
var recommendedNextStepSchema = z31.object({
|
|
4920
4965
|
/** 'immediate' | 'short-term' | 'medium-term' — bucketed by severity heuristic. */
|
|
4921
|
-
horizon:
|
|
4922
|
-
title:
|
|
4923
|
-
rationale:
|
|
4966
|
+
horizon: z31.enum(["immediate", "short-term", "medium-term"]),
|
|
4967
|
+
title: z31.string(),
|
|
4968
|
+
rationale: z31.string()
|
|
4924
4969
|
});
|
|
4925
|
-
var reportRateDeltaSchema =
|
|
4970
|
+
var reportRateDeltaSchema = z31.object({
|
|
4926
4971
|
/** Current value (0..100 for rates, raw count otherwise). When `window`
|
|
4927
4972
|
* is present this is the average over the last `window` checks. */
|
|
4928
|
-
current:
|
|
4973
|
+
current: z31.number(),
|
|
4929
4974
|
/** Prior value compared against. When `window` is present this is the
|
|
4930
4975
|
* average over the prior `window` checks before that. */
|
|
4931
|
-
prior:
|
|
4976
|
+
prior: z31.number(),
|
|
4932
4977
|
/** Absolute delta (current − prior). Negative = decrease. */
|
|
4933
|
-
deltaAbs:
|
|
4978
|
+
deltaAbs: z31.number(),
|
|
4934
4979
|
/**
|
|
4935
4980
|
* Signed percent change vs `prior`, rounded to a whole number. Null when
|
|
4936
4981
|
* `prior <= 0` (percentage undefined). Renderers route count/traffic tiles
|
|
4937
4982
|
* through the "smart %" rule — percentage when the prior base is large
|
|
4938
4983
|
* enough (`MIN_PCT_BASE`), otherwise a rounded raw delta.
|
|
4939
4984
|
*/
|
|
4940
|
-
deltaPct:
|
|
4985
|
+
deltaPct: z31.number().nullable(),
|
|
4941
4986
|
/**
|
|
4942
4987
|
* Direction tag for tone mapping. Threshold is metric-specific (3pp for
|
|
4943
4988
|
* rates, 0.5 for counts) so small noise lands as 'flat' rather than
|
|
4944
4989
|
* flipping up/down each run.
|
|
4945
4990
|
*/
|
|
4946
|
-
direction:
|
|
4991
|
+
direction: z31.enum(["up", "down", "flat"]),
|
|
4947
4992
|
/**
|
|
4948
4993
|
* How many points went into each side of the average. Omitted (or 1)
|
|
4949
4994
|
* means point-to-point (legacy "since last check"). Higher values mean
|
|
4950
4995
|
* a rolling-average comparison — renderers should label it as
|
|
4951
4996
|
* "vs prior N checks" when this is ≥ 2.
|
|
4952
4997
|
*/
|
|
4953
|
-
window:
|
|
4998
|
+
window: z31.number().optional()
|
|
4954
4999
|
});
|
|
4955
|
-
var reportProviderMovementSchema =
|
|
4956
|
-
provider:
|
|
4957
|
-
current:
|
|
4958
|
-
prior:
|
|
4959
|
-
deltaAbs:
|
|
4960
|
-
direction:
|
|
5000
|
+
var reportProviderMovementSchema = z31.object({
|
|
5001
|
+
provider: z31.string(),
|
|
5002
|
+
current: z31.number(),
|
|
5003
|
+
prior: z31.number(),
|
|
5004
|
+
deltaAbs: z31.number(),
|
|
5005
|
+
direction: z31.enum(["up", "down", "flat"])
|
|
4961
5006
|
});
|
|
4962
|
-
var whatsChangedSectionSchema =
|
|
5007
|
+
var whatsChangedSectionSchema = z31.object({
|
|
4963
5008
|
/**
|
|
4964
5009
|
* False when there's no prior run (or fewer than the trend baseline),
|
|
4965
5010
|
* meaning all per-metric deltas will be null. Renderers use this to swap
|
|
4966
5011
|
* in a "establishing baseline" fallback rather than rendering empty
|
|
4967
5012
|
* delta tiles.
|
|
4968
5013
|
*/
|
|
4969
|
-
enoughHistory:
|
|
5014
|
+
enoughHistory: z31.boolean(),
|
|
4970
5015
|
/**
|
|
4971
5016
|
* One-sentence narrative summary suitable as a section subtitle.
|
|
4972
5017
|
* Always present — even on baseline, narrates whatever signal exists.
|
|
4973
5018
|
*/
|
|
4974
|
-
headline:
|
|
5019
|
+
headline: z31.string(),
|
|
4975
5020
|
/** Citation rate delta vs the prior completed run. Null when no prior run. */
|
|
4976
5021
|
citationRate: reportRateDeltaSchema.nullable(),
|
|
4977
5022
|
/** Mention rate delta vs the prior completed run. Null when no prior run. */
|
|
@@ -4999,30 +5044,30 @@ var whatsChangedSectionSchema = z30.object({
|
|
|
4999
5044
|
* deltas "vs prior {comparisonWindowDays} days" off this single value so the
|
|
5000
5045
|
* SPA and HTML stay verbatim-identical.
|
|
5001
5046
|
*/
|
|
5002
|
-
comparisonWindowDays:
|
|
5047
|
+
comparisonWindowDays: z31.number().int().positive(),
|
|
5003
5048
|
/**
|
|
5004
5049
|
* Per-provider citation rate movements (latest run vs prior run). Empty
|
|
5005
5050
|
* when no prior run. Sorted by |deltaAbs| desc — providers with the
|
|
5006
5051
|
* biggest swing first.
|
|
5007
5052
|
*/
|
|
5008
|
-
providerMovements:
|
|
5053
|
+
providerMovements: z31.array(reportProviderMovementSchema),
|
|
5009
5054
|
/**
|
|
5010
5055
|
* Top wins this period — gains surfaced by the intelligence engine.
|
|
5011
5056
|
* Capped at 5; sourced from `insights` filtered to `type: 'gain'`.
|
|
5012
5057
|
*/
|
|
5013
|
-
wins:
|
|
5058
|
+
wins: z31.array(reportInsightSchema),
|
|
5014
5059
|
/**
|
|
5015
5060
|
* Top regressions this period — citations or mentions lost. Capped at 5;
|
|
5016
5061
|
* sourced from `insights` filtered to `type: 'regression'`.
|
|
5017
5062
|
*/
|
|
5018
|
-
regressions:
|
|
5019
|
-
});
|
|
5020
|
-
var reportAudienceSchema =
|
|
5021
|
-
var reportActionAudienceSchema =
|
|
5022
|
-
var reportActionHorizonSchema =
|
|
5023
|
-
var reportActionConfidenceSchema =
|
|
5024
|
-
var reportToneSchema =
|
|
5025
|
-
var reportActionCategorySchema =
|
|
5063
|
+
regressions: z31.array(reportInsightSchema)
|
|
5064
|
+
});
|
|
5065
|
+
var reportAudienceSchema = z31.enum(["agency", "client"]);
|
|
5066
|
+
var reportActionAudienceSchema = z31.enum(["agency", "client", "both"]);
|
|
5067
|
+
var reportActionHorizonSchema = z31.enum(["immediate", "short-term", "medium-term"]);
|
|
5068
|
+
var reportActionConfidenceSchema = z31.enum(["high", "medium", "low"]);
|
|
5069
|
+
var reportToneSchema = z31.enum(["positive", "caution", "negative", "neutral"]);
|
|
5070
|
+
var reportActionCategorySchema = z31.enum([
|
|
5026
5071
|
"content",
|
|
5027
5072
|
"competitors",
|
|
5028
5073
|
"provider",
|
|
@@ -5031,23 +5076,23 @@ var reportActionCategorySchema = z30.enum([
|
|
|
5031
5076
|
"location",
|
|
5032
5077
|
"monitoring"
|
|
5033
5078
|
]);
|
|
5034
|
-
var reportActionPlanItemSchema =
|
|
5079
|
+
var reportActionPlanItemSchema = z31.object({
|
|
5035
5080
|
/** Which report audience should see this action. `both` renders in both modes. */
|
|
5036
5081
|
audience: reportActionAudienceSchema,
|
|
5037
5082
|
/** Stable sort priority. Lower numbers render earlier. */
|
|
5038
|
-
priority:
|
|
5083
|
+
priority: z31.number(),
|
|
5039
5084
|
/** When this should be tackled. */
|
|
5040
5085
|
horizon: reportActionHorizonSchema,
|
|
5041
5086
|
category: reportActionCategorySchema,
|
|
5042
|
-
title:
|
|
5087
|
+
title: z31.string(),
|
|
5043
5088
|
/** Direct next step written as an operator/client-friendly imperative. */
|
|
5044
|
-
action:
|
|
5089
|
+
action: z31.string(),
|
|
5045
5090
|
/** Why this matters. Keep each entry concise and evidence-backed. */
|
|
5046
|
-
why:
|
|
5091
|
+
why: z31.array(z31.string()),
|
|
5047
5092
|
/** Specific observations that justify the action. */
|
|
5048
|
-
evidence:
|
|
5093
|
+
evidence: z31.array(z31.string()),
|
|
5049
5094
|
/** What should move if the action worked. */
|
|
5050
|
-
successMetric:
|
|
5095
|
+
successMetric: z31.string(),
|
|
5051
5096
|
/** Confidence in the recommendation based on the available evidence. */
|
|
5052
5097
|
confidence: reportActionConfidenceSchema,
|
|
5053
5098
|
/**
|
|
@@ -5059,23 +5104,23 @@ var reportActionPlanItemSchema = z30.object({
|
|
|
5059
5104
|
* load. Actions sourced from other signals (competitor gaps, indexing
|
|
5060
5105
|
* issues, etc.) omit this and use their own dismiss flows.
|
|
5061
5106
|
*/
|
|
5062
|
-
targetRef:
|
|
5107
|
+
targetRef: z31.string().optional()
|
|
5063
5108
|
});
|
|
5064
|
-
var reportClientSummarySchema =
|
|
5065
|
-
headline:
|
|
5066
|
-
overview:
|
|
5067
|
-
actionItems:
|
|
5068
|
-
confidenceNotes:
|
|
5109
|
+
var reportClientSummarySchema = z31.object({
|
|
5110
|
+
headline: z31.string(),
|
|
5111
|
+
overview: z31.string(),
|
|
5112
|
+
actionItems: z31.array(reportActionPlanItemSchema),
|
|
5113
|
+
confidenceNotes: z31.array(z31.string())
|
|
5069
5114
|
});
|
|
5070
|
-
var reportAgencyDiagnosticSchema =
|
|
5071
|
-
title:
|
|
5072
|
-
detail:
|
|
5073
|
-
severity:
|
|
5074
|
-
evidence:
|
|
5115
|
+
var reportAgencyDiagnosticSchema = z31.object({
|
|
5116
|
+
title: z31.string(),
|
|
5117
|
+
detail: z31.string(),
|
|
5118
|
+
severity: z31.enum(["positive", "caution", "negative", "neutral"]),
|
|
5119
|
+
evidence: z31.array(z31.string())
|
|
5075
5120
|
});
|
|
5076
|
-
var reportAgencyDiagnosticsSchema =
|
|
5077
|
-
priorities:
|
|
5078
|
-
diagnostics:
|
|
5121
|
+
var reportAgencyDiagnosticsSchema = z31.object({
|
|
5122
|
+
priorities: z31.array(reportActionPlanItemSchema),
|
|
5123
|
+
diagnostics: z31.array(reportAgencyDiagnosticSchema)
|
|
5079
5124
|
});
|
|
5080
5125
|
function reportActionTone(action) {
|
|
5081
5126
|
if (action.horizon === "immediate") return "negative";
|
|
@@ -5133,7 +5178,7 @@ function reportConfidenceLabel(confidence) {
|
|
|
5133
5178
|
return "Low";
|
|
5134
5179
|
}
|
|
5135
5180
|
}
|
|
5136
|
-
var projectReportDtoSchema =
|
|
5181
|
+
var projectReportDtoSchema = z31.object({
|
|
5137
5182
|
meta: reportMetaSchema,
|
|
5138
5183
|
executiveSummary: reportExecutiveSummarySchema,
|
|
5139
5184
|
citationScorecard: citationScorecardSchema,
|
|
@@ -5147,16 +5192,16 @@ var projectReportDtoSchema = z30.object({
|
|
|
5147
5192
|
/** Server-side log-evidence visibility (crawls + click-through sessions). Null when no traffic source connected. */
|
|
5148
5193
|
serverActivity: serverActivitySectionSchema.nullable(),
|
|
5149
5194
|
indexingHealth: indexingHealthSectionSchema.nullable(),
|
|
5150
|
-
citationsTrend:
|
|
5195
|
+
citationsTrend: z31.array(citationsTrendPointSchema),
|
|
5151
5196
|
/**
|
|
5152
5197
|
* Trend-focused "what's changed" summary for the report's act 2. Always
|
|
5153
5198
|
* present; renderers gate empty/baseline states via `enoughHistory`.
|
|
5154
5199
|
*/
|
|
5155
5200
|
whatsChanged: whatsChangedSectionSchema,
|
|
5156
|
-
insights:
|
|
5157
|
-
recommendedNextSteps:
|
|
5201
|
+
insights: z31.array(reportInsightSchema),
|
|
5202
|
+
recommendedNextSteps: z31.array(recommendedNextStepSchema),
|
|
5158
5203
|
/** Canonical structured actions shared by the client and agency render modes. */
|
|
5159
|
-
actionPlan:
|
|
5204
|
+
actionPlan: z31.array(reportActionPlanItemSchema),
|
|
5160
5205
|
/** Polished client-facing summary and action shortlist. */
|
|
5161
5206
|
clientSummary: reportClientSummarySchema,
|
|
5162
5207
|
/** Technical, evidence-oriented operator diagnostics for agency mode. */
|
|
@@ -5166,17 +5211,17 @@ var projectReportDtoSchema = z30.object({
|
|
|
5166
5211
|
* intelligence layer (`buildContentTargetRows`). Empty when no run has
|
|
5167
5212
|
* produced candidate queries with demand or competitor signal.
|
|
5168
5213
|
*/
|
|
5169
|
-
contentOpportunities:
|
|
5214
|
+
contentOpportunities: z31.array(contentTargetRowDtoSchema),
|
|
5170
5215
|
/**
|
|
5171
5216
|
* Queries where competitors were cited but the project was not. Sourced
|
|
5172
5217
|
* from `buildContentGapRows`. Empty until the first answer-visibility run.
|
|
5173
5218
|
*/
|
|
5174
|
-
contentGaps:
|
|
5219
|
+
contentGaps: z31.array(contentGapRowDtoSchema),
|
|
5175
5220
|
/**
|
|
5176
5221
|
* Per-query grounding source map (own + competitor cited URLs). Sourced
|
|
5177
5222
|
* from `buildContentSourceRows`. Empty until the first answer-visibility run.
|
|
5178
5223
|
*/
|
|
5179
|
-
groundingSources:
|
|
5224
|
+
groundingSources: z31.array(contentSourceRowDtoSchema)
|
|
5180
5225
|
});
|
|
5181
5226
|
|
|
5182
5227
|
// ../contracts/src/report-dedup.ts
|
|
@@ -5247,10 +5292,10 @@ function dedupeReportOpportunities(report) {
|
|
|
5247
5292
|
}
|
|
5248
5293
|
|
|
5249
5294
|
// ../contracts/src/skills.ts
|
|
5250
|
-
import { z as
|
|
5251
|
-
var codingAgentSchema =
|
|
5295
|
+
import { z as z32 } from "zod";
|
|
5296
|
+
var codingAgentSchema = z32.enum(["claude", "codex"]);
|
|
5252
5297
|
var CodingAgents = codingAgentSchema.enum;
|
|
5253
|
-
var skillsClientSchema =
|
|
5298
|
+
var skillsClientSchema = z32.enum(["claude", "codex", "all"]);
|
|
5254
5299
|
var SkillsClients = skillsClientSchema.enum;
|
|
5255
5300
|
var SKILL_MANIFEST_FILENAME = ".canonry-skill-manifest.json";
|
|
5256
5301
|
function classifySkillFile(params) {
|
|
@@ -5268,22 +5313,22 @@ function coerceSkillManifest(parsed) {
|
|
|
5268
5313
|
}
|
|
5269
5314
|
|
|
5270
5315
|
// ../contracts/src/traffic.ts
|
|
5271
|
-
import { z as
|
|
5272
|
-
var trafficCrawlerSegmentsSchema =
|
|
5273
|
-
content:
|
|
5274
|
-
sitemap:
|
|
5275
|
-
robots:
|
|
5276
|
-
asset:
|
|
5277
|
-
other:
|
|
5278
|
-
});
|
|
5279
|
-
var trafficPathClassSchema =
|
|
5316
|
+
import { z as z33 } from "zod";
|
|
5317
|
+
var trafficCrawlerSegmentsSchema = z33.object({
|
|
5318
|
+
content: z33.number().int().nonnegative(),
|
|
5319
|
+
sitemap: z33.number().int().nonnegative(),
|
|
5320
|
+
robots: z33.number().int().nonnegative(),
|
|
5321
|
+
asset: z33.number().int().nonnegative(),
|
|
5322
|
+
other: z33.number().int().nonnegative()
|
|
5323
|
+
});
|
|
5324
|
+
var trafficPathClassSchema = z33.enum([
|
|
5280
5325
|
"content",
|
|
5281
5326
|
"sitemap",
|
|
5282
5327
|
"robots",
|
|
5283
5328
|
"asset",
|
|
5284
5329
|
"other"
|
|
5285
5330
|
]);
|
|
5286
|
-
var trafficSourceTypeSchema =
|
|
5331
|
+
var trafficSourceTypeSchema = z33.enum([
|
|
5287
5332
|
"cloud-run",
|
|
5288
5333
|
"wordpress",
|
|
5289
5334
|
"cloudflare",
|
|
@@ -5291,7 +5336,7 @@ var trafficSourceTypeSchema = z32.enum([
|
|
|
5291
5336
|
"generic-log"
|
|
5292
5337
|
]);
|
|
5293
5338
|
var TrafficSourceTypes = trafficSourceTypeSchema.enum;
|
|
5294
|
-
var trafficAdapterCapabilitySchema =
|
|
5339
|
+
var trafficAdapterCapabilitySchema = z33.enum([
|
|
5295
5340
|
"raw-request-events",
|
|
5296
5341
|
"aggregate-request-metrics",
|
|
5297
5342
|
"request-url",
|
|
@@ -5302,252 +5347,252 @@ var trafficAdapterCapabilitySchema = z32.enum([
|
|
|
5302
5347
|
"cursor-pull"
|
|
5303
5348
|
]);
|
|
5304
5349
|
var TrafficAdapterCapabilities = trafficAdapterCapabilitySchema.enum;
|
|
5305
|
-
var trafficEvidenceKindSchema =
|
|
5350
|
+
var trafficEvidenceKindSchema = z33.enum(["raw-request", "aggregate-bucket"]);
|
|
5306
5351
|
var TrafficEvidenceKinds = trafficEvidenceKindSchema.enum;
|
|
5307
|
-
var trafficEventConfidenceSchema =
|
|
5352
|
+
var trafficEventConfidenceSchema = z33.enum(["observed", "provider-aggregated", "inferred"]);
|
|
5308
5353
|
var TrafficEventConfidences = trafficEventConfidenceSchema.enum;
|
|
5309
|
-
var trafficProviderResourceSchema =
|
|
5310
|
-
type:
|
|
5311
|
-
labels:
|
|
5354
|
+
var trafficProviderResourceSchema = z33.object({
|
|
5355
|
+
type: z33.string().nullable(),
|
|
5356
|
+
labels: z33.record(z33.string(), z33.string())
|
|
5312
5357
|
});
|
|
5313
|
-
var normalizedTrafficRequestSchema =
|
|
5358
|
+
var normalizedTrafficRequestSchema = z33.object({
|
|
5314
5359
|
sourceType: trafficSourceTypeSchema,
|
|
5315
|
-
evidenceKind:
|
|
5316
|
-
confidence:
|
|
5317
|
-
eventId:
|
|
5318
|
-
observedAt:
|
|
5319
|
-
method:
|
|
5320
|
-
requestUrl:
|
|
5321
|
-
host:
|
|
5322
|
-
path:
|
|
5323
|
-
queryString:
|
|
5324
|
-
status:
|
|
5325
|
-
userAgent:
|
|
5326
|
-
remoteIp:
|
|
5327
|
-
referer:
|
|
5328
|
-
latencyMs:
|
|
5329
|
-
requestSizeBytes:
|
|
5330
|
-
responseSizeBytes:
|
|
5360
|
+
evidenceKind: z33.literal(TrafficEvidenceKinds["raw-request"]),
|
|
5361
|
+
confidence: z33.literal(TrafficEventConfidences.observed),
|
|
5362
|
+
eventId: z33.string().min(1),
|
|
5363
|
+
observedAt: z33.string().min(1),
|
|
5364
|
+
method: z33.string().nullable(),
|
|
5365
|
+
requestUrl: z33.string().nullable(),
|
|
5366
|
+
host: z33.string().nullable(),
|
|
5367
|
+
path: z33.string().min(1),
|
|
5368
|
+
queryString: z33.string().nullable(),
|
|
5369
|
+
status: z33.number().int().nullable(),
|
|
5370
|
+
userAgent: z33.string().nullable(),
|
|
5371
|
+
remoteIp: z33.string().nullable(),
|
|
5372
|
+
referer: z33.string().nullable(),
|
|
5373
|
+
latencyMs: z33.number().nullable(),
|
|
5374
|
+
requestSizeBytes: z33.number().int().nullable(),
|
|
5375
|
+
responseSizeBytes: z33.number().int().nullable(),
|
|
5331
5376
|
providerResource: trafficProviderResourceSchema,
|
|
5332
|
-
providerLabels:
|
|
5377
|
+
providerLabels: z33.record(z33.string(), z33.string())
|
|
5333
5378
|
});
|
|
5334
|
-
var normalizedTrafficPullPageSchema =
|
|
5335
|
-
events:
|
|
5336
|
-
rawEntryCount:
|
|
5337
|
-
skippedEntryCount:
|
|
5338
|
-
nextPageToken:
|
|
5339
|
-
filter:
|
|
5379
|
+
var normalizedTrafficPullPageSchema = z33.object({
|
|
5380
|
+
events: z33.array(normalizedTrafficRequestSchema),
|
|
5381
|
+
rawEntryCount: z33.number().int().nonnegative(),
|
|
5382
|
+
skippedEntryCount: z33.number().int().nonnegative(),
|
|
5383
|
+
nextPageToken: z33.string().optional(),
|
|
5384
|
+
filter: z33.string()
|
|
5340
5385
|
});
|
|
5341
|
-
var trafficSourceStatusSchema =
|
|
5386
|
+
var trafficSourceStatusSchema = z33.enum(["connected", "paused", "error", "archived"]);
|
|
5342
5387
|
var TrafficSourceStatuses = trafficSourceStatusSchema.enum;
|
|
5343
|
-
var trafficSourceAuthModeSchema =
|
|
5388
|
+
var trafficSourceAuthModeSchema = z33.enum(["oauth", "service-account"]);
|
|
5344
5389
|
var TrafficSourceAuthModes = trafficSourceAuthModeSchema.enum;
|
|
5345
|
-
var verificationStatusSchema =
|
|
5390
|
+
var verificationStatusSchema = z33.enum(["verified", "claimed_unverified", "unknown_ai_like"]);
|
|
5346
5391
|
var VerificationStatuses = verificationStatusSchema.enum;
|
|
5347
|
-
var cloudRunSourceConfigSchema =
|
|
5348
|
-
gcpProjectId:
|
|
5349
|
-
serviceName:
|
|
5350
|
-
location:
|
|
5392
|
+
var cloudRunSourceConfigSchema = z33.object({
|
|
5393
|
+
gcpProjectId: z33.string().min(1),
|
|
5394
|
+
serviceName: z33.string().nullable().optional(),
|
|
5395
|
+
location: z33.string().nullable().optional(),
|
|
5351
5396
|
authMode: trafficSourceAuthModeSchema
|
|
5352
5397
|
});
|
|
5353
|
-
var wordpressTrafficSourceConfigSchema =
|
|
5354
|
-
baseUrl:
|
|
5355
|
-
username:
|
|
5398
|
+
var wordpressTrafficSourceConfigSchema = z33.object({
|
|
5399
|
+
baseUrl: z33.string().url(),
|
|
5400
|
+
username: z33.string().min(1)
|
|
5356
5401
|
});
|
|
5357
|
-
var vercelTrafficEnvironmentSchema =
|
|
5402
|
+
var vercelTrafficEnvironmentSchema = z33.enum(["production", "preview"]);
|
|
5358
5403
|
var VercelTrafficEnvironments = vercelTrafficEnvironmentSchema.enum;
|
|
5359
|
-
var vercelTrafficSourceConfigSchema =
|
|
5404
|
+
var vercelTrafficSourceConfigSchema = z33.object({
|
|
5360
5405
|
/** Vercel project id (e.g. `prj_...`). */
|
|
5361
|
-
projectId:
|
|
5406
|
+
projectId: z33.string().min(1),
|
|
5362
5407
|
/** Vercel team or account id: the org that owns the project. */
|
|
5363
|
-
teamId:
|
|
5408
|
+
teamId: z33.string().min(1),
|
|
5364
5409
|
environment: vercelTrafficEnvironmentSchema
|
|
5365
5410
|
});
|
|
5366
|
-
var trafficSourceDtoSchema =
|
|
5367
|
-
id:
|
|
5368
|
-
projectId:
|
|
5411
|
+
var trafficSourceDtoSchema = z33.object({
|
|
5412
|
+
id: z33.string(),
|
|
5413
|
+
projectId: z33.string(),
|
|
5369
5414
|
sourceType: trafficSourceTypeSchema,
|
|
5370
|
-
displayName:
|
|
5415
|
+
displayName: z33.string(),
|
|
5371
5416
|
status: trafficSourceStatusSchema,
|
|
5372
|
-
lastSyncedAt:
|
|
5373
|
-
lastCursor:
|
|
5374
|
-
lastError:
|
|
5375
|
-
archivedAt:
|
|
5376
|
-
config:
|
|
5377
|
-
createdAt:
|
|
5378
|
-
updatedAt:
|
|
5379
|
-
});
|
|
5380
|
-
var trafficConnectCloudRunRequestSchema =
|
|
5381
|
-
gcpProjectId:
|
|
5382
|
-
serviceName:
|
|
5383
|
-
location:
|
|
5384
|
-
displayName:
|
|
5417
|
+
lastSyncedAt: z33.string().nullable(),
|
|
5418
|
+
lastCursor: z33.string().nullable(),
|
|
5419
|
+
lastError: z33.string().nullable(),
|
|
5420
|
+
archivedAt: z33.string().nullable(),
|
|
5421
|
+
config: z33.record(z33.string(), z33.unknown()),
|
|
5422
|
+
createdAt: z33.string(),
|
|
5423
|
+
updatedAt: z33.string()
|
|
5424
|
+
});
|
|
5425
|
+
var trafficConnectCloudRunRequestSchema = z33.object({
|
|
5426
|
+
gcpProjectId: z33.string().min(1),
|
|
5427
|
+
serviceName: z33.string().min(1).optional(),
|
|
5428
|
+
location: z33.string().min(1).optional(),
|
|
5429
|
+
displayName: z33.string().min(1).optional(),
|
|
5385
5430
|
/** Service-account JSON content (string). When omitted, defaults to OAuth via `canonry google connect <project> --type ga4` flow. */
|
|
5386
|
-
keyJson:
|
|
5431
|
+
keyJson: z33.string().optional()
|
|
5387
5432
|
});
|
|
5388
|
-
var trafficConnectWordpressRequestSchema =
|
|
5389
|
-
baseUrl:
|
|
5390
|
-
username:
|
|
5433
|
+
var trafficConnectWordpressRequestSchema = z33.object({
|
|
5434
|
+
baseUrl: z33.string().url(),
|
|
5435
|
+
username: z33.string().min(1),
|
|
5391
5436
|
/** WordPress Application Password (the same auth used by the content client). */
|
|
5392
|
-
applicationPassword:
|
|
5393
|
-
displayName:
|
|
5437
|
+
applicationPassword: z33.string().min(1),
|
|
5438
|
+
displayName: z33.string().min(1).optional()
|
|
5394
5439
|
});
|
|
5395
|
-
var trafficConnectVercelRequestSchema =
|
|
5440
|
+
var trafficConnectVercelRequestSchema = z33.object({
|
|
5396
5441
|
/** Vercel project id (e.g. `prj_...`) — from the Vercel dashboard or `.vercel/project.json`. */
|
|
5397
|
-
projectId:
|
|
5442
|
+
projectId: z33.string().min(1),
|
|
5398
5443
|
/** Vercel team or account id: the org that owns the project ("orgId" in .vercel/project.json). */
|
|
5399
|
-
teamId:
|
|
5444
|
+
teamId: z33.string().min(1),
|
|
5400
5445
|
/** Vercel personal access token. Stored in `~/.canonry/config.yaml`, never the DB. */
|
|
5401
|
-
token:
|
|
5446
|
+
token: z33.string().min(1),
|
|
5402
5447
|
/** Which deployment environment's request logs to pull. Default: `production`. */
|
|
5403
5448
|
environment: vercelTrafficEnvironmentSchema.optional(),
|
|
5404
|
-
displayName:
|
|
5449
|
+
displayName: z33.string().min(1).optional()
|
|
5405
5450
|
});
|
|
5406
|
-
var trafficSyncResponseSchema =
|
|
5407
|
-
sourceId:
|
|
5408
|
-
runId:
|
|
5409
|
-
syncedAt:
|
|
5410
|
-
pulledEvents:
|
|
5451
|
+
var trafficSyncResponseSchema = z33.object({
|
|
5452
|
+
sourceId: z33.string(),
|
|
5453
|
+
runId: z33.string(),
|
|
5454
|
+
syncedAt: z33.string(),
|
|
5455
|
+
pulledEvents: z33.number().int().nonnegative(),
|
|
5411
5456
|
/** Self-traffic events (Canonry's own tooling) dropped before rollup. */
|
|
5412
|
-
selfTrafficExcluded:
|
|
5413
|
-
crawlerHits:
|
|
5414
|
-
aiUserFetchHits:
|
|
5415
|
-
aiReferralHits:
|
|
5416
|
-
unknownHits:
|
|
5417
|
-
crawlerBucketRows:
|
|
5418
|
-
aiUserFetchBucketRows:
|
|
5419
|
-
aiReferralBucketRows:
|
|
5420
|
-
sampleRows:
|
|
5421
|
-
windowStart:
|
|
5422
|
-
windowEnd:
|
|
5423
|
-
});
|
|
5424
|
-
var trafficBackfillRequestSchema =
|
|
5457
|
+
selfTrafficExcluded: z33.number().int().nonnegative(),
|
|
5458
|
+
crawlerHits: z33.number().int().nonnegative(),
|
|
5459
|
+
aiUserFetchHits: z33.number().int().nonnegative(),
|
|
5460
|
+
aiReferralHits: z33.number().int().nonnegative(),
|
|
5461
|
+
unknownHits: z33.number().int().nonnegative(),
|
|
5462
|
+
crawlerBucketRows: z33.number().int().nonnegative(),
|
|
5463
|
+
aiUserFetchBucketRows: z33.number().int().nonnegative(),
|
|
5464
|
+
aiReferralBucketRows: z33.number().int().nonnegative(),
|
|
5465
|
+
sampleRows: z33.number().int().nonnegative(),
|
|
5466
|
+
windowStart: z33.string(),
|
|
5467
|
+
windowEnd: z33.string()
|
|
5468
|
+
});
|
|
5469
|
+
var trafficBackfillRequestSchema = z33.object({
|
|
5425
5470
|
/** Lookback window in days. Capped server-side at the upstream log retention ceiling (Cloud Logging _Default = 30d). Default: 30. */
|
|
5426
|
-
days:
|
|
5471
|
+
days: z33.number().int().positive().optional()
|
|
5427
5472
|
});
|
|
5428
|
-
var trafficResetRequestSchema =
|
|
5429
|
-
advanceToNow:
|
|
5473
|
+
var trafficResetRequestSchema = z33.object({
|
|
5474
|
+
advanceToNow: z33.literal(true)
|
|
5430
5475
|
});
|
|
5431
|
-
var trafficBackfillResponseSchema =
|
|
5432
|
-
sourceId:
|
|
5433
|
-
runId:
|
|
5476
|
+
var trafficBackfillResponseSchema = z33.object({
|
|
5477
|
+
sourceId: z33.string(),
|
|
5478
|
+
runId: z33.string(),
|
|
5434
5479
|
status: runStatusSchema,
|
|
5435
|
-
windowStart:
|
|
5436
|
-
windowEnd:
|
|
5480
|
+
windowStart: z33.string(),
|
|
5481
|
+
windowEnd: z33.string(),
|
|
5437
5482
|
/** Days actually used after server-side clamping (≤ requested). */
|
|
5438
|
-
daysRequested:
|
|
5439
|
-
daysApplied:
|
|
5483
|
+
daysRequested: z33.number().int().positive(),
|
|
5484
|
+
daysApplied: z33.number().int().positive()
|
|
5440
5485
|
});
|
|
5441
|
-
var trafficSourceTotalsSchema =
|
|
5486
|
+
var trafficSourceTotalsSchema = z33.object({
|
|
5442
5487
|
/**
|
|
5443
5488
|
* Total classified-crawler hits in the window. UNCHANGED contract — still the
|
|
5444
5489
|
* full count across every path class. Use `crawlerContentHits` for the
|
|
5445
5490
|
* "content was actually crawled" signal.
|
|
5446
5491
|
*/
|
|
5447
|
-
crawlerHits:
|
|
5492
|
+
crawlerHits: z33.number().int().nonnegative(),
|
|
5448
5493
|
/** Crawler hits against content/document paths only (= `crawlerSegments.content`). */
|
|
5449
|
-
crawlerContentHits:
|
|
5494
|
+
crawlerContentHits: z33.number().int().nonnegative(),
|
|
5450
5495
|
/** Infrastructure crawler hits — sitemap + robots + asset fetches (`crawlerSegments.{sitemap,robots,asset}`). */
|
|
5451
|
-
crawlerInfraHits:
|
|
5496
|
+
crawlerInfraHits: z33.number().int().nonnegative(),
|
|
5452
5497
|
/** Full per-class crawler-hit breakdown; the five buckets sum to `crawlerHits`. */
|
|
5453
5498
|
crawlerSegments: trafficCrawlerSegmentsSchema,
|
|
5454
|
-
aiUserFetchHits:
|
|
5455
|
-
aiReferralHits:
|
|
5456
|
-
sampleCount:
|
|
5499
|
+
aiUserFetchHits: z33.number().int().nonnegative(),
|
|
5500
|
+
aiReferralHits: z33.number().int().nonnegative(),
|
|
5501
|
+
sampleCount: z33.number().int().nonnegative()
|
|
5457
5502
|
});
|
|
5458
|
-
var trafficSourceListResponseSchema =
|
|
5459
|
-
sources:
|
|
5503
|
+
var trafficSourceListResponseSchema = z33.object({
|
|
5504
|
+
sources: z33.array(trafficSourceDtoSchema)
|
|
5460
5505
|
});
|
|
5461
5506
|
var trafficSourceDetailDtoSchema = trafficSourceDtoSchema.extend({
|
|
5462
5507
|
totals24h: trafficSourceTotalsSchema,
|
|
5463
|
-
latestRun:
|
|
5464
|
-
runId:
|
|
5508
|
+
latestRun: z33.object({
|
|
5509
|
+
runId: z33.string(),
|
|
5465
5510
|
status: runStatusSchema,
|
|
5466
|
-
startedAt:
|
|
5467
|
-
finishedAt:
|
|
5468
|
-
error:
|
|
5511
|
+
startedAt: z33.string().nullable(),
|
|
5512
|
+
finishedAt: z33.string().nullable(),
|
|
5513
|
+
error: z33.string().nullable()
|
|
5469
5514
|
}).nullable()
|
|
5470
5515
|
});
|
|
5471
|
-
var trafficStatusResponseSchema =
|
|
5472
|
-
sources:
|
|
5516
|
+
var trafficStatusResponseSchema = z33.object({
|
|
5517
|
+
sources: z33.array(trafficSourceDetailDtoSchema)
|
|
5473
5518
|
});
|
|
5474
|
-
var trafficEventKindSchema =
|
|
5519
|
+
var trafficEventKindSchema = z33.enum(["crawler", "ai-user-fetch", "ai-referral"]);
|
|
5475
5520
|
var TrafficEventKinds = trafficEventKindSchema.enum;
|
|
5476
|
-
var trafficCrawlerEventEntrySchema =
|
|
5477
|
-
kind:
|
|
5478
|
-
sourceId:
|
|
5479
|
-
tsHour:
|
|
5480
|
-
botId:
|
|
5481
|
-
operator:
|
|
5482
|
-
verificationStatus:
|
|
5483
|
-
pathNormalized:
|
|
5521
|
+
var trafficCrawlerEventEntrySchema = z33.object({
|
|
5522
|
+
kind: z33.literal(TrafficEventKinds.crawler),
|
|
5523
|
+
sourceId: z33.string(),
|
|
5524
|
+
tsHour: z33.string(),
|
|
5525
|
+
botId: z33.string(),
|
|
5526
|
+
operator: z33.string(),
|
|
5527
|
+
verificationStatus: z33.string(),
|
|
5528
|
+
pathNormalized: z33.string(),
|
|
5484
5529
|
/** Coarse class of the fetched path — lets the UI split content crawls from sitemap/robots/asset polling. */
|
|
5485
5530
|
pathClass: trafficPathClassSchema,
|
|
5486
|
-
status:
|
|
5487
|
-
hits:
|
|
5488
|
-
});
|
|
5489
|
-
var trafficAiUserFetchEventEntrySchema =
|
|
5490
|
-
kind:
|
|
5491
|
-
sourceId:
|
|
5492
|
-
tsHour:
|
|
5493
|
-
botId:
|
|
5494
|
-
operator:
|
|
5495
|
-
verificationStatus:
|
|
5496
|
-
pathNormalized:
|
|
5497
|
-
status:
|
|
5498
|
-
hits:
|
|
5499
|
-
});
|
|
5500
|
-
var trafficAiReferralEventEntrySchema =
|
|
5501
|
-
kind:
|
|
5502
|
-
sourceId:
|
|
5503
|
-
tsHour:
|
|
5504
|
-
product:
|
|
5505
|
-
operator:
|
|
5506
|
-
sourceDomain:
|
|
5507
|
-
evidenceType:
|
|
5508
|
-
landingPathNormalized:
|
|
5509
|
-
status:
|
|
5531
|
+
status: z33.number().int(),
|
|
5532
|
+
hits: z33.number().int().nonnegative()
|
|
5533
|
+
});
|
|
5534
|
+
var trafficAiUserFetchEventEntrySchema = z33.object({
|
|
5535
|
+
kind: z33.literal(TrafficEventKinds["ai-user-fetch"]),
|
|
5536
|
+
sourceId: z33.string(),
|
|
5537
|
+
tsHour: z33.string(),
|
|
5538
|
+
botId: z33.string(),
|
|
5539
|
+
operator: z33.string(),
|
|
5540
|
+
verificationStatus: z33.string(),
|
|
5541
|
+
pathNormalized: z33.string(),
|
|
5542
|
+
status: z33.number().int(),
|
|
5543
|
+
hits: z33.number().int().nonnegative()
|
|
5544
|
+
});
|
|
5545
|
+
var trafficAiReferralEventEntrySchema = z33.object({
|
|
5546
|
+
kind: z33.literal(TrafficEventKinds["ai-referral"]),
|
|
5547
|
+
sourceId: z33.string(),
|
|
5548
|
+
tsHour: z33.string(),
|
|
5549
|
+
product: z33.string(),
|
|
5550
|
+
operator: z33.string(),
|
|
5551
|
+
sourceDomain: z33.string(),
|
|
5552
|
+
evidenceType: z33.string(),
|
|
5553
|
+
landingPathNormalized: z33.string(),
|
|
5554
|
+
status: z33.number().int(),
|
|
5510
5555
|
/** Total AI-referral sessions in the bucket. `paidHits + organicHits + unknownHits === hits`. */
|
|
5511
|
-
hits:
|
|
5556
|
+
hits: z33.number().int().nonnegative(),
|
|
5512
5557
|
/** Sessions carrying paid-attribution UTM evidence (`utm_medium=cpc`, …). */
|
|
5513
|
-
paidHits:
|
|
5558
|
+
paidHits: z33.number().int().nonnegative(),
|
|
5514
5559
|
/** Sessions with no paid-attribution evidence. Not proof the click was unpaid — an untagged ad click is indistinguishable. */
|
|
5515
|
-
organicHits:
|
|
5560
|
+
organicHits: z33.number().int().nonnegative(),
|
|
5516
5561
|
/**
|
|
5517
5562
|
* Sessions ingested before the classifier shipped. Their UTM tags were never
|
|
5518
5563
|
* persisted, so they can never be resolved to paid or organic. Never fold
|
|
5519
5564
|
* these into `organicHits`.
|
|
5520
5565
|
*/
|
|
5521
|
-
unknownHits:
|
|
5566
|
+
unknownHits: z33.number().int().nonnegative()
|
|
5522
5567
|
});
|
|
5523
|
-
var trafficEventEntrySchema =
|
|
5568
|
+
var trafficEventEntrySchema = z33.discriminatedUnion("kind", [
|
|
5524
5569
|
trafficCrawlerEventEntrySchema,
|
|
5525
5570
|
trafficAiUserFetchEventEntrySchema,
|
|
5526
5571
|
trafficAiReferralEventEntrySchema
|
|
5527
5572
|
]);
|
|
5528
|
-
var trafficEventsResponseSchema =
|
|
5529
|
-
windowStart:
|
|
5530
|
-
windowEnd:
|
|
5531
|
-
totals:
|
|
5573
|
+
var trafficEventsResponseSchema = z33.object({
|
|
5574
|
+
windowStart: z33.string(),
|
|
5575
|
+
windowEnd: z33.string(),
|
|
5576
|
+
totals: z33.object({
|
|
5532
5577
|
/** Total classified-crawler hits across the window. UNCHANGED contract. */
|
|
5533
|
-
crawlerHits:
|
|
5578
|
+
crawlerHits: z33.number().int().nonnegative(),
|
|
5534
5579
|
/** Crawler hits against content/document paths only (= `crawlerSegments.content`). */
|
|
5535
|
-
crawlerContentHits:
|
|
5580
|
+
crawlerContentHits: z33.number().int().nonnegative(),
|
|
5536
5581
|
/** Infrastructure crawler hits — sitemap + robots + asset fetches. */
|
|
5537
|
-
crawlerInfraHits:
|
|
5582
|
+
crawlerInfraHits: z33.number().int().nonnegative(),
|
|
5538
5583
|
/** Full per-class crawler-hit breakdown; the five buckets sum to `crawlerHits`. */
|
|
5539
5584
|
crawlerSegments: trafficCrawlerSegmentsSchema,
|
|
5540
|
-
aiUserFetchHits:
|
|
5585
|
+
aiUserFetchHits: z33.number().int().nonnegative(),
|
|
5541
5586
|
/** Total AI-referral sessions. The three class buckets below sum to it. */
|
|
5542
|
-
aiReferralHits:
|
|
5587
|
+
aiReferralHits: z33.number().int().nonnegative(),
|
|
5543
5588
|
/** AI-referral sessions carrying paid-attribution UTM evidence. */
|
|
5544
|
-
aiReferralPaidHits:
|
|
5589
|
+
aiReferralPaidHits: z33.number().int().nonnegative(),
|
|
5545
5590
|
/** AI-referral sessions with no paid-attribution evidence. */
|
|
5546
|
-
aiReferralOrganicHits:
|
|
5591
|
+
aiReferralOrganicHits: z33.number().int().nonnegative(),
|
|
5547
5592
|
/** AI-referral sessions ingested before the classifier shipped; unresolvable, never organic. */
|
|
5548
|
-
aiReferralUnknownHits:
|
|
5593
|
+
aiReferralUnknownHits: z33.number().int().nonnegative()
|
|
5549
5594
|
}),
|
|
5550
|
-
events:
|
|
5595
|
+
events: z33.array(trafficEventEntrySchema)
|
|
5551
5596
|
});
|
|
5552
5597
|
|
|
5553
5598
|
// ../contracts/src/traffic-path.ts
|
|
@@ -5690,14 +5735,14 @@ function round(value, dp = 4) {
|
|
|
5690
5735
|
const f = 10 ** dp;
|
|
5691
5736
|
return (Math.round(value * f) + 0) / f;
|
|
5692
5737
|
}
|
|
5693
|
-
function wilsonInterval(successes, n,
|
|
5738
|
+
function wilsonInterval(successes, n, z35 = 1.96) {
|
|
5694
5739
|
if (!Number.isFinite(n) || n <= 0) return null;
|
|
5695
5740
|
const s = Math.max(0, Math.min(successes, n));
|
|
5696
5741
|
const p = s / n;
|
|
5697
|
-
const z210 =
|
|
5742
|
+
const z210 = z35 * z35;
|
|
5698
5743
|
const denom = 1 + z210 / n;
|
|
5699
5744
|
const center = (p + z210 / (2 * n)) / denom;
|
|
5700
|
-
const margin =
|
|
5745
|
+
const margin = z35 / denom * Math.sqrt(p * (1 - p) / n + z210 / (4 * n * n));
|
|
5701
5746
|
return {
|
|
5702
5747
|
low: round(Math.max(0, center - margin)),
|
|
5703
5748
|
high: round(Math.min(1, center + margin))
|
|
@@ -5705,118 +5750,241 @@ function wilsonInterval(successes, n, z34 = 1.96) {
|
|
|
5705
5750
|
}
|
|
5706
5751
|
|
|
5707
5752
|
// ../contracts/src/ads.ts
|
|
5708
|
-
import { z as
|
|
5709
|
-
var adsConnectRequestSchema =
|
|
5753
|
+
import { z as z34 } from "zod";
|
|
5754
|
+
var adsConnectRequestSchema = z34.object({
|
|
5710
5755
|
/** Ads Manager "SDK key" scoped to one ad account. Stored in config.yaml, never the DB. */
|
|
5711
|
-
apiKey:
|
|
5712
|
-
});
|
|
5713
|
-
var adsConnectionStatusDtoSchema =
|
|
5714
|
-
connected:
|
|
5715
|
-
adAccountId:
|
|
5716
|
-
displayName:
|
|
5717
|
-
currencyCode:
|
|
5718
|
-
timezone:
|
|
5719
|
-
status:
|
|
5720
|
-
lastSyncedAt:
|
|
5756
|
+
apiKey: z34.string().min(1)
|
|
5757
|
+
});
|
|
5758
|
+
var adsConnectionStatusDtoSchema = z34.object({
|
|
5759
|
+
connected: z34.boolean(),
|
|
5760
|
+
adAccountId: z34.string().nullable().optional(),
|
|
5761
|
+
displayName: z34.string().nullable().optional(),
|
|
5762
|
+
currencyCode: z34.string().nullable().optional(),
|
|
5763
|
+
timezone: z34.string().nullable().optional(),
|
|
5764
|
+
status: z34.string().nullable().optional(),
|
|
5765
|
+
lastSyncedAt: z34.string().nullable().optional(),
|
|
5721
5766
|
/** Whether the ad account has OpenAI conversion tracking (pixel or CAPI) configured,
|
|
5722
5767
|
* detected from synced campaigns carrying conversion_event_setting_ids. Optional:
|
|
5723
5768
|
* only present when connected. */
|
|
5724
|
-
conversionTrackingConfigured:
|
|
5725
|
-
});
|
|
5726
|
-
var adsDisconnectResponseSchema =
|
|
5727
|
-
disconnected:
|
|
5728
|
-
});
|
|
5729
|
-
var adsSyncResponseSchema =
|
|
5730
|
-
runId:
|
|
5731
|
-
status:
|
|
5732
|
-
});
|
|
5733
|
-
var adsCreativeDtoSchema =
|
|
5734
|
-
type:
|
|
5735
|
-
title:
|
|
5736
|
-
body:
|
|
5737
|
-
targetUrl:
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5769
|
+
conversionTrackingConfigured: z34.boolean().optional()
|
|
5770
|
+
});
|
|
5771
|
+
var adsDisconnectResponseSchema = z34.object({
|
|
5772
|
+
disconnected: z34.boolean()
|
|
5773
|
+
});
|
|
5774
|
+
var adsSyncResponseSchema = z34.object({
|
|
5775
|
+
runId: z34.string(),
|
|
5776
|
+
status: z34.string()
|
|
5777
|
+
});
|
|
5778
|
+
var adsCreativeDtoSchema = z34.object({
|
|
5779
|
+
type: z34.string().nullable().optional(),
|
|
5780
|
+
title: z34.string().nullable().optional(),
|
|
5781
|
+
body: z34.string().nullable().optional(),
|
|
5782
|
+
targetUrl: z34.string().nullable().optional(),
|
|
5783
|
+
fileId: z34.string().nullable().optional()
|
|
5784
|
+
});
|
|
5785
|
+
var adsAdDtoSchema = z34.object({
|
|
5786
|
+
id: z34.string(),
|
|
5787
|
+
adGroupId: z34.string(),
|
|
5788
|
+
name: z34.string(),
|
|
5789
|
+
status: z34.string(),
|
|
5790
|
+
reviewStatus: z34.string().nullable().optional(),
|
|
5791
|
+
creative: adsCreativeDtoSchema.nullable().optional(),
|
|
5792
|
+
upstreamUpdatedAt: z34.number().int().nullable().optional(),
|
|
5793
|
+
syncedAt: z34.string().optional()
|
|
5794
|
+
});
|
|
5795
|
+
var adsAdGroupDtoSchema = z34.object({
|
|
5796
|
+
id: z34.string(),
|
|
5797
|
+
campaignId: z34.string(),
|
|
5798
|
+
name: z34.string(),
|
|
5799
|
+
description: z34.string().nullable().optional(),
|
|
5800
|
+
status: z34.string(),
|
|
5801
|
+
billingEventType: z34.string().nullable().optional(),
|
|
5802
|
+
maxBidMicros: z34.number().int().nullable().optional(),
|
|
5754
5803
|
/**
|
|
5755
5804
|
* The targeting primitive: entries are multi-line strings of
|
|
5756
5805
|
* newline-separated example queries (the live Ads Manager format).
|
|
5757
5806
|
*/
|
|
5758
|
-
contextHints:
|
|
5759
|
-
ads:
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5807
|
+
contextHints: z34.array(z34.string()).default([]),
|
|
5808
|
+
ads: z34.array(adsAdDtoSchema).default([]),
|
|
5809
|
+
upstreamUpdatedAt: z34.number().int().nullable().optional(),
|
|
5810
|
+
syncedAt: z34.string().optional()
|
|
5811
|
+
});
|
|
5812
|
+
var adsCampaignDtoSchema = z34.object({
|
|
5813
|
+
id: z34.string(),
|
|
5814
|
+
name: z34.string(),
|
|
5815
|
+
description: z34.string().nullable().optional(),
|
|
5816
|
+
status: z34.string(),
|
|
5817
|
+
startTime: z34.number().int().nullable().optional(),
|
|
5818
|
+
endTime: z34.number().int().nullable().optional(),
|
|
5819
|
+
biddingType: z34.string().nullable().optional(),
|
|
5820
|
+
dailySpendLimitMicros: z34.number().int().nullable().optional(),
|
|
5821
|
+
lifetimeSpendLimitMicros: z34.number().int().nullable().optional(),
|
|
5822
|
+
locationIds: z34.array(z34.string()).optional(),
|
|
5823
|
+
adGroups: z34.array(adsAdGroupDtoSchema).default([]),
|
|
5824
|
+
upstreamUpdatedAt: z34.number().int().nullable().optional(),
|
|
5825
|
+
syncedAt: z34.string().optional()
|
|
5826
|
+
});
|
|
5827
|
+
var adsCampaignListResponseSchema = z34.object({
|
|
5828
|
+
campaigns: z34.array(adsCampaignDtoSchema)
|
|
5829
|
+
});
|
|
5830
|
+
var adsInsightLevelSchema = z34.enum(["campaign", "ad_group"]);
|
|
5774
5831
|
var AdsInsightLevels = adsInsightLevelSchema.enum;
|
|
5775
|
-
var adsInsightRowDtoSchema =
|
|
5832
|
+
var adsInsightRowDtoSchema = z34.object({
|
|
5776
5833
|
level: adsInsightLevelSchema,
|
|
5777
|
-
entityId:
|
|
5778
|
-
date:
|
|
5779
|
-
impressions:
|
|
5780
|
-
clicks:
|
|
5781
|
-
spendMicros:
|
|
5834
|
+
entityId: z34.string(),
|
|
5835
|
+
date: z34.string(),
|
|
5836
|
+
impressions: z34.number().int(),
|
|
5837
|
+
clicks: z34.number().int(),
|
|
5838
|
+
spendMicros: z34.number().int(),
|
|
5782
5839
|
/** Conversion count for the row. 0 when conversion tracking is not configured.
|
|
5783
5840
|
* Conversion VALUE (for ROAS) is a deliberate follow-up: the upstream value
|
|
5784
5841
|
* field is not yet captured against a live conversion-tracking account. */
|
|
5785
|
-
conversions:
|
|
5842
|
+
conversions: z34.number().int(),
|
|
5786
5843
|
/** clicks / impressions; null when impressions is 0. */
|
|
5787
|
-
ctr:
|
|
5844
|
+
ctr: z34.number().nullable(),
|
|
5788
5845
|
/** spendMicros / clicks, rounded to integer micros; null when clicks is 0. */
|
|
5789
|
-
cpcMicros:
|
|
5846
|
+
cpcMicros: z34.number().int().nullable()
|
|
5790
5847
|
});
|
|
5791
|
-
var adsInsightsResponseSchema =
|
|
5792
|
-
rows:
|
|
5848
|
+
var adsInsightsResponseSchema = z34.object({
|
|
5849
|
+
rows: z34.array(adsInsightRowDtoSchema),
|
|
5793
5850
|
/** Account currency for rendering spend/cpc; null before the first sync. */
|
|
5794
|
-
currencyCode:
|
|
5795
|
-
});
|
|
5796
|
-
var adsTotalsDtoSchema =
|
|
5797
|
-
impressions:
|
|
5798
|
-
clicks:
|
|
5799
|
-
spendMicros:
|
|
5800
|
-
conversions:
|
|
5801
|
-
ctr:
|
|
5802
|
-
cpcMicros:
|
|
5803
|
-
});
|
|
5804
|
-
var adsSummaryDtoSchema =
|
|
5805
|
-
connected:
|
|
5806
|
-
displayName:
|
|
5807
|
-
currencyCode:
|
|
5808
|
-
lastSyncedAt:
|
|
5809
|
-
campaignCount:
|
|
5810
|
-
adGroupCount:
|
|
5811
|
-
adCount:
|
|
5851
|
+
currencyCode: z34.string().nullable().optional()
|
|
5852
|
+
});
|
|
5853
|
+
var adsTotalsDtoSchema = z34.object({
|
|
5854
|
+
impressions: z34.number().int(),
|
|
5855
|
+
clicks: z34.number().int(),
|
|
5856
|
+
spendMicros: z34.number().int(),
|
|
5857
|
+
conversions: z34.number().int(),
|
|
5858
|
+
ctr: z34.number().nullable(),
|
|
5859
|
+
cpcMicros: z34.number().int().nullable()
|
|
5860
|
+
});
|
|
5861
|
+
var adsSummaryDtoSchema = z34.object({
|
|
5862
|
+
connected: z34.boolean(),
|
|
5863
|
+
displayName: z34.string().nullable().optional(),
|
|
5864
|
+
currencyCode: z34.string().nullable().optional(),
|
|
5865
|
+
lastSyncedAt: z34.string().nullable().optional(),
|
|
5866
|
+
campaignCount: z34.number().int(),
|
|
5867
|
+
adGroupCount: z34.number().int(),
|
|
5868
|
+
adCount: z34.number().int(),
|
|
5812
5869
|
/** Date range the totals cover (oldest/newest rollup date), null when empty. */
|
|
5813
|
-
window:
|
|
5814
|
-
from:
|
|
5815
|
-
to:
|
|
5870
|
+
window: z34.object({
|
|
5871
|
+
from: z34.string().nullable(),
|
|
5872
|
+
to: z34.string().nullable()
|
|
5816
5873
|
}),
|
|
5817
5874
|
/** Campaign-level rollup totals over the window (levels are not summed across). */
|
|
5818
5875
|
totals: adsTotalsDtoSchema
|
|
5819
5876
|
});
|
|
5877
|
+
var adsOperationKeySchema = z34.string().min(8).max(128).regex(/^[\w.:-]+$/, "operationKey may contain letters, numbers, dot, underscore, colon, and hyphen");
|
|
5878
|
+
var adsEntityIdSchema = z34.string().min(1).max(200);
|
|
5879
|
+
var adsNameSchema = z34.string().min(3).max(1e3).refine((value) => value.trim().length > 0);
|
|
5880
|
+
var adsTimestampSchema = z34.number().int().min(946684800).max(4102444800);
|
|
5881
|
+
var adsMicrosSchema = z34.number().int().positive().max(Number.MAX_SAFE_INTEGER);
|
|
5882
|
+
var adsHttpsUrlSchema = z34.string().url().refine((value) => new URL(value).protocol === "https:", {
|
|
5883
|
+
message: "URL must use https"
|
|
5884
|
+
});
|
|
5885
|
+
var adsOperationKindSchema = z34.enum([
|
|
5886
|
+
"image_upload",
|
|
5887
|
+
"campaign_create",
|
|
5888
|
+
"campaign_update",
|
|
5889
|
+
"campaign_pause",
|
|
5890
|
+
"ad_group_create",
|
|
5891
|
+
"ad_group_update",
|
|
5892
|
+
"ad_group_pause",
|
|
5893
|
+
"ad_create",
|
|
5894
|
+
"ad_update",
|
|
5895
|
+
"ad_pause"
|
|
5896
|
+
]);
|
|
5897
|
+
var AdsOperationKinds = adsOperationKindSchema.enum;
|
|
5898
|
+
var adsOperationStateSchema = z34.enum(["pending", "succeeded", "failed", "unknown"]);
|
|
5899
|
+
var AdsOperationStates = adsOperationStateSchema.enum;
|
|
5900
|
+
var adsEntityStatusSchema = z34.enum(["active", "paused", "archived"]);
|
|
5901
|
+
var AdsEntityStatuses = adsEntityStatusSchema.enum;
|
|
5902
|
+
var adsEntityTypeSchema = z34.enum(["file", "campaign", "ad_group", "ad"]);
|
|
5903
|
+
var AdsEntityTypes = adsEntityTypeSchema.enum;
|
|
5904
|
+
var adsImageUploadRequestSchema = z34.object({
|
|
5905
|
+
operationKey: adsOperationKeySchema,
|
|
5906
|
+
imageUrl: adsHttpsUrlSchema
|
|
5907
|
+
});
|
|
5908
|
+
var adsCampaignCreateRequestSchema = z34.object({
|
|
5909
|
+
operationKey: adsOperationKeySchema,
|
|
5910
|
+
name: adsNameSchema,
|
|
5911
|
+
description: z34.string().max(4e3).optional(),
|
|
5912
|
+
startTime: adsTimestampSchema.optional(),
|
|
5913
|
+
endTime: adsTimestampSchema.optional(),
|
|
5914
|
+
lifetimeSpendLimitMicros: adsMicrosSchema.min(1e6),
|
|
5915
|
+
locationIds: z34.array(adsEntityIdSchema).min(1).max(100)
|
|
5916
|
+
}).superRefine((value, ctx) => {
|
|
5917
|
+
if (value.startTime !== void 0 && value.endTime !== void 0 && value.endTime <= value.startTime) {
|
|
5918
|
+
ctx.addIssue({ code: "custom", path: ["endTime"], message: "endTime must be after startTime" });
|
|
5919
|
+
}
|
|
5920
|
+
});
|
|
5921
|
+
var adsAdGroupCreateRequestSchema = z34.object({
|
|
5922
|
+
operationKey: adsOperationKeySchema,
|
|
5923
|
+
campaignId: adsEntityIdSchema,
|
|
5924
|
+
name: adsNameSchema,
|
|
5925
|
+
description: z34.string().max(4e3).optional(),
|
|
5926
|
+
contextHints: z34.array(z34.string().min(1).max(1e3)).min(1).max(100),
|
|
5927
|
+
maxBidMicros: adsMicrosSchema.max(1e8)
|
|
5928
|
+
});
|
|
5929
|
+
var adsChatCardCreativeRequestSchema = z34.object({
|
|
5930
|
+
title: z34.string().min(3).max(50),
|
|
5931
|
+
body: z34.string().min(1).max(100),
|
|
5932
|
+
targetUrl: adsHttpsUrlSchema,
|
|
5933
|
+
fileId: adsEntityIdSchema
|
|
5934
|
+
});
|
|
5935
|
+
var adsAdCreateRequestSchema = z34.object({
|
|
5936
|
+
operationKey: adsOperationKeySchema,
|
|
5937
|
+
adGroupId: adsEntityIdSchema,
|
|
5938
|
+
name: adsNameSchema,
|
|
5939
|
+
creative: adsChatCardCreativeRequestSchema
|
|
5940
|
+
});
|
|
5941
|
+
function hasMutationField(value) {
|
|
5942
|
+
return Object.keys(value).some((key) => key !== "operationKey" && key !== "expectedUpdatedAt");
|
|
5943
|
+
}
|
|
5944
|
+
var adsCampaignUpdateRequestSchema = z34.object({
|
|
5945
|
+
operationKey: adsOperationKeySchema,
|
|
5946
|
+
expectedUpdatedAt: z34.number().int().nonnegative(),
|
|
5947
|
+
name: adsNameSchema.optional(),
|
|
5948
|
+
description: z34.string().max(4e3).nullable().optional(),
|
|
5949
|
+
startTime: adsTimestampSchema.nullable().optional(),
|
|
5950
|
+
endTime: adsTimestampSchema.nullable().optional(),
|
|
5951
|
+
lifetimeSpendLimitMicros: adsMicrosSchema.min(1e6).optional(),
|
|
5952
|
+
locationIds: z34.array(adsEntityIdSchema).min(1).max(100).optional()
|
|
5953
|
+
}).refine(hasMutationField, { message: "At least one campaign field must be updated" });
|
|
5954
|
+
var adsAdGroupUpdateRequestSchema = z34.object({
|
|
5955
|
+
operationKey: adsOperationKeySchema,
|
|
5956
|
+
expectedUpdatedAt: z34.number().int().nonnegative(),
|
|
5957
|
+
name: adsNameSchema.optional(),
|
|
5958
|
+
description: z34.string().max(4e3).nullable().optional(),
|
|
5959
|
+
contextHints: z34.array(z34.string().min(1).max(1e3)).min(1).max(100).optional(),
|
|
5960
|
+
maxBidMicros: adsMicrosSchema.max(1e8).optional()
|
|
5961
|
+
}).refine(hasMutationField, { message: "At least one ad group field must be updated" });
|
|
5962
|
+
var adsAdUpdateRequestSchema = z34.object({
|
|
5963
|
+
operationKey: adsOperationKeySchema,
|
|
5964
|
+
expectedUpdatedAt: z34.number().int().nonnegative(),
|
|
5965
|
+
name: adsNameSchema.optional(),
|
|
5966
|
+
creative: adsChatCardCreativeRequestSchema.optional()
|
|
5967
|
+
}).refine(hasMutationField, { message: "At least one ad field must be updated" });
|
|
5968
|
+
var adsPauseRequestSchema = z34.object({
|
|
5969
|
+
operationKey: adsOperationKeySchema
|
|
5970
|
+
});
|
|
5971
|
+
var adsOperationDtoSchema = z34.object({
|
|
5972
|
+
id: z34.string(),
|
|
5973
|
+
operationKey: z34.string(),
|
|
5974
|
+
kind: adsOperationKindSchema,
|
|
5975
|
+
state: adsOperationStateSchema,
|
|
5976
|
+
entityType: adsEntityTypeSchema.nullable(),
|
|
5977
|
+
entityId: z34.string().nullable(),
|
|
5978
|
+
upstreamUpdatedAt: z34.number().int().nullable(),
|
|
5979
|
+
errorCode: z34.string().nullable(),
|
|
5980
|
+
errorMessage: z34.string().nullable(),
|
|
5981
|
+
createdAt: z34.string(),
|
|
5982
|
+
updatedAt: z34.string()
|
|
5983
|
+
});
|
|
5984
|
+
var adsOperationResponseSchema = z34.object({
|
|
5985
|
+
operation: adsOperationDtoSchema,
|
|
5986
|
+
replayed: z34.boolean()
|
|
5987
|
+
});
|
|
5820
5988
|
function adsCtr(clicks, impressions) {
|
|
5821
5989
|
return impressions > 0 ? clicks / impressions : null;
|
|
5822
5990
|
}
|
|
@@ -6019,6 +6187,7 @@ export {
|
|
|
6019
6187
|
notificationCreateRequestSchema,
|
|
6020
6188
|
AppError,
|
|
6021
6189
|
notFound,
|
|
6190
|
+
alreadyExists,
|
|
6022
6191
|
validationError,
|
|
6023
6192
|
authRequired,
|
|
6024
6193
|
authInvalid,
|
|
@@ -6217,6 +6386,7 @@ export {
|
|
|
6217
6386
|
visibilityStateFromAnswerMentioned,
|
|
6218
6387
|
mentionStateFromAnswerMentioned,
|
|
6219
6388
|
brandKeyFromText,
|
|
6389
|
+
healthSnapshotDtoSchema,
|
|
6220
6390
|
agentProvidersResponseDtoSchema,
|
|
6221
6391
|
MemorySources,
|
|
6222
6392
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
@@ -6313,6 +6483,19 @@ export {
|
|
|
6313
6483
|
adsInsightLevelSchema,
|
|
6314
6484
|
adsInsightsResponseSchema,
|
|
6315
6485
|
adsSummaryDtoSchema,
|
|
6486
|
+
AdsOperationKinds,
|
|
6487
|
+
AdsOperationStates,
|
|
6488
|
+
AdsEntityStatuses,
|
|
6489
|
+
AdsEntityTypes,
|
|
6490
|
+
adsImageUploadRequestSchema,
|
|
6491
|
+
adsCampaignCreateRequestSchema,
|
|
6492
|
+
adsAdGroupCreateRequestSchema,
|
|
6493
|
+
adsAdCreateRequestSchema,
|
|
6494
|
+
adsCampaignUpdateRequestSchema,
|
|
6495
|
+
adsAdGroupUpdateRequestSchema,
|
|
6496
|
+
adsAdUpdateRequestSchema,
|
|
6497
|
+
adsPauseRequestSchema,
|
|
6498
|
+
adsOperationResponseSchema,
|
|
6316
6499
|
adsCtr,
|
|
6317
6500
|
adsCpcMicros,
|
|
6318
6501
|
dollarsToMicros,
|
|
@@ -6323,6 +6506,7 @@ export {
|
|
|
6323
6506
|
AI_PROVIDER_INFRA_DOMAINS,
|
|
6324
6507
|
escapeLikePattern,
|
|
6325
6508
|
READ_ONLY_SCOPE,
|
|
6509
|
+
ADS_WRITE_SCOPE,
|
|
6326
6510
|
isReadOnlyKey,
|
|
6327
6511
|
splitList,
|
|
6328
6512
|
parseOriginList,
|