- Login: Appwrite-User mit Label 'admin' (Ticketsystem-Mitarbeiter) bekommen eine Admin-Session und landen auf /admin.html - Admin-Dashboard: Statistik-Uebersicht, Projektsuche ueber alle Projekte (inkl. Preview-/Gitea-Links, Vorschau ohne Kunden-Login), Kundenliste mit Portal-Status, letztem Login und Projektanzahl - Kundennummer (code) direkt im Admin-Bereich pflegbar - 'Als Kunde ansehen': Admin sieht das Portal exakt wie der Kunde (Banner mit Rueckweg zur Admin-Uebersicht) - Kunden-Dashboard: neue Bereiche 'Meine Rechnungen' (InvoiceNinja inkl. Link ins Rechnungsportal) und 'Was wurde gemacht' (Tickets + Worksheets aus dem Ticketsystem, ohne interne Akquise-Tickets); Kundennummer im Header - Admin-API /api/portal-admin/* (Session-basiert), Kunden-API /api/invoices und /api/activity - appwriteClient: uebrig gebliebene Debug-Instrumentierung entfernt Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.6 KiB
JavaScript
45 lines
1.6 KiB
JavaScript
import { Router } from 'express'
|
|
import { config } from '../config.js'
|
|
import { getSessionCustomerId, requireSession } from '../middleware/session.js'
|
|
import { getDocument } from '../services/appwriteAdmin.js'
|
|
import { getCustomerActivity } from '../services/customerActivity.js'
|
|
import { listInvoicesForClient } from '../services/invoiceNinja.js'
|
|
|
|
const router = Router()
|
|
|
|
/** Rechnungen des eingeloggten Kunden (InvoiceNinja, sofern verknuepft). */
|
|
router.get('/invoices', requireSession, async (req, res) => {
|
|
try {
|
|
const customer = await getDocument(
|
|
config.collections.customers,
|
|
getSessionCustomerId(req)
|
|
).catch(() => null)
|
|
if (!customer) {
|
|
return res.status(404).json({ error: 'Kunde nicht gefunden' })
|
|
}
|
|
if (!customer.invoiceNinjaClientId) {
|
|
return res.json({ linked: false, invoices: [] })
|
|
}
|
|
const invoices = await listInvoicesForClient(customer.invoiceNinjaClientId)
|
|
return res.json({ linked: true, invoices })
|
|
} catch (err) {
|
|
return res.status(500).json({ error: err.message || 'Rechnungen konnten nicht geladen werden' })
|
|
}
|
|
})
|
|
|
|
/** Ticket-/Arbeitshistorie des eingeloggten Kunden ("was wurde gemacht"). */
|
|
router.get('/activity', requireSession, async (req, res) => {
|
|
try {
|
|
const tickets = await getCustomerActivity(getSessionCustomerId(req), {
|
|
ticketLimit: 25,
|
|
// Interne Akquise-Tickets gehoeren nicht in die Kundenansicht
|
|
excludeTypes: ['Akquise'],
|
|
})
|
|
return res.json({ tickets })
|
|
} catch (err) {
|
|
return res.status(500).json({ error: err.message || 'Aktivität konnte nicht geladen werden' })
|
|
}
|
|
})
|
|
|
|
export default router
|