58 lines
3 KiB
MySQL
58 lines
3 KiB
MySQL
|
|
-- Migration 945: Creator Analytics v0.11.0 (F381-F385)
|
||
|
|
-- Adds tables for geographic stats, discovery sources, and daily aggregated stats
|
||
|
|
|
||
|
|
-- Daily aggregated track stats for efficient creator dashboard queries
|
||
|
|
CREATE TABLE IF NOT EXISTS daily_track_stats (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
track_id UUID NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||
|
|
date DATE NOT NULL,
|
||
|
|
total_plays BIGINT NOT NULL DEFAULT 0,
|
||
|
|
unique_listeners BIGINT NOT NULL DEFAULT 0,
|
||
|
|
complete_listens BIGINT NOT NULL DEFAULT 0,
|
||
|
|
total_play_time BIGINT NOT NULL DEFAULT 0, -- seconds
|
||
|
|
avg_completion_rate DECIMAL(5,2) NOT NULL DEFAULT 0, -- percentage 0-100
|
||
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||
|
|
CONSTRAINT uq_daily_track_stats_track_date UNIQUE(track_id, date)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_daily_track_stats_track_id ON daily_track_stats(track_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_daily_track_stats_date ON daily_track_stats(date);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_daily_track_stats_track_date ON daily_track_stats(track_id, date);
|
||
|
|
|
||
|
|
-- Discovery sources: how users find tracks
|
||
|
|
CREATE TABLE IF NOT EXISTS track_discovery_sources (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
track_id UUID NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||
|
|
source VARCHAR(50) NOT NULL, -- 'search', 'feed', 'share', 'profile', 'playlist', 'direct'
|
||
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_track_discovery_track_id ON track_discovery_sources(track_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_track_discovery_source ON track_discovery_sources(source);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_track_discovery_created_at ON track_discovery_sources(created_at);
|
||
|
|
|
||
|
|
-- Geographic play stats (aggregated, anonymized — never store individual user locations)
|
||
|
|
CREATE TABLE IF NOT EXISTS geographic_play_stats (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
track_id UUID NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||
|
|
country_code VARCHAR(2) NOT NULL, -- ISO 3166-1 alpha-2
|
||
|
|
region VARCHAR(100) NOT NULL DEFAULT '',
|
||
|
|
date DATE NOT NULL,
|
||
|
|
play_count BIGINT NOT NULL DEFAULT 0,
|
||
|
|
unique_listeners BIGINT NOT NULL DEFAULT 0,
|
||
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||
|
|
CONSTRAINT uq_geo_stats_track_country_region_date UNIQUE(track_id, country_code, region, date)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_geo_stats_track_id ON geographic_play_stats(track_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_geo_stats_country ON geographic_play_stats(country_code);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_geo_stats_date ON geographic_play_stats(date);
|
||
|
|
|
||
|
|
-- Add source column to track_plays for discovery tracking
|
||
|
|
ALTER TABLE track_plays ADD COLUMN IF NOT EXISTS source VARCHAR(50) DEFAULT '';
|
||
|
|
-- Add country_code to track_plays for geographic aggregation
|
||
|
|
ALTER TABLE track_plays ADD COLUMN IF NOT EXISTS country_code VARCHAR(2) DEFAULT '';
|