@coursebuilder/analytics 1.1.1 → 1.1.2-canary.0.0c9beb2ae

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/database.ts","../../src/providers/attribution-recovery.ts"],"sourcesContent":["import {\n\tand,\n\tcount,\n\tdesc,\n\teq,\n\tgt,\n\tgte,\n\tinArray,\n\tlte,\n\tsql,\n\tsum,\n} from 'drizzle-orm'\n\nimport { SHORTLINK_RECOVERY_LANE } from './attribution-recovery'\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type AnalyticsTimeRange = '24h' | '7d' | '30d' | '90d' | 'all'\n\nexport interface AttributionTrailEvent {\n\ttype: 'click' | 'signup' | 'progress' | 'purchase'\n\ttimestamp: Date\n\tdetail: Record<string, any>\n}\n\nexport interface AttributionTrail {\n\tuser: {\n\t\tid: string\n\t\temail: string | null\n\t\tname: string | null\n\t\tcreatedAt: Date\n\t} | null\n\tevents: AttributionTrailEvent[]\n\tpurchases: {\n\t\tid: string\n\t\ttotalAmount: number\n\t\tproductName: string\n\t\tcreatedAt: Date\n\t\tcountry: string | null\n\t\tutmSource: string | null\n\t\tutmMedium: string | null\n\t\tutmCampaign: string | null\n\t}[]\n}\n\n// ─── Schema type ─────────────────────────────────────────────────────────────\n\nexport interface DatabaseAnalyticsSchema {\n\tpurchases: any\n\tproducts: any\n\tusers: any\n\tcoupon: any\n\tresourceProgress: any\n\tshortlink: any\n\tshortlinkAttribution: any\n\tshortlinkClick: any\n\tquestionResponse?: any\n\tcontactEvent?: any\n\tsideEffectIntent?: any\n}\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\n/**\n * Creates a database analytics provider that wraps all analytics query\n * functions with an injected drizzle db instance and schema tables.\n *\n * @param db - Drizzle database instance\n * @param schema - Object containing the required table references\n */\nexport function createDatabaseProvider(\n\tdb: any,\n\tschema: DatabaseAnalyticsSchema,\n) {\n\tconst {\n\t\tpurchases,\n\t\tproducts,\n\t\tusers,\n\t\tcoupon,\n\t\tresourceProgress,\n\t\tshortlink,\n\t\tshortlinkAttribution,\n\t\tshortlinkClick,\n\t\tquestionResponse,\n\t\tcontactEvent,\n\t\tsideEffectIntent,\n\t} = schema\n\n\t// ─── Internal helpers ───────────────────────────────────────────────────\n\n\tconst PAID_STATUSES = ['Valid', 'Restricted'] as const\n\n\tfunction commerceRecord() {\n\t\treturn inArray(purchases.status, [...PAID_STATUSES])\n\t}\n\n\tfunction paidPurchase() {\n\t\treturn and(commerceRecord(), gt(purchases.totalAmount, 0))\n\t}\n\n\tfunction accessGrant() {\n\t\treturn and(commerceRecord(), sql`${purchases.totalAmount} = 0`)\n\t}\n\n\tfunction backfillFreeUpgrade() {\n\t\treturn and(\n\t\t\taccessGrant(),\n\t\t\tsql`JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'`,\n\t\t)\n\t}\n\n\tconst syntheticSignalSql = sql`(\n\t\tJSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.synthetic')) = 'true'\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.synthetic')) = 'true'\n\t\tOR JSON_SEARCH(JSON_EXTRACT(${purchases.fields}, '$.attribution.clickIds'), 'one', 'TEST_%') IS NOT NULL\n\t)`\n\n\tfunction syntheticPurchase() {\n\t\treturn and(commerceRecord(), syntheticSignalSql)\n\t}\n\n\tconst purchaseFieldAttributionSignalSql = sql`(\n\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution') IS NOT NULL\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')) IS NOT NULL\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.gaClientId')) IS NOT NULL\n\t)`\n\n\tconst exactShortlinkPurchaseAttributionSignalSql = sql`EXISTS (\n\t\tSELECT 1\n\t\tFROM ${shortlinkAttribution}\n\t\tWHERE ${shortlinkAttribution.type} = 'purchase'\n\t\t\tAND JSON_VALID(${shortlinkAttribution.metadata})\n\t\t\tAND JSON_UNQUOTE(JSON_EXTRACT(${shortlinkAttribution.metadata}, '$.purchaseId')) = ${purchases.id}\n\t)`\n\n\tconst shortlinkRecoveredAttributionSignalSql = sql`(\n\t\tNOT ${purchaseFieldAttributionSignalSql}\n\t\tAND ${exactShortlinkPurchaseAttributionSignalSql}\n\t)`\n\n\tconst attributionSignalSql = sql`(\n\t\t${purchaseFieldAttributionSignalSql}\n\t\tOR ${exactShortlinkPurchaseAttributionSignalSql}\n\t)`\n\n\tfunction rangeToDate(range: AnalyticsTimeRange): Date | null {\n\t\tif (range === 'all') return null\n\t\tconst now = new Date()\n\t\tconst hours: Record<string, number> = {\n\t\t\t'24h': 24,\n\t\t\t'7d': 7 * 24,\n\t\t\t'30d': 30 * 24,\n\t\t\t'90d': 90 * 24,\n\t\t}\n\t\treturn new Date(now.getTime() - (hours[range] ?? 30 * 24) * 60 * 60 * 1000)\n\t}\n\n\t// ─── Revenue ───────────────────────────────────────────────────────────\n\n\tasync function getRevenueSummary(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst [totals] = await db\n\t\t\t.select({\n\t\t\t\ttotalRevenue: sum(purchases.totalAmount),\n\t\t\t\tpurchaseCount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\n\t\treturn {\n\t\t\ttotalRevenue: Number(totals?.totalRevenue ?? 0),\n\t\t\tpurchaseCount: totals?.purchaseCount ?? 0,\n\t\t\tavgOrderValue:\n\t\t\t\ttotals?.purchaseCount && totals.purchaseCount > 0\n\t\t\t\t\t? Number(totals.totalRevenue ?? 0) / totals.purchaseCount\n\t\t\t\t\t: 0,\n\t\t}\n\t}\n\n\tasync function getRevenueByDay(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tdate: sql<string>`DATE(${purchases.createdAt})`.as('date'),\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(sql`DATE(${purchases.createdAt})`)\n\t\t\t.orderBy(sql`DATE(${purchases.createdAt})`)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tdate: r.date,\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\t/**\n\t * Revenue by day for the previous period of equal length.\n\t * E.g., if range = '30d', returns the 30 days before those 30 days.\n\t * Returns data with a `dayOffset` (0 = start of period) for overlay\n\t * alignment.\n\t */\n\tasync function getPreviousPeriodRevenueByDay(\n\t\trange: AnalyticsTimeRange = '30d',\n\t) {\n\t\tif (range === 'all') return []\n\n\t\tconst hours: Record<string, number> = {\n\t\t\t'24h': 24,\n\t\t\t'7d': 7 * 24,\n\t\t\t'30d': 30 * 24,\n\t\t\t'90d': 90 * 24,\n\t\t}\n\t\tconst periodMs = (hours[range] ?? 30 * 24) * 60 * 60 * 1000\n\t\tconst now = new Date()\n\t\tconst periodStart = new Date(now.getTime() - periodMs)\n\t\tconst prevStart = new Date(periodStart.getTime() - periodMs)\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tdate: sql<string>`DATE(${purchases.createdAt})`.as('date'),\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\tpaidPurchase(),\n\t\t\t\t\tgte(purchases.createdAt, prevStart),\n\t\t\t\t\tlte(purchases.createdAt, periodStart),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.groupBy(sql`DATE(${purchases.createdAt})`)\n\t\t\t.orderBy(sql`DATE(${purchases.createdAt})`)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tdate: r.date,\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getRevenueByProduct(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tproductId: purchases.productId,\n\t\t\t\tproductName: products.name,\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(purchases.productId, products.name)\n\t\t\t.orderBy(desc(sum(purchases.totalAmount)))\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tproductId: r.productId,\n\t\t\tproductName: r.productName ?? '(unknown)',\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getRevenueByCountry(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tcountry: purchases.country,\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(purchases.country)\n\t\t\t.orderBy(desc(sum(purchases.totalAmount)))\n\t\t\t.limit(20)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tcountry: r.country ?? '(unknown)',\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getRecentPurchases(\n\t\tlimit: number = 20,\n\t\tfilter: 'all' | 'team' | 'individual' = 'all',\n\t\trange: AnalyticsTimeRange = 'all',\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tif (filter === 'team') {\n\t\t\t// Multi-seat purchases: join coupon to filter seats > 1, sort by amount\n\t\t\tconditions.push(sql`${purchases.bulkCouponId} IS NOT NULL`)\n\n\t\t\tconst rows = await db\n\t\t\t\t.select({\n\t\t\t\t\tid: purchases.id,\n\t\t\t\t\tcreatedAt: purchases.createdAt,\n\t\t\t\t\ttotalAmount: purchases.totalAmount,\n\t\t\t\t\tproductName: products.name,\n\t\t\t\t\tproductId: purchases.productId,\n\t\t\t\t\tcountry: purchases.country,\n\t\t\t\t\tcouponId: purchases.couponId,\n\t\t\t\t\tuserId: purchases.userId,\n\t\t\t\t\tuserName: users.name,\n\t\t\t\t\tuserEmail: users.email,\n\t\t\t\t\torganizationId: purchases.organizationId,\n\t\t\t\t\tseats: coupon.maxUses,\n\t\t\t\t})\n\t\t\t\t.from(purchases)\n\t\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t\t.leftJoin(users, eq(purchases.userId, users.id))\n\t\t\t\t.leftJoin(coupon, eq(purchases.bulkCouponId, coupon.id))\n\t\t\t\t.where(and(...conditions, gt(coupon.maxUses, 1)))\n\t\t\t\t.orderBy(desc(purchases.totalAmount))\n\t\t\t\t.limit(limit)\n\n\t\t\treturn rows.map((r: any) => ({\n\t\t\t\tid: r.id,\n\t\t\t\tcreatedAt: r.createdAt,\n\t\t\t\ttotalAmount: Number(r.totalAmount),\n\t\t\t\tproductName: r.productName ?? '(unknown)',\n\t\t\t\tproductId: r.productId,\n\t\t\t\tcountry: r.country,\n\t\t\t\tcouponId: r.couponId,\n\t\t\t\tuserName: r.userName ?? null,\n\t\t\t\tuserEmail: r.userEmail ?? null,\n\t\t\t\tisTeam: true,\n\t\t\t\tseats: r.seats ?? null,\n\t\t\t}))\n\t\t}\n\n\t\tif (filter === 'individual') {\n\t\t\tconditions.push(sql`${purchases.bulkCouponId} IS NULL`)\n\t\t}\n\n\t\tconst rows = await db.query.purchases.findMany({\n\t\t\twhere: and(...conditions),\n\t\t\torderBy: [desc(purchases.totalAmount)],\n\t\t\tlimit,\n\t\t\twith: {\n\t\t\t\tproduct: true,\n\t\t\t\tuser: true,\n\t\t\t},\n\t\t})\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tid: r.id,\n\t\t\tcreatedAt: r.createdAt,\n\t\t\ttotalAmount: Number(r.totalAmount),\n\t\t\tproductName: r.product?.name ?? '(unknown)',\n\t\t\tproductId: r.productId,\n\t\t\tcountry: r.country,\n\t\t\tcouponId: r.couponId,\n\t\t\tuserName: r.user?.name ?? null,\n\t\t\tuserEmail: r.user?.email ?? null,\n\t\t\tisTeam: r.organizationId != null,\n\t\t\tseats: null as number | null,\n\t\t}))\n\t}\n\n\t// ─── Attribution ────────────────────────────────────────────────────────\n\n\tasync function getAttributionSummary(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions: any[] = []\n\t\tif (since) conditions.push(gte(shortlinkAttribution.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\ttype: shortlinkAttribution.type,\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(shortlinkAttribution)\n\t\t\t.where(conditions.length > 0 ? and(...conditions) : undefined)\n\t\t\t.groupBy(shortlinkAttribution.type)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\ttype: r.type,\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getShortlinkPerformance(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst clickConditions: any[] = []\n\t\tif (since) clickConditions.push(gte(shortlinkClick.timestamp, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tshortlinkId: shortlinkClick.shortlinkId,\n\t\t\t\tslug: shortlink.slug,\n\t\t\t\turl: shortlink.url,\n\t\t\t\tclicks: count(),\n\t\t\t})\n\t\t\t.from(shortlinkClick)\n\t\t\t.innerJoin(shortlink, eq(shortlinkClick.shortlinkId, shortlink.id))\n\t\t\t.where(clickConditions.length > 0 ? and(...clickConditions) : undefined)\n\t\t\t.groupBy(shortlinkClick.shortlinkId, shortlink.slug, shortlink.url)\n\t\t\t.orderBy(desc(count()))\n\t\t\t.limit(20)\n\n\t\t// Get attribution counts per shortlink\n\t\tconst attrConditions: any[] = []\n\t\tif (since) attrConditions.push(gte(shortlinkAttribution.createdAt, since))\n\n\t\tconst attrRows = await db\n\t\t\t.select({\n\t\t\t\tshortlinkId: shortlinkAttribution.shortlinkId,\n\t\t\t\ttype: shortlinkAttribution.type,\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(shortlinkAttribution)\n\t\t\t.where(attrConditions.length > 0 ? and(...attrConditions) : undefined)\n\t\t\t.groupBy(shortlinkAttribution.shortlinkId, shortlinkAttribution.type)\n\n\t\tconst attrMap = new Map<string, { signups: number; purchases: number }>()\n\t\tfor (const a of attrRows) {\n\t\t\tconst existing = attrMap.get(a.shortlinkId) ?? {\n\t\t\t\tsignups: 0,\n\t\t\t\tpurchases: 0,\n\t\t\t}\n\t\t\tif (a.type === 'signup') existing.signups = a.count\n\t\t\tif (a.type === 'purchase') existing.purchases = a.count\n\t\t\tattrMap.set(a.shortlinkId, existing)\n\t\t}\n\n\t\treturn rows.map((r: any) => {\n\t\t\tconst attr = attrMap.get(r.shortlinkId)\n\t\t\treturn {\n\t\t\t\tshortlinkId: r.shortlinkId,\n\t\t\t\tslug: r.slug,\n\t\t\t\turl: r.url,\n\t\t\t\tclicks: r.clicks,\n\t\t\t\tsignups: attr?.signups ?? 0,\n\t\t\t\tpurchases: attr?.purchases ?? 0,\n\t\t\t}\n\t\t})\n\t}\n\n\t// ─── Revenue Attribution ─────────────────────────────────────────────────\n\n\tasync function getRevenueBySource(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [commerceRecord()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId)\n\t\t\tconditions.push(eq(purchases.productId, filters.productId))\n\n\t\tconst kindExpr = sql<string>`CASE\n\t\t\tWHEN ${syntheticSignalSql} THEN 'synthetic'\n\t\t\tWHEN ${purchases.totalAmount} = 0 THEN 'access_grant'\n\t\t\tWHEN ${purchases.totalAmount} > 0 THEN 'paid_conversion'\n\t\t\tELSE 'unknown'\n\t\tEND`\n\t\tconst sourceExpr = sql<string>`CASE\n\t\t\tWHEN JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'\n\t\t\t\tTHEN 'internal'\n\t\t\tWHEN ${shortlinkRecoveredAttributionSignalSql} THEN ${SHORTLINK_RECOVERY_LANE}\n\t\t\tELSE COALESCE(\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.source')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.utm.source')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')), 'null'),\n\t\t\t\tCASE\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug') IS NOT NULL THEN 'shortlink'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL THEN 'self_reported'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL THEN 'ga4'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.gaClientId') IS NOT NULL THEN 'ga4'\n\t\t\t\t\tELSE NULL\n\t\t\t\tEND\n\t\t\t)\n\t\tEND`\n\t\tconst mediumExpr = sql<string>`CASE\n\t\t\tWHEN JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'\n\t\t\t\tTHEN 'free_upgrade'\n\t\t\tWHEN ${shortlinkRecoveredAttributionSignalSql} THEN 'shortlink'\n\t\t\tELSE COALESCE(\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.medium')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.utm.medium')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmMedium')), 'null'),\n\t\t\t\tCASE\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug') IS NOT NULL THEN 'shortlink'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL THEN 'checkout_survey'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL THEN 'client_id'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.gaClientId') IS NOT NULL THEN 'client_id'\n\t\t\t\t\tELSE NULL\n\t\t\t\tEND\n\t\t\t)\n\t\tEND`\n\t\tconst campaignExpr = sql<string>`CASE\n\t\t\tWHEN JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'\n\t\t\t\tTHEN COALESCE(\n\t\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.migrationBatchId')), 'null'),\n\t\t\t\t\t'free_upgrade'\n\t\t\t\t)\n\t\t\tWHEN ${shortlinkRecoveredAttributionSignalSql} THEN NULL\n\t\t\tELSE COALESCE(\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.campaign')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.utm.campaign')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmCampaign')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource')), 'null')\n\t\t\t)\n\t\tEND`\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tkind: kindExpr.as('kind'),\n\t\t\t\tsource: sourceExpr.as('source'),\n\t\t\t\tmedium: mediumExpr.as('medium'),\n\t\t\t\tcampaign: campaignExpr.as('campaign'),\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(sql`1`, sql`2`, sql`3`, sql`4`)\n\t\t\t.orderBy(desc(sum(purchases.totalAmount)), desc(count()))\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tkind: r.kind ?? 'unknown',\n\t\t\tsource: r.source ?? null,\n\t\t\tmedium: r.medium ?? null,\n\t\t\tcampaign: r.campaign ?? null,\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getConversionFunnel(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\n\t\tconst userConditions = since ? [gte(users.createdAt, since)] : []\n\t\tconst purchaseConditions = [paidPurchase()]\n\t\tif (since) purchaseConditions.push(gte(purchases.createdAt, since))\n\n\t\tconst [userCount] = await db\n\t\t\t.select({ total: count() })\n\t\t\t.from(users)\n\t\t\t.where(userConditions.length > 0 ? and(...userConditions) : undefined)\n\n\t\tconst [purchaseCount] = await db\n\t\t\t.select({ total: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions))\n\n\t\tconst [attributedCount] = await db\n\t\t\t.select({ total: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions, attributionSignalSql))\n\n\t\tconst totalSignups = userCount?.total ?? 0\n\t\tconst totalPurchases = purchaseCount?.total ?? 0\n\t\tconst attributedPurchases = attributedCount?.total ?? 0\n\n\t\treturn {\n\t\t\ttotalSignups,\n\t\t\ttotalPurchases,\n\t\t\tattributedPurchases,\n\t\t\tconversionRate: totalSignups > 0 ? totalPurchases / totalSignups : 0,\n\t\t\tattributionCoverage:\n\t\t\t\ttotalPurchases > 0 ? attributedPurchases / totalPurchases : 0,\n\t\t}\n\t}\n\n\tasync function getCommerceLaneSummary(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [commerceRecord()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId)\n\t\t\tconditions.push(eq(purchases.productId, filters.productId))\n\n\t\tconst [commerce] = await db\n\t\t\t.select({ count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\tconst [paid] = await db\n\t\t\t.select({ count: count(), revenue: sum(purchases.totalAmount) })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, paidPurchase()))\n\t\tconst [grants] = await db\n\t\t\t.select({ count: count(), revenue: sum(purchases.totalAmount) })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, accessGrant()))\n\t\tconst [freeUpgrades] = await db\n\t\t\t.select({ count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, backfillFreeUpgrade()))\n\t\tconst [synthetic] = await db\n\t\t\t.select({ count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, syntheticPurchase()))\n\t\tconst reasonRows = await db\n\t\t\t.select({\n\t\t\t\treason: sql<string>`COALESCE(\n\t\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfillReason')), 'null'),\n\t\t\t\t\t'access_grant'\n\t\t\t\t)`.as('reason'),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, accessGrant()))\n\t\t\t.groupBy(\n\t\t\t\tsql`COALESCE(\n\t\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfillReason')), 'null'),\n\t\t\t\t\t'access_grant'\n\t\t\t\t)`,\n\t\t\t)\n\n\t\treturn {\n\t\t\tcommerceRecords: commerce?.count ?? 0,\n\t\t\tpaidPurchases: paid?.count ?? 0,\n\t\t\tpaidRevenue: Number(paid?.revenue ?? 0),\n\t\t\taccessGrants: grants?.count ?? 0,\n\t\t\taccessGrantRevenue: Number(grants?.revenue ?? 0),\n\t\t\tfreeUpgrades: freeUpgrades?.count ?? 0,\n\t\t\tsyntheticPurchases: synthetic?.count ?? 0,\n\t\t\tbyAccessGrantReason: Object.fromEntries(\n\t\t\t\treasonRows.map((row: any) => [row.reason, row.count]),\n\t\t\t),\n\t\t}\n\t}\n\n\tasync function getAttributedRevenueSummary(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId)\n\t\t\tconditions.push(eq(purchases.productId, filters.productId))\n\n\t\tconst [totals] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\n\t\tconst [attributed] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, attributionSignalSql))\n\n\t\tconst [purchaseFieldAttributed] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, purchaseFieldAttributionSignalSql))\n\n\t\tconst [recoveredFromShortlinkAttributionTable] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, shortlinkRecoveredAttributionSignalSql))\n\n\t\tconst signalConditions = since\n\t\t\t? [commerceRecord(), gte(purchases.createdAt, since)]\n\t\t\t: [commerceRecord()]\n\t\tif (filters.productId) {\n\t\t\tsignalConditions.push(eq(purchases.productId, filters.productId))\n\t\t}\n\t\tconst signalCount = async (condition: any) => {\n\t\t\tconst [row] = await db\n\t\t\t\t.select({ count: count() })\n\t\t\t\t.from(purchases)\n\t\t\t\t.where(and(...signalConditions, condition))\n\t\t\treturn row?.count ?? 0\n\t\t}\n\t\tconst [\n\t\t\tshortlinkCount,\n\t\t\tutmCount,\n\t\t\tclickIdCount,\n\t\t\tgaClientIdCount,\n\t\t\tselfReportedSourceCount,\n\t\t\trecoveredFromShortlinkAttributionTableCount,\n\t\t] = await Promise.all([\n\t\t\tsignalCount(\n\t\t\t\tsql`(\n\t\t\t\t\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug') IS NOT NULL\n\t\t\t\t\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.shortlinkRef')) IS NOT NULL\n\t\t\t\t\t)`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`(\n\t\t\t\t\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.utm') IS NOT NULL\n\t\t\t\t\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')) IS NOT NULL\n\t\t\t\t\t)`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`JSON_EXTRACT(${purchases.fields}, '$.attribution.clickIds') IS NOT NULL`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`(\n\t\t\t\t\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL\n\t\t\t\t\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.gaClientId')) IS NOT NULL\n\t\t\t\t\t)`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL`,\n\t\t\t),\n\t\t\tsignalCount(shortlinkRecoveredAttributionSignalSql),\n\t\t])\n\n\t\tconst commerce = await getCommerceLaneSummary(range, filters)\n\t\tconst totalRevenue = Number(totals?.total ?? 0)\n\t\tconst attributedRevenue = Number(attributed?.total ?? 0)\n\t\tconst purchaseFieldAttributedRevenue = Number(\n\t\t\tpurchaseFieldAttributed?.total ?? 0,\n\t\t)\n\t\tconst recoveredFromShortlinkAttributionTableRevenue = Number(\n\t\t\trecoveredFromShortlinkAttributionTable?.total ?? 0,\n\t\t)\n\t\tconst unattributedRevenue = totalRevenue - attributedRevenue\n\t\tconst paidPurchases = totals?.count ?? 0\n\n\t\treturn {\n\t\t\ttotalRevenue,\n\t\t\tattributedRevenue,\n\t\t\tunattributedRevenue,\n\t\t\tattributionRate: totalRevenue > 0 ? attributedRevenue / totalRevenue : 0,\n\t\t\ttotalPurchases: commerce.commerceRecords,\n\t\t\tpaidPurchases,\n\t\t\tpurchaseFieldAttributedPurchases: purchaseFieldAttributed?.count ?? 0,\n\t\t\tpurchaseFieldAttributedRevenue,\n\t\t\trecoveredFromShortlinkAttributionTablePurchases:\n\t\t\t\trecoveredFromShortlinkAttributionTable?.count ?? 0,\n\t\t\trecoveredFromShortlinkAttributionTableRevenue,\n\t\t\tcommerceRecords: commerce.commerceRecords,\n\t\t\taccessGrants: commerce.accessGrants,\n\t\t\tfreeUpgrades: commerce.freeUpgrades,\n\t\t\tsyntheticPurchases: commerce.syntheticPurchases,\n\t\t\tcommerce,\n\t\t\tsignals: {\n\t\t\t\tshortlink: shortlinkCount,\n\t\t\t\tutm: utmCount,\n\t\t\t\tpaidClickId: clickIdCount,\n\t\t\t\tgaClientId: gaClientIdCount,\n\t\t\t\tselfReportedSource: selfReportedSourceCount,\n\t\t\t\trecoveredFromShortlinkAttributionTable:\n\t\t\t\t\trecoveredFromShortlinkAttributionTableCount,\n\t\t\t\tinternalFreeUpgrade: commerce.freeUpgrades,\n\t\t\t},\n\t\t}\n\t}\n\n\tasync function getContentPurchaseCorrelation(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tlimit: number = 20,\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst purchaseConditions = [paidPurchase()]\n\t\tif (since) purchaseConditions.push(gte(purchases.createdAt, since))\n\n\t\tconst purchaserRows = await db\n\t\t\t.selectDistinct({ userId: purchases.userId })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions))\n\n\t\tconst purchaserIds = purchaserRows\n\t\t\t.map((r: any) => r.userId)\n\t\t\t.filter((id: any): id is string => id !== null)\n\n\t\tif (purchaserIds.length === 0) return []\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tresourceId: resourceProgress.resourceId,\n\t\t\t\tpurchaserCount: count(),\n\t\t\t})\n\t\t\t.from(resourceProgress)\n\t\t\t.where(\n\t\t\t\tsql`${resourceProgress.userId} IN (${sql.join(\n\t\t\t\t\tpurchaserIds.map((id: string) => sql`${id}`),\n\t\t\t\t\tsql`, `,\n\t\t\t\t)})`,\n\t\t\t)\n\t\t\t.groupBy(resourceProgress.resourceId)\n\t\t\t.orderBy(desc(count()))\n\t\t\t.limit(limit)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tresourceId: r.resourceId,\n\t\t\tpurchaserCount: r.purchaserCount,\n\t\t}))\n\t}\n\n\t/**\n\t * Parses an unknown JSON-like value into a plain record.\n\t *\n\t * @param value Unknown input value from a JSON database column.\n\t * @returns A Record<string, any> when the value is a record, otherwise an empty object.\n\t */\n\tfunction parseJsonRecord(value: unknown): Record<string, any> {\n\t\treturn Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n\t\t\t? (value as Record<string, any>)\n\t\t\t: {}\n\t}\n\n\t/**\n\t * Checks whether a record contains at least one non-empty string value.\n\t *\n\t * @param value Unknown input value to inspect.\n\t * @returns True when at least one record value is a non-empty string.\n\t */\n\tfunction hasRecordValue(value: unknown) {\n\t\treturn (\n\t\t\tBoolean(value) &&\n\t\t\ttypeof value === 'object' &&\n\t\t\t!Array.isArray(value) &&\n\t\t\tObject.values(value as Record<string, unknown>).some(\n\t\t\t\t(entry) => typeof entry === 'string' && entry.length > 0,\n\t\t\t)\n\t\t)\n\t}\n\n\t/**\n\t * Checks whether a click ID record contains a synthetic TEST_ value.\n\t *\n\t * @param value Unknown input value to inspect.\n\t * @returns True when any record value is a string starting with TEST_.\n\t */\n\tfunction hasSyntheticClickId(value: unknown) {\n\t\treturn (\n\t\t\tBoolean(value) &&\n\t\t\ttypeof value === 'object' &&\n\t\t\t!Array.isArray(value) &&\n\t\t\tObject.values(value as Record<string, unknown>).some(\n\t\t\t\t(entry) => typeof entry === 'string' && entry.startsWith('TEST_'),\n\t\t\t)\n\t\t)\n\t}\n\n\tasync function getCheckoutAttributionReceipt(opts: { purchaseId?: string }) {\n\t\tif (!opts.purchaseId) {\n\t\t\treturn {\n\t\t\t\tpurchase: null,\n\t\t\t\tchecks: {\n\t\t\t\t\tpurchaseFound: false,\n\t\t\t\t\tattributionSnapshot: false,\n\t\t\t\t\tutm: false,\n\t\t\t\t\tactualUtm: false,\n\t\t\t\t\tclickId: false,\n\t\t\t\t\tsynthetic: false,\n\t\t\t\t\tshortlink: false,\n\t\t\t\t\tselfReportedSource: false,\n\t\t\t\t\tgaClientId: false,\n\t\t\t\t},\n\t\t\t\tattribution: null,\n\t\t\t\tlegacy: {},\n\t\t\t\tfieldKeys: [],\n\t\t\t}\n\t\t}\n\n\t\tconst [row] = await db\n\t\t\t.select({\n\t\t\t\tid: purchases.id,\n\t\t\t\tcreatedAt: purchases.createdAt,\n\t\t\t\tproductId: purchases.productId,\n\t\t\t\tproductName: products.name,\n\t\t\t\ttotalAmount: purchases.totalAmount,\n\t\t\t\tstatus: purchases.status,\n\t\t\t\tcountry: purchases.country,\n\t\t\t\tfields: purchases.fields,\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t.where(eq(purchases.id, opts.purchaseId))\n\t\t\t.limit(1)\n\n\t\tif (!row) {\n\t\t\treturn {\n\t\t\t\tpurchase: null,\n\t\t\t\tchecks: {\n\t\t\t\t\tpurchaseFound: false,\n\t\t\t\t\tattributionSnapshot: false,\n\t\t\t\t\tutm: false,\n\t\t\t\t\tactualUtm: false,\n\t\t\t\t\tclickId: false,\n\t\t\t\t\tsynthetic: false,\n\t\t\t\t\tshortlink: false,\n\t\t\t\t\tselfReportedSource: false,\n\t\t\t\t\tgaClientId: false,\n\t\t\t\t},\n\t\t\t\tattribution: null,\n\t\t\t\tlegacy: {},\n\t\t\t\tfieldKeys: [],\n\t\t\t}\n\t\t}\n\n\t\tconst fields = parseJsonRecord(row.fields)\n\t\tconst attribution = parseJsonRecord(fields.attribution)\n\t\tconst utm = parseJsonRecord(attribution.utm)\n\t\tconst clickIds = parseJsonRecord(attribution.clickIds)\n\t\tconst shortlinkSnapshot = parseJsonRecord(attribution.shortlink)\n\t\tconst ga = parseJsonRecord(attribution.ga)\n\t\tconst legacy = Object.fromEntries(\n\t\t\t[\n\t\t\t\t'utmSource',\n\t\t\t\t'utmMedium',\n\t\t\t\t'utmCampaign',\n\t\t\t\t'gaClientId',\n\t\t\t\t'shortlinkRef',\n\t\t\t\t'landingPath',\n\t\t\t\t'referrer',\n\t\t\t\t'ltUtmSource',\n\t\t\t\t'ltUtmMedium',\n\t\t\t\t'ltUtmCampaign',\n\t\t\t]\n\t\t\t\t.map((key) => [key, fields[key]])\n\t\t\t\t.filter(([, value]) => value !== undefined && value !== null),\n\t\t)\n\t\tconst hasActualUtm = Boolean(\n\t\t\tutm.source || utm.medium || utm.campaign || fields.utmSource,\n\t\t)\n\t\tconst synthetic = Boolean(\n\t\t\tattribution.synthetic ||\n\t\t\tfields.synthetic ||\n\t\t\thasSyntheticClickId(clickIds),\n\t\t)\n\n\t\treturn {\n\t\t\tpurchase: {\n\t\t\t\tid: row.id,\n\t\t\t\tcreatedAt: row.createdAt,\n\t\t\t\tproductId: row.productId,\n\t\t\t\tproductName: row.productName ?? null,\n\t\t\t\ttotalAmount: Number(row.totalAmount ?? 0),\n\t\t\t\tstatus: row.status,\n\t\t\t\tcountry: row.country,\n\t\t\t},\n\t\t\tchecks: {\n\t\t\t\tpurchaseFound: true,\n\t\t\t\tattributionSnapshot: Object.keys(attribution).length > 0,\n\t\t\t\tutm: hasActualUtm,\n\t\t\t\tactualUtm: hasActualUtm,\n\t\t\t\tclickId: hasRecordValue(clickIds),\n\t\t\t\tsynthetic,\n\t\t\t\tshortlink: Boolean(shortlinkSnapshot.slug || fields.shortlinkRef),\n\t\t\t\tselfReportedSource: Boolean(attribution.selfReportedSource),\n\t\t\t\tgaClientId: Boolean(ga.clientId || fields.gaClientId),\n\t\t\t},\n\t\t\tattribution: Object.keys(attribution).length > 0 ? attribution : null,\n\t\t\tlegacy,\n\t\t\tfieldKeys: Object.keys(fields).sort(),\n\t\t}\n\t}\n\n\tasync function getCheckoutSurveyFallbackReport(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tlimit: number = 20,\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst label = 'recovered_from_checkout_survey_response'\n\t\tif (!questionResponse) {\n\t\t\treturn {\n\t\t\t\tlabel,\n\t\t\t\tproductId: filters.productId ?? null,\n\t\t\t\ttotalDarkPurchases: 0,\n\t\t\t\ttotalDarkRevenue: 0,\n\t\t\t\texactPurchaseLinkedPurchases: 0,\n\t\t\t\texactPurchaseLinkedRevenue: 0,\n\t\t\t\tuserLinkedPurchases: 0,\n\t\t\t\tuserLinkedRevenue: 0,\n\t\t\t\tbyAnswer: [],\n\t\t\t\tnotes: ['questionResponse table was not provided to this provider'],\n\t\t\t}\n\t\t}\n\n\t\tconst since = rangeToDate(range)\n\t\tconst purchaseConditions = [\n\t\t\tpaidPurchase(),\n\t\t\tsql`NOT ${attributionSignalSql}`,\n\t\t]\n\t\tif (since) purchaseConditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId) {\n\t\t\tpurchaseConditions.push(eq(purchases.productId, filters.productId))\n\t\t}\n\n\t\tconst darkRows = await db\n\t\t\t.select({\n\t\t\t\tid: purchases.id,\n\t\t\t\tuserId: purchases.userId,\n\t\t\t\trevenue: purchases.totalAmount,\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions))\n\n\t\tconst totalDarkRevenue = darkRows.reduce(\n\t\t\t(total: number, row: any) => total + Number(row.revenue ?? 0),\n\t\t\t0,\n\t\t)\n\n\t\tif (darkRows.length === 0) {\n\t\t\treturn {\n\t\t\t\tlabel,\n\t\t\t\tproductId: filters.productId ?? null,\n\t\t\t\ttotalDarkPurchases: 0,\n\t\t\t\ttotalDarkRevenue: 0,\n\t\t\t\texactPurchaseLinkedPurchases: 0,\n\t\t\t\texactPurchaseLinkedRevenue: 0,\n\t\t\t\tuserLinkedPurchases: 0,\n\t\t\t\tuserLinkedRevenue: 0,\n\t\t\t\tbyAnswer: [],\n\t\t\t\tnotes: ['No dark paid purchases matched the filters'],\n\t\t\t}\n\t\t}\n\n\t\tconst darkById = new Map<string, (typeof darkRows)[number]>(\n\t\t\tdarkRows.map((row: (typeof darkRows)[number]) => [row.id, row]),\n\t\t)\n\t\tconst darkByUserId = new Map<string, any[]>()\n\t\tfor (const row of darkRows) {\n\t\t\tif (!row.userId) continue\n\t\t\tconst bucket = darkByUserId.get(row.userId) ?? []\n\t\t\tbucket.push(row)\n\t\t\tdarkByUserId.set(row.userId, bucket)\n\t\t}\n\n\t\tconst responseConditions: any[] = []\n\t\tif (since) responseConditions.push(gte(questionResponse.createdAt, since))\n\t\tconst darkIds = [...darkById.keys()]\n\t\tconst darkUserIds = [...darkByUserId.keys()]\n\t\tconst exactPurchaseCondition = sql`JSON_UNQUOTE(JSON_EXTRACT(${questionResponse.fields}, '$.purchaseId')) IN (${sql.join(\n\t\t\tdarkIds.map((id) => sql`${id}`),\n\t\t\tsql`, `,\n\t\t)})`\n\t\tconst userCondition =\n\t\t\tdarkUserIds.length > 0\n\t\t\t\t? sql`${questionResponse.userId} IN (${sql.join(\n\t\t\t\t\t\tdarkUserIds.map((id) => sql`${id}`),\n\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t)})`\n\t\t\t\t: sql`FALSE`\n\t\tresponseConditions.push(\n\t\t\tsql`(${exactPurchaseCondition} OR ${userCondition})`,\n\t\t)\n\n\t\tconst responseRows = await db\n\t\t\t.select({\n\t\t\t\tpurchaseId: sql<string>`JSON_UNQUOTE(JSON_EXTRACT(${questionResponse.fields}, '$.purchaseId'))`,\n\t\t\t\tanswer: sql<string>`JSON_UNQUOTE(JSON_EXTRACT(${questionResponse.fields}, '$.answer'))`,\n\t\t\t\tuserId: questionResponse.userId,\n\t\t\t\tcreatedAt: questionResponse.createdAt,\n\t\t\t})\n\t\t\t.from(questionResponse)\n\t\t\t.where(and(...responseConditions))\n\n\t\tconst exactByPurchase = new Map<string, any>()\n\t\tconst latestByUser = new Map<string, any>()\n\t\tfor (const row of responseRows) {\n\t\t\tif (row.purchaseId && darkById.has(row.purchaseId)) {\n\t\t\t\texactByPurchase.set(row.purchaseId, row)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!row.userId) continue\n\t\t\tconst current = latestByUser.get(row.userId)\n\t\t\tconst rowTime = new Date(row.createdAt ?? 0).getTime()\n\t\t\tconst currentTime = current\n\t\t\t\t? new Date(current.createdAt ?? 0).getTime()\n\t\t\t\t: -1\n\t\t\tif (!current || rowTime >= currentTime) latestByUser.set(row.userId, row)\n\t\t}\n\n\t\tconst classified = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tconfidence: 'exact_purchase_link' | 'user_linked'\n\t\t\t\tanswer: string\n\t\t\t\trevenue: number\n\t\t\t}\n\t\t>()\n\t\tfor (const [purchaseId, response] of exactByPurchase) {\n\t\t\tconst purchase = darkById.get(purchaseId)\n\t\t\tclassified.set(purchaseId, {\n\t\t\t\tconfidence: 'exact_purchase_link',\n\t\t\t\tanswer: response.answer || '(no answer)',\n\t\t\t\trevenue: Number(purchase?.revenue ?? 0),\n\t\t\t})\n\t\t}\n\t\tfor (const row of darkRows) {\n\t\t\tif (classified.has(row.id) || !row.userId) continue\n\t\t\tconst response = latestByUser.get(row.userId)\n\t\t\tif (!response) continue\n\t\t\tclassified.set(row.id, {\n\t\t\t\tconfidence: 'user_linked',\n\t\t\t\tanswer: response.answer || '(no answer)',\n\t\t\t\trevenue: Number(row.revenue ?? 0),\n\t\t\t})\n\t\t}\n\n\t\tconst byAnswer = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tanswer: string\n\t\t\t\tconfidence: 'exact_purchase_link' | 'user_linked'\n\t\t\t\tpurchases: number\n\t\t\t\trevenue: number\n\t\t\t}\n\t\t>()\n\t\tlet exactPurchaseLinkedPurchases = 0\n\t\tlet exactPurchaseLinkedRevenue = 0\n\t\tlet userLinkedPurchases = 0\n\t\tlet userLinkedRevenue = 0\n\t\tfor (const entry of classified.values()) {\n\t\t\tif (entry.confidence === 'exact_purchase_link') {\n\t\t\t\texactPurchaseLinkedPurchases += 1\n\t\t\t\texactPurchaseLinkedRevenue += entry.revenue\n\t\t\t} else {\n\t\t\t\tuserLinkedPurchases += 1\n\t\t\t\tuserLinkedRevenue += entry.revenue\n\t\t\t}\n\t\t\tconst key = `${entry.confidence}:${entry.answer}`\n\t\t\tconst current = byAnswer.get(key) ?? {\n\t\t\t\tanswer: entry.answer,\n\t\t\t\tconfidence: entry.confidence,\n\t\t\t\tpurchases: 0,\n\t\t\t\trevenue: 0,\n\t\t\t}\n\t\t\tcurrent.purchases += 1\n\t\t\tcurrent.revenue += entry.revenue\n\t\t\tbyAnswer.set(key, current)\n\t\t}\n\n\t\treturn {\n\t\t\tlabel,\n\t\t\tproductId: filters.productId ?? null,\n\t\t\ttotalDarkPurchases: darkRows.length,\n\t\t\ttotalDarkRevenue,\n\t\t\texactPurchaseLinkedPurchases,\n\t\t\texactPurchaseLinkedRevenue,\n\t\t\tuserLinkedPurchases,\n\t\t\tuserLinkedRevenue,\n\t\t\tbyAnswer: [...byAnswer.values()]\n\t\t\t\t.sort((a, b) => b.revenue - a.revenue || b.purchases - a.purchases)\n\t\t\t\t.slice(0, limit),\n\t\t\tnotes: [\n\t\t\t\t'Report-only fallback. No purchase fields are mutated.',\n\t\t\t\t'Exact purchase-linked responses use QuestionResponse.fields.purchaseId when present.',\n\t\t\t\t'User-linked responses are lower-confidence and remain report-only.',\n\t\t\t],\n\t\t}\n\t}\n\n\t// ─── Attribution Trail ───────────────────────────────────────────────────\n\n\t/**\n\t * Trace the full attribution journey for a user by email or purchaseId.\n\t * Walks: ShortlinkClick → ShortlinkAttribution (signup) →\n\t * ResourceProgress → Purchase\n\t */\n\n\tasync function getValuePathSummary(range: AnalyticsTimeRange = '30d') {\n\t\tif (!contactEvent || !sideEffectIntent) {\n\t\t\treturn {\n\t\t\t\tcontacts: 0,\n\t\t\t\tevents: 0,\n\t\t\t\tintents: 0,\n\t\t\t\tcompletedIntents: 0,\n\t\t\t\tpendingIntents: 0,\n\t\t\t\tblockedIntents: 0,\n\t\t\t\tanswerEvents: 0,\n\t\t\t\tdripEvents: 0,\n\t\t\t\tenteredEvents: 0,\n\t\t\t\tparticipantsWithAnswerClicks: 0,\n\t\t\t\tparticipantsWithNoAnswerClicks: 0,\n\t\t\t\tterminalParticipants: 0,\n\t\t\t\tanswerOptions: [],\n\t\t\t\tanswerSteps: [],\n\t\t\t\tterminalSteps: [],\n\t\t\t\tnotes: ['Contact Event and SideEffectIntent tables are unavailable.'],\n\t\t\t}\n\t\t}\n\n\t\tconst since = rangeToDate(range)\n\t\tconst eventConditions = [sql`${contactEvent.eventType} LIKE 'value-path.%'`]\n\t\tconst intentConditions = [\n\t\t\teq(sideEffectIntent.type, 'send-value-path-email'),\n\t\t]\n\t\tif (since) {\n\t\t\teventConditions.push(gte(contactEvent.occurredAt, since))\n\t\t\tintentConditions.push(gte(sideEffectIntent.createdAt, since))\n\t\t}\n\n\t\tconst [events, intents] = await Promise.all([\n\t\t\tdb\n\t\t\t\t.select({\n\t\t\t\t\tcontactId: contactEvent.contactId,\n\t\t\t\t\teventType: contactEvent.eventType,\n\t\t\t\t\tproviderEventId: contactEvent.providerEventId,\n\t\t\t\t\toccurredAt: contactEvent.occurredAt,\n\t\t\t\t})\n\t\t\t\t.from(contactEvent)\n\t\t\t\t.where(and(...eventConditions)),\n\t\t\tdb\n\t\t\t\t.select({\n\t\t\t\t\tcontactId: sideEffectIntent.contactId,\n\t\t\t\t\tstatus: sideEffectIntent.status,\n\t\t\t\t\tmetadata: sideEffectIntent.metadata,\n\t\t\t\t\tcreatedAt: sideEffectIntent.createdAt,\n\t\t\t\t})\n\t\t\t\t.from(sideEffectIntent)\n\t\t\t\t.where(and(...intentConditions)),\n\t\t])\n\n\t\tconst contactIds = new Set<string>()\n\t\tfor (const event of events) contactIds.add(event.contactId)\n\t\tfor (const intent of intents) contactIds.add(intent.contactId)\n\n\t\tconst answerEvents = events.filter(\n\t\t\t(event: any) => event.eventType === 'value-path.answer-selected',\n\t\t)\n\t\tconst dripEvents = events.filter(\n\t\t\t(event: any) => event.eventType === 'value-path.drip-progressed',\n\t\t)\n\t\tconst enteredEvents = events.filter(\n\t\t\t(event: any) => event.eventType === 'value-path.entered',\n\t\t)\n\n\t\tconst answersByContact = new Map<string, number>()\n\t\tfor (const event of answerEvents) {\n\t\t\tanswersByContact.set(\n\t\t\t\tevent.contactId,\n\t\t\t\t(answersByContact.get(event.contactId) ?? 0) + 1,\n\t\t\t)\n\t\t}\n\n\t\tconst answerKeyCounts = new Map<string, number>()\n\t\tconst answerStepCounts = new Map<string, number>()\n\t\tfor (const event of answerEvents) {\n\t\t\tconst key = parseValuePathAnswerKey(event.providerEventId)\n\t\t\tanswerKeyCounts.set(key, (answerKeyCounts.get(key) ?? 0) + 1)\n\t\t\tconst step = answerStepFromKey(key)\n\t\t\tanswerStepCounts.set(step, (answerStepCounts.get(step) ?? 0) + 1)\n\t\t}\n\n\t\tconst latestIntentByContact = new Map<string, any>()\n\t\tfor (const intent of [...intents].sort(\n\t\t\t(a: any, b: any) =>\n\t\t\t\tnew Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(),\n\t\t)) {\n\t\t\tlatestIntentByContact.set(intent.contactId, intent)\n\t\t}\n\n\t\tconst terminalCounts = new Map<string, number>()\n\t\tfor (const intent of latestIntentByContact.values()) {\n\t\t\tconst emailResourceId = String(intent.metadata?.emailResourceId ?? '')\n\t\t\tif (!isTerminalValuePathEmail(emailResourceId)) continue\n\t\t\tterminalCounts.set(\n\t\t\t\temailResourceId,\n\t\t\t\t(terminalCounts.get(emailResourceId) ?? 0) + 1,\n\t\t\t)\n\t\t}\n\n\t\treturn {\n\t\t\tcontacts: contactIds.size,\n\t\t\tevents: events.length,\n\t\t\tintents: intents.length,\n\t\t\tcompletedIntents: intents.filter(\n\t\t\t\t(intent: any) => intent.status === 'completed',\n\t\t\t).length,\n\t\t\tpendingIntents: intents.filter(\n\t\t\t\t(intent: any) => intent.status === 'pending',\n\t\t\t).length,\n\t\t\tblockedIntents: intents.filter(\n\t\t\t\t(intent: any) => intent.status === 'blocked',\n\t\t\t).length,\n\t\t\tanswerEvents: answerEvents.length,\n\t\t\tdripEvents: dripEvents.length,\n\t\t\tenteredEvents: enteredEvents.length,\n\t\t\tparticipantsWithAnswerClicks: answersByContact.size,\n\t\t\tparticipantsWithNoAnswerClicks: Math.max(\n\t\t\t\t0,\n\t\t\t\tcontactIds.size - answersByContact.size,\n\t\t\t),\n\t\t\tterminalParticipants: [...terminalCounts.values()].reduce(\n\t\t\t\t(total, count) => total + count,\n\t\t\t\t0,\n\t\t\t),\n\t\t\tanswerOptions: [...answerKeyCounts.entries()]\n\t\t\t\t.map(([key, count]) => ({\n\t\t\t\t\tkey,\n\t\t\t\t\tstep: answerStepFromKey(key),\n\t\t\t\t\toptionValue: answerOptionFromKey(key),\n\t\t\t\t\tcount,\n\t\t\t\t}))\n\t\t\t\t.sort((a, b) => b.count - a.count),\n\t\t\tanswerSteps: [...answerStepCounts.entries()]\n\t\t\t\t.map(([step, count]) => ({ step, count }))\n\t\t\t\t.sort((a, b) => b.count - a.count),\n\t\t\tterminalSteps: [...terminalCounts.entries()]\n\t\t\t\t.map(([emailResourceId, count]) => ({ emailResourceId, count }))\n\t\t\t\t.sort((a, b) => b.count - a.count),\n\t\t\tnotes: [\n\t\t\t\t'Counts are based on Contact Events and SideEffectIntents.',\n\t\t\t\t'Kit-native opens, unsubscribes, complaints, and raw Kit link clicks are not included.',\n\t\t\t],\n\t\t}\n\t}\n\n\tfunction parseValuePathAnswerKey(providerEventId: string | null | undefined) {\n\t\tconst match = String(providerEventId ?? '').match(/:answer:(.+)$/)\n\t\treturn match?.[1] ?? 'unknown'\n\t}\n\n\tfunction answerStepFromKey(key: string) {\n\t\tconst index = key.lastIndexOf('.')\n\t\treturn index > -1 ? key.slice(0, index) : key\n\t}\n\n\tfunction answerOptionFromKey(key: string) {\n\t\tconst index = key.lastIndexOf('.')\n\t\treturn index > -1 ? key.slice(index + 1) : 'unknown'\n\t}\n\n\tfunction isTerminalValuePathEmail(emailResourceId: string) {\n\t\treturn /(?:^|\\.)(?:email-6|team-email-6)$/.test(emailResourceId)\n\t}\n\n\tasync function traceAttribution(opts: {\n\t\temail?: string\n\t\tpurchaseId?: string\n\t}): Promise<AttributionTrail> {\n\t\tconst events: AttributionTrailEvent[] = []\n\n\t\t// Resolve user\n\t\tlet userId: string | null = null\n\t\tlet userEmail: string | null = opts.email ?? null\n\t\tlet userRecord: AttributionTrail['user'] = null\n\n\t\tif (opts.purchaseId) {\n\t\t\tconst [purchase] = await db\n\t\t\t\t.select({\n\t\t\t\t\tuserId: purchases.userId,\n\t\t\t\t\temail: users.email,\n\t\t\t\t})\n\t\t\t\t.from(purchases)\n\t\t\t\t.leftJoin(users, eq(purchases.userId, users.id))\n\t\t\t\t.where(eq(purchases.id, opts.purchaseId))\n\t\t\t\t.limit(1)\n\t\t\tuserId = purchase?.userId ?? null\n\t\t\tuserEmail = purchase?.email ?? userEmail\n\t\t}\n\n\t\tif (userEmail && !userId) {\n\t\t\tconst [u] = await db\n\t\t\t\t.select({ id: users.id })\n\t\t\t\t.from(users)\n\t\t\t\t.where(eq(users.email, userEmail))\n\t\t\t\t.limit(1)\n\t\t\tuserId = u?.id ?? null\n\t\t}\n\n\t\tif (userId) {\n\t\t\tconst [u] = await db\n\t\t\t\t.select({\n\t\t\t\t\tid: users.id,\n\t\t\t\t\temail: users.email,\n\t\t\t\t\tname: users.name,\n\t\t\t\t\tcreatedAt: users.createdAt,\n\t\t\t\t})\n\t\t\t\t.from(users)\n\t\t\t\t.where(eq(users.id, userId))\n\t\t\t\t.limit(1)\n\t\t\tuserRecord = u\n\t\t\t\t? {\n\t\t\t\t\t\tid: u.id,\n\t\t\t\t\t\temail: u.email,\n\t\t\t\t\t\tname: u.name ?? null,\n\t\t\t\t\t\tcreatedAt: u.createdAt!,\n\t\t\t\t\t}\n\t\t\t\t: null\n\t\t}\n\n\t\t// Find shortlink attributions for this user (by userId or email)\n\t\tconst attrConditions: any[] = []\n\t\tif (userId) attrConditions.push(eq(shortlinkAttribution.userId, userId))\n\t\tif (userEmail)\n\t\t\tattrConditions.push(eq(shortlinkAttribution.email, userEmail))\n\n\t\tif (attrConditions.length > 0) {\n\t\t\tconst attrs = await db\n\t\t\t\t.select({\n\t\t\t\t\ttype: shortlinkAttribution.type,\n\t\t\t\t\tcreatedAt: shortlinkAttribution.createdAt,\n\t\t\t\t\tmetadata: shortlinkAttribution.metadata,\n\t\t\t\t\tshortlinkId: shortlinkAttribution.shortlinkId,\n\t\t\t\t\tslug: shortlink.slug,\n\t\t\t\t\turl: shortlink.url,\n\t\t\t\t})\n\t\t\t\t.from(shortlinkAttribution)\n\t\t\t\t.leftJoin(shortlink, eq(shortlinkAttribution.shortlinkId, shortlink.id))\n\t\t\t\t.where(sql`(${sql.join(attrConditions, sql` OR `)})`)\n\t\t\t\t.orderBy(shortlinkAttribution.createdAt)\n\n\t\t\tfor (const attr of attrs) {\n\t\t\t\t// Find clicks on this shortlink before the attribution event\n\t\t\t\tconst clicks = await db\n\t\t\t\t\t.select({\n\t\t\t\t\t\ttimestamp: shortlinkClick.timestamp,\n\t\t\t\t\t\treferrer: shortlinkClick.referrer,\n\t\t\t\t\t\tcountry: shortlinkClick.country,\n\t\t\t\t\t\tdevice: shortlinkClick.device,\n\t\t\t\t\t})\n\t\t\t\t\t.from(shortlinkClick)\n\t\t\t\t\t.where(\n\t\t\t\t\t\tand(\n\t\t\t\t\t\t\teq(shortlinkClick.shortlinkId, attr.shortlinkId),\n\t\t\t\t\t\t\tlte(shortlinkClick.timestamp, attr.createdAt),\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\t.orderBy(desc(shortlinkClick.timestamp))\n\t\t\t\t\t.limit(3) // last 3 clicks before attribution\n\n\t\t\t\tfor (const click of clicks) {\n\t\t\t\t\tevents.push({\n\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\ttimestamp: click.timestamp,\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\tshortlink: `/s/${attr.slug}`,\n\t\t\t\t\t\t\tdestination: attr.url,\n\t\t\t\t\t\t\treferrer: click.referrer,\n\t\t\t\t\t\t\tcountry: click.country,\n\t\t\t\t\t\t\tdevice: click.device,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tevents.push({\n\t\t\t\t\ttype: attr.type === 'purchase' ? 'purchase' : 'signup',\n\t\t\t\t\ttimestamp: attr.createdAt,\n\t\t\t\t\tdetail: {\n\t\t\t\t\t\tshortlink: `/s/${attr.slug}`,\n\t\t\t\t\t\tmetadata: attr.metadata ? JSON.parse(attr.metadata) : null,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Find resource progress for this user\n\t\tif (userId) {\n\t\t\tconst progress = await db\n\t\t\t\t.select({\n\t\t\t\t\tresourceId: resourceProgress.resourceId,\n\t\t\t\t\tcompletedAt: resourceProgress.completedAt,\n\t\t\t\t\tcreatedAt: resourceProgress.createdAt,\n\t\t\t\t})\n\t\t\t\t.from(resourceProgress)\n\t\t\t\t.where(eq(resourceProgress.userId, userId))\n\t\t\t\t.orderBy(resourceProgress.createdAt)\n\t\t\t\t.limit(20) // cap at 20 most recent\n\n\t\t\tfor (const p of progress) {\n\t\t\t\tevents.push({\n\t\t\t\t\ttype: 'progress',\n\t\t\t\t\ttimestamp: p.completedAt ?? p.createdAt,\n\t\t\t\t\tdetail: { resourceId: p.resourceId },\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Find purchases\n\t\tconst purchaseConditions = [paidPurchase()]\n\t\tif (opts.purchaseId) {\n\t\t\tpurchaseConditions.push(eq(purchases.id, opts.purchaseId))\n\t\t} else if (userId) {\n\t\t\tpurchaseConditions.push(eq(purchases.userId, userId))\n\t\t} else {\n\t\t\t// No user found, return empty\n\t\t\treturn { user: userRecord, events: [], purchases: [] }\n\t\t}\n\n\t\tconst purchaseRows = await db\n\t\t\t.select({\n\t\t\t\tid: purchases.id,\n\t\t\t\ttotalAmount: purchases.totalAmount,\n\t\t\t\tproductName: products.name,\n\t\t\t\tcreatedAt: purchases.createdAt,\n\t\t\t\tcountry: purchases.country,\n\t\t\t\tfields: purchases.fields,\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t.where(and(...purchaseConditions))\n\t\t\t.orderBy(purchases.createdAt)\n\n\t\tconst purchaseResults = purchaseRows.map((p: any) => {\n\t\t\tconst fields = (p.fields as Record<string, any>) ?? {}\n\t\t\tevents.push({\n\t\t\t\ttype: 'purchase',\n\t\t\t\ttimestamp: p.createdAt,\n\t\t\t\tdetail: {\n\t\t\t\t\tpurchaseId: p.id,\n\t\t\t\t\tamount: Number(p.totalAmount),\n\t\t\t\t\tproduct: p.productName,\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn {\n\t\t\t\tid: p.id,\n\t\t\t\ttotalAmount: Number(p.totalAmount),\n\t\t\t\tproductName: p.productName ?? 'Unknown',\n\t\t\t\tcreatedAt: p.createdAt,\n\t\t\t\tcountry: p.country,\n\t\t\t\tutmSource: fields.utmSource ?? null,\n\t\t\t\tutmMedium: fields.utmMedium ?? null,\n\t\t\t\tutmCampaign: fields.utmCampaign ?? null,\n\t\t\t}\n\t\t})\n\n\t\t// Sort all events by timestamp\n\t\tevents.sort(\n\t\t\t(a, b) =>\n\t\t\t\tnew Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),\n\t\t)\n\n\t\treturn { user: userRecord, events, purchases: purchaseResults }\n\t}\n\n\treturn {\n\t\tgetRevenueSummary,\n\t\tgetRevenueByDay,\n\t\tgetPreviousPeriodRevenueByDay,\n\t\tgetRevenueByProduct,\n\t\tgetRevenueByCountry,\n\t\tgetRecentPurchases,\n\t\tgetAttributionSummary,\n\t\tgetShortlinkPerformance,\n\t\tgetRevenueBySource,\n\t\tgetConversionFunnel,\n\t\tgetCommerceLaneSummary,\n\t\tgetAttributedRevenueSummary,\n\t\tgetContentPurchaseCorrelation,\n\t\tgetCheckoutAttributionReceipt,\n\t\tgetCheckoutSurveyFallbackReport,\n\t\tgetValuePathSummary,\n\t\ttraceAttribution,\n\t}\n}\n\nexport type DatabaseAnalyticsProvider = ReturnType<\n\ttypeof createDatabaseProvider\n>\n","export const SHORTLINK_RECOVERY_LANE =\n\t'recovered_from_shortlink_attribution_table' as const\n\nexport type PurchaseAttributionClass =\n\t| 'purchase_field'\n\t| typeof SHORTLINK_RECOVERY_LANE\n\t| 'dark'\n\nexport interface ShortlinkAttributionEvidence {\n\ttype?: string | null\n\tmetadata?: unknown\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction nonEmptyString(value: unknown) {\n\treturn typeof value === 'string' && value.trim().length > 0\n}\n\nfunction parseMetadata(value: unknown): Record<string, unknown> | null {\n\tif (typeof value === 'string') {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(value) as unknown\n\t\t\treturn isRecord(parsed) ? parsed : null\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t}\n\n\treturn isRecord(value) ? value : null\n}\n\n/**\n * Detects durable purchase-field attribution on a purchase fields object.\n *\n * @param fields Unknown purchase fields payload.\n * @returns True when the purchase already has attribution, legacy UTM source, or legacy GA client ID evidence.\n * @example\n * hasPurchaseFieldAttribution({ attribution: { source: 'email' } })\n */\nexport function hasPurchaseFieldAttribution(fields: unknown) {\n\tconst record = isRecord(fields) ? fields : {}\n\tconst attribution = record.attribution\n\n\treturn Boolean(\n\t\t(isRecord(attribution) && Object.keys(attribution).length > 0) ||\n\t\tnonEmptyString(record.utmSource) ||\n\t\tnonEmptyString(record.gaClientId),\n\t)\n}\n\n/**\n * Detects exact shortlink purchase evidence for one purchase.\n *\n * @param params.purchaseId Purchase ID that must match attribution metadata.purchaseId.\n * @param params.attributions ShortlinkAttributionEvidence rows to inspect.\n * @returns True only for purchase rows with valid JSON metadata and an exact purchase ID match.\n */\nexport function hasExactShortlinkPurchaseAttribution(params: {\n\tpurchaseId: string\n\tattributions: readonly ShortlinkAttributionEvidence[]\n}) {\n\treturn params.attributions.some((attribution) => {\n\t\tif (attribution.type !== 'purchase') return false\n\t\tconst metadata = parseMetadata(attribution.metadata)\n\t\treturn metadata?.purchaseId === params.purchaseId\n\t})\n}\n\n/**\n * Classifies purchase attribution with purchase fields taking precedence.\n *\n * @param params.purchaseId Purchase ID being classified.\n * @param params.fields Purchase fields payload.\n * @param params.shortlinkAttributions ShortlinkAttributionEvidence rows used as exact fallback evidence.\n * @returns A PurchaseAttributionClass: 'purchase_field', SHORTLINK_RECOVERY_LANE, or 'dark'.\n * @example\n * classifyPurchaseAttribution({ purchaseId: 'p1', fields: {}, shortlinkAttributions: [] })\n */\nexport function classifyPurchaseAttribution(params: {\n\tpurchaseId: string\n\tfields?: unknown\n\tshortlinkAttributions?: readonly ShortlinkAttributionEvidence[]\n}): PurchaseAttributionClass {\n\tif (hasPurchaseFieldAttribution(params.fields)) return 'purchase_field'\n\tif (\n\t\thasExactShortlinkPurchaseAttribution({\n\t\t\tpurchaseId: params.purchaseId,\n\t\t\tattributions: params.shortlinkAttributions ?? [],\n\t\t})\n\t) {\n\t\treturn SHORTLINK_RECOVERY_LANE\n\t}\n\treturn 'dark'\n}\n"],"mappings":";;;;AAAA,SACCA,KACAC,OACAC,MACAC,IACAC,IACAC,KACAC,SACAC,KACAC,KACAC,WACM;;;ACXA,IAAMC,0BACZ;;;ADqEM,SAASC,uBACfC,IACAC,QAA+B;AAE/B,QAAM,EACLC,WACAC,UACAC,OACAC,QACAC,kBACAC,WACAC,sBACAC,gBACAC,kBACAC,cACAC,iBAAgB,IACbX;AAIJ,QAAMY,gBAAgB;IAAC;IAAS;;AAEhC,WAASC,iBAAAA;AACR,WAAOC,QAAQb,UAAUc,QAAQ;SAAIH;KAAc;EACpD;AAFSC;AAIT,WAASG,eAAAA;AACR,WAAOC,IAAIJ,eAAAA,GAAkBK,GAAGjB,UAAUkB,aAAa,CAAA,CAAA;EACxD;AAFSH;AAIT,WAASI,cAAAA;AACR,WAAOH,IAAIJ,eAAAA,GAAkBQ,MAAMpB,UAAUkB,WAAW,MAAM;EAC/D;AAFSC;AAIT,WAASE,sBAAAA;AACR,WAAOL,IACNG,YAAAA,GACAC,gCAAgCpB,UAAUsB,MAAM,2BAA2B;EAE7E;AALSD;AAOT,QAAME,qBAAqBH;8BACEpB,UAAUsB,MAAM;iCACbtB,UAAUsB,MAAM;gCACjBtB,UAAUsB,MAAM;;AAG/C,WAASE,oBAAAA;AACR,WAAOR,IAAIJ,eAAAA,GAAkBW,kBAAAA;EAC9B;AAFSC;AAIT,QAAMC,oCAAoCL;iBAC1BpB,UAAUsB,MAAM;iCACAtB,UAAUsB,MAAM;iCAChBtB,UAAUsB,MAAM;;AAGhD,QAAMI,6CAA6CN;;SAE3Cd,oBAAAA;UACCA,qBAAqBqB,IAAI;oBACfrB,qBAAqBsB,QAAQ;mCACdtB,qBAAqBsB,QAAQ,wBAAwB5B,UAAU6B,EAAE;;AAGnG,QAAMC,yCAAyCV;QACxCK,iCAAAA;QACAC,0CAAAA;;AAGP,QAAMK,uBAAuBX;IAC1BK,iCAAAA;OACGC,0CAAAA;;AAGN,WAASM,YAAYC,OAAyB;AAC7C,QAAIA,UAAU;AAAO,aAAO;AAC5B,UAAMC,MAAM,oBAAIC,KAAAA;AAChB,UAAMC,QAAgC;MACrC,OAAO;MACP,MAAM,IAAI;MACV,OAAO,KAAK;MACZ,OAAO,KAAK;IACb;AACA,WAAO,IAAID,KAAKD,IAAIG,QAAO,KAAMD,MAAMH,KAAAA,KAAU,KAAK,MAAM,KAAK,KAAK,GAAA;EACvE;AAVSD;AAcT,iBAAeM,kBAAkBL,QAA4B,OAAK;AACjE,UAAMM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAACzB,aAAAA;;AACpB,QAAIwB;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAEpD,UAAM,CAACK,MAAAA,IAAU,MAAM9C,GACrB+C,OAAO;MACPC,cAAcC,IAAI/C,UAAUkB,WAAW;MACvC8B,eAAeC,MAAAA;IAChB,CAAA,EACCC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,UAAAA,CAAAA;AAEf,WAAO;MACNM,cAAcM,OAAOR,QAAQE,gBAAgB,CAAA;MAC7CE,eAAeJ,QAAQI,iBAAiB;MACxCK,eACCT,QAAQI,iBAAiBJ,OAAOI,gBAAgB,IAC7CI,OAAOR,OAAOE,gBAAgB,CAAA,IAAKF,OAAOI,gBAC1C;IACL;EACD;AArBeV;AAuBf,iBAAegB,gBAAgBrB,QAA4B,OAAK;AAC/D,UAAMM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAACzB,aAAAA;;AACpB,QAAIwB;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAEpD,UAAMgB,OAAO,MAAMzD,GACjB+C,OAAO;MACPW,MAAMpC,WAAmBpB,UAAU2C,SAAS,IAAIc,GAAG,MAAA;MACnDC,SAASX,IAAI/C,UAAUkB,WAAW;MAClC+B,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,UAAAA,CAAAA,EACbmB,QAAQvC,WAAWpB,UAAU2C,SAAS,GAAG,EACzCiB,QAAQxC,WAAWpB,UAAU2C,SAAS,GAAG;AAE3C,WAAOY,KAAKM,IAAI,CAACC,OAAY;MAC5BN,MAAMM,EAAEN;MACRE,SAASN,OAAOU,EAAEJ,WAAW,CAAA;MAC7BT,OAAOa,EAAEb;IACV,EAAA;EACD;AArBeK;AA6Bf,iBAAeS,8BACd9B,QAA4B,OAAK;AAEjC,QAAIA,UAAU;AAAO,aAAO,CAAA;AAE5B,UAAMG,QAAgC;MACrC,OAAO;MACP,MAAM,IAAI;MACV,OAAO,KAAK;MACZ,OAAO,KAAK;IACb;AACA,UAAM4B,YAAY5B,MAAMH,KAAAA,KAAU,KAAK,MAAM,KAAK,KAAK;AACvD,UAAMC,MAAM,oBAAIC,KAAAA;AAChB,UAAM8B,cAAc,IAAI9B,KAAKD,IAAIG,QAAO,IAAK2B,QAAAA;AAC7C,UAAME,YAAY,IAAI/B,KAAK8B,YAAY5B,QAAO,IAAK2B,QAAAA;AAEnD,UAAMT,OAAO,MAAMzD,GACjB+C,OAAO;MACPW,MAAMpC,WAAmBpB,UAAU2C,SAAS,IAAIc,GAAG,MAAA;MACnDC,SAASX,IAAI/C,UAAUkB,WAAW;MAClC+B,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAKlD,SAAAA,EACLmD,MACAnC,IACCD,aAAAA,GACA2B,IAAI1C,UAAU2C,WAAWuB,SAAAA,GACzBC,IAAInE,UAAU2C,WAAWsB,WAAAA,CAAAA,CAAAA,EAG1BN,QAAQvC,WAAWpB,UAAU2C,SAAS,GAAG,EACzCiB,QAAQxC,WAAWpB,UAAU2C,SAAS,GAAG;AAE3C,WAAOY,KAAKM,IAAI,CAACC,OAAY;MAC5BN,MAAMM,EAAEN;MACRE,SAASN,OAAOU,EAAEJ,WAAW,CAAA;MAC7BT,OAAOa,EAAEb;IACV,EAAA;EACD;AAtCec;AAwCf,iBAAeK,oBAAoBnC,QAA4B,OAAK;AACnE,UAAMM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAACzB,aAAAA;;AACpB,QAAIwB;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAEpD,UAAMgB,OAAO,MAAMzD,GACjB+C,OAAO;MACPwB,WAAWrE,UAAUqE;MACrBC,aAAarE,SAASsE;MACtBb,SAASX,IAAI/C,UAAUkB,WAAW;MAClC+B,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAKlD,SAAAA,EACLwE,SAASvE,UAAUwE,GAAGzE,UAAUqE,WAAWpE,SAAS4B,EAAE,CAAA,EACtDsB,MAAMnC,IAAAA,GAAOwB,UAAAA,CAAAA,EACbmB,QAAQ3D,UAAUqE,WAAWpE,SAASsE,IAAI,EAC1CX,QAAQc,KAAK3B,IAAI/C,UAAUkB,WAAW,CAAA,CAAA;AAExC,WAAOqC,KAAKM,IAAI,CAACC,OAAY;MAC5BO,WAAWP,EAAEO;MACbC,aAAaR,EAAEQ,eAAe;MAC9BZ,SAASN,OAAOU,EAAEJ,WAAW,CAAA;MAC7BT,OAAOa,EAAEb;IACV,EAAA;EACD;AAxBemB;AA0Bf,iBAAeO,oBAAoB1C,QAA4B,OAAK;AACnE,UAAMM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAACzB,aAAAA;;AACpB,QAAIwB;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAEpD,UAAMgB,OAAO,MAAMzD,GACjB+C,OAAO;MACP+B,SAAS5E,UAAU4E;MACnBlB,SAASX,IAAI/C,UAAUkB,WAAW;MAClC+B,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,UAAAA,CAAAA,EACbmB,QAAQ3D,UAAU4E,OAAO,EACzBhB,QAAQc,KAAK3B,IAAI/C,UAAUkB,WAAW,CAAA,CAAA,EACtC2D,MAAM,EAAA;AAER,WAAOtB,KAAKM,IAAI,CAACC,OAAY;MAC5Bc,SAASd,EAAEc,WAAW;MACtBlB,SAASN,OAAOU,EAAEJ,WAAW,CAAA;MAC7BT,OAAOa,EAAEb;IACV,EAAA;EACD;AAtBe0B;AAwBf,iBAAeG,mBACdD,QAAgB,IAChBE,SAAwC,OACxC9C,QAA4B,OAAK;AAEjC,UAAMM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAACzB,aAAAA;;AACpB,QAAIwB;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAEpD,QAAIwC,WAAW,QAAQ;AAEtBvC,iBAAWC,KAAKrB,MAAMpB,UAAUgF,YAAY,cAAc;AAE1D,YAAMzB,QAAO,MAAMzD,GACjB+C,OAAO;QACPhB,IAAI7B,UAAU6B;QACdc,WAAW3C,UAAU2C;QACrBzB,aAAalB,UAAUkB;QACvBoD,aAAarE,SAASsE;QACtBF,WAAWrE,UAAUqE;QACrBO,SAAS5E,UAAU4E;QACnBK,UAAUjF,UAAUiF;QACpBC,QAAQlF,UAAUkF;QAClBC,UAAUjF,MAAMqE;QAChBa,WAAWlF,MAAMmF;QACjBC,gBAAgBtF,UAAUsF;QAC1BC,OAAOpF,OAAOqF;MACf,CAAA,EACCtC,KAAKlD,SAAAA,EACLwE,SAASvE,UAAUwE,GAAGzE,UAAUqE,WAAWpE,SAAS4B,EAAE,CAAA,EACtD2C,SAAStE,OAAOuE,GAAGzE,UAAUkF,QAAQhF,MAAM2B,EAAE,CAAA,EAC7C2C,SAASrE,QAAQsE,GAAGzE,UAAUgF,cAAc7E,OAAO0B,EAAE,CAAA,EACrDsB,MAAMnC,IAAAA,GAAOwB,YAAYvB,GAAGd,OAAOqF,SAAS,CAAA,CAAA,CAAA,EAC5C5B,QAAQc,KAAK1E,UAAUkB,WAAW,CAAA,EAClC2D,MAAMA,KAAAA;AAER,aAAOtB,MAAKM,IAAI,CAACC,OAAY;QAC5BjC,IAAIiC,EAAEjC;QACNc,WAAWmB,EAAEnB;QACbzB,aAAakC,OAAOU,EAAE5C,WAAW;QACjCoD,aAAaR,EAAEQ,eAAe;QAC9BD,WAAWP,EAAEO;QACbO,SAASd,EAAEc;QACXK,UAAUnB,EAAEmB;QACZE,UAAUrB,EAAEqB,YAAY;QACxBC,WAAWtB,EAAEsB,aAAa;QAC1BK,QAAQ;QACRF,OAAOzB,EAAEyB,SAAS;MACnB,EAAA;IACD;AAEA,QAAIR,WAAW,cAAc;AAC5BvC,iBAAWC,KAAKrB,MAAMpB,UAAUgF,YAAY,UAAU;IACvD;AAEA,UAAMzB,OAAO,MAAMzD,GAAG4F,MAAM1F,UAAU2F,SAAS;MAC9CxC,OAAOnC,IAAAA,GAAOwB,UAAAA;MACdoB,SAAS;QAACc,KAAK1E,UAAUkB,WAAW;;MACpC2D;MACAe,MAAM;QACLC,SAAS;QACTC,MAAM;MACP;IACD,CAAA;AAEA,WAAOvC,KAAKM,IAAI,CAACC,OAAY;MAC5BjC,IAAIiC,EAAEjC;MACNc,WAAWmB,EAAEnB;MACbzB,aAAakC,OAAOU,EAAE5C,WAAW;MACjCoD,aAAaR,EAAE+B,SAAStB,QAAQ;MAChCF,WAAWP,EAAEO;MACbO,SAASd,EAAEc;MACXK,UAAUnB,EAAEmB;MACZE,UAAUrB,EAAEgC,MAAMvB,QAAQ;MAC1Ba,WAAWtB,EAAEgC,MAAMT,SAAS;MAC5BI,QAAQ3B,EAAEwB,kBAAkB;MAC5BC,OAAO;IACR,EAAA;EACD;AA9EeT;AAkFf,iBAAeiB,sBAAsB9D,QAA4B,OAAK;AACrE,UAAMM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAoB,CAAA;AAC1B,QAAID;AAAOC,iBAAWC,KAAKC,IAAIpC,qBAAqBqC,WAAWJ,KAAAA,CAAAA;AAE/D,UAAMgB,OAAO,MAAMzD,GACjB+C,OAAO;MACPlB,MAAMrB,qBAAqBqB;MAC3BsB,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAK5C,oBAAAA,EACL6C,MAAMX,WAAWwD,SAAS,IAAIhF,IAAAA,GAAOwB,UAAAA,IAAcyD,MAAAA,EACnDtC,QAAQrD,qBAAqBqB,IAAI;AAEnC,WAAO4B,KAAKM,IAAI,CAACC,OAAY;MAC5BnC,MAAMmC,EAAEnC;MACRsB,OAAOa,EAAEb;IACV,EAAA;EACD;AAlBe8C;AAoBf,iBAAeG,wBAAwBjE,QAA4B,OAAK;AACvE,UAAMM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMkE,kBAAyB,CAAA;AAC/B,QAAI5D;AAAO4D,sBAAgB1D,KAAKC,IAAInC,eAAe6F,WAAW7D,KAAAA,CAAAA;AAE9D,UAAMgB,OAAO,MAAMzD,GACjB+C,OAAO;MACPwD,aAAa9F,eAAe8F;MAC5BC,MAAMjG,UAAUiG;MAChBC,KAAKlG,UAAUkG;MACfC,QAAQvD,MAAAA;IACT,CAAA,EACCC,KAAK3C,cAAAA,EACLkG,UAAUpG,WAAWoE,GAAGlE,eAAe8F,aAAahG,UAAUwB,EAAE,CAAA,EAChEsB,MAAMgD,gBAAgBH,SAAS,IAAIhF,IAAAA,GAAOmF,eAAAA,IAAmBF,MAAAA,EAC7DtC,QAAQpD,eAAe8F,aAAahG,UAAUiG,MAAMjG,UAAUkG,GAAG,EACjE3C,QAAQc,KAAKzB,MAAAA,CAAAA,CAAAA,EACb4B,MAAM,EAAA;AAGR,UAAM6B,iBAAwB,CAAA;AAC9B,QAAInE;AAAOmE,qBAAejE,KAAKC,IAAIpC,qBAAqBqC,WAAWJ,KAAAA,CAAAA;AAEnE,UAAMoE,WAAW,MAAM7G,GACrB+C,OAAO;MACPwD,aAAa/F,qBAAqB+F;MAClC1E,MAAMrB,qBAAqBqB;MAC3BsB,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAK5C,oBAAAA,EACL6C,MAAMuD,eAAeV,SAAS,IAAIhF,IAAAA,GAAO0F,cAAAA,IAAkBT,MAAAA,EAC3DtC,QAAQrD,qBAAqB+F,aAAa/F,qBAAqBqB,IAAI;AAErE,UAAMiF,UAAU,oBAAIC,IAAAA;AACpB,eAAWC,KAAKH,UAAU;AACzB,YAAMI,WAAWH,QAAQI,IAAIF,EAAET,WAAW,KAAK;QAC9CY,SAAS;QACTjH,WAAW;MACZ;AACA,UAAI8G,EAAEnF,SAAS;AAAUoF,iBAASE,UAAUH,EAAE7D;AAC9C,UAAI6D,EAAEnF,SAAS;AAAYoF,iBAAS/G,YAAY8G,EAAE7D;AAClD2D,cAAQM,IAAIJ,EAAET,aAAaU,QAAAA;IAC5B;AAEA,WAAOxD,KAAKM,IAAI,CAACC,MAAAA;AAChB,YAAMqD,OAAOP,QAAQI,IAAIlD,EAAEuC,WAAW;AACtC,aAAO;QACNA,aAAavC,EAAEuC;QACfC,MAAMxC,EAAEwC;QACRC,KAAKzC,EAAEyC;QACPC,QAAQ1C,EAAE0C;QACVS,SAASE,MAAMF,WAAW;QAC1BjH,WAAWmH,MAAMnH,aAAa;MAC/B;IACD,CAAA;EACD;AAvDekG;AA2Df,iBAAekB,mBACdnF,QAA4B,OAC5BoF,UAAkC,CAAC,GAAC;AAEpC,UAAM9E,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAAC5B,eAAAA;;AACpB,QAAI2B;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AACpD,QAAI8E,QAAQhD;AACX7B,iBAAWC,KAAKgC,GAAGzE,UAAUqE,WAAWgD,QAAQhD,SAAS,CAAA;AAE1D,UAAMiD,WAAWlG;UACTG,kBAAAA;UACAvB,UAAUkB,WAAW;UACrBlB,UAAUkB,WAAW;;;AAG7B,UAAMqG,aAAanG;oCACepB,UAAUsB,MAAM;;UAE1CQ,sCAAAA,SAA+C0F,uBAAAA;;uCAElBxH,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;;yBAE9BtB,UAAUsB,MAAM;yBAChBtB,UAAUsB,MAAM;yBAChBtB,UAAUsB,MAAM;yBAChBtB,UAAUsB,MAAM;;;;;AAKvC,UAAMmG,aAAarG;oCACepB,UAAUsB,MAAM;;UAE1CQ,sCAAAA;;uCAE6B9B,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;;yBAE9BtB,UAAUsB,MAAM;yBAChBtB,UAAUsB,MAAM;yBAChBtB,UAAUsB,MAAM;yBAChBtB,UAAUsB,MAAM;;;;;AAKvC,UAAMoG,eAAetG;oCACapB,UAAUsB,MAAM;;wCAEZtB,UAAUsB,MAAM;;;UAG9CQ,sCAAAA;;uCAE6B9B,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;uCAChBtB,UAAUsB,MAAM;;;AAIrD,UAAMiC,OAAO,MAAMzD,GACjB+C,OAAO;MACP8E,MAAML,SAAS7D,GAAG,MAAA;MAClBmE,QAAQL,WAAW9D,GAAG,QAAA;MACtBoE,QAAQJ,WAAWhE,GAAG,QAAA;MACtBqE,UAAUJ,aAAajE,GAAG,UAAA;MAC1BC,SAASX,IAAI/C,UAAUkB,WAAW;MAClC+B,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,UAAAA,CAAAA,EACbmB,QAAQvC,QAAQA,QAAQA,QAAQA,MAAM,EACtCwC,QAAQc,KAAK3B,IAAI/C,UAAUkB,WAAW,CAAA,GAAIwD,KAAKzB,MAAAA,CAAAA,CAAAA;AAEjD,WAAOM,KAAKM,IAAI,CAACC,OAAY;MAC5B6D,MAAM7D,EAAE6D,QAAQ;MAChBC,QAAQ9D,EAAE8D,UAAU;MACpBC,QAAQ/D,EAAE+D,UAAU;MACpBC,UAAUhE,EAAEgE,YAAY;MACxBpE,SAASN,OAAOU,EAAEJ,WAAW,CAAA;MAC7BT,OAAOa,EAAEb;IACV,EAAA;EACD;AAxFemE;AA0Ff,iBAAeW,oBAAoB9F,QAA4B,OAAK;AACnE,UAAMM,QAAQP,YAAYC,KAAAA;AAE1B,UAAM+F,iBAAiBzF,QAAQ;MAACG,IAAIxC,MAAMyC,WAAWJ,KAAAA;QAAU,CAAA;AAC/D,UAAM0F,qBAAqB;MAAClH,aAAAA;;AAC5B,QAAIwB;AAAO0F,yBAAmBxF,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAE5D,UAAM,CAAC2F,SAAAA,IAAa,MAAMpI,GACxB+C,OAAO;MAAEsF,OAAOlF,MAAAA;IAAQ,CAAA,EACxBC,KAAKhD,KAAAA,EACLiD,MAAM6E,eAAehC,SAAS,IAAIhF,IAAAA,GAAOgH,cAAAA,IAAkB/B,MAAAA;AAE7D,UAAM,CAACjD,aAAAA,IAAiB,MAAMlD,GAC5B+C,OAAO;MAAEsF,OAAOlF,MAAAA;IAAQ,CAAA,EACxBC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOiH,kBAAAA,CAAAA;AAEf,UAAM,CAACG,eAAAA,IAAmB,MAAMtI,GAC9B+C,OAAO;MAAEsF,OAAOlF,MAAAA;IAAQ,CAAA,EACxBC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOiH,oBAAoBlG,oBAAAA,CAAAA;AAEnC,UAAMsG,eAAeH,WAAWC,SAAS;AACzC,UAAMG,iBAAiBtF,eAAemF,SAAS;AAC/C,UAAMI,sBAAsBH,iBAAiBD,SAAS;AAEtD,WAAO;MACNE;MACAC;MACAC;MACAC,gBAAgBH,eAAe,IAAIC,iBAAiBD,eAAe;MACnEI,qBACCH,iBAAiB,IAAIC,sBAAsBD,iBAAiB;IAC9D;EACD;AAlCeP;AAoCf,iBAAeW,uBACdzG,QAA4B,OAC5BoF,UAAkC,CAAC,GAAC;AAEpC,UAAM9E,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAAC5B,eAAAA;;AACpB,QAAI2B;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AACpD,QAAI8E,QAAQhD;AACX7B,iBAAWC,KAAKgC,GAAGzE,UAAUqE,WAAWgD,QAAQhD,SAAS,CAAA;AAE1D,UAAM,CAACsE,QAAAA,IAAY,MAAM7I,GACvB+C,OAAO;MAAEI,OAAOA,MAAAA;IAAQ,CAAA,EACxBC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,UAAAA,CAAAA;AACf,UAAM,CAACoG,IAAAA,IAAQ,MAAM9I,GACnB+C,OAAO;MAAEI,OAAOA,MAAAA;MAASS,SAASX,IAAI/C,UAAUkB,WAAW;IAAE,CAAA,EAC7DgC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYzB,aAAAA,CAAAA,CAAAA;AAC3B,UAAM,CAAC8H,MAAAA,IAAU,MAAM/I,GACrB+C,OAAO;MAAEI,OAAOA,MAAAA;MAASS,SAASX,IAAI/C,UAAUkB,WAAW;IAAE,CAAA,EAC7DgC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYrB,YAAAA,CAAAA,CAAAA;AAC3B,UAAM,CAAC2H,YAAAA,IAAgB,MAAMhJ,GAC3B+C,OAAO;MAAEI,OAAOA,MAAAA;IAAQ,CAAA,EACxBC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYnB,oBAAAA,CAAAA,CAAAA;AAC3B,UAAM,CAAC0H,SAAAA,IAAa,MAAMjJ,GACxB+C,OAAO;MAAEI,OAAOA,MAAAA;IAAQ,CAAA,EACxBC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYhB,kBAAAA,CAAAA,CAAAA;AAC3B,UAAMwH,aAAa,MAAMlJ,GACvB+C,OAAO;MACPoG,QAAQ7H;wCAC4BpB,UAAUsB,MAAM;;OAEjDmC,GAAG,QAAA;MACNR,OAAOA,MAAAA;IACR,CAAA,EACCC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYrB,YAAAA,CAAAA,CAAAA,EACzBwC,QACAvC;wCACoCpB,UAAUsB,MAAM;;MAElD;AAGJ,WAAO;MACN4H,iBAAiBP,UAAU1F,SAAS;MACpCkG,eAAeP,MAAM3F,SAAS;MAC9BmG,aAAahG,OAAOwF,MAAMlF,WAAW,CAAA;MACrC2F,cAAcR,QAAQ5F,SAAS;MAC/BqG,oBAAoBlG,OAAOyF,QAAQnF,WAAW,CAAA;MAC9CoF,cAAcA,cAAc7F,SAAS;MACrCsG,oBAAoBR,WAAW9F,SAAS;MACxCuG,qBAAqBC,OAAOC,YAC3BV,WAAWnF,IAAI,CAAC8F,QAAa;QAACA,IAAIV;QAAQU,IAAI1G;OAAM,CAAA;IAEtD;EACD;AA3DeyF;AA6Df,iBAAekB,4BACd3H,QAA4B,OAC5BoF,UAAkC,CAAC,GAAC;AAEpC,UAAM9E,QAAQP,YAAYC,KAAAA;AAC1B,UAAMO,aAAa;MAACzB,aAAAA;;AACpB,QAAIwB;AAAOC,iBAAWC,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AACpD,QAAI8E,QAAQhD;AACX7B,iBAAWC,KAAKgC,GAAGzE,UAAUqE,WAAWgD,QAAQhD,SAAS,CAAA;AAE1D,UAAM,CAACzB,MAAAA,IAAU,MAAM9C,GACrB+C,OAAO;MAAEsF,OAAOpF,IAAI/C,UAAUkB,WAAW;MAAG+B,OAAOA,MAAAA;IAAQ,CAAA,EAC3DC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,UAAAA,CAAAA;AAEf,UAAM,CAACqH,UAAAA,IAAc,MAAM/J,GACzB+C,OAAO;MAAEsF,OAAOpF,IAAI/C,UAAUkB,WAAW;MAAG+B,OAAOA,MAAAA;IAAQ,CAAA,EAC3DC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYT,oBAAAA,CAAAA;AAE3B,UAAM,CAAC+H,uBAAAA,IAA2B,MAAMhK,GACtC+C,OAAO;MAAEsF,OAAOpF,IAAI/C,UAAUkB,WAAW;MAAG+B,OAAOA,MAAAA;IAAQ,CAAA,EAC3DC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYf,iCAAAA,CAAAA;AAE3B,UAAM,CAACsI,sCAAAA,IAA0C,MAAMjK,GACrD+C,OAAO;MAAEsF,OAAOpF,IAAI/C,UAAUkB,WAAW;MAAG+B,OAAOA,MAAAA;IAAQ,CAAA,EAC3DC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOwB,YAAYV,sCAAAA,CAAAA;AAE3B,UAAMkI,mBAAmBzH,QACtB;MAAC3B,eAAAA;MAAkB8B,IAAI1C,UAAU2C,WAAWJ,KAAAA;QAC5C;MAAC3B,eAAAA;;AACJ,QAAIyG,QAAQhD,WAAW;AACtB2F,uBAAiBvH,KAAKgC,GAAGzE,UAAUqE,WAAWgD,QAAQhD,SAAS,CAAA;IAChE;AACA,UAAM4F,cAAc,8BAAOC,cAAAA;AAC1B,YAAM,CAACP,GAAAA,IAAO,MAAM7J,GAClB+C,OAAO;QAAEI,OAAOA,MAAAA;MAAQ,CAAA,EACxBC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOgJ,kBAAkBE,SAAAA,CAAAA;AACjC,aAAOP,KAAK1G,SAAS;IACtB,GANoB;AAOpB,UAAM,CACLkH,gBACAC,UACAC,cACAC,iBACAC,yBACAC,2CAAAA,IACG,MAAMC,QAAQC,IAAI;MACrBT,YACC7I;qBACiBpB,UAAUsB,MAAM;qCACAtB,UAAUsB,MAAM;OAC9C;MAEJ2I,YACC7I;qBACiBpB,UAAUsB,MAAM;qCACAtB,UAAUsB,MAAM;OAC9C;MAEJ2I,YACC7I,mBAAmBpB,UAAUsB,MAAM,yCAAyC;MAE7E2I,YACC7I;qBACiBpB,UAAUsB,MAAM;qCACAtB,UAAUsB,MAAM;OAC9C;MAEJ2I,YACC7I,mBAAmBpB,UAAUsB,MAAM,mDAAmD;MAEvF2I,YAAYnI,sCAAAA;KACZ;AAED,UAAM6G,WAAW,MAAMD,uBAAuBzG,OAAOoF,OAAAA;AACrD,UAAMvE,eAAeM,OAAOR,QAAQuF,SAAS,CAAA;AAC7C,UAAMwC,oBAAoBvH,OAAOyG,YAAY1B,SAAS,CAAA;AACtD,UAAMyC,iCAAiCxH,OACtC0G,yBAAyB3B,SAAS,CAAA;AAEnC,UAAM0C,gDAAgDzH,OACrD2G,wCAAwC5B,SAAS,CAAA;AAElD,UAAM2C,sBAAsBhI,eAAe6H;AAC3C,UAAMxB,gBAAgBvG,QAAQK,SAAS;AAEvC,WAAO;MACNH;MACA6H;MACAG;MACAC,iBAAiBjI,eAAe,IAAI6H,oBAAoB7H,eAAe;MACvEwF,gBAAgBK,SAASO;MACzBC;MACA6B,kCAAkClB,yBAAyB7G,SAAS;MACpE2H;MACAK,iDACClB,wCAAwC9G,SAAS;MAClD4H;MACA3B,iBAAiBP,SAASO;MAC1BG,cAAcV,SAASU;MACvBP,cAAcH,SAASG;MACvBS,oBAAoBZ,SAASY;MAC7BZ;MACAuC,SAAS;QACR7K,WAAW8J;QACXgB,KAAKf;QACLgB,aAAaf;QACbgB,YAAYf;QACZgB,oBAAoBf;QACpBR,wCACCS;QACDe,qBAAqB5C,SAASG;MAC/B;IACD;EACD;AAtHec;AAwHf,iBAAe4B,8BACdvJ,QAA4B,OAC5B4C,QAAgB,IAAE;AAElB,UAAMtC,QAAQP,YAAYC,KAAAA;AAC1B,UAAMgG,qBAAqB;MAAClH,aAAAA;;AAC5B,QAAIwB;AAAO0F,yBAAmBxF,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAE5D,UAAMkJ,gBAAgB,MAAM3L,GAC1B4L,eAAe;MAAExG,QAAQlF,UAAUkF;IAAO,CAAA,EAC1ChC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOiH,kBAAAA,CAAAA;AAEf,UAAM0D,eAAeF,cACnB5H,IAAI,CAACC,MAAWA,EAAEoB,MAAM,EACxBH,OAAO,CAAClD,OAA0BA,OAAO,IAAA;AAE3C,QAAI8J,aAAa3F,WAAW;AAAG,aAAO,CAAA;AAEtC,UAAMzC,OAAO,MAAMzD,GACjB+C,OAAO;MACP+I,YAAYxL,iBAAiBwL;MAC7BC,gBAAgB5I,MAAAA;IACjB,CAAA,EACCC,KAAK9C,gBAAAA,EACL+C,MACA/B,MAAMhB,iBAAiB8E,MAAM,QAAQ9D,IAAI0K,KACxCH,aAAa9H,IAAI,CAAChC,OAAeT,MAAMS,EAAAA,EAAI,GAC3CT,OAAO,CAAA,GACJ,EAEJuC,QAAQvD,iBAAiBwL,UAAU,EACnChI,QAAQc,KAAKzB,MAAAA,CAAAA,CAAAA,EACb4B,MAAMA,KAAAA;AAER,WAAOtB,KAAKM,IAAI,CAACC,OAAY;MAC5B8H,YAAY9H,EAAE8H;MACdC,gBAAgB/H,EAAE+H;IACnB,EAAA;EACD;AAvCeL;AA+Cf,WAASO,gBAAgBC,OAAc;AACtC,WAAOC,QAAQD,KAAAA,KAAU,OAAOA,UAAU,YAAY,CAACE,MAAMC,QAAQH,KAAAA,IACjEA,QACD,CAAC;EACL;AAJSD;AAYT,WAASK,eAAeJ,OAAc;AACrC,WACCC,QAAQD,KAAAA,KACR,OAAOA,UAAU,YACjB,CAACE,MAAMC,QAAQH,KAAAA,KACfvC,OAAO4C,OAAOL,KAAAA,EAAkCM,KAC/C,CAACC,UAAU,OAAOA,UAAU,YAAYA,MAAMvG,SAAS,CAAA;EAG1D;AATSoG;AAiBT,WAASI,oBAAoBR,OAAc;AAC1C,WACCC,QAAQD,KAAAA,KACR,OAAOA,UAAU,YACjB,CAACE,MAAMC,QAAQH,KAAAA,KACfvC,OAAO4C,OAAOL,KAAAA,EAAkCM,KAC/C,CAACC,UAAU,OAAOA,UAAU,YAAYA,MAAME,WAAW,OAAA,CAAA;EAG5D;AATSD;AAWT,iBAAeE,8BAA8BC,MAA6B;AACzE,QAAI,CAACA,KAAKC,YAAY;AACrB,aAAO;QACNC,UAAU;QACVC,QAAQ;UACPC,eAAe;UACfC,qBAAqB;UACrB7B,KAAK;UACL8B,WAAW;UACXC,SAAS;UACTnE,WAAW;UACX1I,WAAW;UACXiL,oBAAoB;UACpBD,YAAY;QACb;QACA8B,aAAa;QACbC,QAAQ,CAAC;QACTC,WAAW,CAAA;MACZ;IACD;AAEA,UAAM,CAAC1D,GAAAA,IAAO,MAAM7J,GAClB+C,OAAO;MACPhB,IAAI7B,UAAU6B;MACdc,WAAW3C,UAAU2C;MACrB0B,WAAWrE,UAAUqE;MACrBC,aAAarE,SAASsE;MACtBrD,aAAalB,UAAUkB;MACvBJ,QAAQd,UAAUc;MAClB8D,SAAS5E,UAAU4E;MACnBtD,QAAQtB,UAAUsB;IACnB,CAAA,EACC4B,KAAKlD,SAAAA,EACLwE,SAASvE,UAAUwE,GAAGzE,UAAUqE,WAAWpE,SAAS4B,EAAE,CAAA,EACtDsB,MAAMsB,GAAGzE,UAAU6B,IAAI8K,KAAKC,UAAU,CAAA,EACtC/H,MAAM,CAAA;AAER,QAAI,CAAC8E,KAAK;AACT,aAAO;QACNkD,UAAU;QACVC,QAAQ;UACPC,eAAe;UACfC,qBAAqB;UACrB7B,KAAK;UACL8B,WAAW;UACXC,SAAS;UACTnE,WAAW;UACX1I,WAAW;UACXiL,oBAAoB;UACpBD,YAAY;QACb;QACA8B,aAAa;QACbC,QAAQ,CAAC;QACTC,WAAW,CAAA;MACZ;IACD;AAEA,UAAM/L,SAASyK,gBAAgBpC,IAAIrI,MAAM;AACzC,UAAM6L,cAAcpB,gBAAgBzK,OAAO6L,WAAW;AACtD,UAAMhC,MAAMY,gBAAgBoB,YAAYhC,GAAG;AAC3C,UAAMmC,WAAWvB,gBAAgBoB,YAAYG,QAAQ;AACrD,UAAMC,oBAAoBxB,gBAAgBoB,YAAY9M,SAAS;AAC/D,UAAMmN,KAAKzB,gBAAgBoB,YAAYK,EAAE;AACzC,UAAMJ,SAAS3D,OAAOC,YACrB;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MAEC7F,IAAI,CAAC4J,QAAQ;MAACA;MAAKnM,OAAOmM,GAAAA;KAAK,EAC/B1I,OAAO,CAAC,CAAA,EAAGiH,KAAAA,MAAWA,UAAU/F,UAAa+F,UAAU,IAAA,CAAA;AAE1D,UAAM0B,eAAezB,QACpBd,IAAIvD,UAAUuD,IAAItD,UAAUsD,IAAIrD,YAAYxG,OAAOqM,SAAS;AAE7D,UAAM5E,YAAYkD,QACjBkB,YAAYpE,aACZzH,OAAOyH,aACPyD,oBAAoBc,QAAAA,CAAAA;AAGrB,WAAO;MACNT,UAAU;QACThL,IAAI8H,IAAI9H;QACRc,WAAWgH,IAAIhH;QACf0B,WAAWsF,IAAItF;QACfC,aAAaqF,IAAIrF,eAAe;QAChCpD,aAAakC,OAAOuG,IAAIzI,eAAe,CAAA;QACvCJ,QAAQ6I,IAAI7I;QACZ8D,SAAS+E,IAAI/E;MACd;MACAkI,QAAQ;QACPC,eAAe;QACfC,qBAAqBvD,OAAOmE,KAAKT,WAAAA,EAAanH,SAAS;QACvDmF,KAAKuC;QACLT,WAAWS;QACXR,SAASd,eAAekB,QAAAA;QACxBvE;QACA1I,WAAW4L,QAAQsB,kBAAkBjH,QAAQhF,OAAOuM,YAAY;QAChEvC,oBAAoBW,QAAQkB,YAAY7B,kBAAkB;QAC1DD,YAAYY,QAAQuB,GAAGM,YAAYxM,OAAO+J,UAAU;MACrD;MACA8B,aAAa1D,OAAOmE,KAAKT,WAAAA,EAAanH,SAAS,IAAImH,cAAc;MACjEC;MACAC,WAAW5D,OAAOmE,KAAKtM,MAAAA,EAAQyM,KAAI;IACpC;EACD;AAjHerB;AAmHf,iBAAesB,gCACd/L,QAA4B,OAC5B4C,QAAgB,IAChBwC,UAAkC,CAAC,GAAC;AAEpC,UAAM4G,QAAQ;AACd,QAAI,CAACzN,kBAAkB;AACtB,aAAO;QACNyN;QACA5J,WAAWgD,QAAQhD,aAAa;QAChC6J,oBAAoB;QACpBC,kBAAkB;QAClBC,8BAA8B;QAC9BC,4BAA4B;QAC5BC,qBAAqB;QACrBC,mBAAmB;QACnBC,UAAU,CAAA;QACVC,OAAO;UAAC;;MACT;IACD;AAEA,UAAMlM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMgG,qBAAqB;MAC1BlH,aAAAA;MACAK,UAAUW,oBAAAA;;AAEX,QAAIQ;AAAO0F,yBAAmBxF,KAAKC,IAAI1C,UAAU2C,WAAWJ,KAAAA,CAAAA;AAC5D,QAAI8E,QAAQhD,WAAW;AACtB4D,yBAAmBxF,KAAKgC,GAAGzE,UAAUqE,WAAWgD,QAAQhD,SAAS,CAAA;IAClE;AAEA,UAAMqK,WAAW,MAAM5O,GACrB+C,OAAO;MACPhB,IAAI7B,UAAU6B;MACdqD,QAAQlF,UAAUkF;MAClBxB,SAAS1D,UAAUkB;IACpB,CAAA,EACCgC,KAAKlD,SAAAA,EACLmD,MAAMnC,IAAAA,GAAOiH,kBAAAA,CAAAA;AAEf,UAAMkG,mBAAmBO,SAASC,OACjC,CAACxG,OAAewB,QAAaxB,QAAQ/E,OAAOuG,IAAIjG,WAAW,CAAA,GAC3D,CAAA;AAGD,QAAIgL,SAAS1I,WAAW,GAAG;AAC1B,aAAO;QACNiI;QACA5J,WAAWgD,QAAQhD,aAAa;QAChC6J,oBAAoB;QACpBC,kBAAkB;QAClBC,8BAA8B;QAC9BC,4BAA4B;QAC5BC,qBAAqB;QACrBC,mBAAmB;QACnBC,UAAU,CAAA;QACVC,OAAO;UAAC;;MACT;IACD;AAEA,UAAMG,WAAW,IAAI/H,IACpB6H,SAAS7K,IAAI,CAAC8F,QAAmC;MAACA,IAAI9H;MAAI8H;KAAI,CAAA;AAE/D,UAAMkF,eAAe,oBAAIhI,IAAAA;AACzB,eAAW8C,OAAO+E,UAAU;AAC3B,UAAI,CAAC/E,IAAIzE;AAAQ;AACjB,YAAM4J,SAASD,aAAa7H,IAAI2C,IAAIzE,MAAM,KAAK,CAAA;AAC/C4J,aAAOrM,KAAKkH,GAAAA;AACZkF,mBAAa3H,IAAIyC,IAAIzE,QAAQ4J,MAAAA;IAC9B;AAEA,UAAMC,qBAA4B,CAAA;AAClC,QAAIxM;AAAOwM,yBAAmBtM,KAAKC,IAAIlC,iBAAiBmC,WAAWJ,KAAAA,CAAAA;AACnE,UAAMyM,UAAU;SAAIJ,SAAShB,KAAI;;AACjC,UAAMqB,cAAc;SAAIJ,aAAajB,KAAI;;AACzC,UAAMsB,yBAAyB9N,gCAAgCZ,iBAAiBc,MAAM,0BAA0BF,IAAI0K,KACnHkD,QAAQnL,IAAI,CAAChC,OAAOT,MAAMS,EAAAA,EAAI,GAC9BT,OAAO,CAAA;AAER,UAAM+N,gBACLF,YAAYjJ,SAAS,IAClB5E,MAAMZ,iBAAiB0E,MAAM,QAAQ9D,IAAI0K,KACzCmD,YAAYpL,IAAI,CAAChC,OAAOT,MAAMS,EAAAA,EAAI,GAClCT,OAAO,CAAA,MAEPA;AACJ2N,uBAAmBtM,KAClBrB,OAAO8N,sBAAAA,OAA6BC,aAAAA,GAAgB;AAGrD,UAAMC,eAAe,MAAMtP,GACzB+C,OAAO;MACP+J,YAAYxL,gCAAwCZ,iBAAiBc,MAAM;MAC3E+N,QAAQjO,gCAAwCZ,iBAAiBc,MAAM;MACvE4D,QAAQ1E,iBAAiB0E;MACzBvC,WAAWnC,iBAAiBmC;IAC7B,CAAA,EACCO,KAAK1C,gBAAAA,EACL2C,MAAMnC,IAAAA,GAAO+N,kBAAAA,CAAAA;AAEf,UAAMO,kBAAkB,oBAAIzI,IAAAA;AAC5B,UAAM0I,eAAe,oBAAI1I,IAAAA;AACzB,eAAW8C,OAAOyF,cAAc;AAC/B,UAAIzF,IAAIiD,cAAcgC,SAASY,IAAI7F,IAAIiD,UAAU,GAAG;AACnD0C,wBAAgBpI,IAAIyC,IAAIiD,YAAYjD,GAAAA;AACpC;MACD;AACA,UAAI,CAACA,IAAIzE;AAAQ;AACjB,YAAMuK,UAAUF,aAAavI,IAAI2C,IAAIzE,MAAM;AAC3C,YAAMwK,UAAU,IAAIvN,KAAKwH,IAAIhH,aAAa,CAAA,EAAGN,QAAO;AACpD,YAAMsN,cAAcF,UACjB,IAAItN,KAAKsN,QAAQ9M,aAAa,CAAA,EAAGN,QAAO,IACxC;AACH,UAAI,CAACoN,WAAWC,WAAWC;AAAaJ,qBAAarI,IAAIyC,IAAIzE,QAAQyE,GAAAA;IACtE;AAEA,UAAMiG,aAAa,oBAAI/I,IAAAA;AAQvB,eAAW,CAAC+F,YAAYiD,QAAAA,KAAaP,iBAAiB;AACrD,YAAMzC,WAAW+B,SAAS5H,IAAI4F,UAAAA;AAC9BgD,iBAAW1I,IAAI0F,YAAY;QAC1BkD,YAAY;QACZT,QAAQQ,SAASR,UAAU;QAC3B3L,SAASN,OAAOyJ,UAAUnJ,WAAW,CAAA;MACtC,CAAA;IACD;AACA,eAAWiG,OAAO+E,UAAU;AAC3B,UAAIkB,WAAWJ,IAAI7F,IAAI9H,EAAE,KAAK,CAAC8H,IAAIzE;AAAQ;AAC3C,YAAM2K,WAAWN,aAAavI,IAAI2C,IAAIzE,MAAM;AAC5C,UAAI,CAAC2K;AAAU;AACfD,iBAAW1I,IAAIyC,IAAI9H,IAAI;QACtBiO,YAAY;QACZT,QAAQQ,SAASR,UAAU;QAC3B3L,SAASN,OAAOuG,IAAIjG,WAAW,CAAA;MAChC,CAAA;IACD;AAEA,UAAM8K,WAAW,oBAAI3H,IAAAA;AASrB,QAAIuH,+BAA+B;AACnC,QAAIC,6BAA6B;AACjC,QAAIC,sBAAsB;AAC1B,QAAIC,oBAAoB;AACxB,eAAWhC,SAASqD,WAAWvD,OAAM,GAAI;AACxC,UAAIE,MAAMuD,eAAe,uBAAuB;AAC/C1B,wCAAgC;AAChCC,sCAA8B9B,MAAM7I;MACrC,OAAO;AACN4K,+BAAuB;AACvBC,6BAAqBhC,MAAM7I;MAC5B;AACA,YAAM+J,MAAM,GAAGlB,MAAMuD,UAAU,IAAIvD,MAAM8C,MAAM;AAC/C,YAAMI,UAAUjB,SAASxH,IAAIyG,GAAAA,KAAQ;QACpC4B,QAAQ9C,MAAM8C;QACdS,YAAYvD,MAAMuD;QAClB9P,WAAW;QACX0D,SAAS;MACV;AACA+L,cAAQzP,aAAa;AACrByP,cAAQ/L,WAAW6I,MAAM7I;AACzB8K,eAAStH,IAAIuG,KAAKgC,OAAAA;IACnB;AAEA,WAAO;MACNxB;MACA5J,WAAWgD,QAAQhD,aAAa;MAChC6J,oBAAoBQ,SAAS1I;MAC7BmI;MACAC;MACAC;MACAC;MACAC;MACAC,UAAU;WAAIA,SAASnC,OAAM;QAC3B0B,KAAK,CAACjH,GAAGiJ,MAAMA,EAAErM,UAAUoD,EAAEpD,WAAWqM,EAAE/P,YAAY8G,EAAE9G,SAAS,EACjEgQ,MAAM,GAAGnL,KAAAA;MACX4J,OAAO;QACN;QACA;QACA;;IAEF;EACD;AAlMeT;AA4Mf,iBAAeiC,oBAAoBhO,QAA4B,OAAK;AACnE,QAAI,CAACxB,gBAAgB,CAACC,kBAAkB;AACvC,aAAO;QACNwP,UAAU;QACVC,QAAQ;QACRC,SAAS;QACTC,kBAAkB;QAClBC,gBAAgB;QAChBC,gBAAgB;QAChBC,cAAc;QACdC,YAAY;QACZC,eAAe;QACfC,8BAA8B;QAC9BC,gCAAgC;QAChCC,sBAAsB;QACtBC,eAAe,CAAA;QACfC,aAAa,CAAA;QACbC,eAAe,CAAA;QACfvC,OAAO;UAAC;;MACT;IACD;AAEA,UAAMlM,QAAQP,YAAYC,KAAAA;AAC1B,UAAMgP,kBAAkB;MAAC7P,MAAMX,aAAayQ,SAAS;;AACrD,UAAMC,mBAAmB;MACxB1M,GAAG/D,iBAAiBiB,MAAM,uBAAA;;AAE3B,QAAIY,OAAO;AACV0O,sBAAgBxO,KAAKC,IAAIjC,aAAa2Q,YAAY7O,KAAAA,CAAAA;AAClD4O,uBAAiB1O,KAAKC,IAAIhC,iBAAiBiC,WAAWJ,KAAAA,CAAAA;IACvD;AAEA,UAAM,CAAC4N,QAAQC,OAAAA,IAAW,MAAM3F,QAAQC,IAAI;MAC3C5K,GACE+C,OAAO;QACPwO,WAAW5Q,aAAa4Q;QACxBH,WAAWzQ,aAAayQ;QACxBI,iBAAiB7Q,aAAa6Q;QAC9BF,YAAY3Q,aAAa2Q;MAC1B,CAAA,EACClO,KAAKzC,YAAAA,EACL0C,MAAMnC,IAAAA,GAAOiQ,eAAAA,CAAAA;MACfnR,GACE+C,OAAO;QACPwO,WAAW3Q,iBAAiB2Q;QAC5BvQ,QAAQJ,iBAAiBI;QACzBc,UAAUlB,iBAAiBkB;QAC3Be,WAAWjC,iBAAiBiC;MAC7B,CAAA,EACCO,KAAKxC,gBAAAA,EACLyC,MAAMnC,IAAAA,GAAOmQ,gBAAAA,CAAAA;KACf;AAED,UAAMI,aAAa,oBAAIC,IAAAA;AACvB,eAAWC,SAAStB;AAAQoB,iBAAWG,IAAID,MAAMJ,SAAS;AAC1D,eAAWM,UAAUvB;AAASmB,iBAAWG,IAAIC,OAAON,SAAS;AAE7D,UAAMb,eAAeL,OAAOpL,OAC3B,CAAC0M,UAAeA,MAAMP,cAAc,4BAAA;AAErC,UAAMT,aAAaN,OAAOpL,OACzB,CAAC0M,UAAeA,MAAMP,cAAc,4BAAA;AAErC,UAAMR,gBAAgBP,OAAOpL,OAC5B,CAAC0M,UAAeA,MAAMP,cAAc,oBAAA;AAGrC,UAAMU,mBAAmB,oBAAI/K,IAAAA;AAC7B,eAAW4K,SAASjB,cAAc;AACjCoB,uBAAiB1K,IAChBuK,MAAMJ,YACLO,iBAAiB5K,IAAIyK,MAAMJ,SAAS,KAAK,KAAK,CAAA;IAEjD;AAEA,UAAMQ,kBAAkB,oBAAIhL,IAAAA;AAC5B,UAAMiL,mBAAmB,oBAAIjL,IAAAA;AAC7B,eAAW4K,SAASjB,cAAc;AACjC,YAAM/C,MAAMsE,wBAAwBN,MAAMH,eAAe;AACzDO,sBAAgB3K,IAAIuG,MAAMoE,gBAAgB7K,IAAIyG,GAAAA,KAAQ,KAAK,CAAA;AAC3D,YAAMuE,OAAOC,kBAAkBxE,GAAAA;AAC/BqE,uBAAiB5K,IAAI8K,OAAOF,iBAAiB9K,IAAIgL,IAAAA,KAAS,KAAK,CAAA;IAChE;AAEA,UAAME,wBAAwB,oBAAIrL,IAAAA;AAClC,eAAW8K,UAAU;SAAIvB;MAASrC,KACjC,CAACjH,GAAQiJ,MACR,IAAI5N,KAAK2E,EAAEnE,SAAS,EAAEN,QAAO,IAAK,IAAIF,KAAK4N,EAAEpN,SAAS,EAAEN,QAAO,CAAA,GAC9D;AACF6P,4BAAsBhL,IAAIyK,OAAON,WAAWM,MAAAA;IAC7C;AAEA,UAAMQ,iBAAiB,oBAAItL,IAAAA;AAC3B,eAAW8K,UAAUO,sBAAsB7F,OAAM,GAAI;AACpD,YAAM+F,kBAAkBC,OAAOV,OAAO/P,UAAUwQ,mBAAmB,EAAA;AACnE,UAAI,CAACE,yBAAyBF,eAAAA;AAAkB;AAChDD,qBAAejL,IACdkL,kBACCD,eAAenL,IAAIoL,eAAAA,KAAoB,KAAK,CAAA;IAE/C;AAEA,WAAO;MACNlC,UAAUqB,WAAWgB;MACrBpC,QAAQA,OAAOnK;MACfoK,SAASA,QAAQpK;MACjBqK,kBAAkBD,QAAQrL,OACzB,CAAC4M,WAAgBA,OAAO7Q,WAAW,WAAA,EAClCkF;MACFsK,gBAAgBF,QAAQrL,OACvB,CAAC4M,WAAgBA,OAAO7Q,WAAW,SAAA,EAClCkF;MACFuK,gBAAgBH,QAAQrL,OACvB,CAAC4M,WAAgBA,OAAO7Q,WAAW,SAAA,EAClCkF;MACFwK,cAAcA,aAAaxK;MAC3ByK,YAAYA,WAAWzK;MACvB0K,eAAeA,cAAc1K;MAC7B2K,8BAA8BiB,iBAAiBW;MAC/C3B,gCAAgC4B,KAAKC,IACpC,GACAlB,WAAWgB,OAAOX,iBAAiBW,IAAI;MAExC1B,sBAAsB;WAAIsB,eAAe9F,OAAM;QAAIsC,OAClD,CAACxG,OAAOlF,WAAUkF,QAAQlF,QAC1B,CAAA;MAED6N,eAAe;WAAIe,gBAAgBa,QAAO;QACxC7O,IAAI,CAAC,CAAC4J,KAAKxK,MAAAA,OAAY;QACvBwK;QACAuE,MAAMC,kBAAkBxE,GAAAA;QACxBkF,aAAaC,oBAAoBnF,GAAAA;QACjCxK,OAAAA;MACD,EAAA,EACC8K,KAAK,CAACjH,GAAGiJ,MAAMA,EAAE9M,QAAQ6D,EAAE7D,KAAK;MAClC8N,aAAa;WAAIe,iBAAiBY,QAAO;QACvC7O,IAAI,CAAC,CAACmO,MAAM/O,MAAAA,OAAY;QAAE+O;QAAM/O,OAAAA;MAAM,EAAA,EACtC8K,KAAK,CAACjH,GAAGiJ,MAAMA,EAAE9M,QAAQ6D,EAAE7D,KAAK;MAClC+N,eAAe;WAAImB,eAAeO,QAAO;QACvC7O,IAAI,CAAC,CAACuO,iBAAiBnP,MAAAA,OAAY;QAAEmP;QAAiBnP,OAAAA;MAAM,EAAA,EAC5D8K,KAAK,CAACjH,GAAGiJ,MAAMA,EAAE9M,QAAQ6D,EAAE7D,KAAK;MAClCwL,OAAO;QACN;QACA;;IAEF;EACD;AAlJewB;AAoJf,WAAS8B,wBAAwBT,iBAA0C;AAC1E,UAAMuB,QAAQR,OAAOf,mBAAmB,EAAA,EAAIuB,MAAM,eAAA;AAClD,WAAOA,QAAQ,CAAA,KAAM;EACtB;AAHSd;AAKT,WAASE,kBAAkBxE,KAAW;AACrC,UAAMqF,QAAQrF,IAAIsF,YAAY,GAAA;AAC9B,WAAOD,QAAQ,KAAKrF,IAAIuC,MAAM,GAAG8C,KAAAA,IAASrF;EAC3C;AAHSwE;AAKT,WAASW,oBAAoBnF,KAAW;AACvC,UAAMqF,QAAQrF,IAAIsF,YAAY,GAAA;AAC9B,WAAOD,QAAQ,KAAKrF,IAAIuC,MAAM8C,QAAQ,CAAA,IAAK;EAC5C;AAHSF;AAKT,WAASN,yBAAyBF,iBAAuB;AACxD,WAAO,oCAAoCY,KAAKZ,eAAAA;EACjD;AAFSE;AAIT,iBAAeW,iBAAiBtG,MAG/B;AACA,UAAMwD,SAAkC,CAAA;AAGxC,QAAIjL,SAAwB;AAC5B,QAAIE,YAA2BuH,KAAKtH,SAAS;AAC7C,QAAI6N,aAAuC;AAE3C,QAAIvG,KAAKC,YAAY;AACpB,YAAM,CAACC,QAAAA,IAAY,MAAM/M,GACvB+C,OAAO;QACPqC,QAAQlF,UAAUkF;QAClBG,OAAOnF,MAAMmF;MACd,CAAA,EACCnC,KAAKlD,SAAAA,EACLwE,SAAStE,OAAOuE,GAAGzE,UAAUkF,QAAQhF,MAAM2B,EAAE,CAAA,EAC7CsB,MAAMsB,GAAGzE,UAAU6B,IAAI8K,KAAKC,UAAU,CAAA,EACtC/H,MAAM,CAAA;AACRK,eAAS2H,UAAU3H,UAAU;AAC7BE,kBAAYyH,UAAUxH,SAASD;IAChC;AAEA,QAAIA,aAAa,CAACF,QAAQ;AACzB,YAAM,CAACiO,CAAAA,IAAK,MAAMrT,GAChB+C,OAAO;QAAEhB,IAAI3B,MAAM2B;MAAG,CAAA,EACtBqB,KAAKhD,KAAAA,EACLiD,MAAMsB,GAAGvE,MAAMmF,OAAOD,SAAAA,CAAAA,EACtBP,MAAM,CAAA;AACRK,eAASiO,GAAGtR,MAAM;IACnB;AAEA,QAAIqD,QAAQ;AACX,YAAM,CAACiO,CAAAA,IAAK,MAAMrT,GAChB+C,OAAO;QACPhB,IAAI3B,MAAM2B;QACVwD,OAAOnF,MAAMmF;QACbd,MAAMrE,MAAMqE;QACZ5B,WAAWzC,MAAMyC;MAClB,CAAA,EACCO,KAAKhD,KAAAA,EACLiD,MAAMsB,GAAGvE,MAAM2B,IAAIqD,MAAAA,CAAAA,EACnBL,MAAM,CAAA;AACRqO,mBAAaC,IACV;QACAtR,IAAIsR,EAAEtR;QACNwD,OAAO8N,EAAE9N;QACTd,MAAM4O,EAAE5O,QAAQ;QAChB5B,WAAWwQ,EAAExQ;MACd,IACC;IACJ;AAGA,UAAM+D,iBAAwB,CAAA;AAC9B,QAAIxB;AAAQwB,qBAAejE,KAAKgC,GAAGnE,qBAAqB4E,QAAQA,MAAAA,CAAAA;AAChE,QAAIE;AACHsB,qBAAejE,KAAKgC,GAAGnE,qBAAqB+E,OAAOD,SAAAA,CAAAA;AAEpD,QAAIsB,eAAeV,SAAS,GAAG;AAC9B,YAAMoN,QAAQ,MAAMtT,GAClB+C,OAAO;QACPlB,MAAMrB,qBAAqBqB;QAC3BgB,WAAWrC,qBAAqBqC;QAChCf,UAAUtB,qBAAqBsB;QAC/ByE,aAAa/F,qBAAqB+F;QAClCC,MAAMjG,UAAUiG;QAChBC,KAAKlG,UAAUkG;MAChB,CAAA,EACCrD,KAAK5C,oBAAAA,EACLkE,SAASnE,WAAWoE,GAAGnE,qBAAqB+F,aAAahG,UAAUwB,EAAE,CAAA,EACrEsB,MAAM/B,OAAOA,IAAI0K,KAAKpF,gBAAgBtF,SAAS,CAAA,GAAI,EACnDwC,QAAQtD,qBAAqBqC,SAAS;AAExC,iBAAWwE,QAAQiM,OAAO;AAEzB,cAAM5M,SAAS,MAAM1G,GACnB+C,OAAO;UACPuD,WAAW7F,eAAe6F;UAC1BiN,UAAU9S,eAAe8S;UACzBzO,SAASrE,eAAeqE;UACxB0O,QAAQ/S,eAAe+S;QACxB,CAAA,EACCpQ,KAAK3C,cAAAA,EACL4C,MACAnC,IACCyD,GAAGlE,eAAe8F,aAAac,KAAKd,WAAW,GAC/ClC,IAAI5D,eAAe6F,WAAWe,KAAKxE,SAAS,CAAA,CAAA,EAG7CiB,QAAQc,KAAKnE,eAAe6F,SAAS,CAAA,EACrCvB,MAAM,CAAA;AAER,mBAAW0O,SAAS/M,QAAQ;AAC3B2J,iBAAO1N,KAAK;YACXd,MAAM;YACNyE,WAAWmN,MAAMnN;YACjBoN,QAAQ;cACPnT,WAAW,MAAM8G,KAAKb,IAAI;cAC1BmN,aAAatM,KAAKZ;cAClB8M,UAAUE,MAAMF;cAChBzO,SAAS2O,MAAM3O;cACf0O,QAAQC,MAAMD;YACf;UACD,CAAA;QACD;AAEAnD,eAAO1N,KAAK;UACXd,MAAMwF,KAAKxF,SAAS,aAAa,aAAa;UAC9CyE,WAAWe,KAAKxE;UAChB6Q,QAAQ;YACPnT,WAAW,MAAM8G,KAAKb,IAAI;YAC1B1E,UAAUuF,KAAKvF,WAAW8R,KAAKC,MAAMxM,KAAKvF,QAAQ,IAAI;UACvD;QACD,CAAA;MACD;IACD;AAGA,QAAIsD,QAAQ;AACX,YAAM0O,WAAW,MAAM9T,GACrB+C,OAAO;QACP+I,YAAYxL,iBAAiBwL;QAC7BiI,aAAazT,iBAAiByT;QAC9BlR,WAAWvC,iBAAiBuC;MAC7B,CAAA,EACCO,KAAK9C,gBAAAA,EACL+C,MAAMsB,GAAGrE,iBAAiB8E,QAAQA,MAAAA,CAAAA,EAClCtB,QAAQxD,iBAAiBuC,SAAS,EAClCkC,MAAM,EAAA;AAER,iBAAWiP,KAAKF,UAAU;AACzBzD,eAAO1N,KAAK;UACXd,MAAM;UACNyE,WAAW0N,EAAED,eAAeC,EAAEnR;UAC9B6Q,QAAQ;YAAE5H,YAAYkI,EAAElI;UAAW;QACpC,CAAA;MACD;IACD;AAGA,UAAM3D,qBAAqB;MAAClH,aAAAA;;AAC5B,QAAI4L,KAAKC,YAAY;AACpB3E,yBAAmBxF,KAAKgC,GAAGzE,UAAU6B,IAAI8K,KAAKC,UAAU,CAAA;IACzD,WAAW1H,QAAQ;AAClB+C,yBAAmBxF,KAAKgC,GAAGzE,UAAUkF,QAAQA,MAAAA,CAAAA;IAC9C,OAAO;AAEN,aAAO;QAAEY,MAAMoN;QAAY/C,QAAQ,CAAA;QAAInQ,WAAW,CAAA;MAAG;IACtD;AAEA,UAAM+T,eAAe,MAAMjU,GACzB+C,OAAO;MACPhB,IAAI7B,UAAU6B;MACdX,aAAalB,UAAUkB;MACvBoD,aAAarE,SAASsE;MACtB5B,WAAW3C,UAAU2C;MACrBiC,SAAS5E,UAAU4E;MACnBtD,QAAQtB,UAAUsB;IACnB,CAAA,EACC4B,KAAKlD,SAAAA,EACLwE,SAASvE,UAAUwE,GAAGzE,UAAUqE,WAAWpE,SAAS4B,EAAE,CAAA,EACtDsB,MAAMnC,IAAAA,GAAOiH,kBAAAA,CAAAA,EACbrE,QAAQ5D,UAAU2C,SAAS;AAE7B,UAAMqR,kBAAkBD,aAAalQ,IAAI,CAACiQ,MAAAA;AACzC,YAAMxS,SAAUwS,EAAExS,UAAkC,CAAC;AACrD6O,aAAO1N,KAAK;QACXd,MAAM;QACNyE,WAAW0N,EAAEnR;QACb6Q,QAAQ;UACP5G,YAAYkH,EAAEjS;UACdoS,QAAQ7Q,OAAO0Q,EAAE5S,WAAW;UAC5B2E,SAASiO,EAAExP;QACZ;MACD,CAAA;AACA,aAAO;QACNzC,IAAIiS,EAAEjS;QACNX,aAAakC,OAAO0Q,EAAE5S,WAAW;QACjCoD,aAAawP,EAAExP,eAAe;QAC9B3B,WAAWmR,EAAEnR;QACbiC,SAASkP,EAAElP;QACX+I,WAAWrM,OAAOqM,aAAa;QAC/BuG,WAAW5S,OAAO4S,aAAa;QAC/BC,aAAa7S,OAAO6S,eAAe;MACpC;IACD,CAAA;AAGAhE,WAAOpC,KACN,CAACjH,GAAGiJ,MACH,IAAI5N,KAAK2E,EAAEV,SAAS,EAAE/D,QAAO,IAAK,IAAIF,KAAK4N,EAAE3J,SAAS,EAAE/D,QAAO,CAAA;AAGjE,WAAO;MAAEyD,MAAMoN;MAAY/C;MAAQnQ,WAAWgU;IAAgB;EAC/D;AArMef;AAuMf,SAAO;IACN3Q;IACAgB;IACAS;IACAK;IACAO;IACAG;IACAiB;IACAG;IACAkB;IACAW;IACAW;IACAkB;IACA4B;IACAkB;IACAsB;IACAiC;IACAgD;EACD;AACD;AAl9CgBpT;","names":["and","count","desc","eq","gt","gte","inArray","lte","sql","sum","SHORTLINK_RECOVERY_LANE","createDatabaseProvider","db","schema","purchases","products","users","coupon","resourceProgress","shortlink","shortlinkAttribution","shortlinkClick","questionResponse","contactEvent","sideEffectIntent","PAID_STATUSES","commerceRecord","inArray","status","paidPurchase","and","gt","totalAmount","accessGrant","sql","backfillFreeUpgrade","fields","syntheticSignalSql","syntheticPurchase","purchaseFieldAttributionSignalSql","exactShortlinkPurchaseAttributionSignalSql","type","metadata","id","shortlinkRecoveredAttributionSignalSql","attributionSignalSql","rangeToDate","range","now","Date","hours","getTime","getRevenueSummary","since","conditions","push","gte","createdAt","totals","select","totalRevenue","sum","purchaseCount","count","from","where","Number","avgOrderValue","getRevenueByDay","rows","date","as","revenue","groupBy","orderBy","map","r","getPreviousPeriodRevenueByDay","periodMs","periodStart","prevStart","lte","getRevenueByProduct","productId","productName","name","leftJoin","eq","desc","getRevenueByCountry","country","limit","getRecentPurchases","filter","bulkCouponId","couponId","userId","userName","userEmail","email","organizationId","seats","maxUses","isTeam","query","findMany","with","product","user","getAttributionSummary","length","undefined","getShortlinkPerformance","clickConditions","timestamp","shortlinkId","slug","url","clicks","innerJoin","attrConditions","attrRows","attrMap","Map","a","existing","get","signups","set","attr","getRevenueBySource","filters","kindExpr","sourceExpr","SHORTLINK_RECOVERY_LANE","mediumExpr","campaignExpr","kind","source","medium","campaign","getConversionFunnel","userConditions","purchaseConditions","userCount","total","attributedCount","totalSignups","totalPurchases","attributedPurchases","conversionRate","attributionCoverage","getCommerceLaneSummary","commerce","paid","grants","freeUpgrades","synthetic","reasonRows","reason","commerceRecords","paidPurchases","paidRevenue","accessGrants","accessGrantRevenue","syntheticPurchases","byAccessGrantReason","Object","fromEntries","row","getAttributedRevenueSummary","attributed","purchaseFieldAttributed","recoveredFromShortlinkAttributionTable","signalConditions","signalCount","condition","shortlinkCount","utmCount","clickIdCount","gaClientIdCount","selfReportedSourceCount","recoveredFromShortlinkAttributionTableCount","Promise","all","attributedRevenue","purchaseFieldAttributedRevenue","recoveredFromShortlinkAttributionTableRevenue","unattributedRevenue","attributionRate","purchaseFieldAttributedPurchases","recoveredFromShortlinkAttributionTablePurchases","signals","utm","paidClickId","gaClientId","selfReportedSource","internalFreeUpgrade","getContentPurchaseCorrelation","purchaserRows","selectDistinct","purchaserIds","resourceId","purchaserCount","join","parseJsonRecord","value","Boolean","Array","isArray","hasRecordValue","values","some","entry","hasSyntheticClickId","startsWith","getCheckoutAttributionReceipt","opts","purchaseId","purchase","checks","purchaseFound","attributionSnapshot","actualUtm","clickId","attribution","legacy","fieldKeys","clickIds","shortlinkSnapshot","ga","key","hasActualUtm","utmSource","keys","shortlinkRef","clientId","sort","getCheckoutSurveyFallbackReport","label","totalDarkPurchases","totalDarkRevenue","exactPurchaseLinkedPurchases","exactPurchaseLinkedRevenue","userLinkedPurchases","userLinkedRevenue","byAnswer","notes","darkRows","reduce","darkById","darkByUserId","bucket","responseConditions","darkIds","darkUserIds","exactPurchaseCondition","userCondition","responseRows","answer","exactByPurchase","latestByUser","has","current","rowTime","currentTime","classified","response","confidence","b","slice","getValuePathSummary","contacts","events","intents","completedIntents","pendingIntents","blockedIntents","answerEvents","dripEvents","enteredEvents","participantsWithAnswerClicks","participantsWithNoAnswerClicks","terminalParticipants","answerOptions","answerSteps","terminalSteps","eventConditions","eventType","intentConditions","occurredAt","contactId","providerEventId","contactIds","Set","event","add","intent","answersByContact","answerKeyCounts","answerStepCounts","parseValuePathAnswerKey","step","answerStepFromKey","latestIntentByContact","terminalCounts","emailResourceId","String","isTerminalValuePathEmail","size","Math","max","entries","optionValue","answerOptionFromKey","match","index","lastIndexOf","test","traceAttribution","userRecord","u","attrs","referrer","device","click","detail","destination","JSON","parse","progress","completedAt","p","purchaseRows","purchaseResults","amount","utmMedium","utmCampaign"]}
1
+ {"version":3,"sources":["../../src/providers/database.ts","../../src/providers/attribution-recovery.ts"],"sourcesContent":["import {\n\tand,\n\tcount,\n\tdesc,\n\teq,\n\tgt,\n\tgte,\n\tinArray,\n\tlte,\n\tsql,\n\tsum,\n} from 'drizzle-orm'\n\nimport { SHORTLINK_RECOVERY_LANE } from './attribution-recovery'\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type AnalyticsTimeRange = '24h' | '7d' | '30d' | '90d' | 'all'\n\nexport interface AttributionTrailEvent {\n\ttype: 'click' | 'signup' | 'progress' | 'purchase'\n\ttimestamp: Date\n\tdetail: Record<string, any>\n}\n\nexport interface AttributionTrail {\n\tuser: {\n\t\tid: string\n\t\temail: string | null\n\t\tname: string | null\n\t\tcreatedAt: Date\n\t} | null\n\tevents: AttributionTrailEvent[]\n\tpurchases: {\n\t\tid: string\n\t\ttotalAmount: number\n\t\tproductName: string\n\t\tcreatedAt: Date\n\t\tcountry: string | null\n\t\tutmSource: string | null\n\t\tutmMedium: string | null\n\t\tutmCampaign: string | null\n\t}[]\n}\n\n// ─── Schema type ─────────────────────────────────────────────────────────────\n\nexport interface DatabaseAnalyticsSchema {\n\tpurchases: any\n\tproducts: any\n\tusers: any\n\tcoupon: any\n\tresourceProgress: any\n\tshortlink: any\n\tshortlinkAttribution: any\n\tshortlinkClick: any\n\tquestionResponse?: any\n\tcontactEvent?: any\n\tsideEffectIntent?: any\n}\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\n/**\n * Creates a database analytics provider that wraps all analytics query\n * functions with an injected drizzle db instance and schema tables.\n *\n * @param db - Drizzle database instance\n * @param schema - Object containing the required table references\n */\nexport function createDatabaseProvider(\n\tdb: any,\n\tschema: DatabaseAnalyticsSchema,\n) {\n\tconst {\n\t\tpurchases,\n\t\tproducts,\n\t\tusers,\n\t\tcoupon,\n\t\tresourceProgress,\n\t\tshortlink,\n\t\tshortlinkAttribution,\n\t\tshortlinkClick,\n\t\tquestionResponse,\n\t\tcontactEvent,\n\t\tsideEffectIntent,\n\t} = schema\n\n\t// ─── Internal helpers ───────────────────────────────────────────────────\n\n\tconst PAID_STATUSES = ['Valid', 'Restricted'] as const\n\n\tfunction commerceRecord() {\n\t\treturn inArray(purchases.status, [...PAID_STATUSES])\n\t}\n\n\tfunction paidPurchase() {\n\t\treturn and(commerceRecord(), gt(purchases.totalAmount, 0))\n\t}\n\n\tfunction accessGrant() {\n\t\treturn and(commerceRecord(), sql`${purchases.totalAmount} = 0`)\n\t}\n\n\tfunction backfillFreeUpgrade() {\n\t\treturn and(\n\t\t\taccessGrant(),\n\t\t\tsql`JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'`,\n\t\t)\n\t}\n\n\tconst syntheticSignalSql = sql`(\n\t\tJSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.synthetic')) = 'true'\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.synthetic')) = 'true'\n\t\tOR JSON_SEARCH(JSON_EXTRACT(${purchases.fields}, '$.attribution.clickIds'), 'one', 'TEST_%') IS NOT NULL\n\t)`\n\n\tfunction syntheticPurchase() {\n\t\treturn and(commerceRecord(), syntheticSignalSql)\n\t}\n\n\tconst purchaseFieldAttributionSignalSql = sql`(\n\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution') IS NOT NULL\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')) IS NOT NULL\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.gaClientId')) IS NOT NULL\n\t)`\n\n\tconst exactShortlinkPurchaseAttributionSignalSql = sql`EXISTS (\n\t\tSELECT 1\n\t\tFROM ${shortlinkAttribution}\n\t\tWHERE ${shortlinkAttribution.type} = 'purchase'\n\t\t\tAND JSON_VALID(${shortlinkAttribution.metadata})\n\t\t\tAND JSON_UNQUOTE(JSON_EXTRACT(${shortlinkAttribution.metadata}, '$.purchaseId')) = ${purchases.id}\n\t)`\n\n\tconst shortlinkRecoveredAttributionSignalSql = sql`(\n\t\tNOT ${purchaseFieldAttributionSignalSql}\n\t\tAND ${exactShortlinkPurchaseAttributionSignalSql}\n\t)`\n\n\tconst attributionSignalSql = sql`(\n\t\t${purchaseFieldAttributionSignalSql}\n\t\tOR ${exactShortlinkPurchaseAttributionSignalSql}\n\t)`\n\n\tconst strongAttributionQualitySql = sql`(\n\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.clickIds') IS NOT NULL\n\t\tOR JSON_EXTRACT(${purchases.fields}, '$.attribution.utm') IS NOT NULL\n\t\tOR JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink') IS NOT NULL\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')) IS NOT NULL\n\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.shortlinkRef')) IS NOT NULL\n\t)`\n\n\tconst mediumAttributionQualitySql = sql`(\n\t\tNOT ${strongAttributionQualitySql}\n\t\tAND ${exactShortlinkPurchaseAttributionSignalSql}\n\t)`\n\n\tconst weakAttributionQualitySql = sql`(\n\t\tNOT ${strongAttributionQualitySql}\n\t\tAND NOT ${exactShortlinkPurchaseAttributionSignalSql}\n\t\tAND (\n\t\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL\n\t\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.gaClientId')) IS NOT NULL\n\t\t\tOR JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL\n\t\t)\n\t)`\n\n\tconst unknownAttributionQualitySql = sql`(\n\t\tNOT ${strongAttributionQualitySql}\n\t\tAND NOT ${mediumAttributionQualitySql}\n\t\tAND NOT ${weakAttributionQualitySql}\n\t)`\n\n\tfunction rangeToDate(range: AnalyticsTimeRange): Date | null {\n\t\tif (range === 'all') return null\n\t\tconst now = new Date()\n\t\tconst hours: Record<string, number> = {\n\t\t\t'24h': 24,\n\t\t\t'7d': 7 * 24,\n\t\t\t'30d': 30 * 24,\n\t\t\t'90d': 90 * 24,\n\t\t}\n\t\treturn new Date(now.getTime() - (hours[range] ?? 30 * 24) * 60 * 60 * 1000)\n\t}\n\n\t// ─── Revenue ───────────────────────────────────────────────────────────\n\n\tasync function getRevenueSummary(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst [totals] = await db\n\t\t\t.select({\n\t\t\t\ttotalRevenue: sum(purchases.totalAmount),\n\t\t\t\tpurchaseCount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\n\t\treturn {\n\t\t\ttotalRevenue: Number(totals?.totalRevenue ?? 0),\n\t\t\tpurchaseCount: totals?.purchaseCount ?? 0,\n\t\t\tavgOrderValue:\n\t\t\t\ttotals?.purchaseCount && totals.purchaseCount > 0\n\t\t\t\t\t? Number(totals.totalRevenue ?? 0) / totals.purchaseCount\n\t\t\t\t\t: 0,\n\t\t}\n\t}\n\n\tasync function getRevenueByDay(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tdate: sql<string>`DATE(${purchases.createdAt})`.as('date'),\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(sql`DATE(${purchases.createdAt})`)\n\t\t\t.orderBy(sql`DATE(${purchases.createdAt})`)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tdate: r.date,\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\t/**\n\t * Revenue by day for the previous period of equal length.\n\t * E.g., if range = '30d', returns the 30 days before those 30 days.\n\t * Returns data with a `dayOffset` (0 = start of period) for overlay\n\t * alignment.\n\t */\n\tasync function getPreviousPeriodRevenueByDay(\n\t\trange: AnalyticsTimeRange = '30d',\n\t) {\n\t\tif (range === 'all') return []\n\n\t\tconst hours: Record<string, number> = {\n\t\t\t'24h': 24,\n\t\t\t'7d': 7 * 24,\n\t\t\t'30d': 30 * 24,\n\t\t\t'90d': 90 * 24,\n\t\t}\n\t\tconst periodMs = (hours[range] ?? 30 * 24) * 60 * 60 * 1000\n\t\tconst now = new Date()\n\t\tconst periodStart = new Date(now.getTime() - periodMs)\n\t\tconst prevStart = new Date(periodStart.getTime() - periodMs)\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tdate: sql<string>`DATE(${purchases.createdAt})`.as('date'),\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\tpaidPurchase(),\n\t\t\t\t\tgte(purchases.createdAt, prevStart),\n\t\t\t\t\tlte(purchases.createdAt, periodStart),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.groupBy(sql`DATE(${purchases.createdAt})`)\n\t\t\t.orderBy(sql`DATE(${purchases.createdAt})`)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tdate: r.date,\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getRevenueByProduct(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tproductId: purchases.productId,\n\t\t\t\tproductName: products.name,\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(purchases.productId, products.name)\n\t\t\t.orderBy(desc(sum(purchases.totalAmount)))\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tproductId: r.productId,\n\t\t\tproductName: r.productName ?? '(unknown)',\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getRevenueByCountry(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tcountry: purchases.country,\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(purchases.country)\n\t\t\t.orderBy(desc(sum(purchases.totalAmount)))\n\t\t\t.limit(20)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tcountry: r.country ?? '(unknown)',\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getRecentPurchases(\n\t\tlimit: number = 20,\n\t\tfilter: 'all' | 'team' | 'individual' = 'all',\n\t\trange: AnalyticsTimeRange = 'all',\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\n\t\tif (filter === 'team') {\n\t\t\t// Multi-seat purchases: join coupon to filter seats > 1, sort by amount\n\t\t\tconditions.push(sql`${purchases.bulkCouponId} IS NOT NULL`)\n\n\t\t\tconst rows = await db\n\t\t\t\t.select({\n\t\t\t\t\tid: purchases.id,\n\t\t\t\t\tcreatedAt: purchases.createdAt,\n\t\t\t\t\ttotalAmount: purchases.totalAmount,\n\t\t\t\t\tproductName: products.name,\n\t\t\t\t\tproductId: purchases.productId,\n\t\t\t\t\tcountry: purchases.country,\n\t\t\t\t\tcouponId: purchases.couponId,\n\t\t\t\t\tuserId: purchases.userId,\n\t\t\t\t\tuserName: users.name,\n\t\t\t\t\tuserEmail: users.email,\n\t\t\t\t\torganizationId: purchases.organizationId,\n\t\t\t\t\tseats: coupon.maxUses,\n\t\t\t\t})\n\t\t\t\t.from(purchases)\n\t\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t\t.leftJoin(users, eq(purchases.userId, users.id))\n\t\t\t\t.leftJoin(coupon, eq(purchases.bulkCouponId, coupon.id))\n\t\t\t\t.where(and(...conditions, gt(coupon.maxUses, 1)))\n\t\t\t\t.orderBy(desc(purchases.totalAmount))\n\t\t\t\t.limit(limit)\n\n\t\t\treturn rows.map((r: any) => ({\n\t\t\t\tid: r.id,\n\t\t\t\tcreatedAt: r.createdAt,\n\t\t\t\ttotalAmount: Number(r.totalAmount),\n\t\t\t\tproductName: r.productName ?? '(unknown)',\n\t\t\t\tproductId: r.productId,\n\t\t\t\tcountry: r.country,\n\t\t\t\tcouponId: r.couponId,\n\t\t\t\tuserName: r.userName ?? null,\n\t\t\t\tuserEmail: r.userEmail ?? null,\n\t\t\t\tisTeam: true,\n\t\t\t\tseats: r.seats ?? null,\n\t\t\t}))\n\t\t}\n\n\t\tif (filter === 'individual') {\n\t\t\tconditions.push(sql`${purchases.bulkCouponId} IS NULL`)\n\t\t}\n\n\t\tconst rows = await db.query.purchases.findMany({\n\t\t\twhere: and(...conditions),\n\t\t\torderBy: [desc(purchases.totalAmount)],\n\t\t\tlimit,\n\t\t\twith: {\n\t\t\t\tproduct: true,\n\t\t\t\tuser: true,\n\t\t\t},\n\t\t})\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tid: r.id,\n\t\t\tcreatedAt: r.createdAt,\n\t\t\ttotalAmount: Number(r.totalAmount),\n\t\t\tproductName: r.product?.name ?? '(unknown)',\n\t\t\tproductId: r.productId,\n\t\t\tcountry: r.country,\n\t\t\tcouponId: r.couponId,\n\t\t\tuserName: r.user?.name ?? null,\n\t\t\tuserEmail: r.user?.email ?? null,\n\t\t\tisTeam: r.organizationId != null,\n\t\t\tseats: null as number | null,\n\t\t}))\n\t}\n\n\t// ─── Attribution ────────────────────────────────────────────────────────\n\n\tasync function getAttributionSummary(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions: any[] = []\n\t\tif (since) conditions.push(gte(shortlinkAttribution.createdAt, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\ttype: shortlinkAttribution.type,\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(shortlinkAttribution)\n\t\t\t.where(conditions.length > 0 ? and(...conditions) : undefined)\n\t\t\t.groupBy(shortlinkAttribution.type)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\ttype: r.type,\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getShortlinkPerformance(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\t\tconst clickConditions: any[] = []\n\t\tif (since) clickConditions.push(gte(shortlinkClick.timestamp, since))\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tshortlinkId: shortlinkClick.shortlinkId,\n\t\t\t\tslug: shortlink.slug,\n\t\t\t\turl: shortlink.url,\n\t\t\t\tclicks: count(),\n\t\t\t})\n\t\t\t.from(shortlinkClick)\n\t\t\t.innerJoin(shortlink, eq(shortlinkClick.shortlinkId, shortlink.id))\n\t\t\t.where(clickConditions.length > 0 ? and(...clickConditions) : undefined)\n\t\t\t.groupBy(shortlinkClick.shortlinkId, shortlink.slug, shortlink.url)\n\t\t\t.orderBy(desc(count()))\n\t\t\t.limit(20)\n\n\t\t// Get attribution counts per shortlink\n\t\tconst attrConditions: any[] = []\n\t\tif (since) attrConditions.push(gte(shortlinkAttribution.createdAt, since))\n\n\t\tconst attrRows = await db\n\t\t\t.select({\n\t\t\t\tshortlinkId: shortlinkAttribution.shortlinkId,\n\t\t\t\ttype: shortlinkAttribution.type,\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(shortlinkAttribution)\n\t\t\t.where(attrConditions.length > 0 ? and(...attrConditions) : undefined)\n\t\t\t.groupBy(shortlinkAttribution.shortlinkId, shortlinkAttribution.type)\n\n\t\tconst attrMap = new Map<string, { signups: number; purchases: number }>()\n\t\tfor (const a of attrRows) {\n\t\t\tconst existing = attrMap.get(a.shortlinkId) ?? {\n\t\t\t\tsignups: 0,\n\t\t\t\tpurchases: 0,\n\t\t\t}\n\t\t\tif (a.type === 'signup') existing.signups = a.count\n\t\t\tif (a.type === 'purchase') existing.purchases = a.count\n\t\t\tattrMap.set(a.shortlinkId, existing)\n\t\t}\n\n\t\treturn rows.map((r: any) => {\n\t\t\tconst attr = attrMap.get(r.shortlinkId)\n\t\t\treturn {\n\t\t\t\tshortlinkId: r.shortlinkId,\n\t\t\t\tslug: r.slug,\n\t\t\t\turl: r.url,\n\t\t\t\tclicks: r.clicks,\n\t\t\t\tsignups: attr?.signups ?? 0,\n\t\t\t\tpurchases: attr?.purchases ?? 0,\n\t\t\t}\n\t\t})\n\t}\n\n\t// ─── Revenue Attribution ─────────────────────────────────────────────────\n\n\tasync function getRevenueBySource(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [commerceRecord()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId)\n\t\t\tconditions.push(eq(purchases.productId, filters.productId))\n\n\t\tconst kindExpr = sql<string>`CASE\n\t\t\tWHEN ${syntheticSignalSql} THEN 'synthetic'\n\t\t\tWHEN ${purchases.totalAmount} = 0 THEN 'access_grant'\n\t\t\tWHEN ${purchases.totalAmount} > 0 THEN 'paid_conversion'\n\t\t\tELSE 'unknown'\n\t\tEND`\n\t\tconst sourceExpr = sql<string>`CASE\n\t\t\tWHEN JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'\n\t\t\t\tTHEN 'internal'\n\t\t\tWHEN ${shortlinkRecoveredAttributionSignalSql} THEN ${SHORTLINK_RECOVERY_LANE}\n\t\t\tELSE COALESCE(\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.source')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.utm.source')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')), 'null'),\n\t\t\t\tCASE\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug') IS NOT NULL THEN 'shortlink'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL THEN 'self_reported'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL THEN 'ga4'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.gaClientId') IS NOT NULL THEN 'ga4'\n\t\t\t\t\tELSE NULL\n\t\t\t\tEND\n\t\t\t)\n\t\tEND`\n\t\tconst mediumExpr = sql<string>`CASE\n\t\t\tWHEN JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'\n\t\t\t\tTHEN 'free_upgrade'\n\t\t\tWHEN ${shortlinkRecoveredAttributionSignalSql} THEN 'shortlink'\n\t\t\tELSE COALESCE(\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.medium')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.utm.medium')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmMedium')), 'null'),\n\t\t\t\tCASE\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug') IS NOT NULL THEN 'shortlink'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL THEN 'checkout_survey'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL THEN 'client_id'\n\t\t\t\t\tWHEN JSON_EXTRACT(${purchases.fields}, '$.gaClientId') IS NOT NULL THEN 'client_id'\n\t\t\t\t\tELSE NULL\n\t\t\t\tEND\n\t\t\t)\n\t\tEND`\n\t\tconst campaignExpr = sql<string>`CASE\n\t\t\tWHEN JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfill')) = 'true'\n\t\t\t\tTHEN COALESCE(\n\t\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.migrationBatchId')), 'null'),\n\t\t\t\t\t'free_upgrade'\n\t\t\t\t)\n\t\t\tWHEN ${shortlinkRecoveredAttributionSignalSql} THEN NULL\n\t\t\tELSE COALESCE(\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.campaign')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.utm.campaign')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmCampaign')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug')), 'null'),\n\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource')), 'null')\n\t\t\t)\n\t\tEND`\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tkind: kindExpr.as('kind'),\n\t\t\t\tsource: sourceExpr.as('source'),\n\t\t\t\tmedium: mediumExpr.as('medium'),\n\t\t\t\tcampaign: campaignExpr.as('campaign'),\n\t\t\t\trevenue: sum(purchases.totalAmount),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\t\t.groupBy(sql`1`, sql`2`, sql`3`, sql`4`)\n\t\t\t.orderBy(desc(sum(purchases.totalAmount)), desc(count()))\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tkind: r.kind ?? 'unknown',\n\t\t\tsource: r.source ?? null,\n\t\t\tmedium: r.medium ?? null,\n\t\t\tcampaign: r.campaign ?? null,\n\t\t\trevenue: Number(r.revenue ?? 0),\n\t\t\tcount: r.count,\n\t\t}))\n\t}\n\n\tasync function getConversionFunnel(range: AnalyticsTimeRange = '30d') {\n\t\tconst since = rangeToDate(range)\n\n\t\tconst userConditions = since ? [gte(users.createdAt, since)] : []\n\t\tconst purchaseConditions = [paidPurchase()]\n\t\tif (since) purchaseConditions.push(gte(purchases.createdAt, since))\n\n\t\tconst [userCount] = await db\n\t\t\t.select({ total: count() })\n\t\t\t.from(users)\n\t\t\t.where(userConditions.length > 0 ? and(...userConditions) : undefined)\n\n\t\tconst [purchaseCount] = await db\n\t\t\t.select({ total: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions))\n\n\t\tconst [attributedCount] = await db\n\t\t\t.select({ total: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions, attributionSignalSql))\n\n\t\tconst totalSignups = userCount?.total ?? 0\n\t\tconst totalPurchases = purchaseCount?.total ?? 0\n\t\tconst attributedPurchases = attributedCount?.total ?? 0\n\n\t\treturn {\n\t\t\ttotalSignups,\n\t\t\ttotalPurchases,\n\t\t\tattributedPurchases,\n\t\t\tconversionRate: totalSignups > 0 ? totalPurchases / totalSignups : 0,\n\t\t\tattributionCoverage:\n\t\t\t\ttotalPurchases > 0 ? attributedPurchases / totalPurchases : 0,\n\t\t}\n\t}\n\n\tasync function getCommerceLaneSummary(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [commerceRecord()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId)\n\t\t\tconditions.push(eq(purchases.productId, filters.productId))\n\n\t\tconst [commerce] = await db\n\t\t\t.select({ count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\t\tconst [paid] = await db\n\t\t\t.select({ count: count(), revenue: sum(purchases.totalAmount) })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, paidPurchase()))\n\t\tconst [grants] = await db\n\t\t\t.select({ count: count(), revenue: sum(purchases.totalAmount) })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, accessGrant()))\n\t\tconst [freeUpgrades] = await db\n\t\t\t.select({ count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, backfillFreeUpgrade()))\n\t\tconst [synthetic] = await db\n\t\t\t.select({ count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, syntheticPurchase()))\n\t\tconst reasonRows = await db\n\t\t\t.select({\n\t\t\t\treason: sql<string>`COALESCE(\n\t\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfillReason')), 'null'),\n\t\t\t\t\t'access_grant'\n\t\t\t\t)`.as('reason'),\n\t\t\t\tcount: count(),\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, accessGrant()))\n\t\t\t.groupBy(\n\t\t\t\tsql`COALESCE(\n\t\t\t\t\tNULLIF(JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.backfillReason')), 'null'),\n\t\t\t\t\t'access_grant'\n\t\t\t\t)`,\n\t\t\t)\n\n\t\treturn {\n\t\t\tcommerceRecords: commerce?.count ?? 0,\n\t\t\tpaidPurchases: paid?.count ?? 0,\n\t\t\tpaidRevenue: Number(paid?.revenue ?? 0),\n\t\t\taccessGrants: grants?.count ?? 0,\n\t\t\taccessGrantRevenue: Number(grants?.revenue ?? 0),\n\t\t\tfreeUpgrades: freeUpgrades?.count ?? 0,\n\t\t\tsyntheticPurchases: synthetic?.count ?? 0,\n\t\t\tbyAccessGrantReason: Object.fromEntries(\n\t\t\t\treasonRows.map((row: any) => [row.reason, row.count]),\n\t\t\t),\n\t\t}\n\t}\n\n\tasync function getAttributedRevenueSummary(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst conditions = [paidPurchase()]\n\t\tif (since) conditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId)\n\t\t\tconditions.push(eq(purchases.productId, filters.productId))\n\n\t\tconst [totals] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions))\n\n\t\tconst [attributed] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, attributionSignalSql))\n\n\t\tconst [purchaseFieldAttributed] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, purchaseFieldAttributionSignalSql))\n\n\t\tconst [recoveredFromShortlinkAttributionTable] = await db\n\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...conditions, shortlinkRecoveredAttributionSignalSql))\n\n\t\tconst signalConditions = since\n\t\t\t? [commerceRecord(), gte(purchases.createdAt, since)]\n\t\t\t: [commerceRecord()]\n\t\tif (filters.productId) {\n\t\t\tsignalConditions.push(eq(purchases.productId, filters.productId))\n\t\t}\n\t\tconst signalCount = async (condition: any) => {\n\t\t\tconst [row] = await db\n\t\t\t\t.select({ count: count() })\n\t\t\t\t.from(purchases)\n\t\t\t\t.where(and(...signalConditions, condition))\n\t\t\treturn row?.count ?? 0\n\t\t}\n\t\tconst qualityLane = async (\n\t\t\tlane: 'strong' | 'medium' | 'weak' | 'unknown',\n\t\t\tcondition: any,\n\t\t\tnotes: string[],\n\t\t) => {\n\t\t\tconst [row] = await db\n\t\t\t\t.select({ total: sum(purchases.totalAmount), count: count() })\n\t\t\t\t.from(purchases)\n\t\t\t\t.where(and(...conditions, condition))\n\t\t\tconst revenue = Number(row?.total ?? 0)\n\t\t\treturn {\n\t\t\t\tlane,\n\t\t\t\tpurchases: row?.count ?? 0,\n\t\t\t\trevenue,\n\t\t\t\trevenuePercent: totalRevenue > 0 ? revenue / totalRevenue : 0,\n\t\t\t\tnotes,\n\t\t\t}\n\t\t}\n\t\tconst [\n\t\t\tshortlinkCount,\n\t\t\tutmCount,\n\t\t\tclickIdCount,\n\t\t\tgaClientIdCount,\n\t\t\tselfReportedSourceCount,\n\t\t\trecoveredFromShortlinkAttributionTableCount,\n\t\t] = await Promise.all([\n\t\t\tsignalCount(\n\t\t\t\tsql`(\n\t\t\t\t\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug') IS NOT NULL\n\t\t\t\t\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.shortlinkRef')) IS NOT NULL\n\t\t\t\t\t)`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`(\n\t\t\t\t\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.utm') IS NOT NULL\n\t\t\t\t\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')) IS NOT NULL\n\t\t\t\t\t)`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`JSON_EXTRACT(${purchases.fields}, '$.attribution.clickIds') IS NOT NULL`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`(\n\t\t\t\t\t\tJSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL\n\t\t\t\t\t\tOR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.gaClientId')) IS NOT NULL\n\t\t\t\t\t)`,\n\t\t\t),\n\t\t\tsignalCount(\n\t\t\t\tsql`JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL`,\n\t\t\t),\n\t\t\tsignalCount(shortlinkRecoveredAttributionSignalSql),\n\t\t])\n\n\t\tconst commerce = await getCommerceLaneSummary(range, filters)\n\t\tconst totalRevenue = Number(totals?.total ?? 0)\n\t\tconst attributedRevenue = Number(attributed?.total ?? 0)\n\t\tconst purchaseFieldAttributedRevenue = Number(\n\t\t\tpurchaseFieldAttributed?.total ?? 0,\n\t\t)\n\t\tconst recoveredFromShortlinkAttributionTableRevenue = Number(\n\t\t\trecoveredFromShortlinkAttributionTable?.total ?? 0,\n\t\t)\n\t\tconst unattributedRevenue = totalRevenue - attributedRevenue\n\t\tconst paidPurchases = totals?.count ?? 0\n\t\tconst [strongQuality, mediumQuality, weakQuality, unknownQuality] =\n\t\t\tawait Promise.all([\n\t\t\t\tqualityLane('strong', strongAttributionQualitySql, [\n\t\t\t\t\t'Purchase-field UTM, shortlink, or paid click evidence.',\n\t\t\t\t]),\n\t\t\t\tqualityLane('medium', mediumAttributionQualitySql, [\n\t\t\t\t\t'Recovered from exact shortlink attribution table purchase match.',\n\t\t\t\t]),\n\t\t\t\tqualityLane('weak', weakAttributionQualitySql, [\n\t\t\t\t\t'GA client ID or self-reported source without stronger campaign evidence.',\n\t\t\t\t]),\n\t\t\t\tqualityLane('unknown', unknownAttributionQualitySql, [\n\t\t\t\t\t'No usable attribution evidence for paid revenue.',\n\t\t\t\t]),\n\t\t\t])\n\n\t\treturn {\n\t\t\ttotalRevenue,\n\t\t\tattributedRevenue,\n\t\t\tunattributedRevenue,\n\t\t\tattributionRate: totalRevenue > 0 ? attributedRevenue / totalRevenue : 0,\n\t\t\ttotalPurchases: commerce.commerceRecords,\n\t\t\tpaidPurchases,\n\t\t\tpurchaseFieldAttributedPurchases: purchaseFieldAttributed?.count ?? 0,\n\t\t\tpurchaseFieldAttributedRevenue,\n\t\t\trecoveredFromShortlinkAttributionTablePurchases:\n\t\t\t\trecoveredFromShortlinkAttributionTable?.count ?? 0,\n\t\t\trecoveredFromShortlinkAttributionTableRevenue,\n\t\t\tcommerceRecords: commerce.commerceRecords,\n\t\t\taccessGrants: commerce.accessGrants,\n\t\t\tfreeUpgrades: commerce.freeUpgrades,\n\t\t\tsyntheticPurchases: commerce.syntheticPurchases,\n\t\t\tcommerce,\n\t\t\tsignals: {\n\t\t\t\tshortlink: shortlinkCount,\n\t\t\t\tutm: utmCount,\n\t\t\t\tpaidClickId: clickIdCount,\n\t\t\t\tgaClientId: gaClientIdCount,\n\t\t\t\tselfReportedSource: selfReportedSourceCount,\n\t\t\t\trecoveredFromShortlinkAttributionTable:\n\t\t\t\t\trecoveredFromShortlinkAttributionTableCount,\n\t\t\t\tinternalFreeUpgrade: commerce.freeUpgrades,\n\t\t\t},\n\t\t\tquality: {\n\t\t\t\tstrong: strongQuality,\n\t\t\t\tmedium: mediumQuality,\n\t\t\t\tweak: weakQuality,\n\t\t\t\tunknown: unknownQuality,\n\t\t\t},\n\t\t}\n\t}\n\n\tasync function getContentPurchaseCorrelation(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tlimit: number = 20,\n\t) {\n\t\tconst since = rangeToDate(range)\n\t\tconst purchaseConditions = [paidPurchase()]\n\t\tif (since) purchaseConditions.push(gte(purchases.createdAt, since))\n\n\t\tconst purchaserRows = await db\n\t\t\t.selectDistinct({ userId: purchases.userId })\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions))\n\n\t\tconst purchaserIds = purchaserRows\n\t\t\t.map((r: any) => r.userId)\n\t\t\t.filter((id: any): id is string => id !== null)\n\n\t\tif (purchaserIds.length === 0) return []\n\n\t\tconst rows = await db\n\t\t\t.select({\n\t\t\t\tresourceId: resourceProgress.resourceId,\n\t\t\t\tpurchaserCount: count(),\n\t\t\t})\n\t\t\t.from(resourceProgress)\n\t\t\t.where(\n\t\t\t\tsql`${resourceProgress.userId} IN (${sql.join(\n\t\t\t\t\tpurchaserIds.map((id: string) => sql`${id}`),\n\t\t\t\t\tsql`, `,\n\t\t\t\t)})`,\n\t\t\t)\n\t\t\t.groupBy(resourceProgress.resourceId)\n\t\t\t.orderBy(desc(count()))\n\t\t\t.limit(limit)\n\n\t\treturn rows.map((r: any) => ({\n\t\t\tresourceId: r.resourceId,\n\t\t\tpurchaserCount: r.purchaserCount,\n\t\t}))\n\t}\n\n\t/**\n\t * Parses an unknown JSON-like value into a plain record.\n\t *\n\t * @param value Unknown input value from a JSON database column.\n\t * @returns A Record<string, any> when the value is a record, otherwise an empty object.\n\t */\n\tfunction parseJsonRecord(value: unknown): Record<string, any> {\n\t\treturn Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n\t\t\t? (value as Record<string, any>)\n\t\t\t: {}\n\t}\n\n\t/**\n\t * Checks whether a record contains at least one non-empty string value.\n\t *\n\t * @param value Unknown input value to inspect.\n\t * @returns True when at least one record value is a non-empty string.\n\t */\n\tfunction hasRecordValue(value: unknown) {\n\t\treturn (\n\t\t\tBoolean(value) &&\n\t\t\ttypeof value === 'object' &&\n\t\t\t!Array.isArray(value) &&\n\t\t\tObject.values(value as Record<string, unknown>).some(\n\t\t\t\t(entry) => typeof entry === 'string' && entry.length > 0,\n\t\t\t)\n\t\t)\n\t}\n\n\t/**\n\t * Checks whether a click ID record contains a synthetic TEST_ value.\n\t *\n\t * @param value Unknown input value to inspect.\n\t * @returns True when any record value is a string starting with TEST_.\n\t */\n\tfunction hasSyntheticClickId(value: unknown) {\n\t\treturn (\n\t\t\tBoolean(value) &&\n\t\t\ttypeof value === 'object' &&\n\t\t\t!Array.isArray(value) &&\n\t\t\tObject.values(value as Record<string, unknown>).some(\n\t\t\t\t(entry) => typeof entry === 'string' && entry.startsWith('TEST_'),\n\t\t\t)\n\t\t)\n\t}\n\n\tasync function getCheckoutAttributionReceipt(opts: { purchaseId?: string }) {\n\t\tif (!opts.purchaseId) {\n\t\t\treturn {\n\t\t\t\tpurchase: null,\n\t\t\t\tchecks: {\n\t\t\t\t\tpurchaseFound: false,\n\t\t\t\t\tattributionSnapshot: false,\n\t\t\t\t\tutm: false,\n\t\t\t\t\tactualUtm: false,\n\t\t\t\t\tclickId: false,\n\t\t\t\t\tsynthetic: false,\n\t\t\t\t\tshortlink: false,\n\t\t\t\t\tselfReportedSource: false,\n\t\t\t\t\tgaClientId: false,\n\t\t\t\t},\n\t\t\t\tattribution: null,\n\t\t\t\tlegacy: {},\n\t\t\t\tfieldKeys: [],\n\t\t\t}\n\t\t}\n\n\t\tconst [row] = await db\n\t\t\t.select({\n\t\t\t\tid: purchases.id,\n\t\t\t\tcreatedAt: purchases.createdAt,\n\t\t\t\tproductId: purchases.productId,\n\t\t\t\tproductName: products.name,\n\t\t\t\ttotalAmount: purchases.totalAmount,\n\t\t\t\tstatus: purchases.status,\n\t\t\t\tcountry: purchases.country,\n\t\t\t\tfields: purchases.fields,\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t.where(eq(purchases.id, opts.purchaseId))\n\t\t\t.limit(1)\n\n\t\tif (!row) {\n\t\t\treturn {\n\t\t\t\tpurchase: null,\n\t\t\t\tchecks: {\n\t\t\t\t\tpurchaseFound: false,\n\t\t\t\t\tattributionSnapshot: false,\n\t\t\t\t\tutm: false,\n\t\t\t\t\tactualUtm: false,\n\t\t\t\t\tclickId: false,\n\t\t\t\t\tsynthetic: false,\n\t\t\t\t\tshortlink: false,\n\t\t\t\t\tselfReportedSource: false,\n\t\t\t\t\tgaClientId: false,\n\t\t\t\t},\n\t\t\t\tattribution: null,\n\t\t\t\tlegacy: {},\n\t\t\t\tfieldKeys: [],\n\t\t\t}\n\t\t}\n\n\t\tconst fields = parseJsonRecord(row.fields)\n\t\tconst attribution = parseJsonRecord(fields.attribution)\n\t\tconst utm = parseJsonRecord(attribution.utm)\n\t\tconst clickIds = parseJsonRecord(attribution.clickIds)\n\t\tconst shortlinkSnapshot = parseJsonRecord(attribution.shortlink)\n\t\tconst ga = parseJsonRecord(attribution.ga)\n\t\tconst legacy = Object.fromEntries(\n\t\t\t[\n\t\t\t\t'utmSource',\n\t\t\t\t'utmMedium',\n\t\t\t\t'utmCampaign',\n\t\t\t\t'gaClientId',\n\t\t\t\t'shortlinkRef',\n\t\t\t\t'landingPath',\n\t\t\t\t'referrer',\n\t\t\t\t'ltUtmSource',\n\t\t\t\t'ltUtmMedium',\n\t\t\t\t'ltUtmCampaign',\n\t\t\t]\n\t\t\t\t.map((key) => [key, fields[key]])\n\t\t\t\t.filter(([, value]) => value !== undefined && value !== null),\n\t\t)\n\t\tconst hasActualUtm = Boolean(\n\t\t\tutm.source || utm.medium || utm.campaign || fields.utmSource,\n\t\t)\n\t\tconst synthetic = Boolean(\n\t\t\tattribution.synthetic ||\n\t\t\tfields.synthetic ||\n\t\t\thasSyntheticClickId(clickIds),\n\t\t)\n\n\t\treturn {\n\t\t\tpurchase: {\n\t\t\t\tid: row.id,\n\t\t\t\tcreatedAt: row.createdAt,\n\t\t\t\tproductId: row.productId,\n\t\t\t\tproductName: row.productName ?? null,\n\t\t\t\ttotalAmount: Number(row.totalAmount ?? 0),\n\t\t\t\tstatus: row.status,\n\t\t\t\tcountry: row.country,\n\t\t\t},\n\t\t\tchecks: {\n\t\t\t\tpurchaseFound: true,\n\t\t\t\tattributionSnapshot: Object.keys(attribution).length > 0,\n\t\t\t\tutm: hasActualUtm,\n\t\t\t\tactualUtm: hasActualUtm,\n\t\t\t\tclickId: hasRecordValue(clickIds),\n\t\t\t\tsynthetic,\n\t\t\t\tshortlink: Boolean(shortlinkSnapshot.slug || fields.shortlinkRef),\n\t\t\t\tselfReportedSource: Boolean(attribution.selfReportedSource),\n\t\t\t\tgaClientId: Boolean(ga.clientId || fields.gaClientId),\n\t\t\t},\n\t\t\tattribution: Object.keys(attribution).length > 0 ? attribution : null,\n\t\t\tlegacy,\n\t\t\tfieldKeys: Object.keys(fields).sort(),\n\t\t}\n\t}\n\n\tasync function getCheckoutSurveyFallbackReport(\n\t\trange: AnalyticsTimeRange = '30d',\n\t\tlimit: number = 20,\n\t\tfilters: { productId?: string } = {},\n\t) {\n\t\tconst label = 'recovered_from_checkout_survey_response'\n\t\tif (!questionResponse) {\n\t\t\treturn {\n\t\t\t\tlabel,\n\t\t\t\tproductId: filters.productId ?? null,\n\t\t\t\ttotalDarkPurchases: 0,\n\t\t\t\ttotalDarkRevenue: 0,\n\t\t\t\texactPurchaseLinkedPurchases: 0,\n\t\t\t\texactPurchaseLinkedRevenue: 0,\n\t\t\t\tuserLinkedPurchases: 0,\n\t\t\t\tuserLinkedRevenue: 0,\n\t\t\t\tbyAnswer: [],\n\t\t\t\tnotes: ['questionResponse table was not provided to this provider'],\n\t\t\t}\n\t\t}\n\n\t\tconst since = rangeToDate(range)\n\t\tconst purchaseConditions = [\n\t\t\tpaidPurchase(),\n\t\t\tsql`NOT ${attributionSignalSql}`,\n\t\t]\n\t\tif (since) purchaseConditions.push(gte(purchases.createdAt, since))\n\t\tif (filters.productId) {\n\t\t\tpurchaseConditions.push(eq(purchases.productId, filters.productId))\n\t\t}\n\n\t\tconst darkRows = await db\n\t\t\t.select({\n\t\t\t\tid: purchases.id,\n\t\t\t\tuserId: purchases.userId,\n\t\t\t\trevenue: purchases.totalAmount,\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.where(and(...purchaseConditions))\n\n\t\tconst totalDarkRevenue = darkRows.reduce(\n\t\t\t(total: number, row: any) => total + Number(row.revenue ?? 0),\n\t\t\t0,\n\t\t)\n\n\t\tif (darkRows.length === 0) {\n\t\t\treturn {\n\t\t\t\tlabel,\n\t\t\t\tproductId: filters.productId ?? null,\n\t\t\t\ttotalDarkPurchases: 0,\n\t\t\t\ttotalDarkRevenue: 0,\n\t\t\t\texactPurchaseLinkedPurchases: 0,\n\t\t\t\texactPurchaseLinkedRevenue: 0,\n\t\t\t\tuserLinkedPurchases: 0,\n\t\t\t\tuserLinkedRevenue: 0,\n\t\t\t\tbyAnswer: [],\n\t\t\t\tnotes: ['No dark paid purchases matched the filters'],\n\t\t\t}\n\t\t}\n\n\t\tconst darkById = new Map<string, (typeof darkRows)[number]>(\n\t\t\tdarkRows.map((row: (typeof darkRows)[number]) => [row.id, row]),\n\t\t)\n\t\tconst darkByUserId = new Map<string, any[]>()\n\t\tfor (const row of darkRows) {\n\t\t\tif (!row.userId) continue\n\t\t\tconst bucket = darkByUserId.get(row.userId) ?? []\n\t\t\tbucket.push(row)\n\t\t\tdarkByUserId.set(row.userId, bucket)\n\t\t}\n\n\t\tconst responseConditions: any[] = []\n\t\tif (since) responseConditions.push(gte(questionResponse.createdAt, since))\n\t\tconst darkIds = [...darkById.keys()]\n\t\tconst darkUserIds = [...darkByUserId.keys()]\n\t\tconst exactPurchaseCondition = sql`JSON_UNQUOTE(JSON_EXTRACT(${questionResponse.fields}, '$.purchaseId')) IN (${sql.join(\n\t\t\tdarkIds.map((id) => sql`${id}`),\n\t\t\tsql`, `,\n\t\t)})`\n\t\tconst userCondition =\n\t\t\tdarkUserIds.length > 0\n\t\t\t\t? sql`${questionResponse.userId} IN (${sql.join(\n\t\t\t\t\t\tdarkUserIds.map((id) => sql`${id}`),\n\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t)})`\n\t\t\t\t: sql`FALSE`\n\t\tresponseConditions.push(\n\t\t\tsql`(${exactPurchaseCondition} OR ${userCondition})`,\n\t\t)\n\n\t\tconst responseRows = await db\n\t\t\t.select({\n\t\t\t\tpurchaseId: sql<string>`JSON_UNQUOTE(JSON_EXTRACT(${questionResponse.fields}, '$.purchaseId'))`,\n\t\t\t\tanswer: sql<string>`JSON_UNQUOTE(JSON_EXTRACT(${questionResponse.fields}, '$.answer'))`,\n\t\t\t\tuserId: questionResponse.userId,\n\t\t\t\tcreatedAt: questionResponse.createdAt,\n\t\t\t})\n\t\t\t.from(questionResponse)\n\t\t\t.where(and(...responseConditions))\n\n\t\tconst exactByPurchase = new Map<string, any>()\n\t\tconst latestByUser = new Map<string, any>()\n\t\tfor (const row of responseRows) {\n\t\t\tif (row.purchaseId && darkById.has(row.purchaseId)) {\n\t\t\t\texactByPurchase.set(row.purchaseId, row)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!row.userId) continue\n\t\t\tconst current = latestByUser.get(row.userId)\n\t\t\tconst rowTime = new Date(row.createdAt ?? 0).getTime()\n\t\t\tconst currentTime = current\n\t\t\t\t? new Date(current.createdAt ?? 0).getTime()\n\t\t\t\t: -1\n\t\t\tif (!current || rowTime >= currentTime) latestByUser.set(row.userId, row)\n\t\t}\n\n\t\tconst classified = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tconfidence: 'exact_purchase_link' | 'user_linked'\n\t\t\t\tanswer: string\n\t\t\t\trevenue: number\n\t\t\t}\n\t\t>()\n\t\tfor (const [purchaseId, response] of exactByPurchase) {\n\t\t\tconst purchase = darkById.get(purchaseId)\n\t\t\tclassified.set(purchaseId, {\n\t\t\t\tconfidence: 'exact_purchase_link',\n\t\t\t\tanswer: response.answer || '(no answer)',\n\t\t\t\trevenue: Number(purchase?.revenue ?? 0),\n\t\t\t})\n\t\t}\n\t\tfor (const row of darkRows) {\n\t\t\tif (classified.has(row.id) || !row.userId) continue\n\t\t\tconst response = latestByUser.get(row.userId)\n\t\t\tif (!response) continue\n\t\t\tclassified.set(row.id, {\n\t\t\t\tconfidence: 'user_linked',\n\t\t\t\tanswer: response.answer || '(no answer)',\n\t\t\t\trevenue: Number(row.revenue ?? 0),\n\t\t\t})\n\t\t}\n\n\t\tconst byAnswer = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\tanswer: string\n\t\t\t\tconfidence: 'exact_purchase_link' | 'user_linked'\n\t\t\t\tpurchases: number\n\t\t\t\trevenue: number\n\t\t\t}\n\t\t>()\n\t\tlet exactPurchaseLinkedPurchases = 0\n\t\tlet exactPurchaseLinkedRevenue = 0\n\t\tlet userLinkedPurchases = 0\n\t\tlet userLinkedRevenue = 0\n\t\tfor (const entry of classified.values()) {\n\t\t\tif (entry.confidence === 'exact_purchase_link') {\n\t\t\t\texactPurchaseLinkedPurchases += 1\n\t\t\t\texactPurchaseLinkedRevenue += entry.revenue\n\t\t\t} else {\n\t\t\t\tuserLinkedPurchases += 1\n\t\t\t\tuserLinkedRevenue += entry.revenue\n\t\t\t}\n\t\t\tconst key = `${entry.confidence}:${entry.answer}`\n\t\t\tconst current = byAnswer.get(key) ?? {\n\t\t\t\tanswer: entry.answer,\n\t\t\t\tconfidence: entry.confidence,\n\t\t\t\tpurchases: 0,\n\t\t\t\trevenue: 0,\n\t\t\t}\n\t\t\tcurrent.purchases += 1\n\t\t\tcurrent.revenue += entry.revenue\n\t\t\tbyAnswer.set(key, current)\n\t\t}\n\n\t\treturn {\n\t\t\tlabel,\n\t\t\tproductId: filters.productId ?? null,\n\t\t\ttotalDarkPurchases: darkRows.length,\n\t\t\ttotalDarkRevenue,\n\t\t\texactPurchaseLinkedPurchases,\n\t\t\texactPurchaseLinkedRevenue,\n\t\t\tuserLinkedPurchases,\n\t\t\tuserLinkedRevenue,\n\t\t\tbyAnswer: [...byAnswer.values()]\n\t\t\t\t.sort((a, b) => b.revenue - a.revenue || b.purchases - a.purchases)\n\t\t\t\t.slice(0, limit),\n\t\t\tnotes: [\n\t\t\t\t'Report-only fallback. No purchase fields are mutated.',\n\t\t\t\t'Exact purchase-linked responses use QuestionResponse.fields.purchaseId when present.',\n\t\t\t\t'User-linked responses are lower-confidence and remain report-only.',\n\t\t\t],\n\t\t}\n\t}\n\n\t// ─── Attribution Trail ───────────────────────────────────────────────────\n\n\t/**\n\t * Trace the full attribution journey for a user by email or purchaseId.\n\t * Walks: ShortlinkClick → ShortlinkAttribution (signup) →\n\t * ResourceProgress → Purchase\n\t */\n\n\tasync function getValuePathSummary(range: AnalyticsTimeRange = '30d') {\n\t\tif (!contactEvent || !sideEffectIntent) {\n\t\t\treturn {\n\t\t\t\tcontacts: 0,\n\t\t\t\tevents: 0,\n\t\t\t\tintents: 0,\n\t\t\t\tcompletedIntents: 0,\n\t\t\t\tpendingIntents: 0,\n\t\t\t\tblockedIntents: 0,\n\t\t\t\tanswerEvents: 0,\n\t\t\t\tdripEvents: 0,\n\t\t\t\tenteredEvents: 0,\n\t\t\t\tparticipantsWithAnswerClicks: 0,\n\t\t\t\tparticipantsWithNoAnswerClicks: 0,\n\t\t\t\tterminalParticipants: 0,\n\t\t\t\tanswerOptions: [],\n\t\t\t\tanswerSteps: [],\n\t\t\t\tterminalSteps: [],\n\t\t\t\tnotes: ['Contact Event and SideEffectIntent tables are unavailable.'],\n\t\t\t}\n\t\t}\n\n\t\tconst since = rangeToDate(range)\n\t\tconst eventConditions = [sql`${contactEvent.eventType} LIKE 'value-path.%'`]\n\t\tconst intentConditions = [\n\t\t\teq(sideEffectIntent.type, 'send-value-path-email'),\n\t\t]\n\t\tif (since) {\n\t\t\teventConditions.push(gte(contactEvent.occurredAt, since))\n\t\t\tintentConditions.push(gte(sideEffectIntent.createdAt, since))\n\t\t}\n\n\t\tconst [events, intents] = await Promise.all([\n\t\t\tdb\n\t\t\t\t.select({\n\t\t\t\t\tcontactId: contactEvent.contactId,\n\t\t\t\t\teventType: contactEvent.eventType,\n\t\t\t\t\tproviderEventId: contactEvent.providerEventId,\n\t\t\t\t\toccurredAt: contactEvent.occurredAt,\n\t\t\t\t})\n\t\t\t\t.from(contactEvent)\n\t\t\t\t.where(and(...eventConditions)),\n\t\t\tdb\n\t\t\t\t.select({\n\t\t\t\t\tcontactId: sideEffectIntent.contactId,\n\t\t\t\t\tstatus: sideEffectIntent.status,\n\t\t\t\t\tmetadata: sideEffectIntent.metadata,\n\t\t\t\t\tcreatedAt: sideEffectIntent.createdAt,\n\t\t\t\t})\n\t\t\t\t.from(sideEffectIntent)\n\t\t\t\t.where(and(...intentConditions)),\n\t\t])\n\n\t\tconst contactIds = new Set<string>()\n\t\tfor (const event of events) contactIds.add(event.contactId)\n\t\tfor (const intent of intents) contactIds.add(intent.contactId)\n\n\t\tconst answerEvents = events.filter(\n\t\t\t(event: any) => event.eventType === 'value-path.answer-selected',\n\t\t)\n\t\tconst dripEvents = events.filter(\n\t\t\t(event: any) => event.eventType === 'value-path.drip-progressed',\n\t\t)\n\t\tconst enteredEvents = events.filter(\n\t\t\t(event: any) => event.eventType === 'value-path.entered',\n\t\t)\n\n\t\tconst answersByContact = new Map<string, number>()\n\t\tfor (const event of answerEvents) {\n\t\t\tanswersByContact.set(\n\t\t\t\tevent.contactId,\n\t\t\t\t(answersByContact.get(event.contactId) ?? 0) + 1,\n\t\t\t)\n\t\t}\n\n\t\tconst answerKeyCounts = new Map<string, number>()\n\t\tconst answerStepCounts = new Map<string, number>()\n\t\tfor (const event of answerEvents) {\n\t\t\tconst key = parseValuePathAnswerKey(event.providerEventId)\n\t\t\tanswerKeyCounts.set(key, (answerKeyCounts.get(key) ?? 0) + 1)\n\t\t\tconst step = answerStepFromKey(key)\n\t\t\tanswerStepCounts.set(step, (answerStepCounts.get(step) ?? 0) + 1)\n\t\t}\n\n\t\tconst latestIntentByContact = new Map<string, any>()\n\t\tfor (const intent of [...intents].sort(\n\t\t\t(a: any, b: any) =>\n\t\t\t\tnew Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(),\n\t\t)) {\n\t\t\tlatestIntentByContact.set(intent.contactId, intent)\n\t\t}\n\n\t\tconst terminalCounts = new Map<string, number>()\n\t\tfor (const intent of latestIntentByContact.values()) {\n\t\t\tconst emailResourceId = String(intent.metadata?.emailResourceId ?? '')\n\t\t\tif (!isTerminalValuePathEmail(emailResourceId)) continue\n\t\t\tterminalCounts.set(\n\t\t\t\temailResourceId,\n\t\t\t\t(terminalCounts.get(emailResourceId) ?? 0) + 1,\n\t\t\t)\n\t\t}\n\n\t\treturn {\n\t\t\tcontacts: contactIds.size,\n\t\t\tevents: events.length,\n\t\t\tintents: intents.length,\n\t\t\tcompletedIntents: intents.filter(\n\t\t\t\t(intent: any) => intent.status === 'completed',\n\t\t\t).length,\n\t\t\tpendingIntents: intents.filter(\n\t\t\t\t(intent: any) => intent.status === 'pending',\n\t\t\t).length,\n\t\t\tblockedIntents: intents.filter(\n\t\t\t\t(intent: any) => intent.status === 'blocked',\n\t\t\t).length,\n\t\t\tanswerEvents: answerEvents.length,\n\t\t\tdripEvents: dripEvents.length,\n\t\t\tenteredEvents: enteredEvents.length,\n\t\t\tparticipantsWithAnswerClicks: answersByContact.size,\n\t\t\tparticipantsWithNoAnswerClicks: Math.max(\n\t\t\t\t0,\n\t\t\t\tcontactIds.size - answersByContact.size,\n\t\t\t),\n\t\t\tterminalParticipants: [...terminalCounts.values()].reduce(\n\t\t\t\t(total, count) => total + count,\n\t\t\t\t0,\n\t\t\t),\n\t\t\tanswerOptions: [...answerKeyCounts.entries()]\n\t\t\t\t.map(([key, count]) => ({\n\t\t\t\t\tkey,\n\t\t\t\t\tstep: answerStepFromKey(key),\n\t\t\t\t\toptionValue: answerOptionFromKey(key),\n\t\t\t\t\tcount,\n\t\t\t\t}))\n\t\t\t\t.sort((a, b) => b.count - a.count),\n\t\t\tanswerSteps: [...answerStepCounts.entries()]\n\t\t\t\t.map(([step, count]) => ({ step, count }))\n\t\t\t\t.sort((a, b) => b.count - a.count),\n\t\t\tterminalSteps: [...terminalCounts.entries()]\n\t\t\t\t.map(([emailResourceId, count]) => ({ emailResourceId, count }))\n\t\t\t\t.sort((a, b) => b.count - a.count),\n\t\t\tnotes: [\n\t\t\t\t'Counts are based on Contact Events and SideEffectIntents.',\n\t\t\t\t'Kit-native opens, unsubscribes, complaints, and raw Kit link clicks are not included.',\n\t\t\t],\n\t\t}\n\t}\n\n\tfunction parseValuePathAnswerKey(providerEventId: string | null | undefined) {\n\t\tconst match = String(providerEventId ?? '').match(/:answer:(.+)$/)\n\t\treturn match?.[1] ?? 'unknown'\n\t}\n\n\tfunction answerStepFromKey(key: string) {\n\t\tconst index = key.lastIndexOf('.')\n\t\treturn index > -1 ? key.slice(0, index) : key\n\t}\n\n\tfunction answerOptionFromKey(key: string) {\n\t\tconst index = key.lastIndexOf('.')\n\t\treturn index > -1 ? key.slice(index + 1) : 'unknown'\n\t}\n\n\tfunction isTerminalValuePathEmail(emailResourceId: string) {\n\t\treturn /(?:^|\\.)(?:email-6|team-email-6)$/.test(emailResourceId)\n\t}\n\n\tasync function traceAttribution(opts: {\n\t\temail?: string\n\t\tpurchaseId?: string\n\t}): Promise<AttributionTrail> {\n\t\tconst events: AttributionTrailEvent[] = []\n\n\t\t// Resolve user\n\t\tlet userId: string | null = null\n\t\tlet userEmail: string | null = opts.email ?? null\n\t\tlet userRecord: AttributionTrail['user'] = null\n\n\t\tif (opts.purchaseId) {\n\t\t\tconst [purchase] = await db\n\t\t\t\t.select({\n\t\t\t\t\tuserId: purchases.userId,\n\t\t\t\t\temail: users.email,\n\t\t\t\t})\n\t\t\t\t.from(purchases)\n\t\t\t\t.leftJoin(users, eq(purchases.userId, users.id))\n\t\t\t\t.where(eq(purchases.id, opts.purchaseId))\n\t\t\t\t.limit(1)\n\t\t\tuserId = purchase?.userId ?? null\n\t\t\tuserEmail = purchase?.email ?? userEmail\n\t\t}\n\n\t\tif (userEmail && !userId) {\n\t\t\tconst [u] = await db\n\t\t\t\t.select({ id: users.id })\n\t\t\t\t.from(users)\n\t\t\t\t.where(eq(users.email, userEmail))\n\t\t\t\t.limit(1)\n\t\t\tuserId = u?.id ?? null\n\t\t}\n\n\t\tif (userId) {\n\t\t\tconst [u] = await db\n\t\t\t\t.select({\n\t\t\t\t\tid: users.id,\n\t\t\t\t\temail: users.email,\n\t\t\t\t\tname: users.name,\n\t\t\t\t\tcreatedAt: users.createdAt,\n\t\t\t\t})\n\t\t\t\t.from(users)\n\t\t\t\t.where(eq(users.id, userId))\n\t\t\t\t.limit(1)\n\t\t\tuserRecord = u\n\t\t\t\t? {\n\t\t\t\t\t\tid: u.id,\n\t\t\t\t\t\temail: u.email,\n\t\t\t\t\t\tname: u.name ?? null,\n\t\t\t\t\t\tcreatedAt: u.createdAt!,\n\t\t\t\t\t}\n\t\t\t\t: null\n\t\t}\n\n\t\t// Find shortlink attributions for this user (by userId or email)\n\t\tconst attrConditions: any[] = []\n\t\tif (userId) attrConditions.push(eq(shortlinkAttribution.userId, userId))\n\t\tif (userEmail)\n\t\t\tattrConditions.push(eq(shortlinkAttribution.email, userEmail))\n\n\t\tif (attrConditions.length > 0) {\n\t\t\tconst attrs = await db\n\t\t\t\t.select({\n\t\t\t\t\ttype: shortlinkAttribution.type,\n\t\t\t\t\tcreatedAt: shortlinkAttribution.createdAt,\n\t\t\t\t\tmetadata: shortlinkAttribution.metadata,\n\t\t\t\t\tshortlinkId: shortlinkAttribution.shortlinkId,\n\t\t\t\t\tslug: shortlink.slug,\n\t\t\t\t\turl: shortlink.url,\n\t\t\t\t})\n\t\t\t\t.from(shortlinkAttribution)\n\t\t\t\t.leftJoin(shortlink, eq(shortlinkAttribution.shortlinkId, shortlink.id))\n\t\t\t\t.where(sql`(${sql.join(attrConditions, sql` OR `)})`)\n\t\t\t\t.orderBy(shortlinkAttribution.createdAt)\n\n\t\t\tfor (const attr of attrs) {\n\t\t\t\t// Find clicks on this shortlink before the attribution event\n\t\t\t\tconst clicks = await db\n\t\t\t\t\t.select({\n\t\t\t\t\t\ttimestamp: shortlinkClick.timestamp,\n\t\t\t\t\t\treferrer: shortlinkClick.referrer,\n\t\t\t\t\t\tcountry: shortlinkClick.country,\n\t\t\t\t\t\tdevice: shortlinkClick.device,\n\t\t\t\t\t})\n\t\t\t\t\t.from(shortlinkClick)\n\t\t\t\t\t.where(\n\t\t\t\t\t\tand(\n\t\t\t\t\t\t\teq(shortlinkClick.shortlinkId, attr.shortlinkId),\n\t\t\t\t\t\t\tlte(shortlinkClick.timestamp, attr.createdAt),\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\t.orderBy(desc(shortlinkClick.timestamp))\n\t\t\t\t\t.limit(3) // last 3 clicks before attribution\n\n\t\t\t\tfor (const click of clicks) {\n\t\t\t\t\tevents.push({\n\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\ttimestamp: click.timestamp,\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\tshortlink: `/s/${attr.slug}`,\n\t\t\t\t\t\t\tdestination: attr.url,\n\t\t\t\t\t\t\treferrer: click.referrer,\n\t\t\t\t\t\t\tcountry: click.country,\n\t\t\t\t\t\t\tdevice: click.device,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tevents.push({\n\t\t\t\t\ttype: attr.type === 'purchase' ? 'purchase' : 'signup',\n\t\t\t\t\ttimestamp: attr.createdAt,\n\t\t\t\t\tdetail: {\n\t\t\t\t\t\tshortlink: `/s/${attr.slug}`,\n\t\t\t\t\t\tmetadata: attr.metadata ? JSON.parse(attr.metadata) : null,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Find resource progress for this user\n\t\tif (userId) {\n\t\t\tconst progress = await db\n\t\t\t\t.select({\n\t\t\t\t\tresourceId: resourceProgress.resourceId,\n\t\t\t\t\tcompletedAt: resourceProgress.completedAt,\n\t\t\t\t\tcreatedAt: resourceProgress.createdAt,\n\t\t\t\t})\n\t\t\t\t.from(resourceProgress)\n\t\t\t\t.where(eq(resourceProgress.userId, userId))\n\t\t\t\t.orderBy(resourceProgress.createdAt)\n\t\t\t\t.limit(20) // cap at 20 most recent\n\n\t\t\tfor (const p of progress) {\n\t\t\t\tevents.push({\n\t\t\t\t\ttype: 'progress',\n\t\t\t\t\ttimestamp: p.completedAt ?? p.createdAt,\n\t\t\t\t\tdetail: { resourceId: p.resourceId },\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Find purchases\n\t\tconst purchaseConditions = [paidPurchase()]\n\t\tif (opts.purchaseId) {\n\t\t\tpurchaseConditions.push(eq(purchases.id, opts.purchaseId))\n\t\t} else if (userId) {\n\t\t\tpurchaseConditions.push(eq(purchases.userId, userId))\n\t\t} else {\n\t\t\t// No user found, return empty\n\t\t\treturn { user: userRecord, events: [], purchases: [] }\n\t\t}\n\n\t\tconst purchaseRows = await db\n\t\t\t.select({\n\t\t\t\tid: purchases.id,\n\t\t\t\ttotalAmount: purchases.totalAmount,\n\t\t\t\tproductName: products.name,\n\t\t\t\tcreatedAt: purchases.createdAt,\n\t\t\t\tcountry: purchases.country,\n\t\t\t\tfields: purchases.fields,\n\t\t\t})\n\t\t\t.from(purchases)\n\t\t\t.leftJoin(products, eq(purchases.productId, products.id))\n\t\t\t.where(and(...purchaseConditions))\n\t\t\t.orderBy(purchases.createdAt)\n\n\t\tconst purchaseResults = purchaseRows.map((p: any) => {\n\t\t\tconst fields = (p.fields as Record<string, any>) ?? {}\n\t\t\tevents.push({\n\t\t\t\ttype: 'purchase',\n\t\t\t\ttimestamp: p.createdAt,\n\t\t\t\tdetail: {\n\t\t\t\t\tpurchaseId: p.id,\n\t\t\t\t\tamount: Number(p.totalAmount),\n\t\t\t\t\tproduct: p.productName,\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn {\n\t\t\t\tid: p.id,\n\t\t\t\ttotalAmount: Number(p.totalAmount),\n\t\t\t\tproductName: p.productName ?? 'Unknown',\n\t\t\t\tcreatedAt: p.createdAt,\n\t\t\t\tcountry: p.country,\n\t\t\t\tutmSource: fields.utmSource ?? null,\n\t\t\t\tutmMedium: fields.utmMedium ?? null,\n\t\t\t\tutmCampaign: fields.utmCampaign ?? null,\n\t\t\t}\n\t\t})\n\n\t\t// Sort all events by timestamp\n\t\tevents.sort(\n\t\t\t(a, b) =>\n\t\t\t\tnew Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),\n\t\t)\n\n\t\treturn { user: userRecord, events, purchases: purchaseResults }\n\t}\n\n\treturn {\n\t\tgetRevenueSummary,\n\t\tgetRevenueByDay,\n\t\tgetPreviousPeriodRevenueByDay,\n\t\tgetRevenueByProduct,\n\t\tgetRevenueByCountry,\n\t\tgetRecentPurchases,\n\t\tgetAttributionSummary,\n\t\tgetShortlinkPerformance,\n\t\tgetRevenueBySource,\n\t\tgetConversionFunnel,\n\t\tgetCommerceLaneSummary,\n\t\tgetAttributedRevenueSummary,\n\t\tgetContentPurchaseCorrelation,\n\t\tgetCheckoutAttributionReceipt,\n\t\tgetCheckoutSurveyFallbackReport,\n\t\tgetValuePathSummary,\n\t\ttraceAttribution,\n\t}\n}\n\nexport type DatabaseAnalyticsProvider = ReturnType<\n\ttypeof createDatabaseProvider\n>\n","export const SHORTLINK_RECOVERY_LANE =\n\t'recovered_from_shortlink_attribution_table' as const\n\nexport type PurchaseAttributionClass =\n\t| 'purchase_field'\n\t| typeof SHORTLINK_RECOVERY_LANE\n\t| 'dark'\n\nexport interface ShortlinkAttributionEvidence {\n\ttype?: string | null\n\tmetadata?: unknown\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction nonEmptyString(value: unknown) {\n\treturn typeof value === 'string' && value.trim().length > 0\n}\n\nfunction parseMetadata(value: unknown): Record<string, unknown> | null {\n\tif (typeof value === 'string') {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(value) as unknown\n\t\t\treturn isRecord(parsed) ? parsed : null\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t}\n\n\treturn isRecord(value) ? value : null\n}\n\n/**\n * Detects durable purchase-field attribution on a purchase fields object.\n *\n * @param fields Unknown purchase fields payload.\n * @returns True when the purchase already has attribution, legacy UTM source, or legacy GA client ID evidence.\n * @example\n * hasPurchaseFieldAttribution({ attribution: { source: 'email' } })\n */\nexport function hasPurchaseFieldAttribution(fields: unknown) {\n\tconst record = isRecord(fields) ? fields : {}\n\tconst attribution = record.attribution\n\n\treturn Boolean(\n\t\t(isRecord(attribution) && Object.keys(attribution).length > 0) ||\n\t\tnonEmptyString(record.utmSource) ||\n\t\tnonEmptyString(record.gaClientId),\n\t)\n}\n\n/**\n * Detects exact shortlink purchase evidence for one purchase.\n *\n * @param params.purchaseId Purchase ID that must match attribution metadata.purchaseId.\n * @param params.attributions ShortlinkAttributionEvidence rows to inspect.\n * @returns True only for purchase rows with valid JSON metadata and an exact purchase ID match.\n */\nexport function hasExactShortlinkPurchaseAttribution(params: {\n\tpurchaseId: string\n\tattributions: readonly ShortlinkAttributionEvidence[]\n}) {\n\treturn params.attributions.some((attribution) => {\n\t\tif (attribution.type !== 'purchase') return false\n\t\tconst metadata = parseMetadata(attribution.metadata)\n\t\treturn metadata?.purchaseId === params.purchaseId\n\t})\n}\n\n/**\n * Classifies purchase attribution with purchase fields taking precedence.\n *\n * @param params.purchaseId Purchase ID being classified.\n * @param params.fields Purchase fields payload.\n * @param params.shortlinkAttributions ShortlinkAttributionEvidence rows used as exact fallback evidence.\n * @returns A PurchaseAttributionClass: 'purchase_field', SHORTLINK_RECOVERY_LANE, or 'dark'.\n * @example\n * classifyPurchaseAttribution({ purchaseId: 'p1', fields: {}, shortlinkAttributions: [] })\n */\nexport function classifyPurchaseAttribution(params: {\n\tpurchaseId: string\n\tfields?: unknown\n\tshortlinkAttributions?: readonly ShortlinkAttributionEvidence[]\n}): PurchaseAttributionClass {\n\tif (hasPurchaseFieldAttribution(params.fields)) return 'purchase_field'\n\tif (\n\t\thasExactShortlinkPurchaseAttribution({\n\t\t\tpurchaseId: params.purchaseId,\n\t\t\tattributions: params.shortlinkAttributions ?? [],\n\t\t})\n\t) {\n\t\treturn SHORTLINK_RECOVERY_LANE\n\t}\n\treturn 'dark'\n}\n"],"mappings":"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","names":["and","count","desc","eq","gt","gte","inArray","lte","sql","sum","SHORTLINK_RECOVERY_LANE","createDatabaseProvider","db","schema","purchases","products","users","coupon","resourceProgress","shortlink","shortlinkAttribution","shortlinkClick","questionResponse","contactEvent","sideEffectIntent","PAID_STATUSES","commerceRecord","inArray","status","paidPurchase","and","gt","totalAmount","accessGrant","sql","backfillFreeUpgrade","fields","syntheticSignalSql","syntheticPurchase","purchaseFieldAttributionSignalSql","exactShortlinkPurchaseAttributionSignalSql","type","metadata","id","shortlinkRecoveredAttributionSignalSql","attributionSignalSql","strongAttributionQualitySql","mediumAttributionQualitySql","weakAttributionQualitySql","unknownAttributionQualitySql","rangeToDate","range","now","Date","hours","getTime","getRevenueSummary","since","conditions","push","gte","createdAt","totals","select","totalRevenue","sum","purchaseCount","count","from","where","Number","avgOrderValue","getRevenueByDay","rows","date","as","revenue","groupBy","orderBy","map","r","getPreviousPeriodRevenueByDay","periodMs","periodStart","prevStart","lte","getRevenueByProduct","productId","productName","name","leftJoin","eq","desc","getRevenueByCountry","country","limit","getRecentPurchases","filter","bulkCouponId","couponId","userId","userName","userEmail","email","organizationId","seats","maxUses","isTeam","query","findMany","with","product","user","getAttributionSummary","length","undefined","getShortlinkPerformance","clickConditions","timestamp","shortlinkId","slug","url","clicks","innerJoin","attrConditions","attrRows","attrMap","Map","a","existing","get","signups","set","attr","getRevenueBySource","filters","kindExpr","sourceExpr","SHORTLINK_RECOVERY_LANE","mediumExpr","campaignExpr","kind","source","medium","campaign","getConversionFunnel","userConditions","purchaseConditions","userCount","total","attributedCount","totalSignups","totalPurchases","attributedPurchases","conversionRate","attributionCoverage","getCommerceLaneSummary","commerce","paid","grants","freeUpgrades","synthetic","reasonRows","reason","commerceRecords","paidPurchases","paidRevenue","accessGrants","accessGrantRevenue","syntheticPurchases","byAccessGrantReason","Object","fromEntries","row","getAttributedRevenueSummary","attributed","purchaseFieldAttributed","recoveredFromShortlinkAttributionTable","signalConditions","signalCount","condition","qualityLane","lane","notes","revenuePercent","shortlinkCount","utmCount","clickIdCount","gaClientIdCount","selfReportedSourceCount","recoveredFromShortlinkAttributionTableCount","Promise","all","attributedRevenue","purchaseFieldAttributedRevenue","recoveredFromShortlinkAttributionTableRevenue","unattributedRevenue","strongQuality","mediumQuality","weakQuality","unknownQuality","attributionRate","purchaseFieldAttributedPurchases","recoveredFromShortlinkAttributionTablePurchases","signals","utm","paidClickId","gaClientId","selfReportedSource","internalFreeUpgrade","quality","strong","weak","unknown","getContentPurchaseCorrelation","purchaserRows","selectDistinct","purchaserIds","resourceId","purchaserCount","join","parseJsonRecord","value","Boolean","Array","isArray","hasRecordValue","values","some","entry","hasSyntheticClickId","startsWith","getCheckoutAttributionReceipt","opts","purchaseId","purchase","checks","purchaseFound","attributionSnapshot","actualUtm","clickId","attribution","legacy","fieldKeys","clickIds","shortlinkSnapshot","ga","key","hasActualUtm","utmSource","keys","shortlinkRef","clientId","sort","getCheckoutSurveyFallbackReport","label","totalDarkPurchases","totalDarkRevenue","exactPurchaseLinkedPurchases","exactPurchaseLinkedRevenue","userLinkedPurchases","userLinkedRevenue","byAnswer","darkRows","reduce","darkById","darkByUserId","bucket","responseConditions","darkIds","darkUserIds","exactPurchaseCondition","userCondition","responseRows","answer","exactByPurchase","latestByUser","has","current","rowTime","currentTime","classified","response","confidence","b","slice","getValuePathSummary","contacts","events","intents","completedIntents","pendingIntents","blockedIntents","answerEvents","dripEvents","enteredEvents","participantsWithAnswerClicks","participantsWithNoAnswerClicks","terminalParticipants","answerOptions","answerSteps","terminalSteps","eventConditions","eventType","intentConditions","occurredAt","contactId","providerEventId","contactIds","Set","event","add","intent","answersByContact","answerKeyCounts","answerStepCounts","parseValuePathAnswerKey","step","answerStepFromKey","latestIntentByContact","terminalCounts","emailResourceId","String","isTerminalValuePathEmail","size","Math","max","entries","optionValue","answerOptionFromKey","match","index","lastIndexOf","test","traceAttribution","userRecord","u","attrs","referrer","device","click","detail","destination","JSON","parse","progress","completedAt","p","purchaseRows","purchaseResults","amount","utmMedium","utmCampaign"]}
@@ -61,6 +61,31 @@ function createDatabaseProvider(db, schema) {
61
61
  ${purchaseFieldAttributionSignalSql}
62
62
  OR ${exactShortlinkPurchaseAttributionSignalSql}
63
63
  )`;
64
+ const strongAttributionQualitySql = sql`(
65
+ JSON_EXTRACT(${purchases.fields}, '$.attribution.clickIds') IS NOT NULL
66
+ OR JSON_EXTRACT(${purchases.fields}, '$.attribution.utm') IS NOT NULL
67
+ OR JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink') IS NOT NULL
68
+ OR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.utmSource')) IS NOT NULL
69
+ OR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.shortlinkRef')) IS NOT NULL
70
+ )`;
71
+ const mediumAttributionQualitySql = sql`(
72
+ NOT ${strongAttributionQualitySql}
73
+ AND ${exactShortlinkPurchaseAttributionSignalSql}
74
+ )`;
75
+ const weakAttributionQualitySql = sql`(
76
+ NOT ${strongAttributionQualitySql}
77
+ AND NOT ${exactShortlinkPurchaseAttributionSignalSql}
78
+ AND (
79
+ JSON_EXTRACT(${purchases.fields}, '$.attribution.ga.clientId') IS NOT NULL
80
+ OR JSON_UNQUOTE(JSON_EXTRACT(${purchases.fields}, '$.gaClientId')) IS NOT NULL
81
+ OR JSON_EXTRACT(${purchases.fields}, '$.attribution.selfReportedSource') IS NOT NULL
82
+ )
83
+ )`;
84
+ const unknownAttributionQualitySql = sql`(
85
+ NOT ${strongAttributionQualitySql}
86
+ AND NOT ${mediumAttributionQualitySql}
87
+ AND NOT ${weakAttributionQualitySql}
88
+ )`;
64
89
  function rangeToDate(range) {
65
90
  if (range === "all")
66
91
  return null;
@@ -505,6 +530,20 @@ function createDatabaseProvider(db, schema) {
505
530
  }).from(purchases).where(and(...signalConditions, condition));
506
531
  return row?.count ?? 0;
507
532
  }, "signalCount");
533
+ const qualityLane = /* @__PURE__ */ __name(async (lane, condition, notes) => {
534
+ const [row] = await db.select({
535
+ total: sum(purchases.totalAmount),
536
+ count: count()
537
+ }).from(purchases).where(and(...conditions, condition));
538
+ const revenue = Number(row?.total ?? 0);
539
+ return {
540
+ lane,
541
+ purchases: row?.count ?? 0,
542
+ revenue,
543
+ revenuePercent: totalRevenue > 0 ? revenue / totalRevenue : 0,
544
+ notes
545
+ };
546
+ }, "qualityLane");
508
547
  const [shortlinkCount, utmCount, clickIdCount, gaClientIdCount, selfReportedSourceCount, recoveredFromShortlinkAttributionTableCount] = await Promise.all([
509
548
  signalCount(sql`(
510
549
  JSON_EXTRACT(${purchases.fields}, '$.attribution.shortlink.slug') IS NOT NULL
@@ -529,6 +568,20 @@ function createDatabaseProvider(db, schema) {
529
568
  const recoveredFromShortlinkAttributionTableRevenue = Number(recoveredFromShortlinkAttributionTable?.total ?? 0);
530
569
  const unattributedRevenue = totalRevenue - attributedRevenue;
531
570
  const paidPurchases = totals?.count ?? 0;
571
+ const [strongQuality, mediumQuality, weakQuality, unknownQuality] = await Promise.all([
572
+ qualityLane("strong", strongAttributionQualitySql, [
573
+ "Purchase-field UTM, shortlink, or paid click evidence."
574
+ ]),
575
+ qualityLane("medium", mediumAttributionQualitySql, [
576
+ "Recovered from exact shortlink attribution table purchase match."
577
+ ]),
578
+ qualityLane("weak", weakAttributionQualitySql, [
579
+ "GA client ID or self-reported source without stronger campaign evidence."
580
+ ]),
581
+ qualityLane("unknown", unknownAttributionQualitySql, [
582
+ "No usable attribution evidence for paid revenue."
583
+ ])
584
+ ]);
532
585
  return {
533
586
  totalRevenue,
534
587
  attributedRevenue,
@@ -553,6 +606,12 @@ function createDatabaseProvider(db, schema) {
553
606
  selfReportedSource: selfReportedSourceCount,
554
607
  recoveredFromShortlinkAttributionTable: recoveredFromShortlinkAttributionTableCount,
555
608
  internalFreeUpgrade: commerce.freeUpgrades
609
+ },
610
+ quality: {
611
+ strong: strongQuality,
612
+ medium: mediumQuality,
613
+ weak: weakQuality,
614
+ unknown: unknownQuality
556
615
  }
557
616
  };
558
617
  }