fix: 修复竞态条件、重置逻辑、无匹配终态等关键问题
- 用 Prisma $transaction 实现 atomicUpdateRoom,防止并发写入覆盖 - 新增 POST /api/room/[id]/reset 端点,修复"再来一轮"按钮死循环 - 新增 swipeCounts 字段追踪滑动进度,检测"无人匹配"终态 - 着陆页 handleCreate 增加 res.ok 检查,防止跳转到无效房间 - 匹配或无匹配后停止轮询,减少无效请求
This commit is contained in:
+33
-7
@@ -5,6 +5,7 @@ export interface RoomData {
|
||||
users: string[];
|
||||
restaurants: Restaurant[];
|
||||
likes: Record<string, string[]>;
|
||||
swipeCounts: Record<string, number>;
|
||||
match: string | null;
|
||||
}
|
||||
|
||||
@@ -12,11 +13,22 @@ function generateRoomId(): string {
|
||||
return String(Math.floor(1000 + Math.random() * 9000));
|
||||
}
|
||||
|
||||
function normalize(raw: Partial<RoomData>): RoomData {
|
||||
return {
|
||||
users: raw.users ?? [],
|
||||
restaurants: raw.restaurants ?? [],
|
||||
likes: raw.likes ?? {},
|
||||
swipeCounts: raw.swipeCounts ?? {},
|
||||
match: raw.match ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
export async function createRoom(restaurants: Restaurant[]): Promise<string> {
|
||||
const data: RoomData = {
|
||||
users: [],
|
||||
restaurants,
|
||||
likes: {},
|
||||
swipeCounts: {},
|
||||
match: null,
|
||||
};
|
||||
|
||||
@@ -47,15 +59,29 @@ export async function getRoomData(
|
||||
): Promise<RoomData | null> {
|
||||
const room = await prisma.room.findUnique({ where: { id: roomId } });
|
||||
if (!room) return null;
|
||||
return JSON.parse(room.data) as RoomData;
|
||||
return normalize(JSON.parse(room.data));
|
||||
}
|
||||
|
||||
export async function updateRoomData(
|
||||
/**
|
||||
* Atomic read-modify-write within a Prisma transaction.
|
||||
* Prevents race conditions when multiple users swipe concurrently.
|
||||
*/
|
||||
export async function atomicUpdateRoom(
|
||||
roomId: string,
|
||||
data: RoomData,
|
||||
): Promise<void> {
|
||||
await prisma.room.update({
|
||||
where: { id: roomId },
|
||||
data: { data: JSON.stringify(data) },
|
||||
updater: (data: RoomData) => RoomData,
|
||||
): Promise<RoomData | null> {
|
||||
return prisma.$transaction(async (tx) => {
|
||||
const room = await tx.room.findUnique({ where: { id: roomId } });
|
||||
if (!room) return null;
|
||||
|
||||
const data = normalize(JSON.parse(room.data));
|
||||
const updated = updater(data);
|
||||
|
||||
await tx.room.update({
|
||||
where: { id: roomId },
|
||||
data: { data: JSON.stringify(updated) },
|
||||
});
|
||||
|
||||
return updated;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user