Acheteur Favorites
Summary
Authenticated acheteurs can save programmes or individual lots as favorites for later reference. Each favorite record links an acheteur to exactly one target — either a programmeId or a lotId, never both. Favorites are returned in reverse chronological order and include a lightweight join to the target’s key fields (name, price, surface, status). Duplicates are rejected (Prisma unique constraint P2002). Favorites cascade-delete when the acheteur account is deleted.
State Diagram
stateDiagram-v2 state "Aucun favori" as NoFavorites state "Favori ajouté" as FavoriteAdded state "Favori supprimé" as FavoriteRemoved [*] --> NoFavorites: authenticated acheteur, empty list NoFavorites --> FavoriteAdded: acheteur adds a favourite FavoriteAdded --> FavoriteAdded: acheteur adds another favourite FavoriteAdded --> FavoriteRemoved: acheteur removes a favourite FavoriteRemoved --> NoFavorites: list empty again FavoriteAdded --> [*]: acheteur lists favourites NoFavorites --> [*]: acheteur lists favourites (empty)
Steps
1. List Favorites (Actor: acheteur)
GET /acheteur/favorites returns all favorites for the authenticated acheteur. Each favorite includes:
- For a programme favorite:
{ id, slug, name, ville, prixMin, prixMax, photos }. - For a lot favorite:
{ id, type, surface, price, status, isComplete }.
Ordered by createdAt DESC.
Outcome: { data: favorites[] }.
2. Add Favorite (Actor: acheteur)
POST /acheteur/favorites accepts { programmeId?, lotId? }.
Exactly one of programmeId or lotId must be provided — if neither or both are given, returns 400 INVALID_FAVORITE.
The favorite is created in prisma.favorite. On Prisma error:
P2002(unique constraint) → 409DUPLICATE— “Already in favorites”.P2003(foreign key violation, target doesn’t exist) → 400NOT_FOUND— “Programme or lot not found”.
Outcome: 201 { data: favorite } on success.
3. Remove Favorite (Actor: acheteur)
DELETE /acheteur/favorites/:id first checks that the favorite exists and belongs to the requesting acheteur (ownership check via findFirst { where: { id, acheteurId } }). If not found or not owned → 404 NOT_FOUND.
On success, the row is deleted.
Outcome: { success: true }.
Error States
- Neither programmeId nor lotId provided → 400
INVALID_FAVORITE - Both programmeId and lotId provided → 400
INVALID_FAVORITE - Programme or lot does not exist (FK violation) → 400
NOT_FOUND - Favorite already exists for this (acheteur, target) → 409
DUPLICATE - Favorite not found or not owned by acheteur → 404
NOT_FOUND
Related Processes
- browsing — favorites are typically added from programme/property detail pages
- registration-email-verification — authentication required; this process depends on a verified account existing
- account-deletion — all favorites are cascade-deleted when the account is anonymized