import { Router } from 'express' import { config } from '../config.js' import { getSessionCustomerId, requireSession } from '../middleware/session.js' import { createDocument, getDocument, listDocuments, updateDocument, Query, ID, } from '../services/appwriteAdmin.js' import { sendChatNotification } from '../services/mailer.js' const router = Router() export function sanitizeMessage(doc) { return { id: doc.$id, sender: doc.sender || '', senderName: doc.senderName || '', text: doc.text || '', createdAt: doc.createdAt || doc.$createdAt || '', } } async function countUnreadForCustomer(customerId) { const docs = await listDocuments(config.collections.portalMessages, [ Query.equal('customerId', customerId), Query.equal('readByCustomer', false), Query.equal('sender', 'admin'), Query.limit(100), ]).catch(() => []) return docs.length } /** Nachrichten des eingeloggten Kunden (optional nur neue seit ?since=ISO). */ router.get('/messages', requireSession, async (req, res) => { const customerId = getSessionCustomerId(req) try { const queries = [ Query.equal('customerId', customerId), Query.orderAsc('createdAt'), Query.limit(200), ] const since = String(req.query.since || '').trim() if (since) queries.push(Query.greaterThan('createdAt', since)) const docs = await listDocuments(config.collections.portalMessages, queries) const unread = await countUnreadForCustomer(customerId) return res.json({ messages: docs.map(sanitizeMessage), unread }) } catch (err) { return res.status(500).json({ error: err.message || 'Nachrichten konnten nicht geladen werden' }) } }) /** Nachricht des Kunden an die Administratoren. */ router.post('/messages', requireSession, async (req, res) => { if (req.session.viewAs) { return res.status(403).json({ error: 'Im Ansichtsmodus kann nicht als Kunde geschrieben werden.' }) } const text = String(req.body?.text || '').trim() if (!text || text.length > 2000) { return res.status(400).json({ error: 'Nachricht muss zwischen 1 und 2000 Zeichen lang sein.' }) } const customerId = getSessionCustomerId(req) try { const doc = await createDocument( config.collections.portalMessages, { customerId, sender: 'customer', senderName: req.session.name || '', text, readByAdmin: false, readByCustomer: true, createdAt: new Date().toISOString(), }, ID.unique() ) // Admins benachrichtigen (gedrosselt, Fehler nicht durchreichen) getDocument(config.collections.customers, customerId) .then((customer) => sendChatNotification(customer, text)) .catch(() => {}) return res.status(201).json({ message: sanitizeMessage(doc) }) } catch (err) { return res.status(500).json({ error: err.message || 'Nachricht konnte nicht gesendet werden' }) } }) /** Admin-Nachrichten als gelesen markieren. */ router.post('/read', requireSession, async (req, res) => { const customerId = getSessionCustomerId(req) try { const docs = await listDocuments(config.collections.portalMessages, [ Query.equal('customerId', customerId), Query.equal('readByCustomer', false), Query.equal('sender', 'admin'), Query.limit(100), ]) for (const doc of docs) { await updateDocument(config.collections.portalMessages, doc.$id, { readByCustomer: true }) } return res.json({ updated: docs.length }) } catch (err) { return res.status(500).json({ error: err.message || 'Fehler beim Markieren' }) } }) /** Billiger Badge-Poll. */ router.get('/unread-count', requireSession, async (req, res) => { try { const unread = await countUnreadForCustomer(getSessionCustomerId(req)) return res.json({ unread }) } catch { return res.json({ unread: 0 }) } }) export default router