feat(rental): Sprint E — emails + plugin toggle + tests #78

Merged
tarzzan merged 1 commit from feat/rental-sprint-e into main 2026-06-02 08:50:16 +00:00
Owner

Sprint E — Emails + plugin gear-rental + tests

Finalisation de la marketplace de location matériel : transactionnel, toggle plugin admin, tests unitaires.

Emails (best-effort, dry-run sans RESEND_API_KEY)

3 nouveaux templates :

  • sendRentalRequestedTenant — récap demande au locataire (1 mail par RentalBooking)
  • sendRentalRequestedProvider — nouvelle demande au prestataire
  • sendRentalConfirmed — confirmation paiement reçu

Branchements :

  • POST /api/rentals/checkout envoie tenant + provider à la création (try/catch — n'est jamais bloquant)
  • Webhook Stripe rental-bundle envoie sendRentalConfirmed à chaque locataire après l'update CONFIRMED+SUCCEEDED

Plugin gear-rental

Ajout au registry (catégorie business). Activable/désactivable depuis /admin/plugins.

Quand désactivé :

  • /materiel, /materiel/[itemId], /panier, /mes-locations, /espace-prestataire/** → 404 (via layout.tsx + requirePluginOr404)
  • POST /api/rentals/checkout → 404
  • SiteHeader masque les liens Matériel / Mes locations / Espace prestataire + le badge 🛒
  • Panneau « Compléter votre séjour » sur /carbets/[slug] retourne null

L'admin reste libre de gérer les providers via /admin/rental-providers (non guard).

Tests vitest (16 tests / fichier)

tests/lib/rentals.test.ts :

  • diffDays (mêmes dates, 1 nuit, 7 jours, end < start)
  • parseCart (null/undefined/garbage/schéma invalide/valide/format date)
  • serializeCart (updatedAt ISO, roundtrip)
  • commission formula (0% System D, 15%, arrondi centime)
  • availability arithmetic (totalQty libre, soustractions, plancher 0)

53 tests passent au total. Build OK.

Test plan

  • Activer le plugin gear-rental sur /admin/plugins
  • /materiel accessible, liens header présents
  • Désactiver le plugin → /materiel renvoie 404, liens header masqués
  • Réactiver et vérifier que tout revient
  • Faire un checkout sans Stripe → log « dry-run » Resend pour tenant + provider
  • Webhook Stripe fictif rental-bundle (curl signé) → log dry-run sendRentalConfirmed

🤖 Generated with Claude Code

## Sprint E — Emails + plugin gear-rental + tests Finalisation de la marketplace de location matériel : transactionnel, toggle plugin admin, tests unitaires. ### Emails (best-effort, dry-run sans `RESEND_API_KEY`) 3 nouveaux templates : - `sendRentalRequestedTenant` — récap demande au locataire (1 mail par RentalBooking) - `sendRentalRequestedProvider` — nouvelle demande au prestataire - `sendRentalConfirmed` — confirmation paiement reçu Branchements : - `POST /api/rentals/checkout` envoie tenant + provider à la création (try/catch — n'est jamais bloquant) - Webhook Stripe `rental-bundle` envoie `sendRentalConfirmed` à chaque locataire après l'update CONFIRMED+SUCCEEDED ### Plugin `gear-rental` Ajout au registry (catégorie business). Activable/désactivable depuis `/admin/plugins`. Quand désactivé : - `/materiel`, `/materiel/[itemId]`, `/panier`, `/mes-locations`, `/espace-prestataire/**` → 404 (via `layout.tsx` + `requirePluginOr404`) - `POST /api/rentals/checkout` → 404 - `SiteHeader` masque les liens Matériel / Mes locations / Espace prestataire + le badge 🛒 - Panneau « Compléter votre séjour » sur `/carbets/[slug]` retourne `null` L'admin reste libre de gérer les providers via `/admin/rental-providers` (non guard). ### Tests vitest (16 tests / fichier) `tests/lib/rentals.test.ts` : - `diffDays` (mêmes dates, 1 nuit, 7 jours, end < start) - `parseCart` (null/undefined/garbage/schéma invalide/valide/format date) - `serializeCart` (updatedAt ISO, roundtrip) - commission formula (0% System D, 15%, arrondi centime) - availability arithmetic (totalQty libre, soustractions, plancher 0) **53 tests passent au total.** Build OK. ### Test plan - [ ] Activer le plugin `gear-rental` sur `/admin/plugins` - [ ] `/materiel` accessible, liens header présents - [ ] Désactiver le plugin → `/materiel` renvoie 404, liens header masqués - [ ] Réactiver et vérifier que tout revient - [ ] Faire un checkout sans Stripe → log « dry-run » Resend pour tenant + provider - [ ] Webhook Stripe fictif `rental-bundle` (curl signé) → log dry-run `sendRentalConfirmed` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tarzzan added 1 commit 2026-06-02 08:50:07 +00:00
feat(rental): Sprint E — emails + plugin toggle + tests
Some checks failed
CI / test (pull_request) Failing after 1m10s
5607a51980
3 nouveaux templates email (best-effort, dry-run sans Resend) :
- sendRentalRequestedTenant : récap de demande au locataire (par RB)
- sendRentalRequestedProvider : nouvelle demande au prestataire
- sendRentalConfirmed : confirmation paiement reçu

Branchements :
- POST /api/rentals/checkout : envoie tenant + provider après création
  des RentalBooking (PENDING), catch global pour ne pas bloquer
- Webhook Stripe rental-bundle : envoie sendRentalConfirmed à chaque
  locataire après update CONFIRMED+SUCCEEDED

Plugin gear-rental :
- Ajout au registry (catégorie business)
- layout.tsx /materiel + /espace-prestataire avec requirePluginOr404
- requirePluginOr404 dans /panier et /mes-locations
- isPluginEnabled guard dans POST /api/rentals/checkout (404 si off)
- SiteHeader masque liens Matériel / Mes locations / Espace prestataire
  + CartBadge si plugin désactivé
- CompleteYourStay renvoie null si plugin désactivé
Décision admin → activable depuis /admin/plugins comme tous les autres.

Tests vitest (tests/lib/rentals.test.ts, 16 tests) :
- diffDays (mêmes dates, 1 nuit, 7 jours, négatif)
- parseCart (null/garbage/schéma invalide/valide/format date)
- serializeCart (updatedAt, roundtrip)
- commission formula (0%, 15%, arrondi centime)
- availability arithmetic (totalQty libre, soustractions, plancher 0)

53 tests pass total. Build OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tarzzan merged commit 740e9958aa into main 2026-06-02 08:50:16 +00:00
tarzzan deleted branch feat/rental-sprint-e 2026-06-02 08:50:16 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: tarzzan/karbe#78
No description provided.