Files
suanming/debug-duplicate-records.cjs
patdelphi d1713be5f5 feat: refactor AI interpretation system and fix recordId issues
- Refactored AI interpretation table to use proper 1-to-1 relationship with reading records
- Fixed recordId parameter passing in AnalysisResultDisplay component
- Updated database schema to use reading_id instead of analysis_id
- Removed complex string ID generation logic
- Fixed TypeScript type definitions for all ID fields
- Added database migration scripts for AI interpretation refactoring
- Improved error handling and debugging capabilities
2025-08-23 23:05:13 +08:00

194 lines
6.9 KiB
JavaScript
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.
const { getDB } = require('./server/database/index.cjs');
/**
* 调试重复记录问题的脚本
* 检查是否存在AI解读后创建新历史记录的情况
*/
function debugDuplicateRecords() {
try {
// 初始化数据库连接
const { dbManager } = require('./server/database/index.cjs');
dbManager.init();
const db = getDB();
console.log('=== 调试重复记录问题 ===\n');
// 1. 检查最近的历史记录
console.log('1. 最近的历史记录 (按创建时间排序):');
const recentRecords = db.prepare(`
SELECT
id,
name,
reading_type,
created_at,
datetime(created_at, 'localtime') as local_time
FROM numerology_readings
ORDER BY created_at DESC
LIMIT 20
`).all();
recentRecords.forEach((record, index) => {
console.log(` ${index + 1}. ID: ${record.id}, name: ${record.name}, type: ${record.reading_type}, created: ${record.local_time}`);
});
// 2. 检查AI解读记录
console.log('\n2. AI解读记录:');
const aiRecords = db.prepare(`
SELECT
id,
analysis_id,
analysis_type,
created_at,
datetime(created_at, 'localtime') as local_time
FROM ai_interpretations
ORDER BY created_at DESC
`).all();
aiRecords.forEach((record, index) => {
console.log(` ${index + 1}. ID: ${record.id}, analysis_id: ${record.analysis_id}, type: ${record.analysis_type}, created: ${record.local_time}`);
});
// 3. 分析可能的重复模式
console.log('\n3. 分析重复模式:');
// 按名称和类型分组,查找可能的重复记录
const duplicateGroups = db.prepare(`
SELECT
name,
reading_type,
COUNT(*) as count,
GROUP_CONCAT(id) as ids,
GROUP_CONCAT(datetime(created_at, 'localtime')) as times
FROM numerology_readings
GROUP BY name, reading_type
HAVING COUNT(*) > 1
ORDER BY count DESC, MAX(created_at) DESC
LIMIT 10
`).all();
if (duplicateGroups.length > 0) {
console.log(' 发现可能的重复记录组:');
duplicateGroups.forEach((group, index) => {
console.log(` ${index + 1}. ${group.name} (${group.reading_type}): ${group.count}条记录`);
console.log(` IDs: ${group.ids}`);
console.log(` 创建时间: ${group.times}`);
});
} else {
console.log(' 未发现明显的重复记录组');
}
// 4. 检查时间相近的记录
console.log('\n4. 检查时间相近的记录 (5分钟内):');
const closeTimeRecords = db.prepare(`
SELECT
r1.id as id1,
r1.name as name1,
r1.reading_type as type1,
r1.created_at as time1,
r2.id as id2,
r2.name as name2,
r2.reading_type as type2,
r2.created_at as time2,
ABS(strftime('%s', r1.created_at) - strftime('%s', r2.created_at)) as time_diff_seconds
FROM numerology_readings r1
JOIN numerology_readings r2 ON r1.id < r2.id
WHERE r1.name = r2.name
AND r1.reading_type = r2.reading_type
AND ABS(strftime('%s', r1.created_at) - strftime('%s', r2.created_at)) <= 300
ORDER BY time_diff_seconds ASC
LIMIT 10
`).all();
if (closeTimeRecords.length > 0) {
console.log(' 发现时间相近的相似记录:');
closeTimeRecords.forEach((pair, index) => {
console.log(` ${index + 1}. ${pair.name1} (${pair.type1}):`);
console.log(` 记录1: ID ${pair.id1}, 时间: ${pair.time1}`);
console.log(` 记录2: ID ${pair.id2}, 时间: ${pair.time2}`);
console.log(` 时间差: ${pair.time_diff_seconds}`);
});
} else {
console.log(' 未发现时间相近的相似记录');
}
// 5. 检查AI解读与历史记录的关联情况
console.log('\n5. AI解读与历史记录关联分析:');
// 数字ID关联
const numericMatches = db.prepare(`
SELECT
ai.id as ai_id,
ai.analysis_id,
ai.analysis_type,
nr.id as record_id,
nr.name,
nr.reading_type,
datetime(ai.created_at, 'localtime') as ai_time,
datetime(nr.created_at, 'localtime') as record_time
FROM ai_interpretations ai
JOIN numerology_readings nr ON ai.analysis_id = nr.id AND ai.user_id = nr.user_id
ORDER BY ai.created_at DESC
`).all();
console.log(` 数字ID成功关联: ${numericMatches.length}`);
numericMatches.forEach((match, index) => {
console.log(` ${index + 1}. AI记录${match.ai_id} → 历史记录${match.record_id} (${match.name}, ${match.reading_type})`);
console.log(` AI创建: ${match.ai_time}, 记录创建: ${match.record_time}`);
});
// 字符串ID无法关联
const stringIdRecords = db.prepare(`
SELECT
ai.id as ai_id,
ai.analysis_id,
ai.analysis_type,
datetime(ai.created_at, 'localtime') as ai_time
FROM ai_interpretations ai
LEFT JOIN numerology_readings nr ON ai.analysis_id = nr.id AND ai.user_id = nr.user_id
WHERE nr.id IS NULL
ORDER BY ai.created_at DESC
`).all();
console.log(`\n 字符串ID无法关联: ${stringIdRecords.length}`);
stringIdRecords.forEach((record, index) => {
console.log(` ${index + 1}. AI记录${record.ai_id}, analysis_id: ${record.analysis_id}, type: ${record.analysis_type}`);
console.log(` 创建时间: ${record.ai_time}`);
});
// 6. 总结分析
console.log('\n=== 问题分析总结 ===');
const totalRecords = recentRecords.length;
const totalAI = aiRecords.length;
const duplicateCount = duplicateGroups.reduce((sum, group) => sum + (group.count - 1), 0);
console.log(`历史记录总数: ${totalRecords}`);
console.log(`AI解读记录总数: ${totalAI}`);
console.log(`可能的重复记录: ${duplicateCount}`);
console.log(`成功关联的AI解读: ${numericMatches.length}`);
console.log(`无法关联的AI解读: ${stringIdRecords.length}`);
if (stringIdRecords.length > 0) {
console.log('\n⚠ 发现问题:');
console.log(' - 存在无法关联到历史记录的AI解读');
console.log(' - 这些AI解读使用了字符串ID不对应任何历史记录');
console.log(' - 可能的原因AI解读时没有正确的recordId');
}
if (duplicateGroups.length > 0) {
console.log('\n⚠ 发现重复记录:');
console.log(' - 存在相同名称和类型的多条历史记录');
console.log(' - 可能的原因:用户多次提交相同的分析请求');
}
} catch (error) {
console.error('调试过程中发生错误:', error);
}
}
// 如果直接运行此脚本
if (require.main === module) {
debugDuplicateRecords();
}
module.exports = { debugDuplicateRecords };