feat(M01-B): 增加迁移执行器与旧库只读兼容层

This commit is contained in:
Codex
2026-06-18 09:31:29 +08:00
parent 3cabb71de5
commit e069c50331
8 changed files with 487 additions and 1 deletions
@@ -0,0 +1,66 @@
import assert from 'node:assert/strict';
import { LegacyReadRepository } from '../dist/db/legacy-read-repository.js';
const calls = [];
const fakePool = {
async query(sql, parameters) {
calls.push({ sql, parameters });
return [[{
legacyId: '7',
tenantId: '2',
parentId: '3',
name: 'Room A',
code: 'A01',
status: 'OPEN',
startAt: null,
endAt: null
}], []];
}
};
const repository = new LegacyReadRepository(fakePool);
const rooms = await repository.listRooms({ tenantId: 2, parentId: 3, limit: 25 });
assert.equal(rooms.length, 1);
assert.equal(calls.length, 1);
assert.match(calls[0].sql, /FROM `member_room_info`/);
assert.match(calls[0].sql, /`tenant_id` = \?/);
assert.match(calls[0].sql, /`store_id` = \?/);
assert.match(calls[0].sql, /ORDER BY `id` ASC LIMIT \?/);
assert.deepEqual(calls[0].parameters, [2, 3, 25]);
assert.doesNotMatch(calls[0].sql, /\b(?:INSERT|UPDATE|DELETE|REPLACE)\b/i);
await assert.rejects(
() => repository.listStores({ tenantId: 2, limit: 501 }),
/between 1 and 500/
);
const unsafeRepository = new LegacyReadRepository(fakePool, {
stores: {
table: 'member_store_info; DROP TABLE users',
idColumn: 'id',
tenantColumn: 'tenant_id'
},
rooms: {
table: 'member_room_info',
idColumn: 'id',
tenantColumn: 'tenant_id'
},
orders: {
table: 'member_order_info',
idColumn: 'id',
tenantColumn: 'tenant_id'
},
devices: {
table: 'member_device_info',
idColumn: 'id',
tenantColumn: 'tenant_id'
}
});
await assert.rejects(
() => unsafeRepository.listStores({ tenantId: 2 }),
/Unsafe legacy SQL identifier/
);
console.log('PASS: legacy read-only repository contracts are present.');