import { Router } from 'express' import { config } from '../config.js' import { getDocument } from '../services/appwriteAdmin.js' import { getSessionCustomerId, requireSession } from '../middleware/session.js' import { createFeatureCheckout } from '../services/stripeBilling.js' import { assertOwnProject, getFeatureDoc, listCustomerFeatures, markOrdered, runActivation } from '../services/siteFeatures.js' const router = Router() const DAY_MS = 24 * 60 * 60 * 1000 function fail(res, err) { const status = err.status >= 400 && err.status < 600 ? err.status : 500 return res.status(status).json({ error: err.message || 'Interner Serverfehler' }) } // Zustaende der Funktionen je Projekt; geschlossene Einrichtungs-Tickets dieses Kunden werden vorher freigeschaltet router.get('/', requireSession, async (req, res) => { try { const customerId = getSessionCustomerId(req) await runActivation({ customerId }) res.json({ projects: await listCustomerFeatures(customerId), setupEstimate: config.funktionen.setupEstimate }) } catch (err) { fail(res, err) } }) router.post('/news/checkout', requireSession, async (req, res) => { try { if (req.session.viewAs) { return res.status(403).json({ error: 'Im "Als Kunde ansehen"-Modus kann nicht bestellt werden.' }) } const { projectId, consent } = req.body || {} if (consent !== true) { return res.status(400).json({ error: 'Bitte stimme der Erklärung zu, um zu bestellen.' }) } if (typeof projectId !== 'string' || !projectId) { return res.status(400).json({ error: 'Bitte wähle ein Projekt.' }) } const customerId = getSessionCustomerId(req) await assertOwnProject(customerId, projectId) // Zustand vor dem Stripe-Aufruf pruefen: bezahlt/aktiv oder eine noch gueltige offene Bestellung -> 409 const existing = await getFeatureDoc(customerId, projectId, 'news') const freshOrder = existing?.state === 'ordered' && Date.now() - new Date(existing.orderedAt || 0).getTime() < DAY_MS if (existing?.state === 'setup' || existing?.state === 'active' || freshOrder) { return res.status(409).json({ error: 'Die News-Pinnwand ist für dieses Projekt schon bestellt.' }) } const customer = await getDocument(config.collections.customers, customerId) const now = new Date().toISOString() const session = await createFeatureCheckout(customer, { projectId, key: 'news', consentAt: now }) await markOrdered({ customerId, projectId, key: 'news', sessionId: session.id, consent: { text: config.funktionen.consentText, at: now, ip: req.ip, userAgent: req.get('user-agent') }, }) res.json({ url: session.url }) } catch (err) { fail(res, err) } }) export default router