enhance booking and contract notification systems

- Added detailed logging for socket connection events in useBookingWindowSocket.
- Introduced new notification types for contract status and schedule updates.
- Updated notification visuals to include new icons for contract status.
- Enhanced notification href resolution for contract status and schedule updates.
- Implemented booking lifecycle notifier service for customer and staff notifications.
- Created contract notifier service for managing contract lifecycle notifications.
- Added end-to-end tests for booking window socket functionality.
This commit is contained in:
Marshal
2026-07-06 21:03:08 +00:00
parent 8bd00ea78a
commit 05b13e84a8
38 changed files with 1450 additions and 95 deletions

View File

@@ -9,6 +9,7 @@ import { Contract } from './entities/contract.entity';
import { ContractClearanceCycle } from './entities/contract-clearance-cycle.entity';
import { ClearanceMilestone } from './entities/clearance-milestone.entity';
import { BookingsRepository } from '../bookings/bookings.repository';
import { BookingLifecycleNotifierService } from '../bookings/booking-lifecycle-notifier.service';
import { Booking } from '../bookings/entities/booking.entity';
import type { ClearanceMetaState } from './clearance-workflow.types';
import { metaFromBooking } from './clearance-workflow.types';
@@ -34,6 +35,7 @@ export class ClearanceWorkflowService {
private readonly contractsRepository: ContractsRepository,
private readonly milestoneService: ClearanceMilestoneService,
private readonly bookingsRepository: BookingsRepository,
private readonly notifier: BookingLifecycleNotifierService,
) {}
boundaryMilestone(tradeDirection: string): string {
@@ -264,6 +266,14 @@ export class ClearanceWorkflowService {
status: 'CLEARANCE_READY',
clearanceCurrentPhase: ContractDocPhase.GlEtPostClearance,
} as never);
// Tell the customer clearance is done and operation can be requested. Load
// failure only skips the notice — the status change above already committed.
try {
const booking = await this.bookingsRepository.findByIdWithFiles(bookingId);
if (booking) this.notifier.clearanceReady(booking);
} catch {
/* notification is best-effort */
}
}
resolvePhase(