Programme and Lot Editing
Summary
Admins have a full back-office view of programmes and their lots, with partial-update endpoints (PATCH) for editorial corrections. Only fields present in explicit server-side whitelists are applied — non-whitelisted fields are silently ignored. Rich-text fields go through script-tag sanitization. The editorial JSON object (pinned content, highlight flags, etc.) has its own dedicated PATCH route backed by Zod validation. Document categories in documentsVente can be patched individually by array index, and a bulk reclassification endpoint re-runs the AI classifier on all programmes.
State Diagram
stateDiagram-v2 state "Liste des programmes" as Browsing state "Détail programme" as DetailView state "Liste des lots" as LotsView state "Modification programme" as Editing state "Modification lot" as LotEditing state "Modification éditoriale" as EditorialEditing state "Modification document" as DocumentEditing [*] --> Browsing: admin opens programmes list Browsing --> DetailView: admin opens programme detail DetailView --> LotsView: admin views lots DetailView --> Editing: admin patches programme LotsView --> LotEditing: admin patches lot DetailView --> EditorialEditing: admin patches editorial DetailView --> DocumentEditing: admin patches document category Editing --> DetailView: updated programme returned LotEditing --> LotsView: updated lot returned EditorialEditing --> DetailView: updated programme returned DocumentEditing --> DetailView: updated documentsVente returned
Steps
1. List Programmes (Actor: admin)
GET /admin/programmes with optional query parameters:
q: text search onvilleandname(case-insensitive)statuses: comma-separated status filter (en_cours,livre,a_venir,retire)types: comma-separated lot type filter (filters programmes that have lots of those types)price_min,price_max: range onprixMin/prixMaxsurface_min,surface_max: range onsurfaceMin/surfaceMaxpromoteur: partial match on promoteur namepartnerId: exact partner UUID filtercursor,limit: cursor pagination (createdAt + id compound)
Returns lightweight summary fields including _count.lots and partner name.
2. Programme Detail (Actor: admin)
GET /admin/programmes/:id — full programme record including partner name. Does not include lots (separate endpoint to avoid payload bloat).
3. Programme Lots (Actor: admin)
GET /admin/programmes/:id/lots — offset pagination (page, limit). Returns { data: lots, pagination: { page, totalPages, total } }.
4. Patch Programme (Actor: admin)
PATCH /admin/programmes/:id — partial update using the PROGRAMME_PATCH_WHITELIST set (covers name, promoteur, description, location fields, all dispositifs fiscaux, display flags, rich text fields, and more). Non-whitelisted keys are silently dropped. Rich-text fields (description, texteAccroche, aProximite, prestations, presentation, immeuble, environnement) go through stripScriptTags(). Returns 400 NO_VALID_FIELDS if the body contains no whitelisted fields.
5. Patch Lot (Actor: admin)
PATCH /admin/programmes/:id/lots/:lotId — partial update using LOT_PATCH_WHITELIST (covers numeroLot, type, surface, status, all price columns, dispositif-specific prices, performance metrics). Ownership verified: lot must belong to the programme. Returns 400 NO_VALID_FIELDS if no valid fields.
6. Patch Editorial (Actor: admin)
PATCH /admin/programmes/:id/editorial — body passed to setEditorial(id, body) from lib/editorial.ts. Validated by Zod inside setEditorial(). Zod errors surface as 400 VALIDATION_ERROR.
7. Patch Document Category (Actor: admin)
PATCH /admin/programmes/:id/documents/:index with { category: string | null }. The index is 0-based position in documentsVente JSON array. category: null resets the category to “Non catégorisé”. Returns 400 INVALID_INDEX if out of range.
8. Bulk Reclassify Documents (Actor: admin)
POST /admin/programmes/reclassify-documents — iterates all programmes, runs classifyDocument(doc.nom) from lib/document-classifier.ts on each document in documentsVente. Only writes back rows where at least one category changed. Returns { programmesUpdated, programmesTotal }.
Error States
- Programme not found → 404
NOT_FOUND - Lot not found or not belonging to programme → 404
NOT_FOUND - No whitelisted fields in PATCH body → 400
NO_VALID_FIELDS - Invalid enum value in PATCH → 400
INVALID_VALUE - Zod validation error in editorial PATCH → 400
VALIDATION_ERROR - Document index out of range → 400
INVALID_INDEX
Related Processes
- partner-mapping-activation — programmes are created during ingestion triggered by partner activation
- sftp-xml-ingestion — the ingestion pipeline that populates programme and lot data