Architecture Overview¶
This page describes system boundaries, core components, and key design decisions. It intentionally avoids deployment runbook detail.
Scope and Boundaries¶
In scope:
- API service behavior and boundaries
- data storage model at a high level
- rule evaluation flow
- access-control and audit model
Out of scope:
- step-by-step deployment commands (see Deployment Guide)
- environment variable tuning (see Configuration)
System Context¶
Web UI (Angular) ---> FastAPI service (api/v2 + evaluate) ---> PostgreSQL
|
+--> Redis/Celery (backtesting tasks)
External systems ---> POST /api/v2/evaluate
Primary runtime boundary:
ezrules apiis the main backend process- rule execution happens inside that backend process
Core Components¶
| Component | Responsibility | Notes |
|---|---|---|
| FastAPI service | Serves API v2 endpoints and evaluator endpoint | Stateless app process |
| Rule engine | Executes active rules against incoming event payloads | Uses configured rules and persists evaluation output |
| PostgreSQL | Stores rules, outcomes, events, labels, users, and audit history | Source of truth |
| Celery worker (optional) | Executes async backtesting jobs | Uses Redis broker |
| Angular frontend | Operator/analyst/admin UI | Connects to API v2 |
Data Model Areas¶
High-level storage domains:
- Rules/config history:
rules,rules_history,rule_engine_config,rule_engine_config_history - Event evaluation:
event_versions,evaluation_decisions,evaluation_rule_results - Event evaluation ledgers persist event payload versions, served decisions, per-rule outcomes, and the resolved winning outcome
- Separate
RuleEngineConfiglabels are used for the main production rule set and the allowlist rule lane - Shadow evaluation:
shadow_results_log(parallel results, never returned to callers) - Decision controls:
allowed_outcomes,event_labels, user list tables - Access control:
user,role,roles_users,actions,role_actions - Audit history: rule/config/user-list/outcome/label history tables
Key Flows¶
1) Event Evaluation Flow¶
- Caller sends
POST /api/v2/evaluate - API validates payload
- Active allowlist configuration is loaded/executed first
- If allowlist rules match, the main rule set is skipped and the allowlist result is returned/stored
- Otherwise, the active main rule configuration is loaded/executed
- Outcomes are aggregated (
rule_results,outcome_counters,outcome_set) - A single
resolved_outcomeis selected from the configured outcome hierarchy - Exact duplicate transaction versions return the existing evaluation; otherwise the payload is appended as an event version and the served response is stored as an immutable evaluation decision
- Response returned to caller
Repeated submissions with the same transaction_id and new facts are represented as later event versions. The current transaction projection points at the latest effective non-terminal truth, while late-arriving and post-terminal versions remain audit-visible historical evaluations. Downstream replay and Tested Events can anchor to immutable served decisions; dashboard analytics and alert thresholds use the current projection.
Allowlist rules exist for explicit trust decisions where a match should stop the normal decision flow entirely.
2) Shadow Evaluation Flow¶
- A rule is deployed to the shadow
RuleEngineConfig(via UI or API) - Every
POST /api/v2/evaluatecall runs the production evaluation (result returned to caller) and enqueues a parallel shadow evaluation using the same event payload and config snapshot - Shadow results accumulate against the same served-decision provenance as production results, enabling direct outcome comparison
- Operator observes shadow vs production outcome distribution via
GET /api/v2/shadow/stats - Operator promotes (atomic: writes shadow logic to rules table + production config, clears shadow entry) or removes
Shadow evaluation errors are silenced — production response is never affected.
3) Rule Lifecycle Flow¶
- User creates/updates rule via API/UI
- Rule change is persisted
- Rule/config history entries are captured with
changed_byattribution - Updated rules become part of subsequent evaluations
4) Label Feedback Flow¶
- Labels are applied via API (
mark-eventor upload) - Label data is stored
- Analytics endpoints aggregate outcomes/labels for UI charts
Key Design Decisions and Tradeoffs¶
| Decision | Why | Tradeoff |
|---|---|---|
| Unified API service for management + evaluation | Simplifies local/dev topology and operations | One service handles mixed workloads |
| Evaluate endpoint with API key or Bearer auth | Supports service-to-service usage while preserving org scoping | Callers must provision credentials for every request |
| Rule execution in-process | Low integration overhead and direct access to model context | Poorly written rules can impact latency |
| PostgreSQL as source of truth | Strong relational model and auditability | Requires schema/index care at larger scale |
| Optional Celery for backtesting | Keeps heavy reprocessing async | Adds Redis/worker operational dependency |
| Shadow evaluation best-effort (errors silenced) | Production response must never be blocked by shadow path | Shadow result gaps for events where shadow rule errors |
Decision Log¶
For rationale history and consolidated decision records, see Architecture Decisions.
Security Model (High Level)¶
- JWT auth for most API v2 endpoints
- RBAC permissions enforced at endpoint layer
- Audit history recorded for key mutable resources
- Evaluate endpoint intended for internal/service access; protect it with gateway/network controls
Scalability Model (High Level)¶
- API service is stateless and can be horizontally scaled
- Database remains central shared state
- Backtesting workload can be scaled by worker capacity
For production sizing, benchmark with your real rule mix and event load.
Extension Points¶
Common customization directions:
- custom helper functions used by rules
- custom execution wrappers/instrumentation around rule execution
- organization-specific list and outcome governance
Keep extensions observable and testable to avoid hidden runtime risk.