feat(ce): Sprint I — CRUD carbets côté CE #83

Merged
tarzzan merged 1 commit from feat/ce-sprint-i into main 2026-06-02 23:34:49 +00:00
Owner

Sprint I — CRUD carbets côté CE

Suite du plan CE management. Permet à un CE_MANAGER de créer/éditer/publier des carbets co-gérés par tous les CE_MANAGERs de son organisation.

Session étendue

  • session.user.organizationId ajouté (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
  • canManageCarbet(session, carbetOwnerId, linkedOrgIds=[]) :
    • ADMIN → toujours vrai
    • OWNER + session.user.id === carbetOwnerId → vrai
    • CE_MANAGER + session.user.organizationId ∈ linkedOrgIds → vrai
    • sinon faux
  • Callers historiques (sans linkedOrgIds) restent sûrs : CE_MANAGER ne peut rien gérer par défaut

createCarbet action étendue

  • 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 callers canManageCarbet (8 sites)

  • updateCarbet, setCarbetStatus, deleteCarbet, reorderMedia, deleteMedia dans espace-hote/carbets/actions.ts
  • espace-hote/carbets/[carbetId]/page.tsx
  • POST /api/carbets/[carbetId]/media

Tous chargent désormais Carbet.organizations (memberships) + passent linkedOrgIds.

Nouvelles 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, pas de duplication)
  • nouveau/page.tsxrequireApprovedOrg (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 cliquable (le lien marche même en pending, l'org peut préparer des brouillons, seule la publication est bloquée).

Test plan

  • npm test 53/53 ✓
  • typecheck / lint / build ✓
  • CE_MANAGER signup → valide org → /espace-ce/carbets/nouveau → créer carbet → vérif membership + redirect vers /espace-ce/carbets/[id]
  • Édit carbet via CE → updateCarbet OK, status PUBLISHED bloqué tant qu'aucun média
  • CE pending : bouton « Nouveau carbet » masqué, message « Publication bloquée »
  • Owner historique → /espace-hote/carbets fonctionne toujours (zéro régression)

🤖 Generated with Claude Code

## Sprint I — CRUD carbets côté CE Suite du plan CE management. Permet à un CE_MANAGER de créer/éditer/publier des carbets co-gérés par tous les CE_MANAGERs de son organisation. ### Session étendue - `session.user.organizationId` ajouté (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` - `canManageCarbet(session, carbetOwnerId, linkedOrgIds=[])` : - ADMIN → toujours vrai - OWNER + `session.user.id === carbetOwnerId` → vrai - CE_MANAGER + `session.user.organizationId ∈ linkedOrgIds` → vrai - sinon faux - Callers historiques (sans `linkedOrgIds`) restent sûrs : CE_MANAGER ne peut rien gérer par défaut ### `createCarbet` action étendue - 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 callers `canManageCarbet` (8 sites) - `updateCarbet`, `setCarbetStatus`, `deleteCarbet`, `reorderMedia`, `deleteMedia` dans `espace-hote/carbets/actions.ts` - `espace-hote/carbets/[carbetId]/page.tsx` - `POST /api/carbets/[carbetId]/media` Tous chargent désormais `Carbet.organizations` (memberships) + passent `linkedOrgIds`. ### Nouvelles 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, pas de duplication) - `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 cliquable (le lien marche même en pending, l'org peut préparer des brouillons, seule la publication est bloquée). ### Test plan - [x] `npm test` 53/53 ✓ - [x] typecheck / lint / build ✓ - [ ] CE_MANAGER signup → valide org → `/espace-ce/carbets/nouveau` → créer carbet → vérif membership + redirect vers /espace-ce/carbets/[id] - [ ] Édit carbet via CE → updateCarbet OK, status PUBLISHED bloqué tant qu'aucun média - [ ] CE pending : bouton « Nouveau carbet » masqué, message « Publication bloquée » - [ ] Owner historique → `/espace-hote/carbets` fonctionne toujours (zéro régression) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tarzzan added 1 commit 2026-06-02 23:34:48 +00:00
feat(ce): Sprint I — CRUD carbets côté CE
All checks were successful
CI / test (pull_request) Successful in 2m36s
74ea280f28
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>
tarzzan merged commit 03b740dfff into main 2026-06-02 23:34:49 +00:00
tarzzan deleted branch feat/ce-sprint-i 2026-06-02 23:34:50 +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#83
No description provided.