Add privacy-safe product analytics
CI / verify (push) Has been cancelled
CI / publish (push) Has been cancelled

Establish an idempotent analytics pipeline and internal decision dashboard while keeping event metadata allowlisted and account deletion enforceable.
This commit is contained in:
Rocky
2026-08-20 15:20:01 +08:00
parent 231c5040a5
commit 4b465e0e5e
38 changed files with 4275 additions and 80 deletions
@@ -123,6 +123,29 @@ class DeploymentConsistencyTest : FunSpec({
}
}
test("product analytics contract stays allowlisted and account deletions cascade") {
val migration = root.read(
"src/main/resources/db/migration/V16__product_analytics_events.sql",
)
migration shouldContain "product_analytics_installations"
migration shouldContain "product_analytics_events"
migration shouldContain "REFERENCES accounts (id) ON DELETE CASCADE"
migration shouldContain "PRIMARY KEY (installation_hash, client_event_id)"
val openApi = root.read("docs/openapi.yaml")
val eventSchema = openApi
.substringAfter(" ProductAnalyticsEvent:")
.substringBefore(" AdminSessionState:")
eventSchema shouldContain "additionalProperties: false"
eventSchema shouldContain "AI_FEATURE_SUCCEEDED"
eventSchema shouldContain "INSUFFICIENT_CREDITS"
eventSchema shouldNotContain "prompt"
eventSchema shouldNotContain "transcript"
eventSchema shouldNotContain "audio"
eventSchema shouldNotContain "modelOutput"
openApi shouldContain "schema: { \$ref: \"#/components/schemas/AdminProductAnalytics\" }"
}
test("production Compose reuses private MySQL and hardens the application container") {
val compose = root.read("compose.yaml")
@@ -228,6 +251,7 @@ private val EXPECTED_PUBLIC_PATHS = setOf(
"/v1/auth/logout",
"/v1/account",
"/v1/apple/events",
"/v1/analytics/events",
"/v1/credits/balance",
"/v1/credits/ledger",
"/v1/credits/rates",
@@ -255,6 +279,7 @@ private val EXPECTED_PUBLIC_PATHS = setOf(
"/v1/admin/auth/logout",
"/v1/admin/overview",
"/v1/admin/referrals",
"/v1/admin/analytics",
"/v1/admin/users",
"/v1/admin/users/{userId}",
"/v1/admin/users/{userId}/ledger",