Files
skills-source-products/delay-list-skill/SKILL.md
T

17 KiB

name, description
name description
delay-list-processor Daily delay list processing skill for the traffic team. Fetches the delay list via API, categorizes orders, auto-snoozes packaged orders from known suppliers, sends bundled supplier emails, notifies customers, logs complaints, and updates tracking. Use this skill whenever the user mentions: delay list, delayed orders, dispatch delays, snooze orders, supplier outreach, delay processing, traffic team workflow, daily delays, or order not shipped. Also trigger when the user asks to process delays or check today's delays.

Overview

Each day, orders that have surpassed their expected dispatch date appear on the delay list — whether still in production or packaged. This skill processes that list systematically: auto-snoozing where safe, emailing suppliers (bundled per supplier), notifying customers, logging complaints, and flagging edge cases for human review.

Scale: ~4,000 orders/day, delay list can be extensive.


Inputs

  1. Delay List — Fetched via the Delay List API (not a file upload). The API returns the current delay list with the following fields per order:

    • Order (order number)
    • id_order_detail (order line ID)
    • Assigned (team member or blank)
    • Status (Open, Customer Informed, Checking, etc.)
    • Delay Reason (No delay reason given, Email Sent to Supplier, etc.)
    • New Target Dispatch (updated date if any)
    • Product (product type/SKU)
    • Supplier (supplier name)
    • Sales Price
    • State (production/packaging state — see values below)
    • Delay (days past target dispatch)
    • Carrier (carrier name if available)
    • Tracking Link (if available)
    • Target Dispatch Date
    • Actual Dispatched Date
    • Latest Delivery Date
    • shop_country_code
    • Shop_name
    • Supplier Order number
    • Postcode
  2. Operator context — Any special notes for the day (supplier outages, holidays, known issues).

  3. Supplier Complaint Classification Spreadsheet — Reference for whether a supplier is volume-based (zero cost complaint) or discount-based (10% discount complaint). Read from references/supplier-classification.md if available.


Processing Workflow — Execution Order

Process in this exact order to ensure data is fresh for downstream decisions:

Step 1: Fetch & Validate the Delay List

  • Call the Delay List API to retrieve today's current delay list
  • Validate expected fields are present in the API response
  • Flag any records with missing critical data (Order, Supplier, State) for MANUAL_REVIEW
  • Calculate correct delay days: business days between Target Dispatch Date and today (note: the system's built-in delay count can be incorrect — see Edge Cases)

Step 2: Auto-Snooze Packaged Orders (High Confidence)

Criteria — ALL must match:

Field Required Value
State Your order has been packaged
Target Dispatch Date Previous working day
Carrier One of: UPS-UPS_STANDARD, UPS-UPS_SAVER, DPDINT-STANDARD_UK, DPDINT-STANDARD, CORREOS-STANDARD
Tracking Link Must be present (non-empty)
Supplier One of the approved auto-snooze suppliers (see list below)

Attention Always pass the full raw API response into the filter. Never manually subset the data before filtering. Validate record counts before executing any snoozes.

Approved Auto-Snooze Suppliers:

  • De Groot Drukkerij B.V.
  • The Postermen
  • Intervlag
  • Vila Etiketten
  • VG Print B.V.
  • Zalsman B.V.
  • Oakdene Services
  • I print 1925
  • Digiforce
  • Enson
  • Probo
  • Promio
  • Inpromo
  • Today's Media
  • Pressing
  • Drukkerij Van As
  • Oakdene Services

Action: If you want to snooze an order call traffic-mcp snooze-order workflow. with a body like this: { orderDetailId: %id_orderdetail% }

Action: Sent information to traffic-mcp with call slack-feed-traffic-delay-list. Use the format below.

Slack Message Format for Snoozed Orders

When posting snoozed order results to Slack, always use this exact format with Slack mrkdwn syntax.

1. Header

A bold line with the total count:

*Here are all {count} snoozed orders:*

2. Table

Wrap the table in a Slack code block (triple backticks) so columns stay aligned:

Order Detail ID | Supplier | Carrier | Product 5768484 | De Groot Drukkerij B.V. | DPFINT-STANDARD | foldedleafletsv2 5785996 | Probo | UPS-UPS_STANDARD | smallstickersownsize

  • Use | as column separator for readability
  • Include every order — never truncate or summarize with "and X more"
  • Column order is fixed: Order Detail ID → Supplier → Carrier → Product
  • The header count must match the actual number of rows

After the code block, add a summary line in italic:

_All had state "Your order has been packaged", target dispatch date of March 13, and valid tracking links._

If orders have different states or dispatch dates, group them:

_• {count} orders with state "{state_a}", target dispatch date of {date_a}_
_• {count} orders with state "{state_b}", target dispatch date of {date_b}_
_All had valid tracking links._

Posting Rules & Slack Character Limit

Slack has a ~4000 character limit per message. If the full table exceeds 25 rows, you must split it into multiple messages to prevent the code block formatting from breaking. Don't send the message as json.

Important — Slack message formatting: Always send message text with actual line breaks, not \n escape characters. If you type \n literally in the input, the entire message will appear as one long line in Slack. Write the message across multiple lines in the input field itself

Splitting logic:

  1. Calculate the number of parts needed: ceil(total_rows / 25)
  2. Each message must be a self-contained code block (with its own opening and closing triple backticks)
  3. First message starts with the bold header: *Snoozed orders (part 1/{total_parts}):*
  4. Middle messages use: *Snoozed orders (part X/{total_parts}):*
  5. Last message includes the italic summary footer after the code block
  6. If all orders fit in a single message (≤25 rows), use the standard header: *Here are all {count} snoozed orders:*

Example with 56 orders (3 parts):

Message 1:

*Snoozed orders (part 1/3):*
``` ```
Order Detail ID | Supplier                    | Carrier            | Product
5768484         | De Groot Drukkerij B.V.     | DPFINT-STANDARD    | foldedleafletsv2
...rows 1-25...
``` ```

Message 2:

*Snoozed orders (part 2/3):*
``` ```
Order Detail ID | Supplier                    | Carrier            | Product
...rows 26-50...
``` ```

Message 3:

*Snoozed orders (part 3/3):*
``` ```
Order Detail ID | Supplier                    | Carrier            | Product
...rows 51-56...
``` ```
_All had state "Your order has been packaged", target dispatch date of March 13, and valid tracking links._

Send each part as a separate call to mcp__traffic-mcp__Call_slack-feed-traffic-delay-list_.

Confidence: If ALL criteria match exactly → auto-execute (99%+ confidence). If any field is ambiguous or missing → MANUAL_REVIEW.



Step 3: Supplier Outreach — "In Production" Past Dispatch

Criteria

  • Dispatch date has passed
  • State = Your order is in production OR Ready for production
  • No tracking information

Pre-check (if HubSpot integration available)

Check HubSpot for existing communication on the order item using the mandatory 3-step search below. Then categorize each order:

  • If email found explaining delay WITH reason → print reason in chat with order, skip outreach email
  • If email found but NO reason provided → print new dispatch date in chat with order_id, add order to markdownfile per supplier.
  • If email shows internal issue (e.g., artwork, stock) → tell which orders are internal reason.
  • If no email found → add order information to markdown file

HubSpot Search Strategy (MANDATORY — execute ALL 3 steps)

The hp_order_line_id and hp_order_id fields in HubSpot frequently contain multiple comma-separated values in a single field (e.g., "9155560, 9162986"). IN/EQ filters only match when the field contains exactly one value, so they will miss multi-value fields. All 3 steps below are required — skipping step 3 consistently causes 10-20% of tickets to be missed.

Step 1 — Batch IN-filter on hp_order_line_id Search tickets using IN operator on hp_order_line_id with batches of max 50 detail IDs. Record which detail IDs got a hit.

Step 2 — Batch IN-filter on hp_order_id For all orders where NO hit was found in step 1: search tickets using IN operator on hp_order_id with batches of max 50 order IDs. Record which orders got a hit.

Step 3 — Individual full-text query search (DO NOT SKIP) For every detail ID that STILL has no hit after steps 1 and 2: search tickets using the query parameter (not a filter) with the individual detail ID as search string. This finds tickets where the ID is embedded in a multi-value field. Do this for every remaining id_order_detail. If that returns 0, also try the id_order.

Why this matters: In practice, ~15% of HubSpot tickets use multi-value fields. Without step 3, you will miss existing supplier communication and send unnecessary outreach emails for orders that already have a known status.

Supplier-Specific Handling

Before creating generic outreach emails, check if the supplier has a specific workflow:

Probo

  • False delay check (automated): Probo orders often trigger false delays when multiple order lines are shipped together. Check Presta for linked order lines:
    1. Gather all linked order lines for the order
    2. Check the "despatch" tab on all order lines
    3. If lines were shipped together → remove from delay list (false delay)
  • Portal status check (manual): The Probo portal is not accessible to the AI. List all remaining Probo delayed orders (after false-delay filtering) in a separate "Manual Action Required — Probo" section so the operator can verify actual production status in the Probo portal.
  • Probo delay email received in HubSpot → Flag these orders: update to "not sent on time", note the need to follow up for a new dispatch date.
  • Outreach: Do NOT include Probo orders in the generic supplier email drafts. All Probo follow-up is handled via their portal or based on portal findings.

Flyeralarm

  • Any delay → Do NOT send an outreach email and do NOT include in the supplier email drafts. Flyeralarm delays are handled via their own supplier portal (case creation), which requires manual access.
  • Action: List all Flyeralarm delayed orders in a separate "Manual Action Required — Flyeralarm" section in the output so the operator can handle them in the portal.

Masterprint

  • Skip entirely — Masterprint tracking is already automated. Orders packaged on the Masterprint tracking sheet are auto-removed from the delay list. No outreach needed.

Action

For all remaining suppliers (not covered by supplier-specific handling above), create drafts in a markdown file with emails per supplier so we can review them.

CRITICAL RULE: Bundle emails per supplier. Never create multiple emails to the same supplier. Group all delayed order lines for a supplier into ONE email in the markdown file.

The email should include:

  • All affected order IDs and order detail IDs
  • Target dispatch dates
  • Product
  • Supplier Order
  • Carrier

Logging & Tracking

Every action must be logged. No exceptions.

Processing Log

Maintain a structured log (CSV) saved to the outputs directory with the following fields per order processed:

Field Description
timestamp ISO 8601 timestamp of action
order_id Order number
id_order_detail Order line ID
supplier Supplier name
product Product type
state Order state at time of processing
delay_days Calculated delay in business days
category Action category (see list below)
action_taken Specific action executed
confidence Confidence percentage
auto_or_manual AUTO / FLAGGED_FOR_REVIEW
human_decision Operator decision if flagged (blank if auto)
batch_number Batch ID
status SUCCESS / FAILED / PENDING_REVIEW
error_details Error info if failed
email_sent_to Supplier/customer email triggered
email_bundled_with Other order IDs in same supplier email
complaint_logged true/false
complaint_type Carrier / Supplier
complaint_cost Zero / 10% discount
snooze_hours Hours snoozed
notes Additional context

Action categories: SNOOZE | SUPPLIER_EMAIL | CUSTOMER_NOTIFY | COMPLAINT_CARRIER | COMPLAINT_SUPPLIER | TRACKING_UPDATE | STATUS_UPDATE | LABEL_REISSUE | MANUAL_REVIEW

Daily Summary Report

Generate at end of processing and save as a file:

  • Total orders on delay list and total processed
  • Breakdown by action category (counts and percentages)
  • Auto-processed vs. flagged for review (counts)
  • Supplier emails sent — count and list of suppliers contacted
  • Customer notifications sent — count
  • Complaints logged — carrier vs. supplier, with cost breakdown
  • Orders snoozed — count and average snooze duration
  • Failed actions with details
  • Pending manual review — full list with proposed actions
  • Top delayed suppliers — ranked by number of delayed orders
  • Orders delayed 3+ days — highlighted for urgency

MCP & API Integration Points

Action Integration Template/Endpoint
Fetch delay list traffic-mcp get-delay-list workflow
Snooze order traffic-mcp snooze-orders workflow

Before processing begins, verify all required MCP servers and API endpoints are accessible. If any integration is unavailable, flag ALL affected orders for MANUAL_REVIEW rather than failing silently.


Configuration

These defaults can be overridden by the operator at the start of each run:

snooze_default_hours: 12
max_batch_size: 100
confidence_threshold: 99       # Percentage — below this → MANUAL_REVIEW
customer_notify_after_days: 2  # Notify customer after X business days delayed
supplier_email_after_days: 1   # Email supplier after X days with no movement
auto_snooze_carriers:
  - UPS-UPS_STANDARD
  - UPS-UPS_SAVER
  - DPDINT-STANDARD_UK
  - DPDINT-STANDARD
supplier_specific_processes:
  probo: on_hold
  flyeralarm: on_hold
  masterprint: completed

Edge Cases & Known Issues

  1. Incorrect delay day calculation — The system sometimes shows different delay counts for orders with the same dispatch date. Always recalculate: business days between Target Dispatch Date and today.

  2. Sales price shows full order, not order-line — The delay list may show full order price. Be aware when assessing value thresholds.

  3. False delays from Probo — Orders shipped together across multiple order lines trigger false delays. When Probo processes activate, always check if lines were shipped together before acting.

  4. Duplicate supplier emails — The bundling rule is critical. Always deduplicate and group before sending. Check if a supplier was already emailed today.

  5. Tracking lag vs. genuine delay — Packaged orders with tracking from approved carriers/suppliers are most often tracking lag. Auto-snooze handles this, but if an order reappears after multiple snoozes, escalate to MANUAL_REVIEW.

  6. Orders assigned to team members — If an order has an Assigned value, it means someone is already working on it. Consider skipping or noting this in the review queue.

  7. Incomplete order evaluation when filtering When filtering the delay list, always feed the raw API response directly into the filter logic — never manually reconstruct or subset the data. After filtering, validate that: Every order with statename = "Your order has been packaged" appears in either the match list or the reject list The count of (matches + rejects) equals the total number of packaged orders in the raw response

  8. The Posterman Exception When the supplier is The Postermen, the carrier field may be any value when validating snooze applicability. All other matching criteria still apply as normal.

  9. Orders from supplier Oakdene Services with a carrier of DPDUK-STANDARD or DPDUK-EXPRESSPAK are eligible for auto-snooze if all other auto-snooze criteria are also met.


Example Run

Operator: "Process today's delay list. No special notes."

Step 1: Fetched delay list via API → 347 delayed orders. 4 records missing data → MANUAL_REVIEW.
Step 2: 89 orders match auto-snooze criteria → Snoozed 12h. Batch 1/1 (89). All succeeded

SUMMARY: 343 processed | 16 manual review | 0 failures
Logs saved: delay_log_2026-02-12.csv, summary_2026-02-12.md