Files
AIclinicalresearch/backend/src/tests/test-postgres-cache.ts
HaHafeng fa72beea6c feat(platform): Complete Postgres-Only architecture refactoring (Phase 1-7)
Major Changes:
- Implement Platform-Only architecture pattern (unified task management)
- Add PostgresCacheAdapter for unified caching (platform_schema.app_cache)
- Add PgBossQueue for job queue management (platform_schema.job)
- Implement CheckpointService using job.data (generic for all modules)
- Add intelligent threshold-based dual-mode processing (THRESHOLD=50)
- Add task splitting mechanism (auto chunk size recommendation)
- Refactor ASL screening service with smart mode selection
- Refactor DC extraction service with smart mode selection
- Register workers for ASL and DC modules

Technical Highlights:
- All task management data stored in platform_schema.job.data (JSONB)
- Business tables remain clean (no task management fields)
- CheckpointService is generic (shared by all modules)
- Zero code duplication (DRY principle)
- Follows 3-layer architecture principle
- Zero additional cost (no Redis needed, save 8400 CNY/year)

Code Statistics:
- New code: ~1750 lines
- Modified code: ~500 lines
- Test code: ~1800 lines
- Documentation: ~3000 lines

Testing:
- Unit tests: 8/8 passed
- Integration tests: 2/2 passed
- Architecture validation: passed
- Linter errors: 0

Files:
- Platform layer: PostgresCacheAdapter, PgBossQueue, CheckpointService, utils
- ASL module: screeningService, screeningWorker
- DC module: ExtractionController, extractionWorker
- Tests: 11 test files
- Docs: Updated 4 key documents

Status: Phase 1-7 completed, Phase 8-9 pending
2025-12-13 16:10:04 +08:00

117 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 测试 PostgresCacheAdapter
*
* 运行方式:
* npx ts-node src/tests/test-postgres-cache.ts
*/
import { PostgresCacheAdapter } from '../common/cache/PostgresCacheAdapter.js';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function testPostgresCache() {
console.log('🚀 开始测试 PostgresCacheAdapter...\n');
const cache = new PostgresCacheAdapter(prisma);
try {
// ========== 测试 1: 基本读写 ==========
console.log('📝 测试 1: 基本读写');
await cache.set('test:key1', { name: 'Alice', age: 25 }, 3600);
const value1 = await cache.get('test:key1');
console.log(' ✅ 写入并读取:', value1);
console.assert(value1?.name === 'Alice', '❌ 读取失败');
// ========== 测试 2: 过期机制 ==========
console.log('\n⏰ 测试 2: 过期机制');
await cache.set('test:expire', { data: 'temp' }, 2); // 2秒后过期
console.log(' 写入缓存2秒后过期...');
await new Promise(resolve => setTimeout(resolve, 3000));
const expiredValue = await cache.get('test:expire');
console.log(' ✅ 3秒后读取:', expiredValue);
console.assert(expiredValue === null, '❌ 过期机制失败');
// ========== 测试 3: 批量操作 ==========
console.log('\n📦 测试 3: 批量操作');
await cache.mset([
{ key: 'test:batch1', value: { id: 1 } },
{ key: 'test:batch2', value: { id: 2 } },
{ key: 'test:batch3', value: { id: 3 } },
], 3600);
const batchValues = await cache.mget(['test:batch1', 'test:batch2', 'test:batch3']);
console.log(' ✅ 批量写入并读取:', batchValues);
console.assert(batchValues.length === 3, '❌ 批量操作失败');
// ========== 测试 4: 删除操作 ==========
console.log('\n🗑 测试 4: 删除操作');
await cache.set('test:delete', { data: 'will be deleted' }, 3600);
await cache.delete('test:delete');
const deletedValue = await cache.get('test:delete');
console.log(' ✅ 删除后读取:', deletedValue);
console.assert(deletedValue === null, '❌ 删除失败');
// ========== 测试 5: has() 方法 ==========
console.log('\n🔍 测试 5: has() 方法');
await cache.set('test:exists', { data: 'exists' }, 3600);
const keyExists = await cache.has('test:exists');
const keyNotExists = await cache.has('test:not-exists');
console.log(' ✅ 存在的key:', keyExists);
console.log(' ✅ 不存在的key:', keyNotExists);
console.assert(keyExists === true && keyNotExists === false, '❌ has()失败');
// ========== 测试 6: 缓存清理 ==========
console.log('\n🧹 测试 6: 过期缓存自动删除');
// 创建一个已过期的缓存expiresAt在过去
await prisma.appCache.create({
data: {
key: 'test:expired1',
value: { data: 'old' },
expiresAt: new Date(Date.now() - 10000) // 10秒前过期
}
});
console.log(' 创建了一个已过期的缓存...');
// 尝试读取(应该触发懒删除)
const expiredData = await cache.get('test:expired1');
console.log(' 尝试读取过期数据:', expiredData);
console.assert(expiredData === null, '❌ 过期数据应返回null');
// 验证已被删除
const recordExists = await prisma.appCache.findUnique({
where: { key: 'test:expired1' }
});
console.log(` ✅ 过期数据已自动删除: ${recordExists === null ? '是' : '否'}`);
// ========== 清理测试数据 ==========
console.log('\n🧹 清理测试数据...');
await prisma.appCache.deleteMany({
where: {
key: { startsWith: 'test:' }
}
});
console.log(' ✅ 清理完成');
console.log('\n🎉 所有测试通过!\n');
} catch (error) {
console.error('❌ 测试失败:', error);
throw error;
} finally {
await prisma.$disconnect();
}
}
// 运行测试
testPostgresCache()
.then(() => {
console.log('✅ PostgresCacheAdapter 测试完成');
process.exit(0);
})
.catch((error) => {
console.error('❌ 测试失败:', error);
process.exit(1);
});