diff --git a/server/api/defects.post.ts b/server/api/defects.post.ts index 7bbf48e..5ddf3f5 100644 --- a/server/api/defects.post.ts +++ b/server/api/defects.post.ts @@ -3,6 +3,7 @@ import { getDb } from '../db/client' import { createDefect } from '../db/repositories/defects' import { DefectInput } from '../utils/defectInput' import { getReporter } from '../utils/getReporter' +import { sendPushOnDefectFiled } from '../utils/sendPush' // File a defect against a board section (F2). Reporter comes from the seam, // not the client; the timestamp defaults in the DB. @@ -11,5 +12,24 @@ export default defineEventHandler(async (event) => { if (input instanceof type.errors) { throw createError({ statusCode: 400, statusMessage: input.summary }) } - return createDefect(getDb(), { ...input, reporterEmail: await getReporter(event) }) + + const db = getDb() + const defect = await createDefect(db, { ...input, reporterEmail: await getReporter(event) }) + + // Notify subscribed devices (F7) — fire-and-forget so filing stays fast. + // `waitUntil` keeps the runtime alive for the send without delaying the response. + const config = useRuntimeConfig(event) + event.waitUntil( + sendPushOnDefectFiled( + db, + { + subject: config.vapidSubject, + publicKey: config.public.vapidPublicKey, + privateKey: config.vapidPrivateKey, + }, + { sectionId: defect.sectionId, projectId: defect.projectId, verbatim: defect.verbatim }, + ), + ) + + return defect }) diff --git a/server/db/repositories/defects.ts b/server/db/repositories/defects.ts index 643ef53..85b2ca0 100644 --- a/server/db/repositories/defects.ts +++ b/server/db/repositories/defects.ts @@ -15,7 +15,7 @@ export interface NewDefect { /** Persist a filed defect and return the stored row. */ export async function createDefect(db: Db, input: NewDefect) { const [row] = await db.insert(defects).values(input).returning() - return row + return row! } /** Recent defects, newest first — the dashboard feed (F5/F6). */