feat(db): add hardware seed script, db:seed command, and initial migration

- Create lib/db/seed.ts with idempotent hardware seeding
- Add db:seed script and fix db:* scripts to load .env.local via bun --env-file
- Generate initial Drizzle migration (0000_crazy_nick_fury)
- Apply migration and seed 3 hardware devices (steamdeck-oled, steamdeck-lcd, steam-machine)
This commit is contained in:
2026-04-25 11:53:10 +08:00
parent 50f737f686
commit 65d13933bf
5 changed files with 696 additions and 4 deletions
+80
View File
@@ -0,0 +1,80 @@
CREATE TYPE "public"."anti_cheat_status" AS ENUM('none', 'supported', 'unsupported', 'unknown');--> statement-breakpoint
CREATE TYPE "public"."proton_status" AS ENUM('native', 'proton', 'unsupported', 'unknown');--> statement-breakpoint
CREATE TYPE "public"."device_type" AS ENUM('handled', 'console');--> statement-breakpoint
CREATE TABLE "game_platform_support" (
"id" text PRIMARY KEY NOT NULL,
"game_id" text NOT NULL,
"hardware_slug" text NOT NULL,
"is_supported" boolean DEFAULT false NOT NULL,
"proton_status" "proton_status" DEFAULT 'unknown' NOT NULL,
"anti_cheat_relevant" boolean DEFAULT false NOT NULL,
"anti_cheat_name" text,
"anti_cheat_version" text,
"anti_cheat_status" "anti_cheat_status" DEFAULT 'unknown' NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
CONSTRAINT "game_hardware_unique" UNIQUE("game_id","hardware_slug")
);
--> statement-breakpoint
CREATE TABLE "game_versions" (
"id" text PRIMARY KEY NOT NULL,
"game_id" text NOT NULL,
"build_id" text,
"version_string" text,
"is_latest" boolean DEFAULT false NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
CONSTRAINT "game_build_unique" UNIQUE("game_id","build_id")
);
--> statement-breakpoint
CREATE TABLE "games" (
"id" text PRIMARY KEY NOT NULL,
"steam_app_id" integer NOT NULL,
"title" text NOT NULL,
"description" text,
"publisher" text,
"developer" text,
"genres" jsonb,
"header_image" text,
"capsule_image" text,
"store_url" text,
"last_sync" timestamp,
"sync_status" text DEFAULT 'pending',
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
CONSTRAINT "games_steam_app_id_unique" UNIQUE("steam_app_id")
);
--> statement-breakpoint
CREATE TABLE "hardware" (
"slug" text PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"device_type" "device_type" NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "performance_entries" (
"id" text PRIMARY KEY NOT NULL,
"version_id" text NOT NULL,
"hardware_slug" text NOT NULL,
"user_id" text NOT NULL,
"fps_avg" real NOT NULL,
"fps_low" real,
"fps_high" real,
"proton_version" text,
"os_version" text,
"is_fsr_enabled" boolean DEFAULT false NOT NULL,
"is_frame_gen_enabled" boolean DEFAULT false NOT NULL,
"load_time_ssd" real,
"load_time_sd" real,
"settings_json" jsonb,
"user_notes" text,
"is_removed" boolean DEFAULT false NOT NULL,
"removed_reason" text,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "game_platform_support" ADD CONSTRAINT "game_platform_support_game_id_games_id_fk" FOREIGN KEY ("game_id") REFERENCES "public"."games"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "game_platform_support" ADD CONSTRAINT "game_platform_support_hardware_slug_hardware_slug_fk" FOREIGN KEY ("hardware_slug") REFERENCES "public"."hardware"("slug") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "game_versions" ADD CONSTRAINT "game_versions_game_id_games_id_fk" FOREIGN KEY ("game_id") REFERENCES "public"."games"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "performance_entries" ADD CONSTRAINT "performance_entries_version_id_game_versions_id_fk" FOREIGN KEY ("version_id") REFERENCES "public"."game_versions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "performance_entries" ADD CONSTRAINT "performance_entries_hardware_slug_hardware_slug_fk" FOREIGN KEY ("hardware_slug") REFERENCES "public"."hardware"("slug") ON DELETE restrict ON UPDATE no action;
+551
View File
@@ -0,0 +1,551 @@
{
"id": "7ddf967c-480b-4279-aae8-a9bc7cd6bc51",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.game_platform_support": {
"name": "game_platform_support",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"game_id": {
"name": "game_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"hardware_slug": {
"name": "hardware_slug",
"type": "text",
"primaryKey": false,
"notNull": true
},
"is_supported": {
"name": "is_supported",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"proton_status": {
"name": "proton_status",
"type": "proton_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'unknown'"
},
"anti_cheat_relevant": {
"name": "anti_cheat_relevant",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"anti_cheat_name": {
"name": "anti_cheat_name",
"type": "text",
"primaryKey": false,
"notNull": false
},
"anti_cheat_version": {
"name": "anti_cheat_version",
"type": "text",
"primaryKey": false,
"notNull": false
},
"anti_cheat_status": {
"name": "anti_cheat_status",
"type": "anti_cheat_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'unknown'"
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"game_platform_support_game_id_games_id_fk": {
"name": "game_platform_support_game_id_games_id_fk",
"tableFrom": "game_platform_support",
"tableTo": "games",
"columnsFrom": [
"game_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"game_platform_support_hardware_slug_hardware_slug_fk": {
"name": "game_platform_support_hardware_slug_hardware_slug_fk",
"tableFrom": "game_platform_support",
"tableTo": "hardware",
"columnsFrom": [
"hardware_slug"
],
"columnsTo": [
"slug"
],
"onDelete": "restrict",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"game_hardware_unique": {
"name": "game_hardware_unique",
"nullsNotDistinct": false,
"columns": [
"game_id",
"hardware_slug"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.game_versions": {
"name": "game_versions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"game_id": {
"name": "game_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"build_id": {
"name": "build_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"version_string": {
"name": "version_string",
"type": "text",
"primaryKey": false,
"notNull": false
},
"is_latest": {
"name": "is_latest",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"game_versions_game_id_games_id_fk": {
"name": "game_versions_game_id_games_id_fk",
"tableFrom": "game_versions",
"tableTo": "games",
"columnsFrom": [
"game_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"game_build_unique": {
"name": "game_build_unique",
"nullsNotDistinct": false,
"columns": [
"game_id",
"build_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.games": {
"name": "games",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"steam_app_id": {
"name": "steam_app_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"publisher": {
"name": "publisher",
"type": "text",
"primaryKey": false,
"notNull": false
},
"developer": {
"name": "developer",
"type": "text",
"primaryKey": false,
"notNull": false
},
"genres": {
"name": "genres",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"header_image": {
"name": "header_image",
"type": "text",
"primaryKey": false,
"notNull": false
},
"capsule_image": {
"name": "capsule_image",
"type": "text",
"primaryKey": false,
"notNull": false
},
"store_url": {
"name": "store_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"last_sync": {
"name": "last_sync",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"sync_status": {
"name": "sync_status",
"type": "text",
"primaryKey": false,
"notNull": false,
"default": "'pending'"
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"games_steam_app_id_unique": {
"name": "games_steam_app_id_unique",
"nullsNotDistinct": false,
"columns": [
"steam_app_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hardware": {
"name": "hardware",
"schema": "",
"columns": {
"slug": {
"name": "slug",
"type": "text",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"device_type": {
"name": "device_type",
"type": "device_type",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.performance_entries": {
"name": "performance_entries",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"version_id": {
"name": "version_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"hardware_slug": {
"name": "hardware_slug",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"fps_avg": {
"name": "fps_avg",
"type": "real",
"primaryKey": false,
"notNull": true
},
"fps_low": {
"name": "fps_low",
"type": "real",
"primaryKey": false,
"notNull": false
},
"fps_high": {
"name": "fps_high",
"type": "real",
"primaryKey": false,
"notNull": false
},
"proton_version": {
"name": "proton_version",
"type": "text",
"primaryKey": false,
"notNull": false
},
"os_version": {
"name": "os_version",
"type": "text",
"primaryKey": false,
"notNull": false
},
"is_fsr_enabled": {
"name": "is_fsr_enabled",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"is_frame_gen_enabled": {
"name": "is_frame_gen_enabled",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"load_time_ssd": {
"name": "load_time_ssd",
"type": "real",
"primaryKey": false,
"notNull": false
},
"load_time_sd": {
"name": "load_time_sd",
"type": "real",
"primaryKey": false,
"notNull": false
},
"settings_json": {
"name": "settings_json",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"user_notes": {
"name": "user_notes",
"type": "text",
"primaryKey": false,
"notNull": false
},
"is_removed": {
"name": "is_removed",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"removed_reason": {
"name": "removed_reason",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"performance_entries_version_id_game_versions_id_fk": {
"name": "performance_entries_version_id_game_versions_id_fk",
"tableFrom": "performance_entries",
"tableTo": "game_versions",
"columnsFrom": [
"version_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"performance_entries_hardware_slug_hardware_slug_fk": {
"name": "performance_entries_hardware_slug_hardware_slug_fk",
"tableFrom": "performance_entries",
"tableTo": "hardware",
"columnsFrom": [
"hardware_slug"
],
"columnsTo": [
"slug"
],
"onDelete": "restrict",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {
"public.anti_cheat_status": {
"name": "anti_cheat_status",
"schema": "public",
"values": [
"none",
"supported",
"unsupported",
"unknown"
]
},
"public.proton_status": {
"name": "proton_status",
"schema": "public",
"values": [
"native",
"proton",
"unsupported",
"unknown"
]
},
"public.device_type": {
"name": "device_type",
"schema": "public",
"values": [
"handled",
"console"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1777089104474,
"tag": "0000_crazy_nick_fury",
"breakpoints": true
}
]
}