Fix slow GRN button and sms timeout

This commit is contained in:
Hagernesh
2026-07-09 08:59:58 +00:00
parent a811dbe0ce
commit fa5fde6b6b
2 changed files with 44 additions and 8 deletions

View File

@@ -22,6 +22,10 @@ export class SmsNotificationStrategy implements NotificationStrategy {
this.logger.debug(`Sending SMS to ${recipient} via ${url}`); this.logger.debug(`Sending SMS to ${recipient} via ${url}`);
// axios defaults to no timeout — a hanging gateway would block the caller
// (and any transaction it sits in) indefinitely. Always bound the wait.
const timeout = Number(this.configService.get<string>("SMS_TIMEOUT_MS") ?? 8000);
try { try {
const response = await axios.post( const response = await axios.post(
url, url,
@@ -34,6 +38,7 @@ export class SmsNotificationStrategy implements NotificationStrategy {
callbackUrl: "", callbackUrl: "",
}, },
{ {
timeout,
headers: { headers: {
accept: "*/*", accept: "*/*",
"Content-Type": "application/json", "Content-Type": "application/json",

View File

@@ -860,6 +860,25 @@ export class WarehouseInventoryService {
/** Bulk-receive eligible PAID bookings into a location. Skips duplicates / wrong direction. */ /** Bulk-receive eligible PAID bookings into a location. Skips duplicates / wrong direction. */
async bulkReceive(dto: BulkReceiveDto): Promise<BulkReceiveResult> { async bulkReceive(dto: BulkReceiveDto): Promise<BulkReceiveResult> {
const result: BulkReceiveResult = { receivedCount: 0, skippedCount: 0, results: [] }; const result: BulkReceiveResult = { receivedCount: 0, skippedCount: 0, results: [] };
/** Sent after the transaction commits so the gateway never blocks the receive. */
const pendingNotifications: Array<{
owner: {
phone?: string | null;
ownerName?: string | null;
bookingReference?: string | null;
grnNumber: string;
direction?: string | null;
warehouseId?: string | null;
};
booking: {
companyId?: string | null;
reference?: string | null;
hasFirstMile?: boolean;
hasLastMile?: boolean;
customerTruckAssignedAt?: string | null;
};
bookingId: string;
}> = [];
await this.dataSource.transaction(async (manager) => { await this.dataSource.transaction(async (manager) => {
await this.validateLocation(manager, { await this.validateLocation(manager, {
@@ -1032,21 +1051,33 @@ export class WarehouseInventoryService {
manager, manager,
); );
await this.notifyOwnerInventoryReceived({ // Queued, not sent here: an SMS/email round-trip inside the transaction
phone: truckEntrance?.customerPhone ?? booking.customerPhone, // holds capacity/location locks open for the whole gateway latency.
ownerName: truckEntrance?.ownerName ?? booking.customer, pendingNotifications.push({
bookingReference: truckEntrance?.edrDigitalBookingId ?? booking.reference, owner: {
grnNumber, phone: truckEntrance?.customerPhone ?? booking.customerPhone,
direction: dto.direction, ownerName: truckEntrance?.ownerName ?? booking.customer,
warehouseId: dto.warehouseId, bookingReference: truckEntrance?.edrDigitalBookingId ?? booking.reference,
grnNumber,
direction: dto.direction,
warehouseId: dto.warehouseId,
},
booking,
bookingId,
}); });
result.receivedCount += 1; result.receivedCount += 1;
result.results.push({ bookingId, status: 'RECEIVED', inventoryId: saved.id, grnNumber }); result.results.push({ bookingId, status: 'RECEIVED', inventoryId: saved.id, grnNumber });
void this.notifyTruckAssignmentNeeded(booking, bookingId);
} }
}); });
// Fan out after commit, un-awaited: the receive response must not wait on the
// SMS gateway. Both notifiers swallow their own errors.
for (const pending of pendingNotifications) {
void this.notifyOwnerInventoryReceived(pending.owner);
void this.notifyTruckAssignmentNeeded(pending.booking, pending.bookingId);
}
return result; return result;
} }