Kundenansicht: Beenden mit Rueckweg ins Ticketsystem, /me mit Ansichts-Kennung, Team-Routen Portal-Status, Protokoll, Preview-Link

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-01 19:32:59 +00:00
1 parent 7d8ba56088
commit c5afd42a5f
9 files changed
+284 -23

No files matched your search

+32 -20
View File
@@ -35,21 +35,18 @@ function previewUrlForSubdomain(subdomain) {
return `https://${safe}.${config.preview.baseHost}`
}
router.use(requireAppwriteStaff)
router.post('/', async (req, res) => {
const user = req.appwriteUser
if (!isStaffAdmin(user)) {
return res.status(403).json({ error: 'Admin-Berechtigung erforderlich' })
}
const subdomain = String(req.body?.subdomain || '')
/**
* Einmal-Link fuer die Preview eines Projekts (eingeloest von GET /api/auth/staff-preview). Genutzt von dieser
* Admin-Route und vom Team-Eingang (/api/team/preview-link, alle Mitarbeiter). Liefert { status, body }.
*/
export async function buildStaffPreviewLink({ userId, email, name, subdomain: rawSubdomain, previewUrl: rawPreviewUrl }) {
const subdomain = String(rawSubdomain || '')
.trim()
.toLowerCase()
const previewUrl = safePreviewUrl(req.body?.previewUrl) || previewUrlForSubdomain(subdomain)
const previewUrl = safePreviewUrl(rawPreviewUrl) || previewUrlForSubdomain(subdomain)
if (!subdomain || !previewUrl) {
return res.status(400).json({ error: 'subdomain oder gueltige previewUrl erforderlich' })
return { status: 400, body: { error: 'subdomain oder gueltige previewUrl erforderlich' } }
}
try {
@@ -59,27 +56,42 @@ router.post('/', async (req, res) => {
])
const project = projects[0]
if (!project) {
return res.status(404).json({ error: 'Projekt nicht gefunden' })
return { status: 404, body: { error: 'Projekt nicht gefunden' } }
}
if (!isPreviewProjectReady(project)) {
return res.status(409).json({ error: 'Projekt-Vorschau ist noch nicht bereit' })
return { status: 409, body: { error: 'Projekt-Vorschau ist noch nicht bereit' } }
}
const token = createStaffPreviewToken({
userId: user.$id,
email: user.email || '',
name: user.name || user.email || 'Admin',
userId,
email: email || '',
name: name || email || 'Admin',
previewUrl,
customerId: project.customerId || '',
})
const portalBase = `https://${config.preview.baseHost}`
return res.json({
openUrl: `${portalBase}/api/auth/staff-preview?token=${encodeURIComponent(token)}`,
})
return { status: 200, body: { openUrl: `${portalBase}/api/auth/staff-preview?token=${encodeURIComponent(token)}` } }
} catch (err) {
return res.status(err.status || 500).json({ error: err.message || 'Preview-Login fehlgeschlagen' })
return { status: err.status || 500, body: { error: err.message || 'Preview-Login fehlgeschlagen' } }
}
}
router.use(requireAppwriteStaff)
router.post('/', async (req, res) => {
const user = req.appwriteUser
if (!isStaffAdmin(user)) {
return res.status(403).json({ error: 'Admin-Berechtigung erforderlich' })
}
const { status, body } = await buildStaffPreviewLink({
userId: user.$id,
email: user.email,
name: user.name,
subdomain: req.body?.subdomain,
previewUrl: req.body?.previewUrl,
})
return res.status(status).json(body)
})
export default router