Dispatch Incoming and Workflow
Process
-
Webhook
POST /api/dispatch/inboundcreates aDispatchItemand triggers the AI Analysis (/api/dispatch/[id]/analyze). -
The AI fills in the following: Triage (entry category, whether the Dev Team is needed, structured Dev Handoff, next steps for MEC, questions for the sender) and, if editorial guidance is needed: content type, Center Assignment (
centerIdsin order of plausibility,centerMatchNote,centerMatchAmbiguous), channels, Responsibility (User-ID), deadlines, urgency, teaser, Social Caption (which replaces manual follow-ups and Gmail tags). The center list in the prompt is alphabetical — the model is not allowed to arbitrarily choose the first element; unknown UUIDs are discarded server-side (sanitizeAndSyncCenters). -
“Create Draft” generates
ContentIntent+ContentDraft(source: dispatch, StatusPENDING) — not directNews; the draft belongs to exactly one selected center. For multiple checked centers, the interface determines which center to create (default: most likely according to AI order incenterIds). -
Editors edit and approve under Workflow & Approvals (
/dashboard/workflow). Deep-Link:?highlight=<contentDraftId>. In the dashboard, Dispatch, Workflow, and Content Planner link to the same Editorial Flow (three steps, current page highlighted). Delete Draft:DELETE /api/content/drafts/[draftId]— session required; setsDispatchItem.contentDraftIdtonullfor this draft and deletes theContentDraft(the associatedContentIntentremains without a draft). -
Upon Approval,
executeContentDraftcreates the actual entity (e.g.,News). Afterward:DispatchItem.status→PUBLISHED- if
preferredPublishAtis set: optionallyContentSchedule(News,date_range) for the Content Planner
Fields / Prisma: Only columns explicitly set in
executeContentDraft(apps/dashboard/src/app/api/content/drafts/[draftId]/route.ts) are filled — not the full dashboard forms. Offer: Draft JSONvalidFrom/validTo(orstartDate/endDate) →Offer.startDate/Offer.endDate. Job: among other things,typefromtype,departmentoremploymentType; long text fromcontent→requirements(no Prisma fieldcontenton the job). Shop: The Prisma model includesshopChainId, nochainSlug; the draft can containchainSlug,chainId(UUID of the chain) orshopChainId— upon creation, it is resolved or the chain field omitted.openingHoursas an object is saved as a JSON string (not"[object Object]"). Service: DraftopeningHoursalso needs to be serialized to JSON if necessary. Missing SEO, Hero, or shop links should be added in the respective content editing view after approval.
Dispatch Detail (/dashboard/dispatch/[id])
- Status: In the Assignment tab, each status from the enum can be selected and saved with Save & Assign via
PATCH /api/dispatch/[id]— including Entry (INBOX), to place a case back in the entry column of the board view.
AI Analysis (Dispatch & General)
- Email Content for AI:
POST /api/dispatch/[id]/analyzepulls the plain text frombodyText; ifbodyHtml(e.g., PostmarkHtmlBody) is significantly longer or the plain text is just a stub,htmlToPlainText(bodyHtml)is used, so that not just the "first" plain text block is analyzed. Optional:DISPATCH_ANALYZE_MAX_BODY_CHARS(default 24,000, min 4,000, max 80,000); very long emails are shortened with head and tail and mid-section notes. For legacy models with 8k context (gpt-4without “o”/Turbo), the email is automatically shortened more (max. 10,000 characters), andmax_tokensfor the response is limited to 3072 — otherwise the API returnscontext_length_exceeded(e.g., ifmax_tokenswas 8192). Recommendation in AI configuration:gpt-4o-minior similar Larger Models: up to 8192 Completion Tokens. In Development, the route returns an additionaldetailwith the error message at 500. - Fields in
aiSuggestion(Excerpt):intakeCategory,primaryOwner,needsDevTeam,mecNextSteps,questionsForSender,devHandoff(Title, Problem, URLs, Repro,suspectedLayer, Priority),centerIds/centerNames(multiple hits possible, order = best guess first),centerMatchNote(justification from the email),centerMatchAmbiguous, plus existing content fields (typenews/offer/eventornoneif no post). Goal: small MEC team can categorize emails without lengthy investigations. Additionally optionalcustomerCommunication: structured suggestion for personal feedback to the sender (subject, email text, channel note) — transferred toContentDraft.dataupon "Create Draft," so that the supervisor does not lose track of relationship management. - Manual Workflow (without new DB column): Under
aiSuggestion.workflow—handoffToDev(boolean),handoffToDevAt(ISO, set upon first activation),handoffNote(optional). Saved viaPATCH /api/dispatch/[id]with bodyworkflowPatch; upon Re-analysis, theworkflowremains through merge (seedispatch-workflow.ts). - Dispatch Overview: Filter by triage category (
intakeCategory), "Dev needed / handed over" combinesneedsDevTeamorworkflow.handoffToDev. - Dispatch:
POST /api/dispatch/[id]/analyzeutilizes the global AI configuration (getAIConfig) and the central HTTP clientopenAIChatCompletion(apps/dashboard/src/lib/openai-chat.ts). Empty or relativebaseUrlin the DB would previously lead tofetch("/chat/completions")— the client normalizes tohttps://api.openai.com/v1orOPENAI_API_BASE_URL. If the configured model does not support OpenAI’s JSON Mode (response_format: json_object, e.g., oldergpt-4), a second request without JSON Mode is automatically executed; the response is parsed as plaintext in JSON (including Markdown code blocks). - General (Dashboard):
POST /api/ai/chat– session required, body:messages[], optionalcenterId,model,temperature,max_tokens,response_format. Response:{ success, content }.
Environment
DISPATCH_WEBHOOK_SECRET– optional, headerX-Dispatch-Secretfor inbound and possibly internal triggers.
Legacy
Older entries may still lead with contentDraftId as a former News ID; new entries use the ContentDraft-ID until approval, after which the ID may be updated to the published content ID.
Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /en/developer-guide/dispatch-und-workflow