feat: objects_created flag on pictures, native_lang on users

- pictures: add objects_created (bool) + objects_created_at (auto timestamp)
  GET /pictures supports ?objects_created=true/false filter
  PATCH /pictures/:id allows setting objects_created
- db-migrate: seed German language, link to all existing users
- auth/login: include native_lang (from languages table) in response + JWT

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 19:20:43 +02:00
parent cea19083b4
commit 5411e478cb
3 changed files with 38 additions and 5 deletions

View File

@@ -5,7 +5,7 @@ const { query } = require('../db');
function signToken(user) {
return jwt.sign(
{ userId: user.id, email: user.email, role: user.role },
{ userId: user.id, email: user.email, role: user.role, native_lang: user.native_lang || 'de' },
process.env.JWT_SECRET,
{ expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
);
@@ -60,7 +60,11 @@ router.post('/login', async (req, res, next) => {
return res.status(400).json({ error: 'email and password are required' });
const result = await query(
`SELECT id, email, role, password_hash, is_active FROM users WHERE lower(email) = $1`,
`SELECT u.id, u.email, u.role, u.password_hash, u.is_active,
COALESCE(l.short_en, 'de') AS native_lang
FROM users u
LEFT JOIN languages l ON l.id = u.language_native_id
WHERE lower(u.email) = $1`,
[email.toLowerCase().trim()]
);
@@ -77,7 +81,7 @@ router.post('/login', async (req, res, next) => {
return res.status(401).json({ error: 'Invalid credentials' });
const { password_hash: _, is_active: __, ...safeUser } = user;
res.json({ user: safeUser, token: signToken(safeUser) });
res.json({ user: safeUser, token: signToken(safeUser), native_lang: safeUser.native_lang });
} catch (err) { next(err); }
});