gigafibre-fsm/apps/ops/src/api
louispaulb d529019106 feat(campaigns): gifts inventory page + expiry presets
Wizard: gift_expiry_days now lives behind a preset toggle
(15/30/60/90/180 + Custom) instead of a naked number input. Operator
clicks a chip; the value flows back into the existing campaign param.

Inventory page (/campaigns/gifts):
- Cross-campaign view of every wrapper token with status taxonomy
  (active / redeemed / expired / revoked / pending). Each card on
  the counters strip is a click-to-filter shortcut.
- "Réassignables" highlighted in amber when > 0 — these are gifts
  whose wrapper expired or was revoked but the Giftbit URL is still
  unredeemed, ready for a fresh recipient.
- Search across name/email/url/token; per-status and per-campaign
  filter dropdowns.
- One-click copy on the Giftbit URL with a tailored toast that walks
  the operator through the reassignment workflow (paste into manual-
  add dialog of a new campaign).
- Revoke action with confirmation; explicit about what survives
  (the Giftbit URL stays valid on their side) vs what changes (our
  wrapper stops redirecting).

Backend:
- GET /campaigns/gifts flattens every recipient with a gift across
  every campaign — single-shot, no pagination yet (we're under 10k
  gifts total).
- POST /campaigns/:id/recipients/:row/revoke sets gift_revoked=true
  and broadcasts the recipient-update SSE event.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 10:21:05 -04:00
..
auth.js feat: dispatch planning mode, offer pool, shared presets, recurrence selector 2026-04-08 22:44:18 -04:00
campaigns.js feat(campaigns): gifts inventory page + expiry presets 2026-05-22 10:21:05 -04:00
dispatch.js feat: dispatch planning mode, offer pool, shared presets, recurrence selector 2026-04-08 22:44:18 -04:00
erp.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
flow-templates.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
ocr.js feat: unify vision on Gemini + port field tech scan/device into /j 2026-04-22 11:26:01 -04:00
offers.js feat: dispatch planning mode, offer pool, shared presets, recurrence selector 2026-04-08 22:44:18 -04:00
presets.js feat: dispatch planning mode, offer pool, shared presets, recurrence selector 2026-04-08 22:44:18 -04:00
reports.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
service-request.js feat: add ops app + CONTEXT.md, simplify URL to /ops/ 2026-03-30 22:41:58 -04:00
sms.js feat: telephony UI, performance indexes, Twilio softphone, lazy-load invoices 2026-04-02 13:59:59 -04:00
traccar.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00