{
  "name": "Daily Queue Selector v0.1.0",
  "nodes": [
    {
      "id": "wf011-manual",
      "name": "Manual test",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "parameters": {},
      "position": [
        0,
        0
      ]
    },
    {
      "id": "wf011-input",
      "name": "Fictional demonstration only",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "parameters": {
        "jsCode": "// Fake data only; not approval, verified pricing, balance proof or authorization.\nreturn [{json:{\n  \"now\": \"2026-09-30T17:00:00+01:00\",\n  \"timezone\": \"Africa/Luanda\",\n  \"max_items\": 1,\n  \"items\": [\n    {\n      \"content_id\": \"demo-C\",\n      \"status\": \"ready_for_brief\",\n      \"priority\": 1,\n      \"planned_date\": \"2026-09-30\",\n      \"topic_approved\": true,\n      \"sources_ready\": true,\n      \"images_ready\": true,\n      \"reserved_by\": null\n    },\n    {\n      \"content_id\": \"demo-B\",\n      \"status\": \"ready_for_brief\",\n      \"priority\": 1,\n      \"planned_date\": \"2026-09-30\",\n      \"topic_approved\": true,\n      \"sources_ready\": true,\n      \"images_ready\": true,\n      \"reserved_by\": null\n    },\n    {\n      \"content_id\": \"demo-A\",\n      \"status\": \"ready_for_brief\",\n      \"priority\": 1,\n      \"planned_date\": \"2026-09-30\",\n      \"topic_approved\": true,\n      \"sources_ready\": true,\n      \"images_ready\": true,\n      \"reserved_by\": null\n    }\n  ]\n}}];"
      },
      "position": [
        280,
        0
      ]
    },
    {
      "id": "wf011-calculate",
      "name": "Offline advisory result",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "parameters": {
        "jsCode": "function selectDailyQueue(input) {\n  const fail = message => { throw new Error(message); };\n  const object = v => v !== null && typeof v === 'object' && !Array.isArray(v);\n  const date = v => {\n    if (typeof v !== 'string' || v.length !== 10 || !/^\\d{4}-\\d{2}-\\d{2}$/.test(v)) return false;\n    const [y, m, d] = v.split('-').map(Number);\n    return y >= 2000 && y <= 2099 && m >= 1 && m <= 12 && d >= 1 && d <= [31, y % 4 === 0 ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m - 1];\n  };\n  if (!object(input)) fail('Invalid queue input');\n  if (input.timezone !== 'Africa/Luanda') fail('timezone must be Africa/Luanda');\n  if (input.max_items !== 1) fail('max_items must be 1; no batch generation');\n  const now = input.now;\n  const match = typeof now === 'string' && now.length <= 29 && /^(\\d{4}-\\d{2}-\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.\\d{1,3})?(Z|[+-]\\d{2}:\\d{2})$/.exec(now);\n  if (!match || !date(match[1]) || +match[2] > 23 || +match[3] > 59 || +match[4] > 59) fail('now must be a valid explicit-timezone ISO timestamp');\n  const zone = match[5];\n  if (zone !== 'Z' && (+zone.slice(1, 3) > 14 || +zone.slice(4) > 59 || (+zone.slice(1, 3) === 14 && +zone.slice(4) !== 0) || zone === '-00:00')) fail('Invalid or unknown timezone offset');\n  const instant = Date.parse(now);\n  if (!Number.isFinite(instant)) fail('Invalid now');\n  // Luanda is UTC+01:00 throughout this deliberately bounded 2000–2099 contract.\n  const editorialDate = new Date(instant + 3600000).toISOString().slice(0, 10);\n  if (!date(editorialDate)) fail('Luanda editorial date outside supported range');\n  if (!Array.isArray(input.items) || input.items.length > 1000) fail('items must be an array of at most 1000 entries');\n  const seen = new Set();\n  const states = new Set(['topic_proposed', 'ready_for_brief', 'reserved', 'brief_awaiting_review', 'brief_approved', 'drafting', 'article_awaiting_review', 'delivery_pending', 'awaiting_merge', 'published', 'rejected', 'blocked']);\n  const records = Array.from(input.items, item => {\n    if (!object(item)) fail('Invalid queue item');\n    const id = item.content_id;\n    if (typeof id !== 'string' || id.length < 1 || id.length > 100 || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id)) fail('Invalid content_id');\n    if (seen.has(id)) fail('Duplicate content_id: ' + id);\n    seen.add(id);\n    if (!states.has(item.status)) fail('Invalid status for ' + id);\n    if (!Number.isSafeInteger(item.priority) || item.priority < 0 || item.priority > 1000000) fail('Invalid priority for ' + id);\n    if (!date(item.planned_date)) fail('Invalid planned_date for ' + id);\n    for (const key of ['topic_approved', 'sources_ready', 'images_ready']) if (typeof item[key] !== 'boolean') fail('Invalid ' + key + ' for ' + id);\n    if (!(item.reserved_by === null || (typeof item.reserved_by === 'string' && item.reserved_by.trim().length > 0 && item.reserved_by.length <= 200))) fail('Invalid reserved_by for ' + id);\n    const reasons = [];\n    if (item.status !== 'ready_for_brief') reasons.push('status_not_ready');\n    if (item.planned_date > editorialDate) reasons.push('planned_in_future');\n    if (!item.topic_approved) reasons.push('topic_not_approved');\n    if (!item.sources_ready) reasons.push('sources_not_ready');\n    if (!item.images_ready) reasons.push('images_not_ready');\n    if (item.reserved_by !== null) reasons.push('already_reserved');\n    return { content_id: id, priority: item.priority, planned_date: item.planned_date, reasons };\n  });\n  const compare = (a, b) => a.priority - b.priority || (a.planned_date < b.planned_date ? -1 : a.planned_date > b.planned_date ? 1 : 0) || (a.content_id < b.content_id ? -1 : a.content_id > b.content_id ? 1 : 0);\n  records.sort(compare);\n  const eligible = records.filter(r => r.reasons.length === 0);\n  const chosen = eligible[0];\n  return { status: chosen ? 'candidate_selected' : 'no_work', content_id: chosen ? chosen.content_id : null,\n    editorial_date: editorialDate, timezone: 'Africa/Luanda', eligible_count: eligible.length,\n    reason: chosen ? 'highest_ranked_eligible' : records.length ? 'no_eligible_items' : 'empty_queue',\n    excluded: records.filter(r => r !== chosen).map(r => ({ content_id: r.content_id, reasons: r.reasons.length ? r.reasons : ['lower_ranked_eligible'] })),\n    reservation_required: true, generation_allowed: false, approval_records_authenticated: false };\n}\nreturn $input.all().map((item,index)=>({json:selectDailyQueue(item.json),pairedItem:{item:index}}));"
      },
      "position": [
        560,
        0
      ]
    }
  ],
  "connections": {
    "Manual test": {
      "main": [
        [
          {
            "node": "Fictional demonstration only",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fictional demonstration only": {
      "main": [
        [
          {
            "node": "Offline advisory result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1",
    "timezone": "Africa/Luanda",
    "saveDataSuccessExecution": "none",
    "saveDataErrorExecution": "none",
    "saveManualExecutions": false
  },
  "tags": []
}
