feat(ce): Sprint I — CRUD carbets côté CE
All checks were successful
CI / test (pull_request) Successful in 2m36s
All checks were successful
CI / test (pull_request) Successful in 2m36s
Session étendue : - Ajout session.user.organizationId (typedef + auth callbacks JWT & session). Permet à canManageCarbet de check membership sans refetch DB. src/lib/carbet-access.ts : - MANAGER_ROLES inclut désormais CE_MANAGER → /espace-hote ET /espace-ce sont gardés par requireOwnerSession (CE_MANAGER passe, OWNER passe, ADMIN passe). - canManageCarbet(session, carbetOwnerId, linkedOrgIds=[]) : - ADMIN → toujours vrai - OWNER + session.user.id === carbetOwnerId → vrai - CE_MANAGER + session.user.organizationId ∈ linkedOrgIds → vrai - sinon faux. - Callers historiques (qui ne passent pas linkedOrgIds) restent sûrs : CE_MANAGER ne peut rien gérer par défaut. createCarbet étendu : si role=CE_MANAGER + organizationId présent, crée OrganizationCarbetMembership dans la même transaction. Redirige ensuite vers /espace-ce/carbets/[id] au lieu de /espace-hote/. Sweep des callers canManageCarbet (8 sites) : chargent désormais `Carbet.organizations` + passent linkedOrgIds. Includes : - updateCarbet, setCarbetStatus, deleteCarbet, reorderMedia, deleteMedia dans espace-hote/carbets/actions.ts - espace-hote/carbets/[carbetId]/page.tsx - API POST /api/carbets/[carbetId]/media Pages /espace-ce/carbets/* : - page.tsx : liste les carbets co-gérés via OrganizationCarbetMembership, forms Publier/Dépublier/Supprimer pointent vers les actions existantes de /espace-hote (réutilisation totale) - nouveau/page.tsx : requireApprovedOrg (redirect dashboard si pending), CarbetForm + createCarbet (même action que /espace-hote — détecte CE_MANAGER et crée membership) - [carbetId]/page.tsx : vérif que le carbet est lié à l'org du user + MediaUploader + CarbetForm (updateCarbet partagé) Dashboard /espace-ce/page.tsx : ActionCard « Mes carbets » devient active (le lien marche même en pending — l'org peut préparer des brouillons, c'est juste la publication qui est bloquée). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3d77632ba0
commit
74ea280f28
10 changed files with 462 additions and 28 deletions
|
|
@ -26,7 +26,11 @@ export async function POST(
|
|||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ error: "Non authentifié." }, { status: 401 });
|
||||
}
|
||||
if (session.user.role !== UserRole.OWNER && session.user.role !== UserRole.ADMIN) {
|
||||
if (
|
||||
session.user.role !== UserRole.OWNER &&
|
||||
session.user.role !== UserRole.ADMIN &&
|
||||
session.user.role !== UserRole.CE_MANAGER
|
||||
) {
|
||||
return NextResponse.json({ error: "Accès refusé." }, { status: 403 });
|
||||
}
|
||||
|
||||
|
|
@ -34,12 +38,15 @@ export async function POST(
|
|||
|
||||
const carbet = await prisma.carbet.findUnique({
|
||||
where: { id: carbetId },
|
||||
select: { ownerId: true },
|
||||
select: {
|
||||
ownerId: true,
|
||||
organizations: { select: { organizationId: true } },
|
||||
},
|
||||
});
|
||||
if (!carbet) {
|
||||
return NextResponse.json({ error: "Carbet introuvable." }, { status: 404 });
|
||||
}
|
||||
if (!canManageCarbet(session, carbet.ownerId)) {
|
||||
if (!canManageCarbet(session, carbet.ownerId, carbet.organizations.map((o) => o.organizationId))) {
|
||||
return NextResponse.json({ error: "Accès refusé." }, { status: 403 });
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue