-- CreateEnum CREATE TYPE "NodeStatus" AS ENUM ('ONLINE', 'OFFLINE', 'DEGRADED', 'REVOKED', 'UPDATING', 'SCANNING', 'ERROR'); -- CreateEnum CREATE TYPE "PlaybackSessionStatus" AS ENUM ('ACTIVE', 'IDLE', 'EXPIRED', 'REVOKED', 'COMPLETED'); -- CreateEnum CREATE TYPE "LocationType" AS ENUM ('LOCAL', 'REMOTE'); -- CreateTable CREATE TABLE "users" ( "id" TEXT NOT NULL, "email" TEXT NOT NULL, "password_hash" TEXT NOT NULL, "name" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "users_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "admin_sessions" ( "id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "token_hash" TEXT NOT NULL, "expires_at" TIMESTAMP(3) NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "admin_sessions_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "addon_tokens" ( "id" TEXT NOT NULL, "user_id" TEXT NOT NULL, "token_hash" TEXT NOT NULL, "label" TEXT, "revoked" BOOLEAN NOT NULL DEFAULT false, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "addon_tokens_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "locations" ( "id" TEXT NOT NULL, "name" TEXT NOT NULL, "description" TEXT, "priority" INTEGER NOT NULL DEFAULT 0, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "locations_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "nodes" ( "id" TEXT NOT NULL, "name" TEXT NOT NULL, "hostname" TEXT, "location_id" TEXT, "location_type" "LocationType" NOT NULL DEFAULT 'LOCAL', "status" "NodeStatus" NOT NULL DEFAULT 'OFFLINE', "version" TEXT, "architecture" TEXT, "public_stream_url" TEXT NOT NULL, "last_seen" TIMESTAMP(3), "total_storage" BIGINT NOT NULL DEFAULT 0, "free_storage" BIGINT NOT NULL DEFAULT 0, "active_streams" INTEGER NOT NULL DEFAULT 0, "current_bandwidth" BIGINT NOT NULL DEFAULT 0, "library_file_count" INTEGER NOT NULL DEFAULT 0, "last_revision" INTEGER NOT NULL DEFAULT 0, "revoked" BOOLEAN NOT NULL DEFAULT false, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "nodes_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "node_credentials" ( "id" TEXT NOT NULL, "node_id" TEXT NOT NULL, "api_key_hash" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "rotated_at" TIMESTAMP(3), CONSTRAINT "node_credentials_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "node_enrollment_tokens" ( "id" TEXT NOT NULL, "token_hash" TEXT NOT NULL, "name" TEXT, "location_id" TEXT, "expires_at" TIMESTAMP(3) NOT NULL, "used_at" TIMESTAMP(3), "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "node_enrollment_tokens_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "movies" ( "id" TEXT NOT NULL, "title" TEXT NOT NULL, "original_title" TEXT, "year" INTEGER, "overview" TEXT, "poster_url" TEXT, "backdrop_url" TEXT, "genres" TEXT[] DEFAULT ARRAY[]::TEXT[], "runtime" INTEGER, "imdb_id" TEXT, "tmdb_id" INTEGER, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "movies_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "series" ( "id" TEXT NOT NULL, "title" TEXT NOT NULL, "year" INTEGER, "overview" TEXT, "poster_url" TEXT, "backdrop_url" TEXT, "genres" TEXT[] DEFAULT ARRAY[]::TEXT[], "imdb_id" TEXT, "tmdb_id" INTEGER, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "series_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "seasons" ( "id" TEXT NOT NULL, "series_id" TEXT NOT NULL, "season_number" INTEGER NOT NULL, CONSTRAINT "seasons_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "episodes" ( "id" TEXT NOT NULL, "series_id" TEXT NOT NULL, "season_id" TEXT NOT NULL, "season_number" INTEGER NOT NULL, "episode_number" INTEGER NOT NULL, "title" TEXT, "overview" TEXT, "runtime" INTEGER, "air_date" TIMESTAMP(3), "imdb_id" TEXT, "tmdb_id" INTEGER, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "episodes_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "media_files" ( "id" TEXT NOT NULL, "node_id" TEXT NOT NULL, "movie_id" TEXT, "episode_id" TEXT, "local_file_id" TEXT NOT NULL, "size_bytes" BIGINT NOT NULL, "container" TEXT, "resolution" TEXT, "video_codec" TEXT, "video_bitrate" INTEGER, "hdr_type" TEXT, "audio_codec" TEXT, "audio_channels" TEXT, "audio_language" TEXT, "release_name" TEXT NOT NULL, "available" BOOLEAN NOT NULL DEFAULT true, "last_seen" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "media_files_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "library_matches" ( "id" TEXT NOT NULL, "movie_id" TEXT, "series_id" TEXT, "episode_id" TEXT, "release_name" TEXT NOT NULL, "ignored" BOOLEAN NOT NULL DEFAULT false, "manual" BOOLEAN NOT NULL DEFAULT false, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "library_matches_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "playback_sessions" ( "id" TEXT NOT NULL, "token_hash" TEXT NOT NULL, "user_id" TEXT, "node_id" TEXT NOT NULL, "media_file_id" TEXT NOT NULL, "status" "PlaybackSessionStatus" NOT NULL DEFAULT 'ACTIVE', "idle_timeout_seconds" INTEGER NOT NULL, "absolute_expires_at" TIMESTAMP(3) NOT NULL, "last_activity" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "revoked" BOOLEAN NOT NULL DEFAULT false, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "playback_sessions_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE UNIQUE INDEX "users_email_key" ON "users"("email"); -- CreateIndex CREATE UNIQUE INDEX "admin_sessions_token_hash_key" ON "admin_sessions"("token_hash"); -- CreateIndex CREATE UNIQUE INDEX "addon_tokens_token_hash_key" ON "addon_tokens"("token_hash"); -- CreateIndex CREATE UNIQUE INDEX "locations_name_key" ON "locations"("name"); -- CreateIndex CREATE UNIQUE INDEX "node_credentials_node_id_key" ON "node_credentials"("node_id"); -- CreateIndex CREATE UNIQUE INDEX "node_enrollment_tokens_token_hash_key" ON "node_enrollment_tokens"("token_hash"); -- CreateIndex CREATE UNIQUE INDEX "movies_imdb_id_key" ON "movies"("imdb_id"); -- CreateIndex CREATE UNIQUE INDEX "movies_tmdb_id_key" ON "movies"("tmdb_id"); -- CreateIndex CREATE UNIQUE INDEX "series_imdb_id_key" ON "series"("imdb_id"); -- CreateIndex CREATE UNIQUE INDEX "series_tmdb_id_key" ON "series"("tmdb_id"); -- CreateIndex CREATE UNIQUE INDEX "seasons_series_id_season_number_key" ON "seasons"("series_id", "season_number"); -- CreateIndex CREATE UNIQUE INDEX "episodes_series_id_season_number_episode_number_key" ON "episodes"("series_id", "season_number", "episode_number"); -- CreateIndex CREATE UNIQUE INDEX "media_files_node_id_local_file_id_key" ON "media_files"("node_id", "local_file_id"); -- CreateIndex CREATE UNIQUE INDEX "playback_sessions_token_hash_key" ON "playback_sessions"("token_hash"); -- AddForeignKey ALTER TABLE "admin_sessions" ADD CONSTRAINT "admin_sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "addon_tokens" ADD CONSTRAINT "addon_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "nodes" ADD CONSTRAINT "nodes_location_id_fkey" FOREIGN KEY ("location_id") REFERENCES "locations"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "node_credentials" ADD CONSTRAINT "node_credentials_node_id_fkey" FOREIGN KEY ("node_id") REFERENCES "nodes"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "seasons" ADD CONSTRAINT "seasons_series_id_fkey" FOREIGN KEY ("series_id") REFERENCES "series"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "episodes" ADD CONSTRAINT "episodes_series_id_fkey" FOREIGN KEY ("series_id") REFERENCES "series"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "episodes" ADD CONSTRAINT "episodes_season_id_fkey" FOREIGN KEY ("season_id") REFERENCES "seasons"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "media_files" ADD CONSTRAINT "media_files_node_id_fkey" FOREIGN KEY ("node_id") REFERENCES "nodes"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "media_files" ADD CONSTRAINT "media_files_movie_id_fkey" FOREIGN KEY ("movie_id") REFERENCES "movies"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "media_files" ADD CONSTRAINT "media_files_episode_id_fkey" FOREIGN KEY ("episode_id") REFERENCES "episodes"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "library_matches" ADD CONSTRAINT "library_matches_movie_id_fkey" FOREIGN KEY ("movie_id") REFERENCES "movies"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "library_matches" ADD CONSTRAINT "library_matches_series_id_fkey" FOREIGN KEY ("series_id") REFERENCES "series"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "library_matches" ADD CONSTRAINT "library_matches_episode_id_fkey" FOREIGN KEY ("episode_id") REFERENCES "episodes"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "playback_sessions" ADD CONSTRAINT "playback_sessions_node_id_fkey" FOREIGN KEY ("node_id") REFERENCES "nodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "playback_sessions" ADD CONSTRAINT "playback_sessions_media_file_id_fkey" FOREIGN KEY ("media_file_id") REFERENCES "media_files"("id") ON DELETE RESTRICT ON UPDATE CASCADE;