# Jube Rules — Implementation Plan

**Branch**: `feat/fraud-rules-jube-parity`
**Reference**: Jube source at `aml-fraud-transaction-monitoring-master/` + [Jube-Guiide-document.txt](Jube-Guiide-document.txt)

---

## 1. Source-of-truth field mapping (from Jube `Poco.cs`)

### Gateway Rule (`EntityAnalysisModelGatewayRule`, 26 fields)
| Jube field | mw-core column | Status |
|---|---|---|
| Id, EntityAnalysisModelId | id, entity_model_id | ✅ |
| Name, Active, Locked, Priority | name, active, locked, priority | ✅ |
| BuilderRuleScript (JSON) | rule_expression (text) | ⚠ stored as string |
| CoderRuleScript, RuleScriptTypeId | — | ❌ N/A (we use JSON only) |
| GatewaySample, MaxResponseElevation | gateway_sample, max_response_elevation | ✅ |
| Version, CreatedUser, CreatedDate, UpdatedDate, UpdatedUser | version, created_by | ⚠ partial — need version/audit |
| Guid, ImportId | — | ❌ not needed yet |
| ActivationCounter, ActivationCounterDate, EvaluationCounter | — | ❌ runtime stats, skip |
| Deleted, DeletedUser, DeletedDate | — | ❌ use hard delete |
| InheritedId | — | ❌ skip inheritance |

### Abstraction Rule (`EntityAnalysisModelAbstractionRule`, 32 fields)
| Jube field | mw-core column | Status |
|---|---|---|
| Id, EntityAnalysisModelId, Name, Active, Locked | id, entity_model_id, name, active, locked | ✅ |
| BuilderRuleScript | rule_expression | ⚠ string |
| SearchKey, Search, SearchValue, SearchInterval | search_key, search_enabled, search_value, search_interval_type | ✅ |
| SearchFunctionTypeId, SearchFunctionKey | function_type, function_key | ✅ |
| Offset, OffsetTypeId, OffsetValue | offset_enabled, offset_type, offset_value | ✅ |
| ResponsePayload, ReportTable | response_payload, report_table | ✅ |
| Version, CreatedUser, CreatedDate | — | ⚠ missing |
| Guid, ImportId, Updated*, Deleted* | — | ❌ skip |

### Activation Rule (`EntityAnalysisModelActivationRule`, 57 fields) — **largest gap**
mw-core currently has only 13 fields (rule_type/threshold_value/list_values etc). Jube has 5 logical blocks:

| Block | Jube fields | mw-core today |
|---|---|---|
| Identity | Name, Active, Locked, Priority, ReviewStatusId, BuilderRuleScript | partial |
| Cases | EnableCaseWorkflow, CaseWorkflowGuid, CaseWorkflowStatusGuid, CaseKey, EnableBypass, BypassSuspendSample, BypassSuspendInterval, BypassSuspendValue | ❌ none |
| Response Elevation | EnableResponseElevation, ResponseElevation, ResponseElevationContent, ResponseElevationRedirect, ResponseElevationKey, ResponseElevationForeColor, ResponseElevationBackColor, SendToActivationWatcher | ❌ none |
| TTL Counter Increment | EnableTtlCounter, EntityAnalysisModelTtlCounterGuid, EntityAnalysisModelGuidTtlCounter | ❌ none |
| Notification | EnableNotification, NotificationTypeId, NotificationDestination, NotificationSubject, NotificationBody | ❌ none |
| Operational | ActivationSample, Visible, EnableReprocessing, EnableSuppression, ReportTable, ResponsePayload | ❌ none |

---

## 2. Architectural decisions (Elixir adaptation)

| Jube approach | mw-core approach | Rationale |
|---|---|---|
| VB.NET script compiled at sync time | Structured JSON rule tree evaluated by pure Elixir module | No CLR; safer; live-editable |
| `BuilderRuleScript` + `CoderRuleScript` dual storage | Single `rule_expression` JSON column | UI builds the tree; no free-form scripting |
| MessagePack POCO + LinqToDB | Ecto schemas + JSON `:map` columns | Idiomatic |
| Guid surrogate keys | Integer `id` + tenant scoping | Already established pattern |
| Soft-delete via Deleted flag | Hard delete (or version table later) | Simpler now |
| Versioning via separate `*Version` tables | `version` integer field on the rule, bumped on update | YAGNI for v1 |

---

## 3. Pipeline (already exists, needs wiring)

```
event → MwRisk.GatewayRuleEngine → MwRisk.AbstractionEngine → MwRisk.ActivationEngine → response
                  ✅ exists                ✅ exists                ✅ exists
```

Engines live at:
- [gateway_rule_engine.ex](../../apps/mw_risk/lib/mw_risk/gateway_rule_engine.ex) (124 LOC)
- [abstraction_engine.ex](../../apps/mw_risk/lib/mw_risk/abstraction_engine.ex) (169 LOC)
- [activation_engine.ex](../../apps/mw_risk/lib/mw_risk/activation_engine.ex)

Schemas:
- [risk_gateway_rule.ex](../../apps/infra_repo/lib/infra_repo/schemas/risk_gateway_rule.ex) ✅
- [risk_abstraction_rule.ex](../../apps/infra_repo/lib/infra_repo/schemas/risk_abstraction_rule.ex) ✅
- [risk_activation_rule.ex](../../apps/infra_repo/lib/infra_repo/schemas/risk_activation_rule.ex) ⚠ needs schema extension

---

## 4. Implementation order (this branch)

### Phase A — Gateway Rules UI (smallest delta) ⏳ in progress
1. Migration: add `version` + `created_by` to `risk_gateway_rules`
2. Schema update
3. Add context helpers to `InfraRepo.Risk.Risks` (already exist — verify)
4. New LiveView `GatewayRulesLive` at `/admin/fraud/gateway-rules` (model-agnostic index, model filter)
5. Slide-over drawer matching Lists/Dictionaries pattern (`max-w-lg`)
6. Sidebar nav entry "Gateway Rules"
7. Seed 4–6 demo gateway rules

### Phase B — Abstraction Rules UI
1. Migration: add `version` + `created_by`
2. New LiveView `AbstractionRulesLive` at `/admin/fraud/abstraction-rules`
3. Drawer with: Properties / Search Config / Offset / Function / Rule (builder)
4. Show 14 function types from `RiskAbstractionRule.function_name/1`
5. Seed examples mirroring `Volume1DayUSDForIP`

### Phase C — Activation Rules schema rewrite
1. Migration: add ~30 fields across 5 blocks (Cases / Response Elevation / TTL / Notification / Operational)
2. Schema rewrite with grouped validations
3. New LiveView with collapsible sections per Image-3 screenshot
4. Wire to `MwRisk.ActivationEngine`
5. Seed examples

### Phase D — Rule expression builder component
Reusable LiveComponent rendering an AND/OR/NOT tree:
- Field selector (sourced from Request XPath when that's built; from Payload keys for now)
- Operator (equal/greater/less/in/contains/regex)
- Value input (text/number/select)
- JSON output stored in `rule_expression`

### Phase E — Pipeline integration & sync
Add `MwRisk.Pipeline.run/2` that chains Gateway → Abstraction → Activation, called from the admin "Synchronise" action and from real-time HTTP/AMQP adapters.

---

## 5. Out of scope (this branch) — see [phases/README.md](phases/README.md) for next-phases roadmap

| Item | Branch | Plan |
|---|---|---|
| Request XPath / Search Key mgmt UI                        | `feat/fraud-xpath-search-keys`        | [F](phases/F-request-xpath-search-keys.md) |
| TTL Counter mgmt UI + runtime writer                      | `feat/fraud-ttl-counters`             | [G](phases/G-ttl-counters.md) |
| Sanctions / Tags / Dictionary nodes in RuleBuilder        | `feat/fraud-rule-builder-data-nodes`  | [H](phases/H-rule-builder-data-nodes.md) |
| Activation Watcher real-time stream                       | `feat/fraud-activation-watcher`       | [I](phases/I-activation-watcher.md) |
| Case Workflow / Status mgmt + runtime case opener         | `feat/fraud-case-workflows`           | [J](phases/J-case-workflows.md) |
| Reprocessing job runner                                   | `feat/fraud-reprocessing`             | [K](phases/K-reprocessing-runner.md) |
| Maker-Checker approval flow                               | `feat/fraud-maker-checker`            | [L](phases/L-maker-checker.md) |
