fix: harden channel retry attribution and operations UI
This commit is contained in:
@@ -122,7 +122,35 @@ function getCarrierLabel(carrier?: string | null) {
|
||||
return carrier ? (carrierLabelMap[carrier] ?? carrier) : '-';
|
||||
}
|
||||
|
||||
function buildRouteRows(record: SmsMessageRecord): RouteRow[] {
|
||||
function buildRouteRows(record: SmsMessageRecord, segmentAudits: SmsMessageSegmentAudit[]): RouteRow[] {
|
||||
if (segmentAudits.length > 0) {
|
||||
const attempts = new Map<string, SmsMessageSegmentAudit[]>();
|
||||
segmentAudits.forEach((segment) => {
|
||||
const current = attempts.get(segment.submitId) ?? [];
|
||||
current.push(segment);
|
||||
attempts.set(segment.submitId, current);
|
||||
});
|
||||
return Array.from(attempts.entries())
|
||||
.map(([submitId, segments]) => {
|
||||
const ordered = [...segments].sort((left, right) => left.segmentIndex - right.segmentIndex);
|
||||
const sentTimes = ordered.map((segment) => segment.submittedAt).filter(Boolean) as string[];
|
||||
const receiptTimes = ordered.map((segment) => segment.deliveredAt).filter(Boolean) as string[];
|
||||
const receiptCodes = Array.from(new Set(ordered.map((segment) => segment.rawStatus).filter(Boolean)));
|
||||
const submitStatuses = Array.from(new Set(ordered.map((segment) => segment.submitStatus).filter(Boolean)));
|
||||
return {
|
||||
id: submitId,
|
||||
attempt: Math.min(...ordered.map((segment) => segment.attempt)),
|
||||
channel: ordered.find((segment) => segment.channel?.name)?.channel?.name
|
||||
?? ordered.find((segment) => segment.channelId)?.channelId
|
||||
?? '-',
|
||||
sentAt: sentTimes.sort()[0],
|
||||
receiptAt: receiptTimes.sort()[receiptTimes.length - 1],
|
||||
receiptCode: receiptCodes.join(' / ') || undefined,
|
||||
submitStatus: submitStatuses.join(' / ') || undefined,
|
||||
};
|
||||
})
|
||||
.sort((left, right) => left.attempt - right.attempt);
|
||||
}
|
||||
const receipts = record.receiptRecords ?? [];
|
||||
const receiptByGatewayId = new Map<string, SmsReceiptRecord>();
|
||||
receipts.forEach((receipt) => {
|
||||
@@ -208,7 +236,7 @@ function SendDetailModal({
|
||||
segmentLoading: boolean;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const routeRows = buildRouteRows(record);
|
||||
const routeRows = buildRouteRows(record, segmentAudits);
|
||||
const sentAccessNumber = `${record.channel?.srcId ?? ''}${record.applicationExtension ?? ''}`;
|
||||
const displayStatus = getRecordStatus(record);
|
||||
const receiptNotice = getReceiptNotice(record);
|
||||
@@ -347,12 +375,26 @@ function SendDetailModal({
|
||||
);
|
||||
}
|
||||
|
||||
function dateKey(date: Date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
function defaultSmsRecordDateRange(): DateRangeValue {
|
||||
const today = new Date();
|
||||
const yesterday = new Date(today);
|
||||
yesterday.setDate(today.getDate() - 1);
|
||||
return { start: dateKey(yesterday), end: dateKey(today) };
|
||||
}
|
||||
|
||||
export function AdminSmsRecordsPage() {
|
||||
const pageSize = 25;
|
||||
const [records, setRecords] = useState<SmsMessageRecord[]>([]);
|
||||
const [enterprise, setEnterprise] = useState('all');
|
||||
const [application, setApplication] = useState('all');
|
||||
const [dateRange, setDateRange] = useState<DateRangeValue>({});
|
||||
const [dateRange, setDateRange] = useState<DateRangeValue>(defaultSmsRecordDateRange);
|
||||
const [phoneKeyword, setPhoneKeyword] = useState('');
|
||||
const [contentKeyword, setContentKeyword] = useState('');
|
||||
const [channelKeyword, setChannelKeyword] = useState('');
|
||||
@@ -445,14 +487,15 @@ export function AdminSmsRecordsPage() {
|
||||
const visibleRows = filteredRows.slice((currentPage - 1) * pageSize, currentPage * pageSize);
|
||||
|
||||
function resetFilters() {
|
||||
const defaultDateRange = defaultSmsRecordDateRange();
|
||||
setEnterprise('all');
|
||||
setApplication('all');
|
||||
setDateRange({});
|
||||
setDateRange(defaultDateRange);
|
||||
setPhoneKeyword('');
|
||||
setContentKeyword('');
|
||||
setChannelKeyword('');
|
||||
setStatus('all');
|
||||
loadData({});
|
||||
loadData({ queuedAtFrom: defaultDateRange.start, queuedAtTo: defaultDateRange.end });
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user