AeroToys

Getting started

Prerequisites

  • .NET 9 SDK (the engine targets net9.0)
  • git
  • Optional: a DocumentForge instance (local dfdb serve or hosted)

1. Clone and build

git clone https://github.com/aerotoysio/ruleforge.git
cd ruleforge
dotnet build
dotnet test                           # 126/126 green

2. Run a sample rule, in-process, against the bundled fixtures

The repo ships with versioned rule snapshots under fixtures/rules/ and matching scenarios under fixtures/scenarios/. The default binding points POST /v1/ancillary/bag-policy at rule-bag-policy@7.

dotnet run --project src/RuleForge.Cli -- run \
    --endpoint /v1/ancillary/bag-policy \
    --request  '@fixtures/scenarios/s-bag-3pc-markup15.json' \
    --debug

You'll see the rule's full per-node trace plus the assembled result:

{
  "ruleId": "rule-bag-policy",
  "ruleVersion": 7,
  "decision": "apply",
  "evaluatedAt": "2026-04-27T10:10:20.141Z",
  "result": {
    "code": "BAG",  "weightKg": 23,
    "currency": "AED", "fee": 517.5, "pieces": 3
  },
  "trace": [
    { "nodeId": "n5-bag",    "outcome": "pass", "output": { /* base bag */ } },
    { "nodeId": "n6-pieces", "outcome": "pass", "output": { /* +pieces:3 */ } },
    { "nodeId": "n7-fee",    "outcome": "pass", "output": { /* fee:450 */ } },
    { "nodeId": "n8-markup", "outcome": "pass", "output": { /* fee:517.5 */ } }
  ],
  "durationMs": 47
}

3. Stand up the HTTP API

dotnet run --project src/RuleForge.Api

Boot output lists every endpoint that has an environment binding:

info: Bound POST /v1/ancillary/bag-policy → rule-bag-policy@7
info: Bound POST /v1/ancillary/tier-bonus → rule-tier-bonus@1
info: Now listening on: http://localhost:5050
curl -X POST http://localhost:5050/v1/ancillary/bag-policy \
  -H 'content-type: application/json' \
  --data @fixtures/scenarios/s-bag-3pc-markup15.json

4. Switch to DocumentForge

Swap the rule source by setting environment variables. The engine resolves endpoint + method → ruleId → version → snapshot on first call and caches each step.

# local DocumentForge (recommended for prod-like perf)
RULEFORGE_RULE_SOURCE=df \
RULEFORGE_DF_BASE_URL=http://localhost:5000 \
RULEFORGE_DF_API_KEY=your-key \
RULEFORGE_ENV=staging \
  dotnet run --project src/RuleForge.Api

5. Add API auth

Set RULEFORGE_API_KEY and the engine starts rejecting requests that don't supply X-AERO-Key or Authorization: Bearer with the matching key. /health stays open for liveness probes.

RULEFORGE_API_KEY=secret dotnet run --project src/RuleForge.Api

curl -X POST http://localhost:5050/v1/ancillary/bag-policy \
  -H 'X-AERO-Key: secret' \
  -H 'content-type: application/json' \
  --data @fixtures/scenarios/s-bag-3pc-markup15.json

What's next