Delivery — operator runbook

Операционное руководство для P2c DeliveryRule aggregate (см. ADR-0038).

Feature flags

Engine + admin HTTP + readiness probe — always on. P1 stub retired в commit c028439. Master flags нет.

Env vars

VarDefaultTuning
DELIVERY_SNAPSHOT_POLL_INTERVAL10sIncremental fetch cadence.
DELIVERY_SNAPSHOT_FULL_RELOAD_INTERVAL5mПолный rebuild snapshot — safety net.

JWT admin role: delivery_admin (отдельная permission boundary от pricing_admin / stock_admin).

Readiness

delivery.snapshot health.Checker fails until PollingLoader.Bootstrap completes.

Метрики (counters)

MetricLabelsSource
delivery_snapshot_reload_totalmode ∈ {incremental, full} × result ∈ {ok, failed}PollingLoader.tick / fullReload
delivery_outbox_emit_totalevent_kind × resultCrudService.runInTxAndEmit
delivery_overlap_conflicts_totalOverlapValidator.Check
delivery_rule_mutations_totalevent_kind × resultCrudService post-commit

Rule kinds

4 transformation типа:

KindЧто делает
carrier_filterAllowlist OR blocklist по carrier name. Mismatch → outcome.Status=rejected, reason=carrier_blocked.
lead_time_overrideMode: absolute (Min+Max) / add_days (signed) / multiply (>0). Применяется к baseline lead_time.
logistics_markupCost compute: flat (FlatAmount) / per_warehouse (× warehouse count). per_kg отложен до Phase 5+ (нет weight ingestion).
free_delivery_thresholdКогда order_value (Price.Base × qty) ≥ MinOrderValue → Cost = 0.

Engine применяет в canonical порядке: carrier_filter → lead_time_override → logistics_markup → free_delivery_threshold.

Triage

СимптомШаг
/readyz красный, причина delivery.snapshotПроверить PG. Если PG жив — глянуть delivery.snapshot.bootstrap slog event.
Шквал delivery.metrics.overlap_conflictOperators ставят пересекающиеся правила. Глянуть DeliveryRuleConflictDetected outbox events.
Operator: «cost не считается»Проверить что logistics_markup rule active в snapshot. Cost nil без markup — by design (downstream interpret как “carrier handles”).
free_delivery_threshold not applied при large orderCurrency mismatch: MinOrderValue.Currency() != Price.Base.Currency(). ExchangeRate не выполняется в P2c (defer to P6a).
per_kg mode rejected при ValidateBy design в P2c — нет upstream weight data. Phase 5+ unblock.

Связано