Bun workspace monorepo with shared, server, client packages. Server: Hono + @hono/node-ws, Drizzle + PostgreSQL, in-memory room manager with WebSocket broadcasting, HTTP room creation, DB persistence layer. Client: React 19 + Vite + Tailwind v4 + shadcn/ui, TanStack Router with landing/display/host/player routes, Zustand store, WebSocket connection hook. 20 tests passing (room manager unit + WS integration). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
733 lines
18 KiB
JSON
733 lines
18 KiB
JSON
{
|
|
"id": "476634f4-fc77-43fc-9aaa-043d352b0b53",
|
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
|
"version": "7",
|
|
"dialect": "postgresql",
|
|
"tables": {
|
|
"public.bingo_cards": {
|
|
"name": "bingo_cards",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"player_id": {
|
|
"name": "player_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"room_id": {
|
|
"name": "room_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"squares": {
|
|
"name": "squares",
|
|
"type": "jsonb",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"bingo_cards_player_id_players_id_fk": {
|
|
"name": "bingo_cards_player_id_players_id_fk",
|
|
"tableFrom": "bingo_cards",
|
|
"tableTo": "players",
|
|
"columnsFrom": [
|
|
"player_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
},
|
|
"bingo_cards_room_id_rooms_id_fk": {
|
|
"name": "bingo_cards_room_id_rooms_id_fk",
|
|
"tableFrom": "bingo_cards",
|
|
"tableTo": "rooms",
|
|
"columnsFrom": [
|
|
"room_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.dish_guesses": {
|
|
"name": "dish_guesses",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"player_id": {
|
|
"name": "player_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"dish_id": {
|
|
"name": "dish_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"guessed_country": {
|
|
"name": "guessed_country",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"dish_guesses_player_id_players_id_fk": {
|
|
"name": "dish_guesses_player_id_players_id_fk",
|
|
"tableFrom": "dish_guesses",
|
|
"tableTo": "players",
|
|
"columnsFrom": [
|
|
"player_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
},
|
|
"dish_guesses_dish_id_dishes_id_fk": {
|
|
"name": "dish_guesses_dish_id_dishes_id_fk",
|
|
"tableFrom": "dish_guesses",
|
|
"tableTo": "dishes",
|
|
"columnsFrom": [
|
|
"dish_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.dishes": {
|
|
"name": "dishes",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"room_id": {
|
|
"name": "room_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"name": {
|
|
"name": "name",
|
|
"type": "varchar(100)",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"correct_country": {
|
|
"name": "correct_country",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"revealed": {
|
|
"name": "revealed",
|
|
"type": "boolean",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"dishes_room_id_rooms_id_fk": {
|
|
"name": "dishes_room_id_rooms_id_fk",
|
|
"tableFrom": "dishes",
|
|
"tableTo": "rooms",
|
|
"columnsFrom": [
|
|
"room_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.jury_rounds": {
|
|
"name": "jury_rounds",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"room_id": {
|
|
"name": "room_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"country_code": {
|
|
"name": "country_code",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"status": {
|
|
"name": "status",
|
|
"type": "jury_round_status",
|
|
"typeSchema": "public",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": "'open'"
|
|
},
|
|
"opened_at": {
|
|
"name": "opened_at",
|
|
"type": "timestamp",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": "now()"
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"jury_rounds_room_id_rooms_id_fk": {
|
|
"name": "jury_rounds_room_id_rooms_id_fk",
|
|
"tableFrom": "jury_rounds",
|
|
"tableTo": "rooms",
|
|
"columnsFrom": [
|
|
"room_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.jury_votes": {
|
|
"name": "jury_votes",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"player_id": {
|
|
"name": "player_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"jury_round_id": {
|
|
"name": "jury_round_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"rating": {
|
|
"name": "rating",
|
|
"type": "integer",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"jury_votes_player_id_players_id_fk": {
|
|
"name": "jury_votes_player_id_players_id_fk",
|
|
"tableFrom": "jury_votes",
|
|
"tableTo": "players",
|
|
"columnsFrom": [
|
|
"player_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
},
|
|
"jury_votes_jury_round_id_jury_rounds_id_fk": {
|
|
"name": "jury_votes_jury_round_id_jury_rounds_id_fk",
|
|
"tableFrom": "jury_votes",
|
|
"tableTo": "jury_rounds",
|
|
"columnsFrom": [
|
|
"jury_round_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.players": {
|
|
"name": "players",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"room_id": {
|
|
"name": "room_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"session_id": {
|
|
"name": "session_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"display_name": {
|
|
"name": "display_name",
|
|
"type": "varchar(20)",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"is_host": {
|
|
"name": "is_host",
|
|
"type": "boolean",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": false
|
|
},
|
|
"connected": {
|
|
"name": "connected",
|
|
"type": "boolean",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": false
|
|
},
|
|
"joined_at": {
|
|
"name": "joined_at",
|
|
"type": "timestamp",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": "now()"
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"players_room_id_rooms_id_fk": {
|
|
"name": "players_room_id_rooms_id_fk",
|
|
"tableFrom": "players",
|
|
"tableTo": "rooms",
|
|
"columnsFrom": [
|
|
"room_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {
|
|
"players_session_id_unique": {
|
|
"name": "players_session_id_unique",
|
|
"nullsNotDistinct": false,
|
|
"columns": [
|
|
"session_id"
|
|
]
|
|
}
|
|
},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.predictions": {
|
|
"name": "predictions",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"player_id": {
|
|
"name": "player_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"room_id": {
|
|
"name": "room_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"predicted_winner": {
|
|
"name": "predicted_winner",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"top_3": {
|
|
"name": "top_3",
|
|
"type": "jsonb",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"nul_points_pick": {
|
|
"name": "nul_points_pick",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"predictions_player_id_players_id_fk": {
|
|
"name": "predictions_player_id_players_id_fk",
|
|
"tableFrom": "predictions",
|
|
"tableTo": "players",
|
|
"columnsFrom": [
|
|
"player_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
},
|
|
"predictions_room_id_rooms_id_fk": {
|
|
"name": "predictions_room_id_rooms_id_fk",
|
|
"tableFrom": "predictions",
|
|
"tableTo": "rooms",
|
|
"columnsFrom": [
|
|
"room_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.quiz_answers": {
|
|
"name": "quiz_answers",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"player_id": {
|
|
"name": "player_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"quiz_round_id": {
|
|
"name": "quiz_round_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"buzzed_at": {
|
|
"name": "buzzed_at",
|
|
"type": "timestamp",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": "now()"
|
|
},
|
|
"correct": {
|
|
"name": "correct",
|
|
"type": "boolean",
|
|
"primaryKey": false,
|
|
"notNull": false
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"quiz_answers_player_id_players_id_fk": {
|
|
"name": "quiz_answers_player_id_players_id_fk",
|
|
"tableFrom": "quiz_answers",
|
|
"tableTo": "players",
|
|
"columnsFrom": [
|
|
"player_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
},
|
|
"quiz_answers_quiz_round_id_quiz_rounds_id_fk": {
|
|
"name": "quiz_answers_quiz_round_id_quiz_rounds_id_fk",
|
|
"tableFrom": "quiz_answers",
|
|
"tableTo": "quiz_rounds",
|
|
"columnsFrom": [
|
|
"quiz_round_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.quiz_rounds": {
|
|
"name": "quiz_rounds",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"room_id": {
|
|
"name": "room_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"question_id": {
|
|
"name": "question_id",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"status": {
|
|
"name": "status",
|
|
"type": "quiz_round_status",
|
|
"typeSchema": "public",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": "'showing'"
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {
|
|
"quiz_rounds_room_id_rooms_id_fk": {
|
|
"name": "quiz_rounds_room_id_rooms_id_fk",
|
|
"tableFrom": "quiz_rounds",
|
|
"tableTo": "rooms",
|
|
"columnsFrom": [
|
|
"room_id"
|
|
],
|
|
"columnsTo": [
|
|
"id"
|
|
],
|
|
"onDelete": "no action",
|
|
"onUpdate": "no action"
|
|
}
|
|
},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
},
|
|
"public.rooms": {
|
|
"name": "rooms",
|
|
"schema": "",
|
|
"columns": {
|
|
"id": {
|
|
"name": "id",
|
|
"type": "uuid",
|
|
"primaryKey": true,
|
|
"notNull": true,
|
|
"default": "gen_random_uuid()"
|
|
},
|
|
"code": {
|
|
"name": "code",
|
|
"type": "varchar(4)",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"current_act": {
|
|
"name": "current_act",
|
|
"type": "act",
|
|
"typeSchema": "public",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": "'lobby'"
|
|
},
|
|
"host_session_id": {
|
|
"name": "host_session_id",
|
|
"type": "uuid",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
},
|
|
"actual_winner": {
|
|
"name": "actual_winner",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": false
|
|
},
|
|
"actual_second": {
|
|
"name": "actual_second",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": false
|
|
},
|
|
"actual_third": {
|
|
"name": "actual_third",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": false
|
|
},
|
|
"actual_last": {
|
|
"name": "actual_last",
|
|
"type": "varchar",
|
|
"primaryKey": false,
|
|
"notNull": false
|
|
},
|
|
"created_at": {
|
|
"name": "created_at",
|
|
"type": "timestamp",
|
|
"primaryKey": false,
|
|
"notNull": true,
|
|
"default": "now()"
|
|
},
|
|
"expires_at": {
|
|
"name": "expires_at",
|
|
"type": "timestamp",
|
|
"primaryKey": false,
|
|
"notNull": true
|
|
}
|
|
},
|
|
"indexes": {},
|
|
"foreignKeys": {},
|
|
"compositePrimaryKeys": {},
|
|
"uniqueConstraints": {
|
|
"rooms_code_unique": {
|
|
"name": "rooms_code_unique",
|
|
"nullsNotDistinct": false,
|
|
"columns": [
|
|
"code"
|
|
]
|
|
}
|
|
},
|
|
"policies": {},
|
|
"checkConstraints": {},
|
|
"isRLSEnabled": false
|
|
}
|
|
},
|
|
"enums": {
|
|
"public.act": {
|
|
"name": "act",
|
|
"schema": "public",
|
|
"values": [
|
|
"lobby",
|
|
"act1",
|
|
"act2",
|
|
"act3",
|
|
"ended"
|
|
]
|
|
},
|
|
"public.jury_round_status": {
|
|
"name": "jury_round_status",
|
|
"schema": "public",
|
|
"values": [
|
|
"open",
|
|
"closed"
|
|
]
|
|
},
|
|
"public.quiz_round_status": {
|
|
"name": "quiz_round_status",
|
|
"schema": "public",
|
|
"values": [
|
|
"showing",
|
|
"buzzing",
|
|
"judging",
|
|
"resolved"
|
|
]
|
|
}
|
|
},
|
|
"schemas": {},
|
|
"sequences": {},
|
|
"roles": {},
|
|
"policies": {},
|
|
"views": {},
|
|
"_meta": {
|
|
"columns": {},
|
|
"schemas": {},
|
|
"tables": {}
|
|
}
|
|
} |