# Page Review — Promo (P12) + Reviews (P13) + Notifications (P14)

- **Routes:** `/promo-code` (CRUD) · `/rate` (index, view, delete) · `/notifications` (index, mark-all-read)
- **Controllers:** `PromoCodeController` · `RateController` · `NotificationsController`
- **Reviewed:** 2026-07-01 · **Status:** 🔍 (code agent running)

## 2. Design findings
| # | What | Actual | Sev | Evidence |
|---|------|--------|-----|----------|
| D1 | Promo list | ✅ RTL table (code/type/value/usage 100-0/expiry/status badge مفعل), create + code/status filters | — | ss_2539bp7hq |
| D2 | Promo "Code1" value | discount value 0.00 ر.س on a fixed-amount code (test data / useless promo) | LOW(data) | ss_2539bp7hq |
| D3 | Reviews | ✅ RTL table (specialist/star-rating 5.0/review/booking/date), specialist+rating+text filters | — | ss_210996yft |
| D4 | Notifications | ✅ clean RTL empty state ("no notifications yet · appear after feature launches") | — | ss_30369xolu |

## 3. Logic findings
| Action | Result |
|---|---|
| 🟡 promo create/update · 🔴 promo delete · 🔴 review delete | NOT live-triggered; code-review covers IDOR/mass-assign |
| 🟡 mark-all-read | nothing to act on (empty); code-review covers scoping |
| 🟢 index/view | render verified |

## 4. Code trace
**Code-review agent — 0 CRIT, 0 HIGH, 3 MED, 2 LOW. APPROVE.**
| Sev | File:line | Issue | Status |
|---|---|---|---|
| MED | RateController.php:124 findModel | null-shop identity → `user.shop_id IS NULL` could match shopless rows (edge: owners always have a shop) | ⚠️ LOGGED R-L13 |
| MED | PromoCode.php max_uses | no upper-bound validator (unlimited-use possible) | ⚠️ LOGGED R-L14 (business cap?) |
| MED | RateSearch.php:50 | `with()` before shop `joinWith` — not a leak now, fragile if early-return added | ⚠️ LOGGED R-L15 |
| LOW | PromoCodeController.php:161,238 | inline `<script>` postMessage uses Host-derived origin (XSS surface only behind misconfigured proxy) | ⚠️ LOGGED |
| LOW | RateSearch.php:85 | `LIKE` on integer `user.id` (no index, partial match) | ⚠️ LOGGED |

**Confirmed clean:** PromoCode IDOR (`findModel` double-scoped `id`+`shop_id`) + mass-assignment (`shop_id`/`uses`/`remaining_uses` excluded + re-pinned in create/update); Rate read-only+delete (no mass-assign surface); Notifications `mark-all-read` bound to session `to_id` (no cross-tenant); index scoping hard-scoped; CSRF (VerbFilter POST + tokens) on all.

## 5. Fixes applied
None required — no CRITICAL/HIGH. All findings MED/LOW, logged for hardening pass.

## 6. Sign-off
- [x] Promo/Reviews/Notifications design verified (RTL)
- [x] code-review APPROVE (0 HIGH); MED/LOW logged
