@ainyc/canonry 4.69.2 → 4.69.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27443,6 +27443,7 @@ var VERCEL_MAX_SUB_WINDOWS = 5e3;
27443
27443
  var VERCEL_BACKFILL_CHUNK_MS = 60 * 6e4;
27444
27444
  var MAX_TRACKED_EVENT_IDS = 1e3;
27445
27445
  var DEFAULT_BACKFILL_DAYS = 30;
27446
+ var DEFAULT_TRAFFIC_SYNC_CRON = "*/30 * * * *";
27446
27447
  var MAX_BACKFILL_DAYS = 90;
27447
27448
  var BACKFILL_MAX_PAGES = 1e3;
27448
27449
  var BACKFILL_SAMPLE_LIMIT = 500;
@@ -27899,49 +27900,91 @@ async function trafficRoutes(app, opts) {
27899
27900
  const activeSource = app.db.select().from(trafficSources).where(eq25(trafficSources.projectId, project.id)).all().find((row) => row.sourceType === TrafficSourceTypes.vercel && row.status !== TrafficSourceStatuses.archived);
27900
27901
  const config = { projectId, teamId, environment };
27901
27902
  const fallbackName = displayName ?? `Vercel \xB7 ${projectId}`;
27902
- let sourceRow;
27903
- if (activeSource) {
27904
- app.db.update(trafficSources).set({
27905
- displayName: fallbackName,
27906
- status: TrafficSourceStatuses.connected,
27907
- lastError: null,
27908
- configJson: config,
27909
- updatedAt: now
27910
- }).where(eq25(trafficSources.id, activeSource.id)).run();
27911
- sourceRow = app.db.select().from(trafficSources).where(eq25(trafficSources.id, activeSource.id)).get();
27912
- } else {
27913
- const newId = crypto23.randomUUID();
27914
- app.db.insert(trafficSources).values({
27915
- id: newId,
27903
+ const { sourceRow, scheduleCreated } = app.db.transaction((tx) => {
27904
+ let row;
27905
+ if (activeSource) {
27906
+ tx.update(trafficSources).set({
27907
+ displayName: fallbackName,
27908
+ status: TrafficSourceStatuses.connected,
27909
+ lastError: null,
27910
+ configJson: config,
27911
+ updatedAt: now
27912
+ }).where(eq25(trafficSources.id, activeSource.id)).run();
27913
+ row = tx.select().from(trafficSources).where(eq25(trafficSources.id, activeSource.id)).get();
27914
+ } else {
27915
+ const newId = crypto23.randomUUID();
27916
+ tx.insert(trafficSources).values({
27917
+ id: newId,
27918
+ projectId: project.id,
27919
+ sourceType: TrafficSourceTypes.vercel,
27920
+ displayName: fallbackName,
27921
+ status: TrafficSourceStatuses.connected,
27922
+ // Seed lastSyncedAt to NOW so the first sync uses a tight window.
27923
+ // Leaving this null would make the first sync fall back to
27924
+ // DEFAULT_SYNC_WINDOW_MINUTES (30 days) — which exceeds Vercel's
27925
+ // request-logs retention (~14 days), causing the first sync to
27926
+ // throw a retention error and leaving the source permanently
27927
+ // stuck before it ever drained an event. New users opt into
27928
+ // historical recovery via the explicit `traffic backfill` command;
27929
+ // they do not silently inherit a 30-day pull on connect.
27930
+ lastSyncedAt: now,
27931
+ lastCursor: null,
27932
+ lastError: null,
27933
+ archivedAt: null,
27934
+ configJson: config,
27935
+ createdAt: now,
27936
+ updatedAt: now
27937
+ }).run();
27938
+ row = tx.select().from(trafficSources).where(eq25(trafficSources.id, newId)).get();
27939
+ }
27940
+ const existingSchedule = tx.select().from(schedules).where(
27941
+ and19(
27942
+ eq25(schedules.projectId, project.id),
27943
+ eq25(schedules.kind, SchedulableRunKinds["traffic-sync"])
27944
+ )
27945
+ ).get();
27946
+ let created = false;
27947
+ if (!existingSchedule) {
27948
+ tx.insert(schedules).values({
27949
+ id: crypto23.randomUUID(),
27950
+ projectId: project.id,
27951
+ kind: SchedulableRunKinds["traffic-sync"],
27952
+ cronExpr: DEFAULT_TRAFFIC_SYNC_CRON,
27953
+ preset: null,
27954
+ timezone: "UTC",
27955
+ enabled: true,
27956
+ providers: [],
27957
+ sourceId: row.id,
27958
+ createdAt: now,
27959
+ updatedAt: now
27960
+ }).run();
27961
+ created = true;
27962
+ }
27963
+ writeAuditLog(tx, {
27916
27964
  projectId: project.id,
27917
- sourceType: TrafficSourceTypes.vercel,
27918
- displayName: fallbackName,
27919
- status: TrafficSourceStatuses.connected,
27920
- // Seed lastSyncedAt to NOW so the first sync uses a tight window.
27921
- // Leaving this null would make the first sync fall back to
27922
- // DEFAULT_SYNC_WINDOW_MINUTES (30 days) — which exceeds Vercel's
27923
- // request-logs retention (~14 days), causing the first sync to
27924
- // throw a retention error and leaving the source permanently
27925
- // stuck before it ever drained an event. New users opt into
27926
- // historical recovery via the explicit `traffic backfill` command;
27927
- // they do not silently inherit a 30-day pull on connect.
27928
- lastSyncedAt: now,
27929
- lastCursor: null,
27930
- lastError: null,
27931
- archivedAt: null,
27932
- configJson: config,
27933
- createdAt: now,
27934
- updatedAt: now
27935
- }).run();
27936
- sourceRow = app.db.select().from(trafficSources).where(eq25(trafficSources.id, newId)).get();
27937
- }
27938
- writeAuditLog(app.db, {
27939
- projectId: project.id,
27940
- actor: "api",
27941
- action: "traffic.vercel.connected",
27942
- entityType: "traffic_source",
27943
- entityId: sourceRow.id
27965
+ actor: "api",
27966
+ action: "traffic.vercel.connected",
27967
+ entityType: "traffic_source",
27968
+ entityId: row.id
27969
+ });
27970
+ if (created) {
27971
+ writeAuditLog(tx, {
27972
+ projectId: project.id,
27973
+ actor: "api",
27974
+ action: "schedule.created",
27975
+ entityType: "schedule",
27976
+ diff: {
27977
+ kind: SchedulableRunKinds["traffic-sync"],
27978
+ cronExpr: DEFAULT_TRAFFIC_SYNC_CRON,
27979
+ sourceId: row.id
27980
+ }
27981
+ });
27982
+ }
27983
+ return { sourceRow: row, scheduleCreated: created };
27944
27984
  });
27985
+ if (scheduleCreated) {
27986
+ opts.onScheduleUpdated?.("upsert", project.id, SchedulableRunKinds["traffic-sync"]);
27987
+ }
27945
27988
  return rowToDto(sourceRow);
27946
27989
  });
27947
27990
  app.post("/projects/:name/traffic/sources/:id/sync", async (request) => {
@@ -31154,6 +31197,7 @@ async function apiRoutes(app, opts) {
31154
31197
  vercelTrafficCredentialStore: opts.vercelTrafficCredentialStore,
31155
31198
  pullVercelTrafficEvents: opts.pullVercelTrafficEvents,
31156
31199
  onTrafficSynced: opts.onTrafficSynced,
31200
+ onScheduleUpdated: opts.onScheduleUpdated,
31157
31201
  allowLoopbackWebhooks: opts.allowLoopbackWebhooks
31158
31202
  });
31159
31203
  await api.register(backlinksRoutes, {
@@ -95,7 +95,7 @@ import {
95
95
  runs,
96
96
  schedules,
97
97
  usageCounters
98
- } from "./chunk-WFM2O72W.js";
98
+ } from "./chunk-F74QJKIP.js";
99
99
  import {
100
100
  AGENT_MEMORY_VALUE_MAX_BYTES,
101
101
  AGENT_PROVIDER_IDS,
@@ -5618,7 +5618,7 @@ function readStoredGroundingSources(rawResponse) {
5618
5618
  return result;
5619
5619
  }
5620
5620
  async function backfillInsightsCommand(project, opts) {
5621
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-DVVSE3G7.js");
5621
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-SCTWXI5M.js");
5622
5622
  const config = loadConfig();
5623
5623
  const db = createClient(config.database);
5624
5624
  migrate(db);
package/dist/cli.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  setTelemetrySource,
28
28
  showFirstRunNotice,
29
29
  trackEvent
30
- } from "./chunk-SBYA3LEJ.js";
30
+ } from "./chunk-H7TJ5FQ6.js";
31
31
  import {
32
32
  CliError,
33
33
  EXIT_SYSTEM_ERROR,
@@ -52,7 +52,7 @@ import {
52
52
  projects,
53
53
  queries,
54
54
  renderReportHtml
55
- } from "./chunk-WFM2O72W.js";
55
+ } from "./chunk-F74QJKIP.js";
56
56
  import {
57
57
  CcReleaseSyncStatuses,
58
58
  CheckScopes,
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-SBYA3LEJ.js";
3
+ } from "./chunk-H7TJ5FQ6.js";
4
4
  import {
5
5
  loadConfig
6
6
  } from "./chunk-ZNWMVYYU.js";
7
- import "./chunk-WFM2O72W.js";
7
+ import "./chunk-F74QJKIP.js";
8
8
  import "./chunk-5FM7QRYD.js";
9
9
  export {
10
10
  createServer,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-WFM2O72W.js";
3
+ } from "./chunk-F74QJKIP.js";
4
4
  import "./chunk-5FM7QRYD.js";
5
5
  export {
6
6
  IntelligenceService
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "4.69.2",
3
+ "version": "4.69.3",
4
4
  "type": "module",
5
5
  "description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -62,24 +62,24 @@
62
62
  "@types/node-cron": "^3.0.11",
63
63
  "tsup": "^8.5.1",
64
64
  "tsx": "^4.19.0",
65
- "@ainyc/canonry-api-client": "0.0.0",
66
65
  "@ainyc/canonry-api-routes": "0.0.0",
67
- "@ainyc/canonry-config": "0.0.0",
66
+ "@ainyc/canonry-api-client": "0.0.0",
68
67
  "@ainyc/canonry-contracts": "0.0.0",
69
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
70
68
  "@ainyc/canonry-db": "0.0.0",
69
+ "@ainyc/canonry-config": "0.0.0",
71
70
  "@ainyc/canonry-integration-bing": "0.0.0",
72
71
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
72
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
73
73
  "@ainyc/canonry-integration-google": "0.0.0",
74
74
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
75
- "@ainyc/canonry-integration-wordpress": "0.0.0",
75
+ "@ainyc/canonry-integration-traffic": "0.0.0",
76
76
  "@ainyc/canonry-integration-google-places": "0.0.0",
77
- "@ainyc/canonry-intelligence": "0.0.0",
77
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
78
78
  "@ainyc/canonry-provider-claude": "0.0.0",
79
- "@ainyc/canonry-integration-traffic": "0.0.0",
79
+ "@ainyc/canonry-intelligence": "0.0.0",
80
+ "@ainyc/canonry-provider-cdp": "0.0.0",
80
81
  "@ainyc/canonry-provider-local": "0.0.0",
81
82
  "@ainyc/canonry-provider-gemini": "0.0.0",
82
- "@ainyc/canonry-provider-cdp": "0.0.0",
83
83
  "@ainyc/canonry-provider-openai": "0.0.0",
84
84
  "@ainyc/canonry-provider-perplexity": "0.0.0"
85
85
  },