Skip to main content
This is the technical companion to Rules & rulesets.

Core enumerations

  • Enforcement modeBLOCK (reject), WARN (proceed + surface), LOG (silent audit).
  • Check levelSHOP, BRAND, PRODUCT, VARIANT, INVENTORY_ITEM, PLAN, PLAN_ITEM.
  • CategoryCAPACITY, ASSORTMENT, ORDERING, TRANSFER, PRICING, DISTRIBUTION, COMPLIANCE.
  • Action familyRESTOCK_PLAN, REBALANCE_PLAN, MARKDOWN_PLAN, PRE_SEASON_PLAN, SUPPLIER_RETURN_PLAN, SUPPLIER_EXCHANGE_PLAN, RECOMMENDATION, WORKFLOW.
  • Evaluation pointPRE_PLAN_ITEM_ADD, PRE_PLAN_VALIDATE, RECOMMENDATION_GENERATION, WORKFLOW_EXECUTION, MANUAL_CHECK.

Validation hooks

The exact hooks rules attach to:
RESTOCK_PRE_ADD_ITEM, RESTOCK_PRE_VALIDATE_ITEM, RESTOCK_PRE_CHANGE_STATUS,
REBALANCE_PRE_ADD_ITEM, REBALANCE_PRE_VALIDATE_ITEM, REBALANCE_PRE_CHANGE_STATUS,
MARKDOWN_PRE_ADD_ITEM, MARKDOWN_PRE_VALIDATE_ITEM,
PRE_SEASON_PRE_ADD_ITEM, PRE_SEASON_PRE_VALIDATE_ITEM, PRE_SEASON_PRE_CHANGE_STATUS,
SUPPLIER_RETURN_PRE_ADD_ITEM, SUPPLIER_RETURN_PRE_CHANGE_STATUS,
SUPPLIER_EXCHANGE_PRE_ADD_ITEM, SUPPLIER_EXCHANGE_PRE_CHANGE_STATUS,
RECOMMENDATION_PRE_GENERATE, MANUAL_CHECK

Paradigm & phase

  • ParadigmVALIDATION rules are enforced by the app at hook time (block/warn); DECISION_SHAPING rules are applied only by the Databricks decision layer and are skipped by the app’s evaluator.
  • PhaseSCORING, SIZING, SOURCING, APPROVAL: an orthogonal axis used by the decision layer to scope evaluation to a planning step (nullable for backward compatibility).

Evaluation

evaluateBusinessRules(organizationId, hook, contexts) resolves the applicable rules and returns, per context, the blocks and warnings. Multi-shop mutations (rebalance, supplier exchange) evaluate once per shop and aggregate. Each rule’s condition is fed by context enrichers — small resolvers that fetch live signals (plan totals, current stock, sell-through, OTB remaining, size-curve deviation, supplier MOQ gap, markdown margin, …); there are dozens of enricher types. The catalog of rule templates maps each template to a category, applicable families, default check level, and default condition.

Operations layer

For mutations that need async context resolution (e.g. loading both shops for a rebalance) or that have multiple entry points (action + workflow + API), the logic lives in an operations layer built with defineMutation. An operation:
  1. Optionally bypasses rules with an explicit, auditable bypassRules: { reason }.
  2. Resolves EvaluationContext[] (async).
  3. Evaluates rules; blocks abort before persistence (warnings still surface).
  4. Runs a pure handler (persistence).
  5. Writes the audit entry (best-effort).
This is a pilot; representative migrated mutations include adding a rebalance item and adding/validating a markdown item. Mutations without async rule context continue to use the standard action → service path.

Audit

Every plan mutation is recorded in an append-only audit log. Event types include PLAN_CREATED, PLAN_VALIDATED, PLAN_STATUS_CHANGED, PLAN_CLOSED, PLAN_DELETED, the approval lifecycle (PLAN_APPROVAL_REQUESTED, PLAN_APPROVED, PLAN_REJECTED, PLAN_APPROVAL_EXPIRED), item events (ITEM_ADDED, ITEM_UPDATED, ITEM_REMOVED, ITEM_STATUS_CHANGED), and configuration events (RULESET_CHANGED, PLAN_HEADER_UPDATED). Each row records the actor (USER, WORKFLOW, SCENARIO_GENERATOR, SYSTEM, API_TOKEN), the source, an optional reason, the rules that applied, and — for items — an attribution (MANUAL, DECISION_VECTOR, WORKFLOW_FALLBACK). When rules were bypassed, the reason is stored in the entry.
Human-readable labels (variant, shop, user names) are resolved at read time, not stored — so the audit trail stays accurate even as catalog data changes.