@ainyc/canonry 4.11.0 → 4.12.1

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/index.html CHANGED
@@ -12,7 +12,7 @@
12
12
  <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
13
13
  <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
14
14
  <title>Canonry</title>
15
- <script type="module" crossorigin src="./assets/index-DOcemxPD.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-CCC1E6ji.js"></script>
16
16
  <link rel="stylesheet" crossorigin href="./assets/index-CGXCbiM_.css">
17
17
  </head>
18
18
  <body>
@@ -8,7 +8,7 @@ import {
8
8
  categoryLabel,
9
9
  determineAnswerMentioned,
10
10
  normalizeProjectDomain
11
- } from "./chunk-WWU65YPN.js";
11
+ } from "./chunk-YDGT5CAY.js";
12
12
 
13
13
  // src/intelligence-service.ts
14
14
  import { eq, desc, asc, and, or, inArray } from "drizzle-orm";
@@ -24,6 +24,7 @@ var schema_exports = {};
24
24
  __export(schema_exports, {
25
25
  agentMemory: () => agentMemory,
26
26
  agentSessions: () => agentSessions,
27
+ aiReferralEventsHourly: () => aiReferralEventsHourly,
27
28
  apiKeys: () => apiKeys,
28
29
  auditLog: () => auditLog,
29
30
  backlinkDomains: () => backlinkDomains,
@@ -34,6 +35,7 @@ __export(schema_exports, {
34
35
  bingUrlInspections: () => bingUrlInspections,
35
36
  ccReleaseSyncs: () => ccReleaseSyncs,
36
37
  competitors: () => competitors,
38
+ crawlerEventsHourly: () => crawlerEventsHourly,
37
39
  gaAiReferrals: () => gaAiReferrals,
38
40
  gaConnections: () => gaConnections,
39
41
  gaSocialReferrals: () => gaSocialReferrals,
@@ -51,11 +53,13 @@ __export(schema_exports, {
51
53
  projects: () => projects,
52
54
  queries: () => queries,
53
55
  querySnapshots: () => querySnapshots,
56
+ rawEventSamples: () => rawEventSamples,
54
57
  runs: () => runs,
55
58
  schedules: () => schedules,
59
+ trafficSources: () => trafficSources,
56
60
  usageCounters: () => usageCounters
57
61
  });
58
- import { index, integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
62
+ import { index, integer, primaryKey, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
59
63
  var projects = sqliteTable("projects", {
60
64
  id: text("id").primaryKey(),
61
65
  name: text("name").notNull().unique(),
@@ -540,6 +544,99 @@ var agentMemory = sqliteTable("agent_memory", {
540
544
  uniqueIndex("uniq_agent_memory_project_key").on(table.projectId, table.key),
541
545
  index("idx_agent_memory_project_updated").on(table.projectId, table.updatedAt)
542
546
  ]);
547
+ var trafficSources = sqliteTable("traffic_sources", {
548
+ id: text("id").primaryKey(),
549
+ projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
550
+ sourceType: text("source_type").notNull(),
551
+ displayName: text("display_name").notNull(),
552
+ status: text("status").notNull(),
553
+ lastSyncedAt: text("last_synced_at"),
554
+ lastCursor: text("last_cursor"),
555
+ lastError: text("last_error"),
556
+ archivedAt: text("archived_at"),
557
+ configJson: text("config_json").notNull().default("{}"),
558
+ createdAt: text("created_at").notNull(),
559
+ updatedAt: text("updated_at").notNull()
560
+ }, (table) => [
561
+ index("idx_traffic_sources_project").on(table.projectId),
562
+ index("idx_traffic_sources_project_status").on(table.projectId, table.status)
563
+ ]);
564
+ var crawlerEventsHourly = sqliteTable("crawler_events_hourly", {
565
+ projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
566
+ sourceId: text("source_id").notNull().references(() => trafficSources.id, { onDelete: "cascade" }),
567
+ tsHour: text("ts_hour").notNull(),
568
+ botId: text("bot_id").notNull(),
569
+ operator: text("operator").notNull(),
570
+ verificationStatus: text("verification_status").notNull(),
571
+ pathNormalized: text("path_normalized").notNull(),
572
+ status: integer("status").notNull(),
573
+ hits: integer("hits").notNull().default(0),
574
+ sampledUserAgent: text("sampled_user_agent"),
575
+ createdAt: text("created_at").notNull(),
576
+ updatedAt: text("updated_at").notNull()
577
+ }, (table) => [
578
+ primaryKey({
579
+ columns: [
580
+ table.projectId,
581
+ table.sourceId,
582
+ table.tsHour,
583
+ table.botId,
584
+ table.verificationStatus,
585
+ table.pathNormalized,
586
+ table.status
587
+ ]
588
+ }),
589
+ index("idx_crawler_hourly_project_ts").on(table.projectId, table.tsHour),
590
+ index("idx_crawler_hourly_path").on(table.projectId, table.pathNormalized)
591
+ ]);
592
+ var aiReferralEventsHourly = sqliteTable("ai_referral_events_hourly", {
593
+ projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
594
+ sourceId: text("source_id").notNull().references(() => trafficSources.id, { onDelete: "cascade" }),
595
+ tsHour: text("ts_hour").notNull(),
596
+ product: text("product").notNull(),
597
+ operator: text("operator").notNull(),
598
+ sourceDomain: text("source_domain").notNull(),
599
+ evidenceType: text("evidence_type").notNull(),
600
+ landingPathNormalized: text("landing_path_normalized").notNull(),
601
+ status: integer("status").notNull(),
602
+ sessionsOrHits: integer("sessions_or_hits").notNull().default(0),
603
+ usersEstimated: integer("users_estimated"),
604
+ createdAt: text("created_at").notNull(),
605
+ updatedAt: text("updated_at").notNull()
606
+ }, (table) => [
607
+ primaryKey({
608
+ columns: [
609
+ table.projectId,
610
+ table.sourceId,
611
+ table.tsHour,
612
+ table.product,
613
+ table.sourceDomain,
614
+ table.evidenceType,
615
+ table.landingPathNormalized,
616
+ table.status
617
+ ]
618
+ }),
619
+ index("idx_ai_referral_hourly_project_ts").on(table.projectId, table.tsHour),
620
+ index("idx_ai_referral_hourly_landing").on(table.projectId, table.landingPathNormalized)
621
+ ]);
622
+ var rawEventSamples = sqliteTable("raw_event_samples", {
623
+ id: text("id").primaryKey(),
624
+ projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
625
+ sourceId: text("source_id").notNull().references(() => trafficSources.id, { onDelete: "cascade" }),
626
+ ts: text("ts").notNull(),
627
+ eventType: text("event_type").notNull(),
628
+ ipHash: text("ip_hash"),
629
+ userAgent: text("user_agent"),
630
+ pathNormalized: text("path_normalized").notNull(),
631
+ status: integer("status"),
632
+ refererHost: text("referer_host"),
633
+ classifierDetailsJson: text("classifier_details_json").notNull().default("{}"),
634
+ createdAt: text("created_at").notNull()
635
+ }, (table) => [
636
+ index("idx_raw_event_samples_project_ts").on(table.projectId, table.ts),
637
+ index("idx_raw_event_samples_source_ts").on(table.sourceId, table.ts),
638
+ index("idx_raw_event_samples_event_type").on(table.eventType)
639
+ ]);
543
640
  var migrationsTable = sqliteTable("_migrations", {
544
641
  version: integer("version").primaryKey(),
545
642
  name: text("name").notNull(),
@@ -1399,6 +1496,80 @@ var MIGRATION_VERSIONS = [
1399
1496
  run: (tx) => {
1400
1497
  normalizeLegacyQuerySchema(tx);
1401
1498
  }
1499
+ },
1500
+ {
1501
+ version: 49,
1502
+ name: "server-side-traffic-tables",
1503
+ statements: [
1504
+ `CREATE TABLE IF NOT EXISTS traffic_sources (
1505
+ id TEXT PRIMARY KEY,
1506
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
1507
+ source_type TEXT NOT NULL,
1508
+ display_name TEXT NOT NULL,
1509
+ status TEXT NOT NULL,
1510
+ last_synced_at TEXT,
1511
+ last_cursor TEXT,
1512
+ last_error TEXT,
1513
+ archived_at TEXT,
1514
+ config_json TEXT NOT NULL DEFAULT '{}',
1515
+ created_at TEXT NOT NULL,
1516
+ updated_at TEXT NOT NULL
1517
+ )`,
1518
+ `CREATE INDEX IF NOT EXISTS idx_traffic_sources_project ON traffic_sources(project_id)`,
1519
+ `CREATE INDEX IF NOT EXISTS idx_traffic_sources_project_status ON traffic_sources(project_id, status)`,
1520
+ `CREATE TABLE IF NOT EXISTS crawler_events_hourly (
1521
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
1522
+ source_id TEXT NOT NULL REFERENCES traffic_sources(id) ON DELETE CASCADE,
1523
+ ts_hour TEXT NOT NULL,
1524
+ bot_id TEXT NOT NULL,
1525
+ operator TEXT NOT NULL,
1526
+ verification_status TEXT NOT NULL,
1527
+ path_normalized TEXT NOT NULL,
1528
+ status INTEGER NOT NULL,
1529
+ hits INTEGER NOT NULL DEFAULT 0,
1530
+ sampled_user_agent TEXT,
1531
+ created_at TEXT NOT NULL,
1532
+ updated_at TEXT NOT NULL,
1533
+ PRIMARY KEY (project_id, source_id, ts_hour, bot_id, verification_status, path_normalized, status)
1534
+ )`,
1535
+ `CREATE INDEX IF NOT EXISTS idx_crawler_hourly_project_ts ON crawler_events_hourly(project_id, ts_hour)`,
1536
+ `CREATE INDEX IF NOT EXISTS idx_crawler_hourly_path ON crawler_events_hourly(project_id, path_normalized)`,
1537
+ `CREATE TABLE IF NOT EXISTS ai_referral_events_hourly (
1538
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
1539
+ source_id TEXT NOT NULL REFERENCES traffic_sources(id) ON DELETE CASCADE,
1540
+ ts_hour TEXT NOT NULL,
1541
+ product TEXT NOT NULL,
1542
+ operator TEXT NOT NULL,
1543
+ source_domain TEXT NOT NULL,
1544
+ evidence_type TEXT NOT NULL,
1545
+ landing_path_normalized TEXT NOT NULL,
1546
+ status INTEGER NOT NULL,
1547
+ sessions_or_hits INTEGER NOT NULL DEFAULT 0,
1548
+ users_estimated INTEGER,
1549
+ created_at TEXT NOT NULL,
1550
+ updated_at TEXT NOT NULL,
1551
+ PRIMARY KEY (project_id, source_id, ts_hour, product, source_domain, evidence_type, landing_path_normalized, status)
1552
+ )`,
1553
+ `CREATE INDEX IF NOT EXISTS idx_ai_referral_hourly_project_ts ON ai_referral_events_hourly(project_id, ts_hour)`,
1554
+ `CREATE INDEX IF NOT EXISTS idx_ai_referral_hourly_landing ON ai_referral_events_hourly(project_id, landing_path_normalized)`,
1555
+ `CREATE TABLE IF NOT EXISTS raw_event_samples (
1556
+ id TEXT PRIMARY KEY,
1557
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
1558
+ source_id TEXT NOT NULL REFERENCES traffic_sources(id) ON DELETE CASCADE,
1559
+ ts TEXT NOT NULL,
1560
+ event_type TEXT NOT NULL,
1561
+ ip_hash TEXT,
1562
+ user_agent TEXT,
1563
+ path_normalized TEXT NOT NULL,
1564
+ status INTEGER,
1565
+ referer_host TEXT,
1566
+ classifier_details_json TEXT NOT NULL DEFAULT '{}',
1567
+ created_at TEXT NOT NULL
1568
+ )`,
1569
+ `CREATE INDEX IF NOT EXISTS idx_raw_event_samples_project_ts ON raw_event_samples(project_id, ts)`,
1570
+ `CREATE INDEX IF NOT EXISTS idx_raw_event_samples_source_ts ON raw_event_samples(source_id, ts)`,
1571
+ `CREATE INDEX IF NOT EXISTS idx_raw_event_samples_event_type ON raw_event_samples(event_type)`
1572
+ ]
1402
1573
  }
1403
1574
  ];
1404
1575
  function isDuplicateColumnError(err) {
@@ -3233,6 +3404,10 @@ export {
3233
3404
  backlinkDomains,
3234
3405
  backlinkSummaries,
3235
3406
  agentMemory,
3407
+ trafficSources,
3408
+ crawlerEventsHourly,
3409
+ aiReferralEventsHourly,
3410
+ rawEventSamples,
3236
3411
  createClient,
3237
3412
  parseJsonColumn,
3238
3413
  extractLegacyCredentials,