import { CsvBookingService } from '../../services/csv-booking.service'; import { Capability } from '../capability'; /** * Reservations. * * Les lectures restent cantonnees a l'appelant, sauf `list_organization_bookings` * qui demande un role d'encadrement — c'est la meme frontiere que dans * l'interface, ou seuls ADMIN et MANAGER voient l'onglet organisation. * * Les ecritures sont volontairement limitees aux actions reversibles ou * inoffensives : annuler, et supprimer une reservation impayee. Payer une * commission, envoyer une demande a un transporteur ou televerser un document * engagent un tiers ou de l'argent et restent hors de portee d'un agent. */ export function bookingsCapabilities(bookings: CsvBookingService): Capability[] { return [ { policy: { name: 'list_my_bookings', scope: 'read' }, description: "Liste les réservations de l'utilisateur authentifié, de la plus récente à la plus ancienne.", inputSchema: { type: 'object', properties: { limit: { type: 'integer', description: 'Nombre maximum de réservations.', minimum: 1, maximum: 50, default: 20, }, }, additionalProperties: false, }, handler: async (input, actor) => bookings.getUserBookings(actor.id, 1, (input.limit as number) ?? 20), }, { policy: { name: 'list_organization_bookings', scope: 'read', roles: ['ADMIN', 'MANAGER'] }, description: "Liste les réservations de toute l'organisation. Réservé aux rôles ADMIN et MANAGER.", inputSchema: { type: 'object', properties: { limit: { type: 'integer', description: 'Nombre maximum de réservations.', minimum: 1, maximum: 50, default: 20, }, }, additionalProperties: false, }, handler: async (input, actor) => bookings.getOrganizationBookings(actor.organizationId, 1, (input.limit as number) ?? 20), }, { policy: { name: 'get_booking', scope: 'read' }, description: "Détail d'une réservation : route, marchandise, transporteur, statut, documents.", inputSchema: { type: 'object', properties: { bookingId: { type: 'string', description: 'Identifiant de la réservation (UUID).' }, }, required: ['bookingId'], additionalProperties: false, }, handler: async (input, actor) => bookings.getBookingById(input.bookingId as string, actor.id), }, { policy: { name: 'booking_statistics', scope: 'read' }, description: "Répartition des réservations de l'utilisateur par statut (en attente de paiement, en attente, acceptées, refusées).", inputSchema: { type: 'object', properties: {}, additionalProperties: false }, handler: async (_input, actor) => bookings.getUserStats(actor.id), }, { policy: { name: 'cancel_booking', scope: 'write' }, description: "Annule une réservation de l'utilisateur qui n'a pas encore été acceptée par le transporteur. La réservation est conservée avec le statut annulé.", inputSchema: { type: 'object', properties: { bookingId: { type: 'string', description: 'Identifiant de la réservation (UUID).' }, }, required: ['bookingId'], additionalProperties: false, }, handler: async (input, actor) => bookings.cancelBooking(input.bookingId as string, actor.id), }, { policy: { name: 'delete_unpaid_booking', scope: 'write' }, description: "Supprime définitivement une réservation dont la commission n'a pas été payée. Sans effet sur une réservation payée, qui ne peut être qu'annulée.", inputSchema: { type: 'object', properties: { bookingId: { type: 'string', description: 'Identifiant de la réservation (UUID).' }, }, required: ['bookingId'], additionalProperties: false, }, handler: async (input, actor) => bookings.deleteBooking(input.bookingId as string, actor.id), }, ]; }