70 lines
3.2 KiB
JavaScript
70 lines
3.2 KiB
JavaScript
import { Router } from 'express'
|
|
import { config } from '../../config.js'
|
|
import { listViewLog } from '../../services/customerViewLog.js'
|
|
import { getPortalAccessStatus } from '../../services/portalAccessStatus.js'
|
|
import { PRODUCT_KEYS } from '../../services/products.js'
|
|
import { ACTIVE_STATUSES, getCurrentSubscription } from '../../services/stripeBilling.js'
|
|
import { serviceStartOf } from '../../services/takeoverCredits.js'
|
|
import { createStaffPreviewToken } from '../../services/staffPreviewTokens.js'
|
|
|
|
// Kunden im Team-Eingang (/api/team/customers), requireStaffJwt sitzt in routes/team/index.js
|
|
const router = Router()
|
|
|
|
// Portal-Zugang und letzter Login (Karte "Portal-Zugang" im Ticketsystem)
|
|
router.get('/:id/portal', async (req, res) => {
|
|
try {
|
|
const { customer, hasAccess, lastLoginAt } = await getPortalAccessStatus(req.params.id)
|
|
if (!customer) return res.status(404).json({ error: 'Kunde nicht gefunden' })
|
|
return res.json({ hasAccess, lastLoginAt })
|
|
} catch (err) {
|
|
return res.status(500).json({ error: err.message || 'Portal-Zugang konnte nicht geladen werden' })
|
|
}
|
|
})
|
|
|
|
// Protokoll der Kundenansicht (Reiter "Protokoll"), neueste zuerst
|
|
router.get('/:id/protokoll', async (req, res) => {
|
|
try {
|
|
return res.json({ entries: await listViewLog(req.params.id) })
|
|
} catch (err) {
|
|
return res.status(500).json({ error: err.message || 'Protokoll konnte nicht geladen werden' })
|
|
}
|
|
})
|
|
|
|
// Abo-Status (Kunden-Reiter "Abo & Angebote", Stunden-Pruefung am Ticket): productKey/active wie die Admin-Route
|
|
// /api/admin/customers/:id/abo, dazu Laufzeit und Speicher; nur der Appwrite-Spiegel, kein Stripe
|
|
router.get('/:id/abo', async (req, res) => {
|
|
try {
|
|
const sub = await getCurrentSubscription(req.params.id)
|
|
if (!sub) {
|
|
return res.json({ productKey: null, active: false, status: null, storageUnits: 0, startedAt: null, serviceStart: null, currentPeriodEnd: null, cancelAt: null })
|
|
}
|
|
return res.json({
|
|
productKey: PRODUCT_KEYS.includes(sub.productKey) ? sub.productKey : 'wartung',
|
|
active: ACTIVE_STATUSES.has(sub.status),
|
|
status: sub.status || null,
|
|
storageUnits: Number(sub.storageUnits) || 0,
|
|
startedAt: sub.startedAt || null,
|
|
serviceStart: serviceStartOf(sub),
|
|
currentPeriodEnd: sub.currentPeriodEnd || null,
|
|
cancelAt: sub.cancelAt || null,
|
|
})
|
|
} catch (err) {
|
|
return res.status(err.status || 500).json({ error: err.message || 'Abo konnte nicht geladen werden' })
|
|
}
|
|
})
|
|
|
|
// Kundenansicht oeffnen: Einmal-Link (60 s), den das Ticketsystem in einem neuen Tab aufruft
|
|
router.post('/:id/kundenansicht', async (req, res) => {
|
|
try {
|
|
const { customer, hasAccess } = await getPortalAccessStatus(req.params.id)
|
|
if (!customer) return res.status(404).json({ error: 'Kunde nicht gefunden' })
|
|
if (!hasAccess) return res.status(409).json({ code: 'no_portal_access', error: 'Kein Portal-Zugang' })
|
|
const token = createStaffPreviewToken({ purpose: 'kundenansicht', customerId: customer.$id, staff: req.staff })
|
|
return res.json({ openUrl: `${config.publicBaseUrl}/api/auth/kundenansicht?token=${encodeURIComponent(token)}` })
|
|
} catch (err) {
|
|
return res.status(500).json({ error: err.message || 'Kundenansicht konnte nicht geöffnet werden' })
|
|
}
|
|
})
|
|
|
|
export default router
|