3.2 KiB
08 — Sales Agent Controls
Status: Not Started Depends On: 07 — Ride Close & Reconciliation
Goal
Wire role levels to concrete business limits and approval chains. Covers the approval-routing half
of mainPlan.md §1
(submitOrderForApproval, approveOrder, rejectOrder) and the performance-tracking functions
from §10 SFA/CRM
(trackTargetVsAchievement, calculateIncentive). Lead/interaction functions from §10
(logCustomerInteraction, createLead, convertLeadToStore) are out of scope here — see
16_sfa_crm.md.
Background / Context
Role.Level already exists and drives the permission seed
(Data/Seed/RoleAndPermissionSeed.cs), but nothing today turns a level into a discount limit,
credit limit, or approval threshold — it only gates which API endpoints a role can call.
Data Model Changes
Agent Limit Configuration (per role level)
RoleId, MaxDiscountPercent, MaxSingleTransactionValue — read by both
06_sale_ride.md (line-item discount check) and order approval routing here.
Override Log
OverrideById (the supervisor), TargetType/TargetId (e.g. Order, FieldInvoice), OldValue,
NewValue, Reason, CreatedAt — a one-time exception, logged against the supervisor's account.
Customer Credit Profile
Reuses Store.CreditLimit/Store.OutstandingBalance once added (gap #8 in
00_existing_gaps.md) rather than a separate entity.
API Endpoints
| Function reference | Endpoint intent |
|---|---|
submitOrderForApproval(orderId) (§1) |
Triggered automatically when an order exceeds its agent's limit |
approveOrder(orderId, approverId) / rejectOrder(orderId, reason) (§1) |
POST /api/orders/{id}/approve, POST /api/orders/{id}/reject |
trackTargetVsAchievement(userId, period) (§10) |
GET /api/agents/{userId}/performance?period=... |
calculateIncentive(userId, period) (§10) |
GET /api/agents/{userId}/incentive?period=... |
| — | POST /api/orders/{id}/override — supervisor one-time exception, writes an Override Log entry |
Business Rules
- An order/invoice whose value or discount exceeds the agent's
Agent Limit Configurationcannot proceed without either supervisor approval or a logged override — no silent pass-through. calculateIncentivereads only settled/closed rides (post-07_ride_reconciliation.md), never in-flight ones.
Fraud / Control Considerations
- Every
Override Logentry is permanent and immutable once written — feeds 09_fraud_controls.md's anomaly detection (agents with unusually frequent overrides).
Open Questions
- Are discount/transaction limits configured per
Role, or can an individualUserhave a tighter/looser override of their role's default? - What sales target source feeds
trackTargetVsAchievement— is there a target-setting endpoint needed here, or does it come from §2'ssetRegionalTargetrolled down to the individual?
Implementation Notes
Fill this section in during planning discussion before writing any code.