Orishare

Reference scenario

The audiobook purchase, progress and completion rules, every edge case and its expected result.

Three rules and one historical counter reproduce the reference scenario the engine, the API and the CLI are all tested against. Run it yourself with pnpm scenarios --only f2 in the monorepo.

Configuration

orishare api post /counter_definitions --data '{"name":"purchased_content","event":"content.purchased"}'

purchase awards 100 on content.purchased, once per content per customer:

{
  "schema": "orishare.rule/v1",
  "trigger": { "event": "content.purchased" },
  "limits": [
    { "id": "per_content", "scope": ["customer", "event.properties.content_id"], "max": 1 }
  ],
  "actions": [{ "type": "points.award", "currency": "points", "amount": 100 }]
}

half awards 50 when percent_complete reaches 50, same limit scope:

{
  "schema": "orishare.rule/v1",
  "trigger": { "event": "content.progressed" },
  "conditions": { "path": "event.properties.percent_complete", "op": "gte", "value": 50 },
  "limits": [
    { "id": "per_content", "scope": ["customer", "event.properties.content_id"], "max": 1 }
  ],
  "actions": [{ "type": "points.award", "currency": "points", "amount": 50 }]
}

complete awards 200 on content.completed, only for customers who purchased before:

{
  "schema": "orishare.rule/v1",
  "trigger": { "event": "content.completed" },
  "conditions": { "path": "customer.counters.purchased_content", "op": "gte", "value": 1 },
  "limits": [
    { "id": "per_content", "scope": ["customer", "event.properties.content_id"], "max": 1 }
  ],
  "actions": [{ "type": "points.award", "currency": "points", "amount": 200 }]
}

Expected results

CaseEventsResult
happy pathpurchased, progressed 50, completed+100, +50, +200; balance 350
duplicate purchasepurchased twice with different event idssecond: limit per_content exhausted, no award
40 → 70 jumpprogressed 40, progressed 7040: condition false; 70: +50 once
backward progressprogressed 70, progressed 40second: condition false; nothing is undone
duplicate completioncompleted twicesecond: limit exhausted
consumption without purchasecompleted onlycondition on purchased_content false; trace names it
rule change mid-wayhalf v2 with 75 published between 40 and 7070 evaluates under v2: +75; execution records v2
late eventcompleted with occurred_at 40 days agoaccepted, flagged late, awards under the current rules
same event id twiceidentical id in two requestssecond returns the original result, no re-evaluation

Every row is asserted by scripts/scenarios/run.mjs (F2) against a running API and by the engine's own fixture suite.

On this page