feat: add /auth/feed endpoint for hydrated learning pairs

- GET /auth/feed?lang=sv&limit=20 (JWT, end-user allowed)
- Resolves {{uuid}} placeholders to word labels in all languages
- Includes picture URLs, pos/neg words per statement
- Fix migration seed: use full unique index (non-partial) for ON CONFLICT

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 18:37:06 +02:00
parent 2f4285dbe9
commit 6d13000248
3 changed files with 232 additions and 2 deletions

View File

@@ -469,13 +469,14 @@ async function migrate() {
await query(`CREATE UNIQUE INDEX IF NOT EXISTS users_public_user_id_idx ON users_public (user_id) WHERE user_id IS NOT NULL`);
// Seed languages (de exists, add en + sv)
await query(`CREATE UNIQUE INDEX IF NOT EXISTS languages_short_en_idx ON languages (short_en) WHERE short_en IS NOT NULL`).catch(() => {});
// Full unique constraint (not partial) so ON CONFLICT works cleanly
await query(`CREATE UNIQUE INDEX IF NOT EXISTS languages_short_en_idx ON languages (short_en)`).catch(() => {});
await query(`
INSERT INTO languages (short_en, titel_de, titel_en, titel_sv, status, published_at)
VALUES
('en', 'Englisch', 'English', 'Engelska', 'published', NOW()),
('sv', 'Schwedisch', 'Swedish', 'Svenska', 'published', NOW())
ON CONFLICT (short_en) DO NOTHING
ON CONFLICT (short_en) DO UPDATE SET status = EXCLUDED.status, published_at = COALESCE(languages.published_at, EXCLUDED.published_at)
`).catch(() => {});
console.log('Migration complete');