chore: release v0.20.24

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ulas Kalayci
2026-04-20 10:05:12 +02:00
parent aae895d704
commit e48d249fbe
10 changed files with 606 additions and 115 deletions
+2
View File
@@ -25,6 +25,7 @@ import budgetRouter from './routes/budget.js';
import weatherRouter from './routes/weather.js';
import preferencesRouter from './routes/preferences.js';
import remindersRouter from './routes/reminders.js';
import searchRouter from './routes/search.js';
const log = createLogger('Server');
const logSync = createLogger('Sync');
@@ -167,6 +168,7 @@ app.use('/api/v1/budget', budgetRouter);
app.use('/api/v1/weather', weatherRouter);
app.use('/api/v1/preferences', preferencesRouter);
app.use('/api/v1/reminders', remindersRouter);
app.use('/api/v1/search', searchRouter);
// --------------------------------------------------------
// Health-Check (für Docker)
+62
View File
@@ -0,0 +1,62 @@
/**
* Modul: Globale Suche (Search)
* Zweck: Volltext-Suche über Aufgaben, Kalender-Events und Notizen
* Abhängigkeiten: express, server/db.js
*/
import express from 'express';
import * as db from '../db.js';
const router = express.Router();
const LIMIT = 5;
/**
* GET /api/v1/search?q=<query>
* Durchsucht Aufgaben, Kalender-Events und Notizen des Nutzers.
* Response: { tasks: Task[], events: Event[], notes: Note[] }
*/
router.get('/', (req, res) => {
try {
const q = String(req.query.q ?? '').trim();
if (q.length < 2) return res.json({ tasks: [], events: [], notes: [] });
const like = `%${q}%`;
const userId = req.session.userId;
const tasks = db.get().prepare(`
SELECT id, title, status, priority, due_date
FROM tasks
WHERE parent_task_id IS NULL
AND (created_by = ? OR assigned_to = ?)
AND (title LIKE ? OR description LIKE ?)
ORDER BY CASE status WHEN 'done' THEN 1 ELSE 0 END,
due_date ASC NULLS LAST
LIMIT ?
`).all(userId, userId, like, like, LIMIT);
const events = db.get().prepare(`
SELECT id, title, start_datetime, all_day
FROM calendar_events
WHERE created_by = ?
AND (title LIKE ? OR description LIKE ?)
ORDER BY start_datetime ASC
LIMIT ?
`).all(userId, like, like, LIMIT);
const notes = db.get().prepare(`
SELECT id, title, content
FROM notes
WHERE created_by = ?
AND (title LIKE ? OR content LIKE ?)
ORDER BY pinned DESC, updated_at DESC
LIMIT ?
`).all(userId, like, like, LIMIT);
res.json({ tasks, events, notes });
} catch (err) {
res.status(500).json({ error: 'Interner Fehler', code: 500 });
}
});
export default router;
+2 -2
View File
@@ -20,8 +20,8 @@ const router = express.Router();
const VALID_PRIORITIES = ['none', 'low', 'medium', 'high', 'urgent'];
const VALID_STATUSES = ['open', 'in_progress', 'done'];
const VALID_CATEGORIES = ['Haushalt', 'Schule', 'Einkauf', 'Reparatur',
'Gesundheit', 'Finanzen', 'Freizeit', 'Sonstiges'];
const VALID_CATEGORIES = ['household', 'school', 'shopping', 'repair',
'health', 'finance', 'leisure', 'misc'];
// --------------------------------------------------------
// Hilfsfunktionen