Correct product analytics cohorts and reporting
CI / verify (push) Has been cancelled
CI / publish (push) Has been cancelled

This commit is contained in:
Rocky
2026-08-21 17:50:35 +08:00
parent b25f5ae6e9
commit edd0d9feca
31 changed files with 1134 additions and 262 deletions
+93 -21
View File
@@ -85,6 +85,9 @@ paths:
session is supplied, the installation is linked to the account and is
deleted with that account. Audio, user text, prompts, transcripts,
model output, credentials and arbitrary properties are never accepted.
New clients must send installationId once at the batch level. During
migration, legacy clients that send the same installationId on every
event remain accepted; conflicting or incomplete identities are rejected.
requestBody:
required: true
content:
@@ -1314,6 +1317,7 @@ components:
AdminRange:
name: range
in: query
description: Covers exactly 7, 30, or 90 UTC calendar dates, from 00:00 on the first date through the current instant. The current UTC date is partial.
schema: { type: string, enum: [7d, 30d, 90d], default: 30d }
AdminFrom:
name: from
@@ -1438,12 +1442,20 @@ components:
minLength: 1
maxLength: 32
pattern: "^[A-Za-z0-9._+-]+$"
installationId:
type: string
format: uuid
deprecated: true
description: Transitional legacy field; new clients must use the batch-level installationId.
ProductAnalyticsBatchRequest:
type: object
additionalProperties: false
required: [installationId, events]
required: [events]
properties:
installationId: { type: string, format: uuid }
installationId:
type: string
format: uuid
description: Required for new clients; legacy batches may instead repeat one identical ID on every event.
events:
type: array
minItems: 1
@@ -1793,10 +1805,18 @@ components:
date: { type: string, format: date }
registrations: { type: integer, format: int64, minimum: 0 }
creditsUsed: { type: integer, format: int64, minimum: 0 }
AdminStatsPeriod:
type: object
additionalProperties: false
required: [from, until]
properties:
from: { type: string, format: date-time, description: Inclusive UTC lower bound. }
until: { type: string, format: date-time, description: Exclusive current-instant upper bound. }
AdminOverview:
type: object
additionalProperties: false
required:
- period
- totalUsers
- activeUsers
- newUsers
@@ -1806,8 +1826,13 @@ components:
- trend
- usage
properties:
period: { $ref: "#/components/schemas/AdminStatsPeriod" }
totalUsers: { type: integer, format: int64, minimum: 0 }
activeUsers: { type: integer, format: int64, minimum: 0 }
activeUsers:
type: integer
format: int64
minimum: 0
description: Registered accounts with successful AI use or manually committed keyboard input in the period.
newUsers: { type: integer, format: int64, minimum: 0 }
totalCreditBalance: { type: integer, format: int64, minimum: 0 }
creditsGranted: { type: integer, format: int64, minimum: 0 }
@@ -1825,7 +1850,7 @@ components:
properties:
label:
type: string
enum: [邀请码创建, 成功绑定, 有效使用并奖励]
enum: [成功绑定, 绑定后首次 AI 成功, 完成奖励]
count: { type: integer, format: int64, minimum: 0 }
AdminReferralRank:
type: object
@@ -1839,8 +1864,9 @@ components:
AdminReferralOverview:
type: object
additionalProperties: false
required: [pendingBindings, ineligibleBindings, funnel, ranking]
required: [period, pendingBindings, ineligibleBindings, funnel, ranking]
properties:
period: { $ref: "#/components/schemas/AdminStatsPeriod" }
pendingBindings: { type: integer, format: int64, minimum: 0 }
ineligibleBindings: { type: integer, format: int64, minimum: 0 }
funnel:
@@ -1856,7 +1882,11 @@ components:
properties:
numerator: { type: integer, format: int64, minimum: 0 }
denominator: { type: integer, format: int64, minimum: 0 }
percent: { type: ["number", "null"], minimum: 0, maximum: 100 }
percent:
type: ["number", "null"]
minimum: 0
maximum: 100
description: Null means unavailable, usually because the denominator is zero; clients must not render it as 0%.
AdminAnalyticsFunnelStep:
type: object
additionalProperties: false
@@ -1872,7 +1902,11 @@ components:
channel:
type: string
enum: [APP_STORE_ORGANIC, REFERRAL, SOCIAL_CONTENT, UNKNOWN]
installations: { type: integer, format: int64, minimum: 0 }
installations:
type: integer
format: int64
minimum: 0
description: Installations in this channel with a completed 24-hour observation window.
activated: { type: integer, format: int64, minimum: 0 }
activationRate: { $ref: "#/components/schemas/AdminAnalyticsRate" }
AdminAnalyticsCohort:
@@ -1905,6 +1939,16 @@ components:
executionMode: { type: string, enum: [MANAGED, LOCAL, BYOK] }
users: { type: integer, format: int64, minimum: 0 }
successes: { type: integer, format: int64, minimum: 0 }
AdminAnalyticsLatencyBucket:
type: object
additionalProperties: false
required: [bucket, successful, failed]
properties:
bucket:
type: string
enum: [LT_1S, S1_TO_3, S3_TO_10, S10_TO_30, GTE_30S]
successful: { type: integer, format: int64, minimum: 0 }
failed: { type: integer, format: int64, minimum: 0 }
AdminAnalyticsKeyboardUsage:
type: object
additionalProperties: false
@@ -1955,16 +1999,11 @@ components:
- retention
- aiFeatures
- keyboardUsage
- referralSignals
- referralFunnel
- guardrails
properties:
period:
type: object
additionalProperties: false
required: [from, until]
properties:
from: { type: string, format: date-time }
until: { type: string, format: date-time }
period: { $ref: "#/components/schemas/AdminStatsPeriod" }
northStar:
type: object
additionalProperties: false
@@ -1990,9 +2029,21 @@ components:
additionalProperties: false
required: [dau, wau, mau, successfulAiRequests]
properties:
dau: { type: integer, format: int64, minimum: 0 }
wau: { type: integer, format: int64, minimum: 0 }
mau: { type: integer, format: int64, minimum: 0 }
dau:
type: integer
format: int64
minimum: 0
description: Distinct AI value-active identities in the rolling 1-day window ending at period.until.
wau:
type: integer
format: int64
minimum: 0
description: Distinct AI value-active identities in the rolling 7-day window ending at period.until.
mau:
type: integer
format: int64
minimum: 0
description: Distinct AI value-active identities in the rolling 30-day window ending at period.until.
stickinessPercent: { type: ["number", "null"], minimum: 0, maximum: 100 }
successfulAiRequests: { type: integer, format: int64, minimum: 0 }
successfulRequestsPerActiveUser: { type: ["number", "null"], minimum: 0 }
@@ -2009,14 +2060,23 @@ components:
type: object
additionalProperties: false
required:
[payingUsers, purchases, creditsPurchased, conversion7d, conversion30d, repeatPurchaseRate]
[payingUsers, purchases, creditsPurchased, conversion7d, conversion30d, repeatPurchaseRate, purchaseFunnel, cancelledUsers]
properties:
payingUsers: { type: integer, format: int64, minimum: 0 }
purchases: { type: integer, format: int64, minimum: 0 }
creditsPurchased: { type: integer, format: int64, minimum: 0 }
conversion7d: { $ref: "#/components/schemas/AdminAnalyticsRate" }
conversion30d: { $ref: "#/components/schemas/AdminAnalyticsRate" }
conversion7d:
$ref: "#/components/schemas/AdminAnalyticsRate"
description: Conversion for account cohorts whose full 7-day observation window matures inside the selected report period.
conversion30d:
$ref: "#/components/schemas/AdminAnalyticsRate"
description: Conversion for account cohorts whose full 30-day observation window matures inside the selected report period.
repeatPurchaseRate: { $ref: "#/components/schemas/AdminAnalyticsRate" }
purchaseFunnel:
type: array
description: Strict installation cohort from purchase view through server-verified StoreKit purchase.
items: { $ref: "#/components/schemas/AdminAnalyticsFunnelStep" }
cancelledUsers: { type: integer, format: int64, minimum: 0 }
growthFunnel:
type: array
items: { $ref: "#/components/schemas/AdminAnalyticsFunnelStep" }
@@ -2028,17 +2088,29 @@ components:
items: { $ref: "#/components/schemas/AdminAnalyticsFeatureUsage" }
keyboardUsage:
$ref: "#/components/schemas/AdminAnalyticsKeyboardUsage"
referralSignals:
type: object
additionalProperties: false
required: [shared, opened]
description: Directional signals only; these counts are not funnel stages.
properties:
shared: { type: integer, format: int64, minimum: 0 }
opened: { type: integer, format: int64, minimum: 0 }
referralFunnel:
type: array
items: { $ref: "#/components/schemas/AdminAnalyticsFunnelStep" }
guardrails:
type: object
additionalProperties: false
required: [clientAiSuccessRate, managedSuccessRate, creditBlockedUsers]
required: [clientAiSuccessRate, managedSuccessRate, creditBlockedUsers, latencyBuckets]
properties:
clientAiSuccessRate: { $ref: "#/components/schemas/AdminAnalyticsRate" }
managedSuccessRate: { $ref: "#/components/schemas/AdminAnalyticsRate" }
creditBlockedUsers: { type: integer, format: int64, minimum: 0 }
latencyBuckets:
type: array
description: Client AI terminal events grouped into declared duration buckets.
items: { $ref: "#/components/schemas/AdminAnalyticsLatencyBucket" }
AdminUserSummary:
type: object
additionalProperties: false