1'use strict';23// What generated import code records for each importBookingsAddOn / importBooking result: the4// attempt-journal status (and crosswalk target), and the cutover operator actions for the5// completion report, which the website handoff carries. Deterministic, so no run decides it.6//7// const row = bookingsJournalRow('bookings/booking', result, { sourceId });8// ...append the attempt row (and a crosswalk row when row.targetId and status is imported)...9// createCompletionReport({ ..., operatorActions: [...own, ...bookingsOperatorActions(entity, rows)] })10//11// An outcome whose write may have landed is never a failure: `unknown-outcome` is12// succeeded_unverified, so recovery reads Wix back instead of re-sending.1314const
40 return { status: 'succeeded_unverified', targetId: null, failure: f('unresolved', 'unknown-outcome', 'The create may have landed; read Wix back before any re-send.') };
41 case 'partially-written':
42 // The booking exists and a confirm or cancel step failed, or the add-on exists and placing it
43 // in a service's group failed. A re-run resumes it by its key (the add-on by its fields).
45 ? 'The booking exists but a status step failed; re-run to resume it.'
46 : 'The add-on exists but placing it in a service group failed; re-run to place it.') };
47 case 'target-read-failed':
48 return { status: 'failed_retryable', targetId: null, failure: f('failed_retryable', result.error?.applicationErrorCode || 'target-read-failed', 'The lookup before create failed; nothing was written.') };
49 case 'reconciliation-ambiguous':
50 case 'target-drift':
51 case 'read-back-mismatch':
52 return { status: 'needs_verification', targetId, failure: f('unresolved', result.outcome, 'Wix holds a record for this source row that the writer could not confirm; a cutover operator decides.') };
53 case 'class-session-missing':
54 return { status: 'failed_terminal', targetId: null, failure: f('failed_terminal', 'class-session-missing', 'A class-session booking is not imported: no import produces the session.') };
55 case 'failed':
56 return result.error?.outcomeKnown === false
57 ? { status: 'succeeded_unverified', targetId: null, failure: f('unresolved', 'unknown-outcome', 'The create may have landed; read Wix back before any re-send.') }
69 action: 'Some add-ons were imported but are not bookable: their service already shows 7 add-ons, the Wix limit. In Business Manager > Bookings > Services, open each listed service and choose which add-ons customers see.',
70 deadlineReason: 'Customers cannot pick these extras until they are in a group.',
71 resolutionEvidence: 'Each listed service shows the add-ons the merchant chose.',
72 },
73 'bookings-record-unconfirmed': {
74 severity: 'high',
75 action: 'Wix holds a record for these source rows that the import could not confirm (a duplicate, a change in the source after import, or a read-back that differs). Compare each listed Wix record with the source in Business Manager, then keep, fix or delete it.',
76 deadlineReason: 'A duplicate or stale booking or add-on would show to customers and staff.',
77 resolutionEvidence: 'Each listed record matches the source, or was removed.',
81 action: 'Bookings of class sessions were not imported. In Business Manager > Bookings, create the class session if needed, then add the listed customers to it.',
82 deadlineReason: 'These customers expect a place in the class.',
83 resolutionEvidence: 'Each listed customer is booked into the class session, or the merchant accepted the loss.',
87 if (!ENTITIES.has(entity)) throw new Error(`bookingsOperatorActions: unknown entity ${entity}`);
88 const ids = { 'add-on-ungrouped': new Set(), 'bookings-record-unconfirmed': new Set(), 'class-session-booking-not-imported': new Set() };
89 for (const { sourceId, result } of results || []) {
90 const target = targetOf(entity, result);
91 if (entity === 'bookings/service-add-on' && ['written', 'reconciled-existing'].includes(result.outcome) && result.ungroupedServiceIds?.length) for (const serviceId of result.ungroupedServiceIds) ids['add-on-ungrouped'].add(`${target}@${serviceId}`);
92 if (['reconciliation-ambiguous', 'target-drift', 'read-back-mismatch'].includes(result.outcome)) for (const id of [target, ...(result.candidateIds || [])].filter(Boolean)) ids['bookings-record-unconfirmed'].add(id);
93 if (result.outcome === 'class-session-missing') ids['class-session-booking-not-imported'].add(String(sourceId));