Phase 1.1 Complete: Database & Auth Infrastructure - Configure Drizzle with SQLite and better-sqlite3 - Create schema for users, players, and user_stats tables - Set up database client with foreign keys and WAL mode enabled - Add migration runner and package.json scripts - Generate initial migration (0000_third_carnage.sql) Database Features: - Users table with guestId for guest sessions - Players table with userId FK (cascade delete) - UserStats table with userId FK (cascade delete) - Indexes on foreign keys for performance - Type-safe schema with Drizzle ORM Testing: - 20 unit + e2e tests all passing - Schema validation tests - Migration idempotency tests - Foreign key constraint tests - Cascade delete tests Scripts added: - pnpm db:generate - Generate migration from schema - pnpm db:migrate - Run pending migrations - pnpm db:push - Push schema directly (dev) - pnpm db:studio - Visual DB browser - pnpm db:drop - Drop migration (dev) User tests verified: ✅ Migration runs successfully ✅ Database tables created with correct schema ✅ Migration is idempotent (can run multiple times)
33 lines
1.1 KiB
SQL
33 lines
1.1 KiB
SQL
CREATE TABLE `users` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`guest_id` text NOT NULL,
|
|
`created_at` integer NOT NULL,
|
|
`upgraded_at` integer,
|
|
`email` text,
|
|
`name` text
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `users_guest_id_unique` ON `users` (`guest_id`);--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `users_email_unique` ON `users` (`email`);--> statement-breakpoint
|
|
CREATE TABLE `players` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`user_id` text NOT NULL,
|
|
`name` text NOT NULL,
|
|
`emoji` text NOT NULL,
|
|
`color` text NOT NULL,
|
|
`is_active` integer DEFAULT false NOT NULL,
|
|
`created_at` integer NOT NULL,
|
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE INDEX `players_user_id_idx` ON `players` (`user_id`);--> statement-breakpoint
|
|
CREATE TABLE `user_stats` (
|
|
`user_id` text PRIMARY KEY NOT NULL,
|
|
`games_played` integer DEFAULT 0 NOT NULL,
|
|
`total_wins` integer DEFAULT 0 NOT NULL,
|
|
`favorite_game_type` text,
|
|
`best_time` integer,
|
|
`highest_accuracy` real DEFAULT 0 NOT NULL,
|
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
|
|
);
|