diff --git a/src/app/api/guess/route.js b/src/app/api/guess/route.js index f104fe3..65a80db 100644 --- a/src/app/api/guess/route.js +++ b/src/app/api/guess/route.js @@ -65,7 +65,7 @@ export async function POST(request) { // guessing over 331,000 km2, and the district-scale ladder would zero // almost every honest guess. The picked region is not a secret, so this // reveals nothing. - const pickedCode = session.pickedRegion ?? session.cityCode ?? null; + const pickedCode = session.pickedRegion ?? null; const scoreBands = pickedCode && isRegion(pickedCode) ? bandsForBbox(getRegion(pickedCode).bbox) : SCORE_BANDS; @@ -76,11 +76,7 @@ export async function POST(request) { // The region the panorama was actually in, resolved server-side when the // round was created. Never read from the request: a client that could name // its own region could farm any district's board. - // - // The `?? cityCode` fallback carries sessions created before this deploy. - // They have no district, so they credit province and country only. Sessions - // live 30 minutes, so this can be dropped a release from now. - const scoringRegion = session.regionCode ?? session.cityCode; + const scoringRegion = session.regionCode; // Claim the session before writing, and score only if this request is the // one that removed it. DEL is atomic, so exactly one of N concurrent diff --git a/src/app/api/new-game/route.js b/src/app/api/new-game/route.js index 11b059f..aa4c42d 100644 --- a/src/app/api/new-game/route.js +++ b/src/app/api/new-game/route.js @@ -122,7 +122,7 @@ export async function POST(request) { // Only what the player picked. Neither exactLocation nor regionCode is // exposed: the caller owns this session id, so either one would hand // them the answer to their own round. - pickedRegion: session.pickedRegion ?? session.cityCode ?? null, + pickedRegion: session.pickedRegion ?? null, createdAt: session.createdAt } }); diff --git a/tests/guess-route.test.js b/tests/guess-route.test.js index 77af332..97aae0a 100644 --- a/tests/guess-route.test.js +++ b/tests/guess-route.test.js @@ -103,18 +103,6 @@ describe('POST /api/guess', () => { expect((await getLeaderboard('TPHCM-Q7'))[0].score).toBe(5); }); - it('scores a session created before the tree at province level', async () => { - // Sessions live 30 minutes, so a deploy strands some in the old shape. - // They have no district and must still score rather than throw. - await seedSession('s5', { regionCode: undefined, cityCode: 'TPHCM' }); - const body = await ( - await guess({ username: 'mai', sessionId: 's5', guessLat: HCMC.lat, guessLng: HCMC.lng }) - ).json(); - - expect(body.success).toBe(true); - expect(body.gameResult.levels.map((l) => l.code)).toEqual(['TPHCM', 'VN']); - }); - it('lets exactly one of many concurrent submits score', async () => { // Read-then-delete is not a guard: ten requests all read a live session, // all delete it, and all write. DEL is atomic, so gating on its count is