45 lines
2.6 KiB
JavaScript
45 lines
2.6 KiB
JavaScript
const MODULE = 'dashboard'
|
|||
|
|
const OPTIONS = { scenario: 'platform-live-dashboard', deploymentBlocker: true }
|
||
|
|
const integer = value => (typeof value === 'number' || (typeof value === 'string' && /^\d+$/.test(value)))
|
||
|
|
&& Number.isSafeInteger(Number(value)) && Number(value) >= 0
|
||
|
|
const decimal = value => (typeof value === 'number' || (typeof value === 'string' && /^\d+(?:\.\d+)?$/.test(value)))
|
||
|
|
&& Number.isFinite(Number(value)) && Number(value) >= 0
|
||
|
|
|
||
|
|
export function validOperationalMetrics(value) {
|
||
|
|
return Boolean(value && ['inTransitContainerCount', 'unknownContainerTypeCount', 'pendingCustomsOrderCount']
|
||
|
|
.every(key => integer(value[key])) && decimal(value.inTransitTeu)
|
||
|
|
&& Number(value.unknownContainerTypeCount) <= Number(value.inTransitContainerCount)
|
||
|
|
&& typeof value.asOf === 'string' && Number.isFinite(Date.parse(value.asOf)))
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function run(context) {
|
||
|
|
const proof = context.createdResources.dashboard = { status: 'CHECKING', readOnly: true }
|
||
|
|
const check = (label, response, condition) => {
|
||
|
|
context.assert(MODULE, label, response, Boolean(condition), '', OPTIONS)
|
||
|
|
if (!condition) throw Error(label)
|
||
|
|
}
|
||
|
|
const read = async (path, label) => {
|
||
|
|
const response = await context.request('GET', path)
|
||
|
|
const data = context.apiSuccess(MODULE, label, response, '', OPTIONS)
|
||
|
|
check(`${label}正式HTTP成功`, response, response.http === 200 && String(response.body?.code) === '200' && data != null)
|
||
|
|
return { response, data }
|
||
|
|
}
|
||
|
|
const metrics = await read('/api/platform/v1/first-leg/dashboard/operational-metrics', '读取首页实时运营指标')
|
||
|
|
check('在途柜量与待清关指标完整且非负,不以缺失值冒充零', metrics.response, validOperationalMetrics(metrics.data))
|
||
|
|
proof.operationalMetrics = metrics.data
|
||
|
|
// The deployed TEST services and the desktop page use the Shanghai business day.
|
||
|
|
const date = new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString().slice(0, 10)
|
||
|
|
const query = new URLSearchParams({ createdFrom: `${date}T00:00:00.000`, createdTo: `${date}T23:59:59.999`, page: '1', size: '1' })
|
||
|
|
for (const [key, path, label] of [
|
||
|
|
['todayNewOrderCount', `/api/platform/v1/orders?${query}`, '读取今日新运单总数'],
|
||
|
|
['activeCustomerCount', '/api/platform/v1/iam/tenants?page=1&size=1&status=ACTIVE', '读取启用客户总数'],
|
||
|
|
]) {
|
||
|
|
const { response, data } = await read(path, label)
|
||
|
|
check(`${label}使用服务端分页总数`, response, integer(data.total) && Array.isArray(data.records)
|
||
|
|
&& data.records.length <= 1 && Number(data.total) >= data.records.length)
|
||
|
|
proof[key] = data.total
|
||
|
|
}
|
||
|
|
proof.businessDate = date
|
||
|
|
proof.status = 'VERIFIED'
|
||
|
|
}
|