feat(api): assemble full GameSession with shuffled answer options

Extend the game flow from raw term rows to a complete GameSession
matching the shared schema:

- Add getDistractors model query: fetches N same-POS, same-difficulty,
  same-target-language terms excluding a given termId. Returns bare
  strings since distractors only need their display text.
- Fix getGameTerms select clause to use the neutral field names
  (sourceText, targetText, sourceGloss) that the type already declared.
- Rename gameService entry point to createGameSession; signature now
  takes a GameRequest and returns a GameSession.
- Per question: fetch 3 distractors, combine with the correct answer,
  shuffle (Fisher-Yates), assign optionIds 0-3 by post-shuffle index,
  and assemble into a GameQuestion with a fresh UUID.
- Wrap the questions in a GameSession with its own UUID.
- Run per-question distractor fetches in parallel via Promise.all.

Known gap: the correct option is not yet remembered server-side, so
/game/answer cannot evaluate submissions. SessionStore lands next.
This commit is contained in:
lila 2026-04-10 21:44:36 +02:00
parent 0cf6a852b2
commit f53ac618bb
4 changed files with 95 additions and 20 deletions

View file

@ -10,4 +10,4 @@ config({
export const db = drizzle(process.env["DATABASE_URL"]!);
export { getGameTerms } from "./models/termModel.js";
export * from "./models/termModel.js";