Tickets: createTicketForProject und deleteTicket

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-09-30 18:30:53 +00:00
1 parent 85b972f9dc
commit c93cb93a36
2 files changed
+113

No files matched your search

+45
View File
@@ -1,6 +1,7 @@
import { config } from '../config.js'
import {
createDocument,
deleteDocument,
getDocument,
listDocuments,
updateDocument,
@@ -105,3 +106,47 @@ export async function createFeatureTicket({ customerId, project, featureKey, sit
console.log(`[ticketAdmin] Funktions-Ticket #${woid} (${featureKey}) fuer Projekt ${project?.$id} angelegt`)
return { ticketId: ticket.$id, woid }
}
/**
* Legt ein Ticket fuer ein Projekt an (Zuordnen-Flow, erst beim Abschliessen).
* Unbekannter Kunde => Fehler mit status 400.
*/
export async function createTicketForProject({ customerId, topic, type, requestedBy, startDate, details }) {
const customer = customerId
? await getDocument(config.collections.customers, customerId).catch(() => null)
: null
if (!customer) {
const err = new Error('Kunde nicht gefunden.')
err.status = 400
throw err
}
const woid = await generateNextWoid()
const ticket = await createDocument(
config.collections.workorders,
{
topic,
type,
status: 'Open',
priority: 1,
serviceType: 'Remote',
systemType: 'n/a',
customerId,
customerName: customer.name || '',
customerLocation: customer.location || '',
requestedBy: requestedBy || '',
startDate: startDate || '',
details: details || '',
woid,
createdAt: new Date().toISOString(),
},
ID.unique()
)
console.log(`[ticketAdmin] Ticket #${woid} fuer Kunde ${customerId} angelegt`)
return { $id: ticket.$id, woid }
}
/** Loescht ein Ticket wieder (Rollback, wenn der Zuordnen-Flow scheitert). */
export async function deleteTicket(ticketId) {
await deleteDocument(config.collections.workorders, ticketId)
}
+68
View File
@@ -0,0 +1,68 @@
import { test, before, after } from 'node:test'
import assert from 'node:assert/strict'
import { startFakeAppwrite } from './helpers/fakeAppwrite.js'
let aw
let createTicketForProject
let deleteTicket
before(async () => {
aw = await startFakeAppwrite({
seed: {
workorders: [{ $id: 't1', woid: '100115' }, { $id: 't2', woid: '100120' }],
customers: [{ $id: 'c1', name: 'Döner Nation', location: 'Berlin' }],
},
})
Object.assign(process.env, {
APPWRITE_ENDPOINT: aw.endpoint,
APPWRITE_API_KEY: 'test-key',
})
// config.js liest die Umgebung beim Import
;({ createTicketForProject, deleteTicket } = await import('../server/services/ticketAdmin.js'))
})
after(async () => {
await aw.close()
})
test('createTicketForProject legt ein offenes Ticket mit Kundendaten und nächster WOID an', async () => {
const r = await createTicketForProject({
customerId: 'c1',
topic: 'Website – döner',
type: 'Webpage',
requestedBy: 'Max',
startDate: '2026-10-05',
details: 'Details',
})
assert.equal(r.woid, '100121')
const d = aw.get('workorders', r.$id)
assert.equal(d.topic, 'Website – döner')
assert.equal(d.type, 'Webpage')
assert.equal(d.status, 'Open')
assert.equal(d.priority, 1)
assert.equal(d.serviceType, 'Remote')
assert.equal(d.systemType, 'n/a')
assert.equal(d.customerId, 'c1')
assert.equal(d.customerName, 'Döner Nation')
assert.equal(d.customerLocation, 'Berlin')
assert.equal(d.woid, '100121')
assert.equal(d.requestedBy, 'Max')
assert.equal(d.startDate, '2026-10-05')
assert.equal(d.details, 'Details')
assert.ok(d.createdAt)
})
test('createTicketForProject: unbekannter Kunde ⇒ Fehler mit status 400', async () => {
const before = aw.all('workorders').length
await assert.rejects(
() => createTicketForProject({ customerId: 'nix', topic: 'x', type: 'Webpage' }),
(err) => err.status === 400 && /Kunde/.test(err.message)
)
assert.equal(aw.all('workorders').length, before)
})
test('deleteTicket löscht das Ticket', async () => {
await deleteTicket('t2')
assert.equal(aw.get('workorders', 't2'), undefined)
assert.ok(aw.calls.some((c) => c.method === 'DELETE' && c.path.endsWith('/documents/t2')))
})