# TASK-002 — Customer returns (app + Ops inbox)

**Status:** In progress
**Branch:** feature/TASK-002-customer-returns
**Started:** 2026-07-14
**Last updated:** 2026-07-14

## Goal
Let shoppers request a post-delivery return for a single order line (photo + reason), and give Ops a Returns inbox to review and approve/reject — without auto wallet credit in v1.

## Acceptance criteria
- [x] New Ops `returns` table + `ReturnModel` + `returns.view` / `returns.manage` permissions
- [x] Ops admin Returns list/detail/status + photo stream + nav entry
- [x] `POST /api/v1/returns` (multipart) and `GET /api/v1/returns` with soft order linking
- [x] Flutter: delivered order → Return → select item → photo + comment → submit
- [x] Local line marked return-requested to avoid duplicate prompts
- [x] Migration applied; API smoke-tested (HTTP 201)

## Files touched
| File | Notes |
|------|-------|
| ../baskit_ops/app/Database/Migrations/2026-07-14-200000_CreateReturns.php | `returns` table |
| ../baskit_ops/app/Models/ReturnModel.php | listView + order helpers |
| ../baskit_ops/app/Controllers/Admin/Returns.php | Admin inbox |
| ../baskit_ops/app/Controllers/Api/Returns.php | Customer API |
| ../baskit_ops/app/Views/admin/returns/* | List + detail |
| ../baskit_ops/app/Config/AuthGroups.php | Permissions |
| ../baskit_ops/app/Config/Routes.php | Admin + API routes |
| lib/features/orders/return_screens.dart | Select + submit UI |
| lib/core/api_client.dart | multipart submitReturn |
| lib/widgets/order_widgets.dart | Return button on delivered orders |
| lib/models/order.dart | returnRequested on OrderLine |
| lib/state/order_model.dart | markReturnRequested |
| lib/main.dart | return routes |

## Decisions
- 2026-07-14 — Separate `returns` table from `refunds` — returns are a request inbox; money refund stays the existing Ops path.
- 2026-07-14 — Soft-link by `order_code` because Flutter orders are still local stubs.
- 2026-07-14 — Reuse `X-App-Key` / `APP_ANALYTICS_KEY` for app→Ops auth until customer JWT lands.

## Session log
### 2026-07-14 — Cursor
- Did: Ops migration + admin Returns module + API; Flutter return flow with image_picker; smoke POST returned id=1 pending.
- Broke / deferred: Auto wallet credit on approve; full order sync from Ops.
- Commits: (pending user request)

## Next steps
1. Confirm Ops Returns UI in browser with the smoke-test row.
2. Harden with customer JWT once Shield shopper auth ships.
3. Optional: approve → create linked `refunds` row.

## Open questions
- None for v1.
