Add languages, user_names, users_public tables and routes; fix _se→_sv rename

- Fix broken rename migration array (sed had corrupted from values to _sv)
- Add languages table with status lifecycle and trilingual titles
- Add user_names table with unique lowercase index
- Add users_public table linking to user_names and languages (native/target)
- Wire all three new routes under /api/languages, /api/user-names, /api/users-public

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 13:47:52 +02:00
parent 217aab7dcd
commit 10570786e9
9 changed files with 332 additions and 29 deletions

View File

@@ -53,11 +53,11 @@ router.get('/:id', async (req, res, next) => {
// POST /api/categories
router.post('/', async (req, res, next) => {
try {
const { titel_de, titel_en, titel_se, difficulty_level } = req.body;
const { titel_de, titel_en, titel_sv, difficulty_level } = req.body;
const result = await query(
`INSERT INTO categories (titel_de, titel_en, titel_se, difficulty_level, requested_at)
`INSERT INTO categories (titel_de, titel_en, titel_sv, difficulty_level, requested_at)
VALUES ($1, $2, $3, $4, NOW()) RETURNING *`,
[titel_de || null, titel_en || null, titel_se || null, difficulty_level || null]
[titel_de || null, titel_en || null, titel_sv || null, difficulty_level || null]
);
res.status(201).json({ ...result.rows[0], word_ids: [] });
} catch (err) { next(err); }
@@ -66,7 +66,7 @@ router.post('/', async (req, res, next) => {
// PATCH /api/categories/:id
router.patch('/:id', async (req, res, next) => {
try {
const allowed = ['titel_de', 'titel_en', 'titel_se', 'status',
const allowed = ['titel_de', 'titel_en', 'titel_sv', 'status',
'difficulty_level', 'requested_at', 'published_at', 'blocked_at'];
const fields = Object.keys(req.body).filter(k => allowed.includes(k));
if (!fields.length) return res.status(400).json({ error: 'No valid fields provided' });