feat(intake): tell the admin when a draft is ready (#224)

Sent after the draft commits, fire and forget. A mail failure must never mark a draft that was written correctly as failed: the review queue is what the admin actually works from, and the email is a convenience on top of it.

Every quiet path returns rather than throws. No recipient configured is not an error — nobody has said where to send it and the draft is waiting regardless. No INTAKE_ACTION_SECRET means the two shortcut links render empty rather than broken, because a link that could not be verified is worse than none. An item with no draft row simply returns.

A missing description is said plainly rather than left blank. An empty paragraph in a notification reads as a bug; "no description was drafted for this item" reads as the fact that it is, and tells the admin what to expect on the screen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-01 15:24:54 -05:00
co-authored by Claude Opus 5
parent 0517faca60
commit faed47e105
2 changed files with 79 additions and 0 deletions
+9
View File
@@ -6,6 +6,7 @@ import { typeForExtension } from '../uploadTypes';
import { getAnthropicClient } from './anthropicClient';
import { draftListing } from './draftListing';
import { applyDraft } from './applyDraft';
import { notifyDraftReady } from './notifyDraft';
/**
* Turns queued submissions into drafts.
@@ -144,6 +145,14 @@ export async function draftQueued(limit = DEFAULT_BATCH): Promise<SweepResult> {
}
await draftOne(client, row.item_id, row.submitter_note, photos);
drafted++;
// Fire and forget, and deliberately after the draft is committed. A mail
// failure must never mark a draft that was written correctly as failed —
// the queue is what the admin actually works from, and the email is a
// convenience on top of it.
void notifyDraftReady(row.item_id).catch((err) =>
console.error(`[drafting] notifying for item ${row.item_id}:`, err)
);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
console.error(`[drafting] item ${row.item_id}: ${message}`);