feat(M06-D): 接入控制箱与Sub-1G门锁业务控制
This commit is contained in:
@@ -1727,6 +1727,62 @@ async function assertIotMessages(pool, context) {
|
||||
FROM qipai_iot_dead_letters WHERE topic = '/invalid/topic'`
|
||||
);
|
||||
assert.deepEqual(deadRows, [{ errorCode: 'MQTT_TOPIC_INVALID', receiveCount: 1 }]);
|
||||
|
||||
await service.handle(`/devicesend/${device.deviceId}`, Buffer.from(JSON.stringify({
|
||||
DeviceID: device.deviceId,
|
||||
event: 'record',
|
||||
type: 'card',
|
||||
state: 'open',
|
||||
content: 'PRIVATE-CARD-001',
|
||||
battery: 9,
|
||||
timestamp: 1782120001
|
||||
})));
|
||||
const [recordRows] = await pool.query(
|
||||
`SELECT JSON_UNQUOTE(JSON_EXTRACT(raw_payload, '$.content')) AS content,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(raw_payload, '$.contentHash')) AS contentHash
|
||||
FROM qipai_iot_device_events
|
||||
WHERE tenant_id = ? AND event_type = 'record'`,
|
||||
[context.tenantId]
|
||||
);
|
||||
assert.equal(recordRows[0].content, null);
|
||||
assert.match(recordRows[0].contentHash, /^[a-f0-9]{64}$/);
|
||||
const [alertRows] = await pool.query(
|
||||
`SELECT alert_type AS alertType, severity
|
||||
FROM qipai_device_alerts
|
||||
WHERE tenant_id = ? AND device_id = ? AND status = 'OPEN'`,
|
||||
[context.tenantId, device.id]
|
||||
);
|
||||
assert.deepEqual(alertRows, [{ alertType: 'LOW_BATTERY', severity: 'HIGH' }]);
|
||||
|
||||
await service.createCommand({
|
||||
tenantId: context.tenantId,
|
||||
assetId: String(device.id),
|
||||
storeId: String(device.storeId),
|
||||
roomId: String(device.roomId),
|
||||
commandId: '1782120000002',
|
||||
commandType: 'AddDevice',
|
||||
payload: { action: 'AddDevice', id: '1782120000002', timeout: 60 },
|
||||
traceId: 'm06d-pair-test'
|
||||
});
|
||||
await service.markPublished(context.tenantId, '1782120000002');
|
||||
await service.handle(`/devicesend/${device.deviceId}`, Buffer.from(JSON.stringify({
|
||||
DeviceID: device.deviceId,
|
||||
id: '1782120000002',
|
||||
action: 'AddDevice',
|
||||
result: 'ok',
|
||||
subID: 'SUB-AUTO-001',
|
||||
subtype: '14',
|
||||
timestamp: 1782120002
|
||||
})));
|
||||
const [linkRows] = await pool.query(
|
||||
`SELECT l.sub_id AS subId, l.subtype, d.model
|
||||
FROM qipai_device_links l
|
||||
INNER JOIN qipai_devices d
|
||||
ON d.tenant_id = l.tenant_id AND d.id = l.child_device_id
|
||||
WHERE l.tenant_id = ? AND l.parent_device_id = ? AND l.sub_id = 'SUB-AUTO-001'`,
|
||||
[context.tenantId, device.id]
|
||||
);
|
||||
assert.deepEqual(linkRows, [{ subId: 'SUB-AUTO-001', subtype: '14', model: '701C' }]);
|
||||
}
|
||||
|
||||
const config = loadConfig();
|
||||
@@ -1797,7 +1853,7 @@ try {
|
||||
await executeMigrationPlan(pool, plans.down);
|
||||
assert.deepEqual(await readCoreTables(pool), []);
|
||||
await assertLegacyCompatibility(pool);
|
||||
console.log('PASS: down removed all M01-B through M06-C tables.');
|
||||
console.log('PASS: down removed all M01-B through M06-C migration tables.');
|
||||
|
||||
await executeMigrationPlan(pool, plans.up);
|
||||
await executeMigrationPlan(pool, plans.verify);
|
||||
@@ -1925,6 +1981,10 @@ try {
|
||||
'QoS 1 duplicate event receive count',
|
||||
'ACK correlation without duplicate side effects',
|
||||
'invalid Topic dead-letter persistence'
|
||||
,
|
||||
'door record credential hashing and masking',
|
||||
'low-battery alert upsert',
|
||||
'AddDevice ACK creates 701C parent-child topology'
|
||||
]
|
||||
}, null, 2));
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user