Loading...
;
+ } else if (isError) {
+ body = (
+
+
+
+
+
+ setFilter(e.target.value)}
+ placeholder="Search tasks"
+ aria-label="Search tasks"
+ className="h-11 pl-9 sm:h-10"
+ />
+
+
+ {isError && !data ? (
+
+ Could not load the scheduled tasks.
+
+
+ ) : tasks.length === 0 ? (
+
+
+
{filter ? "No task matches" : "No scheduled tasks"}
+
+ ) : (
+ <>
+ {/* Phones: one card per task */}
+
+ {tasks.map((task) => (
+ -
+
+
+
{task.title}
+
{task.description}
+
+
+
+
+ - Every
+ - {formatInterval(task.intervalMs)}
+ - Last run
+ - {formatRelative(task.lastFinishedAt, now)}
+ - Duration
+ - {formatDuration(task.lastDurationMs)}
+ - Next run
+ - {task.running ? "—" : formatRelative(task.nextRunAt, now)}
+
+ {task.lastError && (
+ {task.lastError}
+ )}
+
+
+ ))}
+
+
+ {/* Tablet and desktop: table */}
+
+
+
+
+ | Task |
+ Interval |
+ Last run |
+ Duration |
+ Result |
+ Next run |
+
+ Actions
+ |
+
+
+
+ {tasks.map((task) => (
+
+ |
+ {task.title}
+ {task.description}
+ {task.lastError && (
+ {task.lastError}
+ )}
+ |
+ {formatInterval(task.intervalMs)} |
+
+ {formatRelative(task.lastFinishedAt, now)}
+ |
+
+ {formatDuration(task.lastDurationMs)}
+ |
+
+
+ |
+
+ {task.running ? "—" : formatRelative(task.nextRunAt, now)}
+ |
+
+
+ |
+
+ ))}
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/migrations-pg/0010_next_pepper_potts.sql b/migrations-pg/0010_next_pepper_potts.sql
new file mode 100644
index 000000000..9ea9e57d4
--- /dev/null
+++ b/migrations-pg/0010_next_pepper_potts.sql
@@ -0,0 +1,15 @@
+CREATE TABLE "download_events" (
+ "id" text PRIMARY KEY NOT NULL,
+ "user_id" text NOT NULL,
+ "game_id" text,
+ "game_title" text NOT NULL,
+ "event_type" text NOT NULL,
+ "release_title" text NOT NULL,
+ "downloader_name" text,
+ "message" text,
+ "created_at" bigint DEFAULT (EXTRACT(EPOCH FROM now()) * 1000)::bigint
+);
+--> statement-breakpoint
+ALTER TABLE "download_events" ADD CONSTRAINT "download_events_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
+ALTER TABLE "download_events" ADD CONSTRAINT "download_events_game_id_games_id_fk" FOREIGN KEY ("game_id") REFERENCES "public"."games"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
+CREATE INDEX "download_events_user_created_idx" ON "download_events" USING btree ("user_id","created_at");
\ No newline at end of file
diff --git a/migrations-pg/meta/0010_snapshot.json b/migrations-pg/meta/0010_snapshot.json
new file mode 100644
index 000000000..68fa46ce7
--- /dev/null
+++ b/migrations-pg/meta/0010_snapshot.json
@@ -0,0 +1,2428 @@
+{
+ "id": "9199bca5-2e0b-425b-8420-f240a59f3b8d",
+ "prevId": "419419c1-f0e2-433d-921f-08747b8a151b",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.ai_auto_download_holds": {
+ "name": "ai_auto_download_holds",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "release_title": {
+ "name": "release_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "ai_auto_download_holds_game_title_idx": {
+ "name": "ai_auto_download_holds_game_title_idx",
+ "columns": [
+ {
+ "expression": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "release_title",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_auto_download_holds_game_id_games_id_fk": {
+ "name": "ai_auto_download_holds_game_id_games_id_fk",
+ "tableFrom": "ai_auto_download_holds",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.api_keys": {
+ "name": "api_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prefix": {
+ "name": "prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "api_keys_key_hash_idx": {
+ "name": "api_keys_key_hash_idx",
+ "columns": [
+ {
+ "expression": "key_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "api_keys_user_id_idx": {
+ "name": "api_keys_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "api_keys_user_id_users_id_fk": {
+ "name": "api_keys_user_id_users_id_fk",
+ "tableFrom": "api_keys",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.download_events": {
+ "name": "download_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "game_title": {
+ "name": "game_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "release_title": {
+ "name": "release_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "downloader_name": {
+ "name": "downloader_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "message": {
+ "name": "message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "download_events_user_created_idx": {
+ "name": "download_events_user_created_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "download_events_user_id_users_id_fk": {
+ "name": "download_events_user_id_users_id_fk",
+ "tableFrom": "download_events",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "download_events_game_id_games_id_fk": {
+ "name": "download_events_game_id_games_id_fk",
+ "tableFrom": "download_events",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.downloaders": {
+ "name": "downloaders",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "port": {
+ "name": "port",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "use_ssl": {
+ "name": "use_ssl",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "url_path": {
+ "name": "url_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "allow_self_signed_certificate": {
+ "name": "allow_self_signed_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "allow_insecure_lan": {
+ "name": "allow_insecure_lan",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "download_path": {
+ "name": "download_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'games'"
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'Questarr'"
+ },
+ "add_stopped": {
+ "name": "add_stopped",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "remove_completed": {
+ "name": "remove_completed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "post_import_category": {
+ "name": "post_import_category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.game_downloads": {
+ "name": "game_downloads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "downloader_id": {
+ "name": "downloader_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "download_type": {
+ "name": "download_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'torrent'"
+ },
+ "download_hash": {
+ "name": "download_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "download_title": {
+ "name": "download_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'downloading'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "added_at": {
+ "name": "added_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "game_downloads_downloader_hash_idx": {
+ "name": "game_downloads_downloader_hash_idx",
+ "columns": [
+ {
+ "expression": "downloader_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "download_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "game_downloads_game_id_games_id_fk": {
+ "name": "game_downloads_game_id_games_id_fk",
+ "tableFrom": "game_downloads",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_downloads_downloader_id_downloaders_id_fk": {
+ "name": "game_downloads_downloader_id_downloaders_id_fk",
+ "tableFrom": "game_downloads",
+ "tableTo": "downloaders",
+ "columnsFrom": ["downloader_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.game_files": {
+ "name": "game_files",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "download_id": {
+ "name": "download_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "original_name": {
+ "name": "original_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stored_name": {
+ "name": "stored_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category_overridden": {
+ "name": "category_overridden",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "file_path": {
+ "name": "file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "game_files_game_id_idx": {
+ "name": "game_files_game_id_idx",
+ "columns": [
+ {
+ "expression": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "game_files_download_id_idx": {
+ "name": "game_files_download_id_idx",
+ "columns": [
+ {
+ "expression": "download_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "game_files_game_id_games_id_fk": {
+ "name": "game_files_game_id_games_id_fk",
+ "tableFrom": "game_files",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_files_download_id_game_downloads_id_fk": {
+ "name": "game_files_download_id_game_downloads_id_fk",
+ "tableFrom": "game_files",
+ "tableTo": "game_downloads",
+ "columnsFrom": ["download_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.game_journal_entries": {
+ "name": "game_journal_entries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "note": {
+ "name": "note",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "game_journal_entries_game_user_idx": {
+ "name": "game_journal_entries_game_user_idx",
+ "columns": [
+ {
+ "expression": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "game_journal_entries_game_id_games_id_fk": {
+ "name": "game_journal_entries_game_id_games_id_fk",
+ "tableFrom": "game_journal_entries",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_journal_entries_user_id_users_id_fk": {
+ "name": "game_journal_entries_user_id_users_id_fk",
+ "tableFrom": "game_journal_entries",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.game_milestones": {
+ "name": "game_milestones",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "game_milestones_game_user_idx": {
+ "name": "game_milestones_game_user_idx",
+ "columns": [
+ {
+ "expression": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "game_milestones_game_id_games_id_fk": {
+ "name": "game_milestones_game_id_games_id_fk",
+ "tableFrom": "game_milestones",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_milestones_user_id_users_id_fk": {
+ "name": "game_milestones_user_id_users_id_fk",
+ "tableFrom": "game_milestones",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.game_screenshots": {
+ "name": "game_screenshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_path": {
+ "name": "file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "caption": {
+ "name": "caption",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "game_screenshots_game_user_idx": {
+ "name": "game_screenshots_game_user_idx",
+ "columns": [
+ {
+ "expression": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "game_screenshots_game_id_games_id_fk": {
+ "name": "game_screenshots_game_id_games_id_fk",
+ "tableFrom": "game_screenshots",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_screenshots_user_id_users_id_fk": {
+ "name": "game_screenshots_user_id_users_id_fk",
+ "tableFrom": "game_screenshots",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.games": {
+ "name": "games",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "igdb_id": {
+ "name": "igdb_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "steam_appid": {
+ "name": "steam_appid",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cover_url": {
+ "name": "cover_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "release_date": {
+ "name": "release_date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rating": {
+ "name": "rating",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "platforms": {
+ "name": "platforms",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_platform_id": {
+ "name": "target_platform_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_platform_name": {
+ "name": "target_platform_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "genres": {
+ "name": "genres",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "themes": {
+ "name": "themes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "publishers": {
+ "name": "publishers",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "developers": {
+ "name": "developers",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "screenshots": {
+ "name": "screenshots",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "videos": {
+ "name": "videos",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'manual'"
+ },
+ "igdb_websites": {
+ "name": "igdb_websites",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expansions": {
+ "name": "expansions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "aggregated_rating": {
+ "name": "aggregated_rating",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time_to_beat_hastily": {
+ "name": "time_to_beat_hastily",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time_to_beat_normally": {
+ "name": "time_to_beat_normally",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time_to_beat_completely": {
+ "name": "time_to_beat_completely",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'wanted'"
+ },
+ "original_release_date": {
+ "name": "original_release_date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "release_status": {
+ "name": "release_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'upcoming'"
+ },
+ "early_access": {
+ "name": "early_access",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "hidden": {
+ "name": "hidden",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_adult_content": {
+ "name": "is_adult_content",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_age_restricted": {
+ "name": "is_age_restricted",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "user_rating": {
+ "name": "user_rating",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "library_path": {
+ "name": "library_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "installed_version": {
+ "name": "installed_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "search_results_available": {
+ "name": "search_results_available",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "search_results_available_at": {
+ "name": "search_results_available_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "update_search_results_available": {
+ "name": "update_search_results_available",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "packs_search_results_available": {
+ "name": "packs_search_results_available",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "added_at": {
+ "name": "added_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "games_user_id_users_id_fk": {
+ "name": "games_user_id_users_id_fk",
+ "tableFrom": "games",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.import_task_items": {
+ "name": "import_task_items",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "item_name": {
+ "name": "item_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "result": {
+ "name": "result",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "game_title": {
+ "name": "game_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "import_task_items_task_id_idx": {
+ "name": "import_task_items_task_id_idx",
+ "columns": [
+ {
+ "expression": "task_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "import_task_items_task_id_import_tasks_id_fk": {
+ "name": "import_task_items_task_id_import_tasks_id_fk",
+ "tableFrom": "import_task_items",
+ "tableTo": "import_tasks",
+ "columnsFrom": ["task_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.import_tasks": {
+ "name": "import_tasks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "task_type": {
+ "name": "task_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "triggered_by": {
+ "name": "triggered_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_items": {
+ "name": "total_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "added_items": {
+ "name": "added_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "skipped_items": {
+ "name": "skipped_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "failed_items": {
+ "name": "failed_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "import_tasks_user_id_users_id_fk": {
+ "name": "import_tasks_user_id_users_id_fk",
+ "tableFrom": "import_tasks",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.indexers": {
+ "name": "indexers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "api_key": {
+ "name": "api_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "protocol": {
+ "name": "protocol",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'torznab'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "categories": {
+ "name": "categories",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'[]'::jsonb"
+ },
+ "rss_enabled": {
+ "name": "rss_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "auto_search_enabled": {
+ "name": "auto_search_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "allow_insecure_lan": {
+ "name": "allow_insecure_lan",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.notifications": {
+ "name": "notifications",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "message": {
+ "name": "message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "read": {
+ "name": "read",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "notifications_user_id_users_id_fk": {
+ "name": "notifications_user_id_users_id_fk",
+ "tableFrom": "notifications",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.path_mappings": {
+ "name": "path_mappings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "remote_path": {
+ "name": "remote_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "local_path": {
+ "name": "local_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "remote_host": {
+ "name": "remote_host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.platform_mappings": {
+ "name": "platform_mappings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "igdb_platform_id": {
+ "name": "igdb_platform_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_platform_name": {
+ "name": "source_platform_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.release_blacklist": {
+ "name": "release_blacklist",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "release_title": {
+ "name": "release_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "indexer_name": {
+ "name": "indexer_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {
+ "release_blacklist_game_title_idx": {
+ "name": "release_blacklist_game_title_idx",
+ "columns": [
+ {
+ "expression": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "release_title",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "release_blacklist_game_id_games_id_fk": {
+ "name": "release_blacklist_game_id_games_id_fk",
+ "tableFrom": "release_blacklist",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.root_folders": {
+ "name": "root_folders",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "allow_delete": {
+ "name": "allow_delete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "accessible": {
+ "name": "accessible",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disk_free_bytes": {
+ "name": "disk_free_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disk_total_bytes": {
+ "name": "disk_total_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_scanned_at": {
+ "name": "last_scanned_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "root_folders_path_unique": {
+ "name": "root_folders_path_unique",
+ "nullsNotDistinct": false,
+ "columns": ["path"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.rss_feed_items": {
+ "name": "rss_feed_items",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "feed_id": {
+ "name": "feed_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "guid": {
+ "name": "guid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pub_date": {
+ "name": "pub_date",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_name": {
+ "name": "source_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "igdb_game_id": {
+ "name": "igdb_game_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "igdb_game_name": {
+ "name": "igdb_game_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cover_url": {
+ "name": "cover_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "rss_feed_items_feed_id_rss_feeds_id_fk": {
+ "name": "rss_feed_items_feed_id_rss_feeds_id_fk",
+ "tableFrom": "rss_feed_items",
+ "tableTo": "rss_feeds",
+ "columnsFrom": ["feed_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.rss_feeds": {
+ "name": "rss_feeds",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'custom'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "mapping": {
+ "name": "mapping",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_check": {
+ "name": "last_check",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'ok'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.system_config": {
+ "name": "system_config",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_settings": {
+ "name": "user_settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "auto_search_enabled": {
+ "name": "auto_search_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "auto_download_enabled": {
+ "name": "auto_download_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "notification_preferences": {
+ "name": "notification_preferences",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "search_interval_hours": {
+ "name": "search_interval_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 6
+ },
+ "igdb_rate_limit_per_second": {
+ "name": "igdb_rate_limit_per_second",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 3
+ },
+ "download_rules": {
+ "name": "download_rules",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_auto_search": {
+ "name": "last_auto_search",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "xrel_scene_releases": {
+ "name": "xrel_scene_releases",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "xrel_p2p_releases": {
+ "name": "xrel_p2p_releases",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "auto_search_unreleased": {
+ "name": "auto_search_unreleased",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "steam_sync_failures": {
+ "name": "steam_sync_failures",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "steam_sync_enabled": {
+ "name": "steam_sync_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "steam_sync_interval_hours": {
+ "name": "steam_sync_interval_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 24
+ },
+ "last_steam_sync": {
+ "name": "last_steam_sync",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "preferred_release_groups": {
+ "name": "preferred_release_groups",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "filter_by_preferred_groups": {
+ "name": "filter_by_preferred_groups",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "release_name_blacklist": {
+ "name": "release_name_blacklist",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "preferred_platform": {
+ "name": "preferred_platform",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hide_adult_content": {
+ "name": "hide_adult_content",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "hide_age_restricted_content": {
+ "name": "hide_age_restricted_content",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "hide_shelved_by_default": {
+ "name": "hide_shelved_by_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "hide_owned_in_has_results": {
+ "name": "hide_owned_in_has_results",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "enable_post_processing": {
+ "name": "enable_post_processing",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "auto_unpack": {
+ "name": "auto_unpack",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "rename_pattern": {
+ "name": "rename_pattern",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{Title} ({Region})'"
+ },
+ "overwrite_existing": {
+ "name": "overwrite_existing",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "transfer_mode": {
+ "name": "transfer_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'hardlink'"
+ },
+ "import_platform_ids": {
+ "name": "import_platform_ids",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'[]'::jsonb"
+ },
+ "ignored_extensions": {
+ "name": "ignored_extensions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'[]'::jsonb"
+ },
+ "min_file_size": {
+ "name": "min_file_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "library_root": {
+ "name": "library_root",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'/data'"
+ },
+ "auto_delete_after_import": {
+ "name": "auto_delete_after_import",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "sort_extras": {
+ "name": "sort_extras",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "telemetry_enabled": {
+ "name": "telemetry_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "user_settings_user_id_users_id_fk": {
+ "name": "user_settings_user_id_users_id_fk",
+ "tableFrom": "user_settings",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_settings_user_id_unique": {
+ "name": "user_settings_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": ["user_id"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password_hash": {
+ "name": "password_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "steam_id_64": {
+ "name": "steam_id_64",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "users_username_unique": {
+ "name": "users_username_unique",
+ "nullsNotDistinct": false,
+ "columns": ["username"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.xrel_notified_releases": {
+ "name": "xrel_notified_releases",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "xrel_release_id": {
+ "name": "xrel_release_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "(EXTRACT(EPOCH FROM now()) * 1000)::bigint"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "xrel_notified_releases_game_id_games_id_fk": {
+ "name": "xrel_notified_releases_game_id_games_id_fk",
+ "tableFrom": "xrel_notified_releases",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
diff --git a/migrations-pg/meta/_journal.json b/migrations-pg/meta/_journal.json
index 986495e19..30da228fe 100644
--- a/migrations-pg/meta/_journal.json
+++ b/migrations-pg/meta/_journal.json
@@ -71,6 +71,13 @@
"when": 1791870870205,
"tag": "0009_goofy_corsair",
"breakpoints": true
+ },
+ {
+ "idx": 10,
+ "version": "7",
+ "when": 1792406180560,
+ "tag": "0010_next_pepper_potts",
+ "breakpoints": true
}
]
}
diff --git a/migrations/0046_unknown_moonstone.sql b/migrations/0046_unknown_moonstone.sql
new file mode 100644
index 000000000..bf08ce876
--- /dev/null
+++ b/migrations/0046_unknown_moonstone.sql
@@ -0,0 +1,15 @@
+CREATE TABLE `download_events` (
+ `id` text PRIMARY KEY NOT NULL,
+ `user_id` text NOT NULL,
+ `game_id` text,
+ `game_title` text NOT NULL,
+ `event_type` text NOT NULL,
+ `release_title` text NOT NULL,
+ `downloader_name` text,
+ `message` text,
+ `created_at` integer DEFAULT (strftime('%s', 'now') * 1000),
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade,
+ FOREIGN KEY (`game_id`) REFERENCES `games`(`id`) ON UPDATE no action ON DELETE set null
+);
+--> statement-breakpoint
+CREATE INDEX `download_events_user_created_idx` ON `download_events` (`user_id`,`created_at`);
\ No newline at end of file
diff --git a/migrations/meta/0046_snapshot.json b/migrations/meta/0046_snapshot.json
new file mode 100644
index 000000000..265acae18
--- /dev/null
+++ b/migrations/meta/0046_snapshot.json
@@ -0,0 +1,2450 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "41ce72ab-0263-4d75-8639-47bcf0401194",
+ "prevId": "001e5cb4-05bf-4371-bda1-81a7ae5b05f2",
+ "tables": {
+ "ai_auto_download_holds": {
+ "name": "ai_auto_download_holds",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "release_title": {
+ "name": "release_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "ai_auto_download_holds_game_title_idx": {
+ "name": "ai_auto_download_holds_game_title_idx",
+ "columns": ["game_id", "release_title"],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "ai_auto_download_holds_game_id_games_id_fk": {
+ "name": "ai_auto_download_holds_game_id_games_id_fk",
+ "tableFrom": "ai_auto_download_holds",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "api_keys": {
+ "name": "api_keys",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "prefix": {
+ "name": "prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "api_keys_key_hash_idx": {
+ "name": "api_keys_key_hash_idx",
+ "columns": ["key_hash"],
+ "isUnique": true
+ },
+ "api_keys_user_id_idx": {
+ "name": "api_keys_user_id_idx",
+ "columns": ["user_id"],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "api_keys_user_id_users_id_fk": {
+ "name": "api_keys_user_id_users_id_fk",
+ "tableFrom": "api_keys",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "download_events": {
+ "name": "download_events",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "game_title": {
+ "name": "game_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "release_title": {
+ "name": "release_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "downloader_name": {
+ "name": "downloader_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "message": {
+ "name": "message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "download_events_user_created_idx": {
+ "name": "download_events_user_created_idx",
+ "columns": ["user_id", "created_at"],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "download_events_user_id_users_id_fk": {
+ "name": "download_events_user_id_users_id_fk",
+ "tableFrom": "download_events",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "download_events_game_id_games_id_fk": {
+ "name": "download_events_game_id_games_id_fk",
+ "tableFrom": "download_events",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "downloaders": {
+ "name": "downloaders",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "port": {
+ "name": "port",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "use_ssl": {
+ "name": "use_ssl",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": false
+ },
+ "url_path": {
+ "name": "url_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "allow_self_signed_certificate": {
+ "name": "allow_self_signed_certificate",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "allow_insecure_lan": {
+ "name": "allow_insecure_lan",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "download_path": {
+ "name": "download_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'games'"
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'Questarr'"
+ },
+ "add_stopped": {
+ "name": "add_stopped",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": false
+ },
+ "remove_completed": {
+ "name": "remove_completed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": false
+ },
+ "post_import_category": {
+ "name": "post_import_category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "game_downloads": {
+ "name": "game_downloads",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "downloader_id": {
+ "name": "downloader_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "download_type": {
+ "name": "download_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'torrent'"
+ },
+ "download_hash": {
+ "name": "download_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "download_title": {
+ "name": "download_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'downloading'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "added_at": {
+ "name": "added_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "game_downloads_downloader_hash_idx": {
+ "name": "game_downloads_downloader_hash_idx",
+ "columns": ["downloader_id", "download_hash"],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "game_downloads_game_id_games_id_fk": {
+ "name": "game_downloads_game_id_games_id_fk",
+ "tableFrom": "game_downloads",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_downloads_downloader_id_downloaders_id_fk": {
+ "name": "game_downloads_downloader_id_downloaders_id_fk",
+ "tableFrom": "game_downloads",
+ "tableTo": "downloaders",
+ "columnsFrom": ["downloader_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "game_files": {
+ "name": "game_files",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "download_id": {
+ "name": "download_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "original_name": {
+ "name": "original_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "stored_name": {
+ "name": "stored_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "category_overridden": {
+ "name": "category_overridden",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "file_path": {
+ "name": "file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "game_files_game_id_idx": {
+ "name": "game_files_game_id_idx",
+ "columns": ["game_id"],
+ "isUnique": false
+ },
+ "game_files_download_id_idx": {
+ "name": "game_files_download_id_idx",
+ "columns": ["download_id"],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "game_files_game_id_games_id_fk": {
+ "name": "game_files_game_id_games_id_fk",
+ "tableFrom": "game_files",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_files_download_id_game_downloads_id_fk": {
+ "name": "game_files_download_id_game_downloads_id_fk",
+ "tableFrom": "game_files",
+ "tableTo": "game_downloads",
+ "columnsFrom": ["download_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "game_journal_entries": {
+ "name": "game_journal_entries",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "note": {
+ "name": "note",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "game_journal_entries_game_user_idx": {
+ "name": "game_journal_entries_game_user_idx",
+ "columns": ["game_id", "user_id"],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "game_journal_entries_game_id_games_id_fk": {
+ "name": "game_journal_entries_game_id_games_id_fk",
+ "tableFrom": "game_journal_entries",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_journal_entries_user_id_users_id_fk": {
+ "name": "game_journal_entries_user_id_users_id_fk",
+ "tableFrom": "game_journal_entries",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "game_milestones": {
+ "name": "game_milestones",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "game_milestones_game_user_idx": {
+ "name": "game_milestones_game_user_idx",
+ "columns": ["game_id", "user_id"],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "game_milestones_game_id_games_id_fk": {
+ "name": "game_milestones_game_id_games_id_fk",
+ "tableFrom": "game_milestones",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_milestones_user_id_users_id_fk": {
+ "name": "game_milestones_user_id_users_id_fk",
+ "tableFrom": "game_milestones",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "game_screenshots": {
+ "name": "game_screenshots",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "file_path": {
+ "name": "file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "caption": {
+ "name": "caption",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "game_screenshots_game_user_idx": {
+ "name": "game_screenshots_game_user_idx",
+ "columns": ["game_id", "user_id"],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "game_screenshots_game_id_games_id_fk": {
+ "name": "game_screenshots_game_id_games_id_fk",
+ "tableFrom": "game_screenshots",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "game_screenshots_user_id_users_id_fk": {
+ "name": "game_screenshots_user_id_users_id_fk",
+ "tableFrom": "game_screenshots",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "games": {
+ "name": "games",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "igdb_id": {
+ "name": "igdb_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "steam_appid": {
+ "name": "steam_appid",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cover_url": {
+ "name": "cover_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "release_date": {
+ "name": "release_date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "rating": {
+ "name": "rating",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "platforms": {
+ "name": "platforms",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "target_platform_id": {
+ "name": "target_platform_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "target_platform_name": {
+ "name": "target_platform_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "genres": {
+ "name": "genres",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "themes": {
+ "name": "themes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "publishers": {
+ "name": "publishers",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "developers": {
+ "name": "developers",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "screenshots": {
+ "name": "screenshots",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "videos": {
+ "name": "videos",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'manual'"
+ },
+ "igdb_websites": {
+ "name": "igdb_websites",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "expansions": {
+ "name": "expansions",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "aggregated_rating": {
+ "name": "aggregated_rating",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_to_beat_hastily": {
+ "name": "time_to_beat_hastily",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_to_beat_normally": {
+ "name": "time_to_beat_normally",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_to_beat_completely": {
+ "name": "time_to_beat_completely",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'wanted'"
+ },
+ "original_release_date": {
+ "name": "original_release_date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "release_status": {
+ "name": "release_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'upcoming'"
+ },
+ "early_access": {
+ "name": "early_access",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "hidden": {
+ "name": "hidden",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "is_adult_content": {
+ "name": "is_adult_content",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "is_age_restricted": {
+ "name": "is_age_restricted",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "user_rating": {
+ "name": "user_rating",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "library_path": {
+ "name": "library_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "installed_version": {
+ "name": "installed_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "search_results_available": {
+ "name": "search_results_available",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "search_results_available_at": {
+ "name": "search_results_available_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "update_search_results_available": {
+ "name": "update_search_results_available",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "packs_search_results_available": {
+ "name": "packs_search_results_available",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "added_at": {
+ "name": "added_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "games_user_id_users_id_fk": {
+ "name": "games_user_id_users_id_fk",
+ "tableFrom": "games",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "import_task_items": {
+ "name": "import_task_items",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "item_name": {
+ "name": "item_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "result": {
+ "name": "result",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "game_title": {
+ "name": "game_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "import_task_items_task_id_idx": {
+ "name": "import_task_items_task_id_idx",
+ "columns": ["task_id"],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "import_task_items_task_id_import_tasks_id_fk": {
+ "name": "import_task_items_task_id_import_tasks_id_fk",
+ "tableFrom": "import_task_items",
+ "tableTo": "import_tasks",
+ "columnsFrom": ["task_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "import_tasks": {
+ "name": "import_tasks",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "task_type": {
+ "name": "task_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "triggered_by": {
+ "name": "triggered_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'pending'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "total_items": {
+ "name": "total_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "added_items": {
+ "name": "added_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "skipped_items": {
+ "name": "skipped_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "failed_items": {
+ "name": "failed_items",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "import_tasks_user_id_users_id_fk": {
+ "name": "import_tasks_user_id_users_id_fk",
+ "tableFrom": "import_tasks",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "indexers": {
+ "name": "indexers",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "api_key": {
+ "name": "api_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "protocol": {
+ "name": "protocol",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'torznab'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "categories": {
+ "name": "categories",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'[]'"
+ },
+ "rss_enabled": {
+ "name": "rss_enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "auto_search_enabled": {
+ "name": "auto_search_enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "allow_insecure_lan": {
+ "name": "allow_insecure_lan",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "notifications": {
+ "name": "notifications",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "message": {
+ "name": "message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "read": {
+ "name": "read",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "notifications_user_id_users_id_fk": {
+ "name": "notifications_user_id_users_id_fk",
+ "tableFrom": "notifications",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "path_mappings": {
+ "name": "path_mappings",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "remote_path": {
+ "name": "remote_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "local_path": {
+ "name": "local_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "remote_host": {
+ "name": "remote_host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "platform_mappings": {
+ "name": "platform_mappings",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "igdb_platform_id": {
+ "name": "igdb_platform_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "source_platform_name": {
+ "name": "source_platform_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "release_blacklist": {
+ "name": "release_blacklist",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "release_title": {
+ "name": "release_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "indexer_name": {
+ "name": "indexer_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "release_blacklist_game_title_idx": {
+ "name": "release_blacklist_game_title_idx",
+ "columns": ["game_id", "release_title"],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "release_blacklist_game_id_games_id_fk": {
+ "name": "release_blacklist_game_id_games_id_fk",
+ "tableFrom": "release_blacklist",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "root_folders": {
+ "name": "root_folders",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "allow_delete": {
+ "name": "allow_delete",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "accessible": {
+ "name": "accessible",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "disk_free_bytes": {
+ "name": "disk_free_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "disk_total_bytes": {
+ "name": "disk_total_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_scanned_at": {
+ "name": "last_scanned_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "root_folders_path_unique": {
+ "name": "root_folders_path_unique",
+ "columns": ["path"],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "rss_feed_items": {
+ "name": "rss_feed_items",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "feed_id": {
+ "name": "feed_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "guid": {
+ "name": "guid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "pub_date": {
+ "name": "pub_date",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "source_name": {
+ "name": "source_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "igdb_game_id": {
+ "name": "igdb_game_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "igdb_game_name": {
+ "name": "igdb_game_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cover_url": {
+ "name": "cover_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "rss_feed_items_feed_id_rss_feeds_id_fk": {
+ "name": "rss_feed_items_feed_id_rss_feeds_id_fk",
+ "tableFrom": "rss_feed_items",
+ "tableTo": "rss_feeds",
+ "columnsFrom": ["feed_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "rss_feeds": {
+ "name": "rss_feeds",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'custom'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "mapping": {
+ "name": "mapping",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_check": {
+ "name": "last_check",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'ok'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "system_config": {
+ "name": "system_config",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "user_settings": {
+ "name": "user_settings",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "auto_search_enabled": {
+ "name": "auto_search_enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "auto_download_enabled": {
+ "name": "auto_download_enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "notification_preferences": {
+ "name": "notification_preferences",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "search_interval_hours": {
+ "name": "search_interval_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 6
+ },
+ "igdb_rate_limit_per_second": {
+ "name": "igdb_rate_limit_per_second",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 3
+ },
+ "download_rules": {
+ "name": "download_rules",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "last_auto_search": {
+ "name": "last_auto_search",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "xrel_scene_releases": {
+ "name": "xrel_scene_releases",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "xrel_p2p_releases": {
+ "name": "xrel_p2p_releases",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "auto_search_unreleased": {
+ "name": "auto_search_unreleased",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "steam_sync_failures": {
+ "name": "steam_sync_failures",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "steam_sync_enabled": {
+ "name": "steam_sync_enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "steam_sync_interval_hours": {
+ "name": "steam_sync_interval_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 24
+ },
+ "last_steam_sync": {
+ "name": "last_steam_sync",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "preferred_release_groups": {
+ "name": "preferred_release_groups",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "filter_by_preferred_groups": {
+ "name": "filter_by_preferred_groups",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "release_name_blacklist": {
+ "name": "release_name_blacklist",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "preferred_platform": {
+ "name": "preferred_platform",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "hide_adult_content": {
+ "name": "hide_adult_content",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "hide_age_restricted_content": {
+ "name": "hide_age_restricted_content",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "hide_shelved_by_default": {
+ "name": "hide_shelved_by_default",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "hide_owned_in_has_results": {
+ "name": "hide_owned_in_has_results",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": true
+ },
+ "enable_post_processing": {
+ "name": "enable_post_processing",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "auto_unpack": {
+ "name": "auto_unpack",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "rename_pattern": {
+ "name": "rename_pattern",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'{Title} ({Region})'"
+ },
+ "overwrite_existing": {
+ "name": "overwrite_existing",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "transfer_mode": {
+ "name": "transfer_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'hardlink'"
+ },
+ "import_platform_ids": {
+ "name": "import_platform_ids",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'[]'"
+ },
+ "ignored_extensions": {
+ "name": "ignored_extensions",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "'[]'"
+ },
+ "min_file_size": {
+ "name": "min_file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "library_root": {
+ "name": "library_root",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'/data'"
+ },
+ "auto_delete_after_import": {
+ "name": "auto_delete_after_import",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "sort_extras": {
+ "name": "sort_extras",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "telemetry_enabled": {
+ "name": "telemetry_enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {
+ "user_settings_user_id_unique": {
+ "name": "user_settings_user_id_unique",
+ "columns": ["user_id"],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "user_settings_user_id_users_id_fk": {
+ "name": "user_settings_user_id_users_id_fk",
+ "tableFrom": "user_settings",
+ "tableTo": "users",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "users": {
+ "name": "users",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "password_hash": {
+ "name": "password_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "steam_id_64": {
+ "name": "steam_id_64",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "users_username_unique": {
+ "name": "users_username_unique",
+ "columns": ["username"],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "xrel_notified_releases": {
+ "name": "xrel_notified_releases",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "game_id": {
+ "name": "game_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "xrel_release_id": {
+ "name": "xrel_release_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(strftime('%s', 'now') * 1000)"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "xrel_notified_releases_game_id_games_id_fk": {
+ "name": "xrel_notified_releases_game_id_games_id_fk",
+ "tableFrom": "xrel_notified_releases",
+ "tableTo": "games",
+ "columnsFrom": ["game_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ }
+ },
+ "views": {},
+ "enums": {},
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ },
+ "internal": {
+ "indexes": {}
+ }
+}
diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json
index 926d8bbe5..95e1e3f9d 100644
--- a/migrations/meta/_journal.json
+++ b/migrations/meta/_journal.json
@@ -330,6 +330,13 @@
"when": 1791870869466,
"tag": "0045_dazzling_namorita",
"breakpoints": true
+ },
+ {
+ "idx": 46,
+ "version": "6",
+ "when": 1792406179382,
+ "tag": "0046_unknown_moonstone",
+ "breakpoints": true
}
]
}
diff --git a/scripts/sqlite-to-pg.ts b/scripts/sqlite-to-pg.ts
index 24e66f2f1..921d98b66 100644
--- a/scripts/sqlite-to-pg.ts
+++ b/scripts/sqlite-to-pg.ts
@@ -55,6 +55,7 @@ const TABLE_ORDER = [
"gameDownloads",
"xrelNotifiedReleases",
"releaseBlacklist",
+ "downloadEvents",
"aiAutoDownloadHolds",
"importTaskItems",
"gameJournalEntries",
diff --git a/server/__tests__/activity_system_routes.test.ts b/server/__tests__/activity_system_routes.test.ts
new file mode 100644
index 000000000..05e538255
--- /dev/null
+++ b/server/__tests__/activity_system_routes.test.ts
@@ -0,0 +1,102 @@
+import express from "express";
+import request from "supertest";
+import { beforeEach, describe, expect, it, vi } from "vitest";
+
+vi.mock("../storage.js", () => ({
+ storage: {
+ getDownloadEvents: vi.fn(),
+ removeAllReleaseBlacklists: vi.fn(),
+ getSystemConfig: vi.fn().mockResolvedValue(undefined),
+ setSystemConfig: vi.fn().mockResolvedValue(undefined),
+ },
+}));
+vi.mock("../socket.js", () => ({ notifyUser: vi.fn() }));
+vi.mock("../logger.js", () => {
+ const l = { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() };
+ return { logger: l, igdbLogger: l, routesLogger: l };
+});
+
+import { activityRouter } from "../routes/activity.js";
+import { systemRouter } from "../routes/system.js";
+import { registerTask, resetTaskRegistry } from "../task-registry.js";
+import { storage } from "../storage.js";
+
+function makeApp(authenticated = true) {
+ const app = express();
+ app.use((req, _res, next) => {
+ if (authenticated) req.user = { id: "u1" } as never;
+ next();
+ });
+ app.use("/api/activity", activityRouter);
+ app.use("/api/system", systemRouter);
+ return app;
+}
+
+describe("activity routes", () => {
+ beforeEach(() => vi.clearAllMocks());
+
+ it("requires authentication", async () => {
+ await request(makeApp(false)).get("/api/activity/history").expect(401);
+ });
+
+ it("passes filters and paging to the storage layer", async () => {
+ vi.mocked(storage.getDownloadEvents).mockResolvedValue({ events: [], total: 0 });
+ await request(makeApp())
+ .get("/api/activity/history?eventType=failed&search=zelda&limit=10&offset=20")
+ .expect(200, { events: [], total: 0 });
+ expect(storage.getDownloadEvents).toHaveBeenCalledWith("u1", {
+ eventType: "failed",
+ search: "zelda",
+ limit: 10,
+ offset: 20,
+ });
+ });
+
+ it("rejects an unknown event type and an oversized page", async () => {
+ await request(makeApp()).get("/api/activity/history?eventType=nope").expect(400);
+ await request(makeApp()).get("/api/activity/history?limit=9999").expect(400);
+ });
+
+ it("reports a storage failure as 500", async () => {
+ vi.mocked(storage.getDownloadEvents).mockRejectedValue(new Error("db"));
+ await request(makeApp()).get("/api/activity/history").expect(500);
+ });
+
+ it("unblocks everything for the user", async () => {
+ vi.mocked(storage.removeAllReleaseBlacklists).mockResolvedValue(3);
+ await request(makeApp()).delete("/api/activity/blocklist").expect(200, { removed: 3 });
+ expect(storage.removeAllReleaseBlacklists).toHaveBeenCalledWith("u1");
+ });
+
+ it("reports a failed unblock-all as 500", async () => {
+ vi.mocked(storage.removeAllReleaseBlacklists).mockRejectedValue(new Error("db"));
+ await request(makeApp()).delete("/api/activity/blocklist").expect(500);
+ });
+});
+
+describe("system task routes", () => {
+ beforeEach(() => {
+ resetTaskRegistry();
+ });
+
+ it("lists tasks, runs one with 202, and refuses a second run while it is running", async () => {
+ let release!: () => void;
+ registerTask({
+ name: "slow",
+ title: "Slow",
+ description: "",
+ intervalMs: 60_000,
+ run: () => new Promise