128 lines
4.9 KiB
MySQL
128 lines
4.9 KiB
MySQL
|
|
-- 041_streaming_analytics.sql
|
||
|
|
-- Analytics and User Interactions (Aligned with ORIGIN)
|
||
|
|
|
||
|
|
-- === PLAYBACK HISTORY ===
|
||
|
|
CREATE TABLE public.playback_history (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
|
||
|
|
track_id UUID NOT NULL REFERENCES public.tracks(id) ON DELETE CASCADE,
|
||
|
|
|
||
|
|
-- Playback
|
||
|
|
played_duration INTEGER NOT NULL,
|
||
|
|
completion_percentage INTEGER NOT NULL,
|
||
|
|
|
||
|
|
-- Context
|
||
|
|
source VARCHAR(50),
|
||
|
|
source_id UUID,
|
||
|
|
device_type VARCHAR(50),
|
||
|
|
|
||
|
|
-- Timestamps
|
||
|
|
played_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
|
||
|
|
CONSTRAINT chk_playback_history_completion CHECK (completion_percentage >= 0 AND completion_percentage <= 100)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX idx_playback_history_user_id_played_at ON public.playback_history(user_id, played_at DESC);
|
||
|
|
CREATE INDEX idx_playback_history_track_id ON public.playback_history(track_id);
|
||
|
|
|
||
|
|
-- === TRACK PLAYS (Legacy - kept for Go compatibility, potentially redundant with history) ===
|
||
|
|
CREATE TABLE public.track_plays (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
track_id UUID NOT NULL REFERENCES public.tracks(id) ON DELETE CASCADE,
|
||
|
|
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
|
||
|
|
|
||
|
|
duration INTEGER NOT NULL,
|
||
|
|
played_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
|
||
|
|
device VARCHAR(100),
|
||
|
|
ip_address VARCHAR(45),
|
||
|
|
user_agent TEXT,
|
||
|
|
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
deleted_at TIMESTAMPTZ
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX idx_track_plays_track_id ON public.track_plays(track_id);
|
||
|
|
CREATE INDEX idx_track_plays_user_id ON public.track_plays(user_id);
|
||
|
|
CREATE INDEX idx_track_plays_played_at ON public.track_plays(played_at DESC);
|
||
|
|
|
||
|
|
-- === TRACK LIKES ===
|
||
|
|
CREATE TABLE public.track_likes (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
|
||
|
|
track_id UUID NOT NULL REFERENCES public.tracks(id) ON DELETE CASCADE,
|
||
|
|
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
|
||
|
|
CONSTRAINT uq_track_likes_user_track UNIQUE (user_id, track_id)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX idx_track_likes_user_id ON public.track_likes(user_id);
|
||
|
|
CREATE INDEX idx_track_likes_track_id_created_at ON public.track_likes(track_id, created_at DESC);
|
||
|
|
|
||
|
|
-- === TRACK COMMENTS ===
|
||
|
|
CREATE TABLE public.track_comments (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
track_id UUID NOT NULL REFERENCES public.tracks(id) ON DELETE CASCADE,
|
||
|
|
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
|
||
|
|
|
||
|
|
content TEXT NOT NULL,
|
||
|
|
parent_comment_id UUID REFERENCES public.track_comments(id) ON DELETE CASCADE,
|
||
|
|
timestamp_seconds INTEGER,
|
||
|
|
|
||
|
|
is_edited BOOLEAN NOT NULL DEFAULT false,
|
||
|
|
is_deleted BOOLEAN NOT NULL DEFAULT false,
|
||
|
|
|
||
|
|
-- Legacy
|
||
|
|
parent_id UUID, -- Maps to parent_comment_id
|
||
|
|
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
|
deleted_at TIMESTAMPTZ,
|
||
|
|
|
||
|
|
CONSTRAINT chk_track_comments_content_length CHECK (LENGTH(content) >= 1 AND LENGTH(content) <= 5000)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX idx_track_comments_track_id_created_at ON public.track_comments(track_id, created_at DESC);
|
||
|
|
CREATE INDEX idx_track_comments_user_id ON public.track_comments(user_id);
|
||
|
|
CREATE INDEX idx_track_comments_parent_comment_id ON public.track_comments(parent_comment_id) WHERE parent_comment_id IS NOT NULL;
|
||
|
|
CREATE INDEX idx_track_comments_timestamp_seconds ON public.track_comments(track_id, timestamp_seconds) WHERE timestamp_seconds IS NOT NULL;
|
||
|
|
|
||
|
|
-- === TRACK SHARES (Legacy) ===
|
||
|
|
CREATE TABLE public.track_shares (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
track_id UUID NOT NULL REFERENCES public.tracks(id) ON DELETE CASCADE,
|
||
|
|
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
|
||
|
|
|
||
|
|
share_token VARCHAR(255) NOT NULL,
|
||
|
|
permissions VARCHAR(50) DEFAULT 'read',
|
||
|
|
expires_at TIMESTAMPTZ,
|
||
|
|
access_count BIGINT DEFAULT 0,
|
||
|
|
|
||
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
deleted_at TIMESTAMPTZ,
|
||
|
|
|
||
|
|
CONSTRAINT uq_track_shares_token UNIQUE (share_token)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX idx_track_shares_track_id ON public.track_shares(track_id);
|
||
|
|
CREATE INDEX idx_track_shares_user_id ON public.track_shares(user_id);
|
||
|
|
|
||
|
|
-- === TRACK HISTORY (Audit Log) ===
|
||
|
|
CREATE TABLE public.track_history (
|
||
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
|
|
track_id UUID NOT NULL REFERENCES public.tracks(id) ON DELETE CASCADE,
|
||
|
|
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
|
||
|
|
|
||
|
|
action VARCHAR(50) NOT NULL,
|
||
|
|
old_value TEXT,
|
||
|
|
new_value TEXT,
|
||
|
|
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX idx_track_history_track_id ON public.track_history(track_id);
|
||
|
|
CREATE INDEX idx_track_history_action ON public.track_history(action);
|
||
|
|
CREATE INDEX idx_track_history_created_at ON public.track_history(created_at DESC);
|