feat(ce): Sprint J — matériel rental côté CE #84

Merged
tarzzan merged 1 commit from feat/ce-sprint-j into main 2026-06-02 23:48:31 +00:00
Owner

Sprint J — Matériel rental côté CE

Suite du plan CE management (Sprint G/H/I déjà mergés). Permet à un CE_MANAGER d'activer un RentalProvider org-scoped, puis de gérer items + réservations.

src/lib/rental-access.ts CE-aware

  • requireRentalProviderSession accepte désormais CE_MANAGER
  • getCurrentRentalProvider : CE_MANAGER → findFirst({ organizationId }), sinon RENTAL_PROVIDER → findFirst({ managedByUserId })
  • getCurrentRentalProviderForCe(orgId) helper explicite pour l'onboarding
  • canManageRentalProvider(userId, role, providerId, userOrgId?) étendu : vrai si manager nominal OU CE_MANAGER + provider.organizationId === userOrgId
  • 5 callers existants passent session.user.organizationId

Actions /espace-prestataire/actions.ts role-aware

requireOwnedProvider() dérive un basePath selon le rôle :

  • CE_MANAGER → /espace-ce/materiel
  • sinon → /espace-prestataire

Tous les redirect / revalidatePath de createHost/updateHost/deleteHost/addItemBlock/removeItemBlock/updateBookingStatus utilisent basePath — l'utilisateur reste dans son contexte après chaque opération.

/espace-ce/materiel/page.tsx — onboarding & dashboard

  • Plugin gear-rental désactivé → message d'info
  • Pas de provider activé → CTA « Activer la location matériel pour » (désactivé si org pending, bannière amber)
  • Provider existant → dashboard KPIs (items actifs, résa pending, confirmées à venir, revenu 30j) + 2 ActionCards Items + Réservations

activateRentalProviderForCeAction

Crée RentalProvider(organizationId, name="Matériel <org>", managedByUserId=session.user.id, approved=true) + audit log + redirect. Bloque si org pas validée.

Pages clonées (zéro duplication métier)

  • /espace-ce/materiel/items/page.tsx
  • /espace-ce/materiel/items/new/page.tsx
  • /espace-ce/materiel/items/[itemId]/page.tsx (MediaUploader + form + ItemBlocksManager)
  • /espace-ce/materiel/reservations/page.tsx

Tous importent depuis /espace-prestataire/{actions, items, reservations} pour réutiliser les composants et la logique métier. Seuls les breadcrumbs/links diffèrent.

Test plan

  • npm test 53/53 ✓
  • typecheck / lint / build ✓
  • CE_MANAGER avec org validée + gear-rental activé → /espace-ce/materiel montre CTA Activer
  • Clic Activer → crée RentalProvider, redirige vers dashboard avec KPIs zéro
  • Items new → créé via espace-ce, redirige vers /espace-ce/materiel/items/[id]
  • Sans org validée → CTA Activer désactivé + message bannière
  • RENTAL_PROVIDER classique → /espace-prestataire/* inchangé (régression zéro)

🤖 Generated with Claude Code

## Sprint J — Matériel rental côté CE Suite du plan CE management (Sprint G/H/I déjà mergés). Permet à un CE_MANAGER d'activer un `RentalProvider` org-scoped, puis de gérer items + réservations. ### `src/lib/rental-access.ts` CE-aware - `requireRentalProviderSession` accepte désormais CE_MANAGER - `getCurrentRentalProvider` : CE_MANAGER → `findFirst({ organizationId })`, sinon RENTAL_PROVIDER → `findFirst({ managedByUserId })` - `getCurrentRentalProviderForCe(orgId)` helper explicite pour l'onboarding - `canManageRentalProvider(userId, role, providerId, userOrgId?)` étendu : vrai si manager nominal OU CE_MANAGER + `provider.organizationId === userOrgId` - 5 callers existants passent `session.user.organizationId` ### Actions `/espace-prestataire/actions.ts` role-aware `requireOwnedProvider()` dérive un `basePath` selon le rôle : - CE_MANAGER → `/espace-ce/materiel` - sinon → `/espace-prestataire` Tous les `redirect` / `revalidatePath` de createHost/updateHost/deleteHost/addItemBlock/removeItemBlock/updateBookingStatus utilisent `basePath` — l'utilisateur reste dans son contexte après chaque opération. ### `/espace-ce/materiel/page.tsx` — onboarding & dashboard - Plugin `gear-rental` désactivé → message d'info - Pas de provider activé → CTA « Activer la location matériel pour <org> » (désactivé si org pending, bannière amber) - Provider existant → dashboard KPIs (items actifs, résa pending, confirmées à venir, revenu 30j) + 2 ActionCards Items + Réservations ### `activateRentalProviderForCeAction` Crée `RentalProvider(organizationId, name="Matériel <org>", managedByUserId=session.user.id, approved=true)` + audit log + redirect. Bloque si org pas validée. ### Pages clonées (zéro duplication métier) - `/espace-ce/materiel/items/page.tsx` - `/espace-ce/materiel/items/new/page.tsx` - `/espace-ce/materiel/items/[itemId]/page.tsx` (MediaUploader + form + ItemBlocksManager) - `/espace-ce/materiel/reservations/page.tsx` Tous importent depuis `/espace-prestataire/{actions, items, reservations}` pour réutiliser les composants et la logique métier. Seuls les breadcrumbs/links diffèrent. ### Test plan - [x] `npm test` 53/53 ✓ - [x] typecheck / lint / build ✓ - [ ] CE_MANAGER avec org validée + `gear-rental` activé → `/espace-ce/materiel` montre CTA Activer - [ ] Clic Activer → crée RentalProvider, redirige vers dashboard avec KPIs zéro - [ ] Items new → créé via espace-ce, redirige vers `/espace-ce/materiel/items/[id]` - [ ] Sans org validée → CTA Activer désactivé + message bannière - [ ] RENTAL_PROVIDER classique → `/espace-prestataire/*` inchangé (régression zéro) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tarzzan added 1 commit 2026-06-02 23:48:29 +00:00
feat(ce): Sprint J — matériel rental côté CE
All checks were successful
CI / test (pull_request) Successful in 2m41s
caa3d5214f
src/lib/rental-access.ts CE-aware :
- requireRentalProviderSession accepte CE_MANAGER (en plus de
  RENTAL_PROVIDER et ADMIN).
- getCurrentRentalProvider : CE_MANAGER → findFirst par
  organizationId ; RENTAL_PROVIDER → par managedByUserId.
- getCurrentRentalProviderForCe(organizationId) helper explicite.
- canManageRentalProvider gagne un userOrgId? optionnel : vrai si
  manager nominal OU CE_MANAGER + provider.organizationId === userOrgId.
- Callers existants (5 sites : actions.ts + 4 routes API rental)
  passent désormais session.user.organizationId.

Actions /espace-prestataire/actions.ts role-aware :
- requireOwnedProvider() dérive basePath selon le rôle :
  CE_MANAGER → /espace-ce/materiel ; sinon → /espace-prestataire.
- Tous les redirect/revalidatePath utilisent basePath, donc
  createHostItemAction, updateHostItemAction, deleteHostItemAction,
  addItemBlockAction, removeItemBlockAction, updateBookingStatusAction
  emmènent le user vers son espace contextuel après chaque opération.

/espace-ce/materiel/page.tsx — onboarding :
- Plugin gear-rental disabled → message d'info.
- Pas de provider activé → CTA « Activer la location matériel pour
  <org> » (bouton bloqué si org pending, message bannière).
- Provider existant → dashboard avec KPIs (items actifs, résa pending,
  confirmées à venir, revenu 30j) + 2 ActionCards Items + Réservations.

actions.ts (CE) :
- activateRentalProviderForCeAction → crée RentalProvider(organizationId,
  name="Matériel <org>", managedByUserId=session.user.id, approved=true)
  + audit + redirect /espace-ce/materiel.

Pages CE clonées (réutilisent les composants, actions, helpers
existants — zéro duplication de logique métier) :
- /espace-ce/materiel/items/page.tsx (liste)
- /espace-ce/materiel/items/new/page.tsx (HostItemForm)
- /espace-ce/materiel/items/[itemId]/page.tsx (MediaUploader +
  HostItemForm + ItemBlocksManager + ItemInlineDelete)
- /espace-ce/materiel/reservations/page.tsx (BookingDecision)

Tous importent depuis /espace-prestataire/{actions, items, reservations}
pour rester DRY. Les breadcrumbs et links sont adaptés au contexte CE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tarzzan merged commit ab1bbb5484 into main 2026-06-02 23:48:31 +00:00
tarzzan deleted branch feat/ce-sprint-j 2026-06-02 23:48:31 +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#84
No description provided.