45 lines
3.2 KiB
JavaScript
45 lines
3.2 KiB
JavaScript
// This checks live, scoped evidence supplied by the TEST fault executor.
|
|||
|
|
// It never accepts historical reports or initiates event replay itself.
|
||
|
|
const identifier = value => typeof value === 'string' && /^[1-9][0-9]{0,19}$/.test(value)
|
||
|
|
const eventIdentifier = value => typeof value === 'string'
|
||
|
|
&& /^(?:[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}|[0-9A-HJKMNP-TV-Z]{26})$/i.test(value)
|
||
|
|
const hash = value => typeof value === 'string' && /^sha256:[0-9a-f]{64}$/i.test(value)
|
||
|
|
const sortedIds = rows => [...rows].sort()
|
||
|
|
|
||
|
|
export function validDirectDeliveryReplayProof(proof, scope) {
|
||
|
|
if (!proof || proof.readOnly !== true || proof.marker !== scope.marker
|
||
|
|
|| !identifier(scope.loadingPlanId) || !identifier(scope.customerId)
|
||
|
|
|| proof.loadingPlanId !== scope.loadingPlanId || proof.customerId !== scope.customerId
|
||
|
|
|| proof.containerBookingId !== scope.containerBookingId) return false
|
||
|
|
const { producer, consumer, attempts, proxyRecords, beforeRetry, afterRetry, retryAudit } = proof
|
||
|
|
if (!eventIdentifier(producer?.eventId) || !hash(producer?.payloadHash)
|
||
|
|
|| !identifier(producer?.entryId) || producer.publishStatus !== 'PUBLISHED'
|
||
|
|
|| producer.eventType !== 'FirstLegLoadingPlanCompleted'
|
||
|
|
|| consumer?.eventId !== producer.eventId || consumer?.payloadHash !== producer.payloadHash
|
||
|
|
|| consumer?.status !== 'PROCESSED' || consumer?.count !== 1) return false
|
||
|
|
if (!Array.isArray(attempts) || attempts.length !== 13
|
||
|
|
|| new Set(attempts.map(row => row.attemptId)).size !== attempts.length
|
||
|
|
|| attempts.some(row => !row.attemptId || row.eventId !== producer.eventId
|
||
|
|
|| row.entryId !== producer.entryId || row.targetName !== 'lastleg-service/internal/lastleg/events')
|
||
|
|
|| attempts.at(-1)?.outcome !== 'DUPLICATE'
|
||
|
|
|| attempts[11]?.outcome !== 'DEAD'
|
||
|
|
|| attempts.slice(0, 11).some(row => row.outcome !== 'RETRY')) return false
|
||
|
|
if (!Array.isArray(proxyRecords) || proxyRecords.length !== 13
|
||
|
|
|| proxyRecords.some(row => row.matched !== true || row.eventId !== producer.eventId
|
||
|
|
|| row.payloadHash !== producer.payloadHash)
|
||
|
|
|| !proxyRecords.some(row => row.outcome === 'APPLIED' && row.errorCode === 'ACK_LOSS_INJECTED')
|
||
|
|
|| !proxyRecords.some(row => row.outcome === 'DUPLICATE' && row.errorCode === 'ACK_LOSS_INJECTED')) return false
|
||
|
|
if (retryAudit?.eventId !== producer.eventId || retryAudit?.payloadHash !== producer.payloadHash
|
||
|
|
|| retryAudit?.entryId !== producer.entryId || !retryAudit.requestId
|
||
|
|
|| retryAudit.previousFailures !== 12 || beforeRetry?.publishStatus !== 'DEAD'
|
||
|
|
|| beforeRetry?.failedAttempts !== 12 || afterRetry?.publishStatus !== 'PUBLISHED'
|
||
|
|
|| beforeRetry.eventId !== producer.eventId || afterRetry.eventId !== producer.eventId
|
||
|
|
|| beforeRetry.payloadHash !== producer.payloadHash || afterRetry.payloadHash !== producer.payloadHash) return false
|
||
|
|
const before = beforeRetry.businessOrderIds, after = afterRetry.businessOrderIds
|
||
|
|
return Array.isArray(before) && Array.isArray(after) && before.length > 0
|
||
|
|
&& before.every(identifier) && after.every(identifier)
|
||
|
|
&& new Set(before).size === before.length && new Set(after).size === after.length
|
||
|
|
&& JSON.stringify(sortedIds(before)) === JSON.stringify(sortedIds(after))
|
||
|
|
&& proof.restored === true
|
||
|
|
}
|