feat(api): implement game terms query with double join

- Add double join on translations for source/target languages
- Left join term_glosses for optional source-language glosses
- Filter difficulty on target side only (intentionally asymmetric:
  a word's difficulty can differ between languages, and what matters
  is the difficulty of the word being learned)
- Return neutral field names (sourceText, targetText, sourceGloss)
  instead of quiz semantics; service layer maps to prompt/answer
- Tighten term_glosses unique constraint to (term_id, language_code)
  to prevent the left join from multiplying question rows
- Add TODO for ORDER BY RANDOM() scaling post-MVP
This commit is contained in:
lila 2026-04-10 18:02:03 +02:00
parent 9fc3ba375a
commit b59fac493d
4 changed files with 356 additions and 28 deletions

View file

@ -51,11 +51,7 @@ export const term_glosses = pgTable(
created_at: timestamp({ withTimezone: true }).defaultNow().notNull(),
},
(table) => [
unique("unique_term_gloss").on(
table.term_id,
table.language_code,
table.text,
),
unique("unique_term_gloss").on(table.term_id, table.language_code),
check(
"language_code_check",
sql`${table.language_code} IN (${sql.raw(SUPPORTED_LANGUAGE_CODES.map((l) => `'${l}'`).join(", "))})`,