karbe/src/app/api
Ubuntu c564028ca9
All checks were successful
CI / test (pull_request) Successful in 2m37s
feat(rental): Sprint M — refonds + annulations Stripe
Politique de remboursement v1 :
- > 7 jours du début → FULL (location + caution)
- 1 à 7 jours → PARTIAL_50 (50% location + caution intégrale)
- < 24h ou passé → DEPOSIT_ONLY (caution seulement, pas de remboursement
  sur la location)

src/lib/rental-refund.ts (NEW) : computeRentalRefund({startDate,
itemsTotal, depositTotal}) → { itemsRefund, depositRefund, totalRefund,
policy, policyLabel }. Arrondi au centime, support de Decimal.

POST /api/rentals/[id]/cancel :
- Auth multi-rôle : tenant de la booking, RENTAL_PROVIDER nominal ou
  CE_MANAGER de l'org du provider, ADMIN. Détecte `cancelledBy` pour
  adapter l'email.
- Refuse si status ∉ {PENDING, CONFIRMED} (HANDED_OVER → non
  annulable, contacter Karbé).
- Calcule le refund selon la politique.
- Stripe refund best-effort si paymentStatus=SUCCEEDED + stripeSessionId
  existante + isStripeConfigured + totalRefund > 0. Retrieve session →
  payment_intent → refunds.create. Échec Stripe = audit-logged mais
  le flip status continue (l'asso pourra rembourser manuellement).
- Transaction : update RentalBooking (CANCELLED + paymentStatus
  REFUNDED si SUCCEEDED sinon FAILED) + delete RentalItemAvailability
  (libère stock).
- Audit log rental.cancel avec montants, policy, cancelledBy,
  stripeRefundId, stripeRefundError.
- Email best-effort : sendRentalCancelled à tenant + provider (sauf si
  provider est le canceller).

src/components/CancelRentalButton.tsx : composant client confirm dialog
inline avec textarea motif (max 500 chars). Branché sur :
- /mes-locations : « Annuler ma location » sur résa PENDING/CONFIRMED
- BookingDecision (utilisé par /espace-prestataire/reservations ET
  /espace-ce/materiel/reservations) : remplace l'ancienne mini-confirm
  qui flippait juste le status, désormais via la vraie API refund

sendRentalCancelled email : adapté selon cancelledBy ("Vous avez annulé"
/ "<Provider> a annulé" / "L'équipe Karbé a annulé").

tests/lib/rental-refund.test.ts : 8 cas (FULL @ 10+ et 7j, PARTIAL_50,
DEPOSIT_ONLY < 24h et passé, arrondi centime, zéro caution, policyLabel).
Total projet : 70/70 ✓.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-03 02:17:58 +00:00
..
admin fix(admin): PATCH content-pages respecte ?lang= (sinon écrasait FR) 2026-06-01 00:51:19 +00:00
auth/[...nextauth] feat(auth): add multi-role NextAuth with role guards 2026-05-29 10:46:54 +00:00
bookings feat(hardening): rate limit (signup/reset/bookings) + tâches cron + backup PostgreSQL nocturne 2026-06-01 20:16:57 +00:00
carbets/[carbetId] feat(ce): Sprint I — CRUD carbets côté CE 2026-06-02 23:34:17 +00:00
cron/run/[task] feat(hardening): rate limit (signup/reset/bookings) + tâches cron + backup PostgreSQL nocturne 2026-06-01 20:16:57 +00:00
favorites feat: « Au fil de l'eau » — Reels mobile + uploader pro + favoris 2026-06-02 00:27:16 +00:00
health feat(p2): vitest + 27 tests + /api/health enrichi + /api/metrics + workflow CI 2026-06-01 02:27:14 +00:00
me/export feat: reset password + page mon-compte (RGPD) + facettes recherche (prix max, équipements) 2026-06-01 10:16:37 +00:00
media feat: « Au fil de l'eau » — Reels mobile + uploader pro + favoris 2026-06-02 00:27:16 +00:00
metrics feat(p2): vitest + 27 tests + /api/health enrichi + /api/metrics + workflow CI 2026-06-01 02:27:14 +00:00
password feat(hardening): rate limit (signup/reset/bookings) + tâches cron + backup PostgreSQL nocturne 2026-06-01 20:16:57 +00:00
rental-media feat(ce): Sprint J — matériel rental côté CE 2026-06-02 23:47:57 +00:00
rentals feat(rental): Sprint M — refonds + annulations Stripe 2026-06-03 02:17:58 +00:00
reviews/[reviewId]/response feat(reviews): avis & notes carbet (SYS-8) 2026-05-30 15:08:55 +00:00
signup feat(ce): Sprint K — public badge + invites CE_MEMBER + tests 2026-06-03 00:03:03 +00:00
stripe feat(rental): Sprint E — emails + plugin toggle + tests 2026-06-02 08:49:39 +00:00
uploads feat(ce): Sprint J — matériel rental côté CE 2026-06-02 23:47:57 +00:00