feat(v0.11.1): F396-F399 database migrations for advanced analytics
Add tables: track_segment_stats (heatmap), product_views (marketplace conversion), metric_alerts, metric_alert_preferences. Add segment_positions JSONB column to playback_analytics. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
217ba95796
commit
80d54527b9
2 changed files with 74 additions and 0 deletions
66
veza-backend-api/migrations/946_advanced_analytics_v0111.sql
Normal file
66
veza-backend-api/migrations/946_advanced_analytics_v0111.sql
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
-- Migration 946: Advanced Analytics v0.11.1 (F396-F399)
|
||||||
|
-- Adds tables for listening heatmaps, period comparisons, marketplace analytics, and metric alerts
|
||||||
|
|
||||||
|
-- F396: Track listening heatmap — stores aggregated segment listen counts
|
||||||
|
CREATE TABLE IF NOT EXISTS track_segment_stats (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
track_id UUID NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||||||
|
segment_index INT NOT NULL, -- 0-based segment index
|
||||||
|
segment_start_ms BIGINT NOT NULL, -- segment start in milliseconds
|
||||||
|
segment_end_ms BIGINT NOT NULL, -- segment end in milliseconds
|
||||||
|
listen_count BIGINT NOT NULL DEFAULT 0,
|
||||||
|
drop_off_count BIGINT NOT NULL DEFAULT 0, -- how many stopped here
|
||||||
|
replay_count BIGINT NOT NULL DEFAULT 0, -- how many seeked back here
|
||||||
|
date DATE NOT NULL,
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
|
CONSTRAINT uq_segment_stats_track_segment_date UNIQUE(track_id, segment_index, date)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_segment_stats_track_id ON track_segment_stats(track_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_segment_stats_date ON track_segment_stats(date);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_segment_stats_track_date ON track_segment_stats(track_id, date);
|
||||||
|
|
||||||
|
-- F398: Marketplace analytics — product view tracking for conversion rates
|
||||||
|
CREATE TABLE IF NOT EXISTS product_views (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
product_id UUID NOT NULL REFERENCES products(id) ON DELETE CASCADE,
|
||||||
|
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||||
|
source VARCHAR(50) NOT NULL DEFAULT 'direct', -- 'search', 'feed', 'profile', 'direct'
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_product_views_product_id ON product_views(product_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_product_views_created_at ON product_views(created_at);
|
||||||
|
|
||||||
|
-- F399: Metric alerts — opt-in milestone notifications for creators
|
||||||
|
CREATE TABLE IF NOT EXISTS metric_alerts (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
metric_type VARCHAR(50) NOT NULL, -- 'plays', 'followers', 'sales', 'listeners'
|
||||||
|
threshold BIGINT NOT NULL, -- e.g., 100, 500, 1000
|
||||||
|
is_triggered BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
triggered_at TIMESTAMP WITH TIME ZONE,
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
|
CONSTRAINT uq_metric_alert_user_type_threshold UNIQUE(user_id, metric_type, threshold)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_metric_alerts_user_id ON metric_alerts(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_metric_alerts_not_triggered ON metric_alerts(user_id) WHERE is_triggered = FALSE;
|
||||||
|
|
||||||
|
-- F399: Metric alert preferences — which alert types are enabled
|
||||||
|
CREATE TABLE IF NOT EXISTS metric_alert_preferences (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
metric_type VARCHAR(50) NOT NULL, -- 'plays', 'followers', 'sales', 'listeners'
|
||||||
|
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||||
|
CONSTRAINT uq_alert_pref_user_type UNIQUE(user_id, metric_type)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_alert_prefs_user_id ON metric_alert_preferences(user_id);
|
||||||
|
|
||||||
|
-- Add segment_positions to playback_analytics for heatmap data collection
|
||||||
|
ALTER TABLE playback_analytics ADD COLUMN IF NOT EXISTS segment_positions JSONB DEFAULT '[]';
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
-- Rollback Migration 946: Advanced Analytics v0.11.1 (F396-F399)
|
||||||
|
|
||||||
|
ALTER TABLE playback_analytics DROP COLUMN IF EXISTS segment_positions;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS metric_alert_preferences;
|
||||||
|
DROP TABLE IF EXISTS metric_alerts;
|
||||||
|
DROP TABLE IF EXISTS product_views;
|
||||||
|
DROP TABLE IF EXISTS track_segment_stats;
|
||||||
Loading…
Reference in a new issue