Gate Pending & Async Resolve ✓ Canlı

Senkron gate penceresine (≤10 sn) sığmayan kararlar için: eklenti allow/deny yerine { decision:'pending' } döner → statü geçişi askıya alınır → eklenti hazır olunca gate-resolve ucunu çağırır → geçiş uygulanır/iptal edilir. Sektör deseni: Shopify fulfillment request (request → accept/reject, async).

← packet.status.update gate

Kapsam

Yalnız packet.status.update. packet.close (tenant-genel, inline) ve table.close (senkron panel gate'i) askıya alınacak durum taşımaz → orada pending yok sayılır, failMode uygulanır.

Neden

packet.status.update gate'i senkrondur: eklenti timeoutMs (≤10 sn) içinde karar vermeli. İnsan onayı, harici mutabakat, kurye atama bekleme gibi kararlar bu pencereye sığmaz. pending, işlemi senkron bloklamadan "kararı sonra vereceğim" demenin standart yoludur.

Eklenti sözleşmesi

İstek (gate, bugünküyle aynı) → cevap üç seçenekli:

{ "decision": "allow" }
{ "decision": "deny",    "message": "…" }
{ "decision": "pending", "message": "Kurye atanıyor, onay birazdan." }   // ← yeni 3. seçenek

pending sonrası eklenti, hazır olunca held geçişi çözer:

# Eklenti hazır olunca held geçişi çözer (allow → uygula, deny → iptal):
curl -X POST https://plugins.restomenum.app/plugin-api/packets/<sid>/<pid>/<packetId>/gate-resolve \
  -H "Authorization: Bearer <sid>.<pid>.<secret>" \
  -d '{ "decision": "allow", "to": "OnDelivery" }'
  • Uç: POST /plugin-api/packets/:serverId/:pluginId/:packetId/gate-resolve — auth: install API key + scope hooks:packet.status.
  • Gövde: { decision: "allow"|"deny", to: "<hedef statü>", message? }.
  • Süre: PENDING_TTL içinde resolve etmezsen deadline'da manifest'teki failMode uygulanır.
  • İdempotent: aynı resolve'u tekrar gönderebilirsin (ikinci çağrı no-op: { ok:true, already:true }).

Durum makinesi

[statü: Approved]
  panel "Yola Çıkar" → packetGate(packet.status.update, to:OnDelivery)
      eklenti: { decision:"pending", message:"Kurye atanıyor…" }
    → handler statüyü YAZMAZ; pakete pendingGate marker yazar (deadline = now + PENDING_TTL)
      statü Approved KALIR (panelde "🟣 Eklenti onayı bekleniyor")
  ── async ──
  eklenti hazır → POST …/gate-resolve { decision:"allow"|"deny", to:"OnDelivery" }
      allow → held geçiş UYGULANIR (statü OnDelivery) + marker temizlenir
      deny  → marker temizlenir, statü Approved kalır, message panele düşer
  ── deadline ──
  now > deadline ve hâlâ pending → failMode uygulanır (open→uygula / closed→iptal) + temizle

Hatalar (gate-resolve)

DurumAnlam
409 expiredDeadline geçmiş — held geçiş artık çözülemez (failMode uygulandı).
no-op (already)Pakette pendingGate yok (zaten çözülmüş/temizlenmiş) → ikinci resolve sessiz geçer.
sahiplik / scopependingGate.pluginId sizinki değilse veya hooks:packet.status yoksa reddedilir.

Güvenlik notları

  • Sahiplik: pending yalnız sahip eklenti için (packet.status.update zaten sahip-modelli).
  • Tek-bekleyen-gate: bir pakette aynı anda yalnız bir pendingGate olur — yarış/çift-resolve karışıklığı önlenir.
  • Deadline + failMode: eklenti hiç dönmezse paket sonsuza dek askıda kalmaz (Shopify request deadline deseni).