# PRP-001 — Foundation reconciliation (manual fee, daily cap, feature flags)

- **Status:** Done
- **Plan:** Lite
- **Depends on:** — (adjusts the scaffolded MVP)
- **Pro KB ref:** §9 (Orders), §12 (Zones), §3 (Settings/flags)

## 1. Goal / Why
The initial scaffold auto-priced order fees from zones. Product decision changed: in Lite the **fee is
a manual operator input** and **zone-based pricing is a Pro feature**. This PRP reconciles the
foundation with the final Lite decisions so every later PRP builds on correct primitives.

## 2. Scope
**In:**
- Switch order `fees` to manual input (drop auto zone-pricing on create).
- Add per-company **daily order cap** (default 30, `ORDER_DAILY_CAP`).
- Centralize **feature flags** so Pro teasers are data-driven; expose via `/api/features`.
- Add config plumbing for `PRO_UPGRADE_URL`, Brevo, cap (env already added).

**Out (Pro):** zone-derived pricing, AI matching, multi-currency (all become teasers in PRP-005/010).

## 3. Functional requirements
- FR-1 `orders.service.create` accepts `fees` (decimal ≥ 0) from the request; it no longer reads the
  zone price. `zone_id` may still be resolved+stored for display/info, but MUST NOT set `fees`.
- FR-2 On create, enforce the daily cap: count this company's orders created today (server local =
  UTC day boundary) and reject the (cap+1)th with `429`-style `{ success:false, code:'DAILY_CAP',
  message, meta:{ cap, used } }`. ROOT acting on a company is also capped (keeps demo honest) unless
  `company.plan = 'pro'` (then uncapped).
- FR-3 `FEATURES` map gains a `teaser` description string per Pro feature for the UI. `/api/features`
  returns `{ plans, upgradeUrl, dailyCap, features }`.
- FR-4 `config/env.js` exposes `orderDailyCap`, `proUpgradeUrl`, and a `brevo` block.

## 4. Data model
No schema change required (fees column already exists). Optional: add `orders.cod_locked`? **No** —
COD stays a plain input. Keep migration count stable.

## 5. API surface
- `POST /api/orders` — body now includes `fees` (required, ≥ 0) and `cod` (optional). Validation via zod.
- `GET /api/features` — extended payload (see FR-3).

## 6. Frontend
- Order create form: add **Fee** input next to COD (both manual). Remove "fee auto-priced" copy.
- Show remaining daily quota (e.g. "12 / 30 orders today") on Orders + Dashboard; block the form and
  show the upgrade CTA when the cap is hit.

## 7. Pro-teaser / gating
- Near the Fee field, a small note: *"Automatic zone-based pricing is a Pro feature"* → `PRO_UPGRADE_URL`.

## 8. Acceptance criteria
- [x] Creating an order stores the fee exactly as entered (no zone override). *(verified: fee 75 stored as 75.00 for Cairo, not zone's 50)*
- [x] The 31st order in a UTC day for a Lite company is rejected with `DAILY_CAP`; a `pro` company is not. *(verified with cap=2)*
- [x] `/api/features` returns `upgradeUrl` and `dailyCap`.

## 9. Test plan
- Create order with `fees:75`, assert stored `75.00` regardless of city.
- Loop-create 30 orders OK, 31st → `DAILY_CAP`. Flip company to `pro`, 31st succeeds.

## 10. Notes
"Today" = UTC calendar day (matches DB `timezone:'Z'`). Reset is midnight UTC; document this.
