From 8f0c61155da0b5a9f2b8dfd816bc10d4a3ce0cee Mon Sep 17 00:00:00 2001 From: Flamur Maliqi Date: Sat, 15 Aug 2026 17:03:53 +0300 Subject: [PATCH] fix(pms): accept property-created manual bookings [VAY-1260] --- ...okingCommandRepository.integration.test.ts | 29 ++++++++++++++++++- .../domains/pmsManualBookingPersistence.ts | 15 ++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/apps/api/src/domains/pmsManualBookingCommandRepository.integration.test.ts b/apps/api/src/domains/pmsManualBookingCommandRepository.integration.test.ts index 1976be5bf3..ffe09315f0 100644 --- a/apps/api/src/domains/pmsManualBookingCommandRepository.integration.test.ts +++ b/apps/api/src/domains/pmsManualBookingCommandRepository.integration.test.ts @@ -162,6 +162,29 @@ describe.skipIf(!TEST_DATABASE_URL)("target manual-booking PostgreSQL transactio commandId: input.commandId, }, }); + const acceptance = await admin.query( + `SELECT event_type AS "eventType", from_status AS "fromStatus", + to_status AS "toStatus", actor_type AS "actorType", + actor_user_id::text AS "actorUserId", public_visible AS "publicVisible", + public_message AS "publicMessage", event_payload AS payload, + occurred_at = $2::timestamptz AS "occurredAtMatches" + FROM booking.booking_status_events + WHERE guest_booking_id = $1::uuid AND event_type = 'guest_booking.accepted'`, + [created.guestBookingId, acceptedAt.toISOString()], + ); + expect(acceptance.rows).toEqual([ + { + eventType: "guest_booking.accepted", + fromStatus: null, + toStatus: "confirmed", + actorType: "property_user", + actorUserId: actorId, + publicVisible: false, + publicMessage: null, + payload: { contractVersion: "pms-manual-booking.v1" }, + occurredAtMatches: true, + }, + ]); const financeAttribution = await admin.query( `SELECT booking_channel AS channel, direct_booking_source AS source FROM booking.finance_booking_attribution WHERE guest_booking_id = $1::uuid`, @@ -188,7 +211,11 @@ describe.skipIf(!TEST_DATABASE_URL)("target manual-booking PostgreSQL transactio ); expect(projection).toMatchObject({ stay: { checkIn: "2027-01-01", checkOut: "2027-01-04", adults: 3, children: 0 }, - primaryGuest: { specialRequests: "Quiet room" }, + primaryGuest: { + email: "ada@example.test", + phone: "+306900000000", + specialRequests: "Quiet room", + }, addOns: [{ addonId, name: "Breakfast", quantity: 1 }], payment: { expectedMethod: "cash", status: "unpaid" }, assignments: [ diff --git a/apps/api/src/domains/pmsManualBookingPersistence.ts b/apps/api/src/domains/pmsManualBookingPersistence.ts index de6cb84fb5..32c4825474 100644 --- a/apps/api/src/domains/pmsManualBookingPersistence.ts +++ b/apps/api/src/domains/pmsManualBookingPersistence.ts @@ -125,6 +125,21 @@ async function persistBookingFacts( command.contractVersion, ], ); + await transaction.query( + `INSERT INTO booking.booking_status_events ( + guest_booking_id, event_type, from_status, to_status, actor_type, + actor_user_id, public_visible, event_payload, occurred_at + ) VALUES ( + $1::uuid, 'guest_booking.accepted', NULL, 'confirmed', 'property_user', + $2::uuid, FALSE, jsonb_build_object('contractVersion', $3::text), $4::timestamptz + )`, + [ + guestBookingId, + command.audit.actor.userId, + command.contractVersion, + command.audit.requestedAt, + ], + ); await insertGuest(transaction, command, guestBookingId); await insertAddons(transaction, command, guestBookingId, preview); return { guestBookingId, bookingReference, total, checkIn, checkOut };