feat(ce): Sprint J — matériel rental côté CE
All checks were successful
CI / test (pull_request) Successful in 2m41s
All checks were successful
CI / test (pull_request) Successful in 2m41s
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>
This commit is contained in:
parent
03b740dfff
commit
caa3d5214f
12 changed files with 714 additions and 25 deletions
|
|
@ -23,6 +23,7 @@ export async function DELETE(_req: Request, ctx: { params: Promise<{ id: string
|
|||
session.user.id,
|
||||
session.user.role,
|
||||
media.item.providerId,
|
||||
session.user.organizationId,
|
||||
);
|
||||
if (!allowed) return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export async function POST(req: Request) {
|
|||
session.user.id,
|
||||
session.user.role,
|
||||
item.providerId,
|
||||
session.user.organizationId,
|
||||
);
|
||||
if (!allowed) return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ export async function POST(req: Request) {
|
|||
session.user.id,
|
||||
session.user.role,
|
||||
item.providerId,
|
||||
session.user.organizationId,
|
||||
);
|
||||
if (!allowed) {
|
||||
return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ export async function POST(req: Request) {
|
|||
session.user.id,
|
||||
session.user.role,
|
||||
item.providerId,
|
||||
session.user.organizationId,
|
||||
);
|
||||
if (!allowed) {
|
||||
return NextResponse.json({ error: "Accès refusé" }, { status: 403 });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue