93 lines
3.1 KiB
Markdown
93 lines
3.1 KiB
Markdown
# Recommendation Engine Contracts (Rule-Based)
|
|
|
|
> **No AI. No implementation.** Contracts for a future rule evaluator.
|
|
> ADR: [ADR-023](../architecture/adr/ADR-023.md)
|
|
> Contract version: `recommendation.v1`
|
|
|
|
---
|
|
|
|
## 1. Purpose
|
|
|
|
Produce **recommendations** for bundles, services, modules, features, and pricing from structured business inputs. Outputs never activate entitlements.
|
|
|
|
---
|
|
|
|
## 2. Input — RecommendationRequest
|
|
|
|
| Field | Type | Meaning |
|
|
| --- | --- | --- |
|
|
| `business_type_code` | string | From Business Type Catalog |
|
|
| `company_size` | enum | `solo` \| `small` \| `medium` \| `large` \| `enterprise` |
|
|
| `employees` | int? | Headcount hint |
|
|
| `branches` | int? | Location count |
|
|
| `needs[]` | string[] | Free-form need tags (open registry) |
|
|
| `online_sales` | bool | |
|
|
| `delivery` | bool | |
|
|
| `appointments` | bool | |
|
|
| `crm` | bool | |
|
|
| `loyalty` | bool | |
|
|
| `website` | bool | |
|
|
| `locale` | string? | |
|
|
| `ext` | object | Additive |
|
|
|
|
### Need tag examples (open)
|
|
|
|
`menu`, `pos`, `fleet`, `sms`, `accounting`, `membership`, `forms`, `b2b_pipeline`
|
|
|
|
---
|
|
|
|
## 3. Output — RecommendationResult
|
|
|
|
| Field | Type | Meaning |
|
|
| --- | --- | --- |
|
|
| `recommended_bundles[]` | RankedRef | `{ code, score, reason }` |
|
|
| `recommended_services[]` | RankedRef | `service_identifier` |
|
|
| `recommended_modules[]` | RankedRef | `module_key` |
|
|
| `recommended_features[]` | RankedRef | `feature_key` |
|
|
| `recommended_pricing[]` | RankedRef | `pricing_item_code` |
|
|
| `rule_trace[]` | string[] | Which rules fired (debug) |
|
|
| `version` | string | `recommendation.v1` |
|
|
|
|
---
|
|
|
|
## 4. Rule — RecommendationRule
|
|
|
|
| Field | Type | Meaning |
|
|
| --- | --- | --- |
|
|
| `rule_id` | string | |
|
|
| `priority` | int | Higher evaluated first / stronger weight |
|
|
| `active` | bool | |
|
|
| `match` | object | Predicates over RecommendationRequest |
|
|
| `emit` | object | What to add to result with `score` + `reason` |
|
|
| `stop` | bool | If true, halt further rules after match |
|
|
|
|
### Match predicates (documented operators)
|
|
|
|
| Operator | Example |
|
|
| --- | --- |
|
|
| `eq` | `business_type_code eq restaurant` |
|
|
| `gte` | `branches gte 2` |
|
|
| `in` | `company_size in [medium, large, enterprise]` |
|
|
| `flag_true` | `delivery == true` |
|
|
| `needs_contains` | `needs contains fleet` |
|
|
|
|
### Example rules (illustrative)
|
|
|
|
| rule_id | Match | Emit |
|
|
| --- | --- | --- |
|
|
| `r.restaurant.base` | type=restaurant | bundle `bundle.restaurant.starter` score 100 |
|
|
| `r.delivery.need` | delivery=true | service `delivery` score 80 |
|
|
| `r.crm.need` | crm=true OR type=corporate_company | service `crm` score 80 |
|
|
| `r.website.need` | website=true | service `experience` score 70 |
|
|
| `r.loyalty.need` | loyalty=true | service `loyalty` score 70 |
|
|
| `r.multi.branch` | branches≥3 | prefer `*.growth` bundle variants score +20 |
|
|
| `r.enterprise.size` | company_size=enterprise | pricing `price.enterprise.custom` score 90 |
|
|
|
|
---
|
|
|
|
## 5. Invariants
|
|
|
|
1. Rules MUST NOT call Payment, Accounting, or vertical write APIs.
|
|
2. Scores are relative; UI may sort but MUST present as recommendations.
|
|
3. No ML / LLM required or permitted by this contract version.
|