feat(api): add answer evaluation endpoint

Complete the game answer flow:

- Add evaluateAnswer service function: looks up the session in the
  GameSessionStore, compares the submitted optionId against the stored
  correct answer, returns an AnswerResult.
- Add submitAnswer controller with safeParse validation and error
  handling (session/question not found → 404).
- Add POST /api/v1/game/answer route.
- Fix createGameSession: was missing the answerKey tracking and the
  gameSessionStore.create() call, so sessions were never persisted.

The full singleplayer game loop now works end-to-end:
POST /game/start → GameSession, POST /game/answer → AnswerResult.
This commit is contained in:
lila 2026-04-11 12:12:54 +02:00
parent 0755c57439
commit 075a691849
4 changed files with 83 additions and 9 deletions

View file

@ -1,5 +1,6 @@
async function main() {
const response = await fetch("http://localhost:3000/api/v1/game/start", {
// Step 1: start a game
const startResponse = await fetch("http://localhost:3000/api/v1/game/start", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
@ -10,9 +11,29 @@ async function main() {
rounds: "3",
}),
});
const game = await startResponse.json();
console.log("Game started:", JSON.stringify(game, null, 2));
const data = await response.json();
console.log(JSON.stringify(data, null, 2));
// Step 2: answer each question (always pick option 0)
for (const question of game.data.questions) {
const answerResponse = await fetch(
"http://localhost:3000/api/v1/game/answer",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
sessionId: game.data.sessionId,
questionId: question.questionId,
selectedOptionId: 0,
}),
},
);
const result = await answerResponse.json();
console.log("Raw result:", JSON.stringify(result, null, 2));
console.log(
`${question.prompt}: ${result.data.isCorrect ? "✓" : "✗"} (picked ${0}, correct was ${result.data.correctOptionId})`,
);
}
}
main();