Add privacy-safe product analytics
Establish an idempotent analytics pipeline and internal decision dashboard while keeping event metadata allowlisted and account deletion enforceable.
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
CREATE TABLE product_analytics_installations (
|
||||
installation_hash CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
account_id VARCHAR(36) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
created_at DATETIME(6) NOT NULL,
|
||||
updated_at DATETIME(6) NOT NULL,
|
||||
PRIMARY KEY (installation_hash),
|
||||
INDEX ix_product_analytics_installations_account (account_id),
|
||||
CONSTRAINT fk_product_analytics_installations_account
|
||||
FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
CREATE TABLE product_analytics_events (
|
||||
installation_hash CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
client_event_id CHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
event_name VARCHAR(32) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
occurred_at DATETIME(6) NOT NULL,
|
||||
surface VARCHAR(16) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
acquisition_channel VARCHAR(32) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
feature VARCHAR(32) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
execution_mode VARCHAR(16) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
failure_category VARCHAR(32) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
duration_bucket VARCHAR(16) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
app_version VARCHAR(32) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
os_version VARCHAR(32) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
payload_hash CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
received_at DATETIME(6) NOT NULL,
|
||||
PRIMARY KEY (installation_hash, client_event_id),
|
||||
INDEX ix_product_analytics_events_type_occurred (event_name, occurred_at),
|
||||
INDEX ix_product_analytics_events_occurred (occurred_at),
|
||||
CONSTRAINT fk_product_analytics_events_installation
|
||||
FOREIGN KEY (installation_hash)
|
||||
REFERENCES product_analytics_installations (installation_hash)
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT chk_product_analytics_events_type CHECK (
|
||||
event_name IN (
|
||||
'FIRST_OPEN',
|
||||
'SESSION_STARTED',
|
||||
'KEYBOARD_ACTIVATED',
|
||||
'AI_FEATURE_STARTED',
|
||||
'AI_FEATURE_SUCCEEDED',
|
||||
'AI_FEATURE_FAILED',
|
||||
'PURCHASE_VIEWED',
|
||||
'PURCHASE_STARTED',
|
||||
'PURCHASE_CANCELLED',
|
||||
'REFERRAL_SHARED',
|
||||
'INVITE_OPENED'
|
||||
)
|
||||
),
|
||||
CONSTRAINT chk_product_analytics_events_surface CHECK (
|
||||
surface IN ('APP', 'KEYBOARD', 'INVITE_WEB')
|
||||
),
|
||||
CONSTRAINT chk_product_analytics_events_acquisition CHECK (
|
||||
acquisition_channel IS NULL
|
||||
OR acquisition_channel IN (
|
||||
'APP_STORE_ORGANIC',
|
||||
'REFERRAL',
|
||||
'SOCIAL_CONTENT',
|
||||
'UNKNOWN'
|
||||
)
|
||||
),
|
||||
CONSTRAINT chk_product_analytics_events_feature CHECK (
|
||||
feature IS NULL
|
||||
OR feature IN (
|
||||
'TRANSCRIPTION',
|
||||
'POLISH',
|
||||
'AI_ASSISTANT',
|
||||
'AGENT',
|
||||
'HOTWORD',
|
||||
'OTHER'
|
||||
)
|
||||
),
|
||||
CONSTRAINT chk_product_analytics_events_execution CHECK (
|
||||
execution_mode IS NULL OR execution_mode IN ('MANAGED', 'LOCAL', 'BYOK')
|
||||
),
|
||||
CONSTRAINT chk_product_analytics_events_failure CHECK (
|
||||
failure_category IS NULL
|
||||
OR failure_category IN (
|
||||
'NETWORK',
|
||||
'PROVIDER',
|
||||
'TIMEOUT',
|
||||
'CANCELLED',
|
||||
'INSUFFICIENT_CREDITS',
|
||||
'VALIDATION',
|
||||
'UNKNOWN'
|
||||
)
|
||||
),
|
||||
CONSTRAINT chk_product_analytics_events_duration CHECK (
|
||||
duration_bucket IS NULL
|
||||
OR duration_bucket IN ('LT_1S', 'S1_TO_3', 'S3_TO_10', 'S10_TO_30', 'GTE_30S')
|
||||
)
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
-- First-party invitation page views are counted without cookies, IP addresses,
|
||||
-- user agents, installation IDs, or referral codes.
|
||||
CREATE TABLE product_analytics_daily_counters (
|
||||
counter_date DATE NOT NULL,
|
||||
counter_name VARCHAR(32) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
counter_value BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
updated_at DATETIME(6) NOT NULL,
|
||||
PRIMARY KEY (counter_date, counter_name),
|
||||
CONSTRAINT chk_product_analytics_daily_counter_name
|
||||
CHECK (counter_name IN ('INVITE_PAGE_OPENED'))
|
||||
) ENGINE = InnoDB;
|
||||
Reference in New Issue
Block a user