feat: 升级结构化计分可信度

This commit is contained in:
2026-06-23 02:21:09 +02:00
parent e3825c5a4e
commit ca77aa0896
10 changed files with 705 additions and 139 deletions
+30 -1
View File
@@ -10,6 +10,7 @@ import {
encryptRecordForDevice,
isEncryptedRecord,
} from '@/lib/record-crypto';
import { buildScoreSummary } from '@/lib/score-summary';
const DB_NAME = 'mindscope';
const DB_VERSION = 1;
@@ -47,6 +48,34 @@ function requestResult<T>(request: IDBRequest<T>): Promise<T> {
});
}
function normalizeRecord(record: AssessmentRecord): AssessmentRecord {
if (record.questionnaireVersion && record.scoreVersion && record.scoreSummary?.questionnaireVersion) {
return record;
}
const scoreSummary = buildScoreSummary(
record.questionnaireId,
record.answers.map((answer) => answer.value),
);
return {
...record,
questionnaireVersion: record.questionnaireVersion || scoreSummary.questionnaireVersion,
scoreVersion: record.scoreVersion || scoreSummary.scoreVersion,
scoreSummary: {
...scoreSummary,
...record.scoreSummary,
questionnaireVersion: record.scoreSummary?.questionnaireVersion || scoreSummary.questionnaireVersion,
scoreVersion: record.scoreSummary?.scoreVersion || scoreSummary.scoreVersion,
min: record.scoreSummary?.min ?? scoreSummary.min,
max: record.scoreSummary?.max ?? scoreSummary.max,
reverseItems: record.scoreSummary?.reverseItems || scoreSummary.reverseItems,
direction: record.scoreSummary?.direction || scoreSummary.direction,
highScoreMeaning: record.scoreSummary?.highScoreMeaning || scoreSummary.highScoreMeaning,
thresholds: record.scoreSummary?.thresholds || scoreSummary.thresholds,
scoringStatus: record.scoreSummary?.scoringStatus || scoreSummary.scoringStatus,
},
};
}
export function getActiveProfileId() {
return localStorage.getItem(ACTIVE_PROFILE_KEY);
}
@@ -150,7 +179,7 @@ export async function getRecords(profileId?: string): Promise<AssessmentRecord[]
db.close();
const typedRecords = storedRecords as Array<AssessmentRecord | EncryptedAssessmentRecord>;
const records = await Promise.all(typedRecords.map(decryptDeviceRecord));
const records = (await Promise.all(typedRecords.map(decryptDeviceRecord))).map(normalizeRecord);
const plaintextRecords = typedRecords.filter((record) => !isEncryptedRecord(record)) as AssessmentRecord[];
if (plaintextRecords.length) {
await migratePlaintextRecords(plaintextRecords);