f96fdcb3b9
Lock health recording behind confirm-only state machines, reject public publishes for the health category, and ship the 14-day experiment Page Data templates with tests. Co-authored-by: Cursor <cursoragent@cursor.com>
50 lines
1.4 KiB
JavaScript
50 lines
1.4 KiB
JavaScript
export const HEALTH_SYMPTOM_CODES = Object.freeze([
|
|
'none',
|
|
'dizziness',
|
|
'headache',
|
|
'chest_tightness',
|
|
'palpitation',
|
|
'fatigue',
|
|
'shortness_of_breath',
|
|
'leg_edema',
|
|
'insomnia',
|
|
'other',
|
|
]);
|
|
|
|
export const HEALTH_SYMPTOM_LABELS = Object.freeze({
|
|
none: '无',
|
|
dizziness: '头晕',
|
|
headache: '头痛',
|
|
chest_tightness: '胸闷',
|
|
palpitation: '心慌心悸',
|
|
fatigue: '乏力',
|
|
shortness_of_breath: '气短',
|
|
leg_edema: '下肢水肿',
|
|
insomnia: '失眠',
|
|
other: '其他',
|
|
});
|
|
|
|
export const HEALTH_SYMPTOM_SEVERITIES = Object.freeze([1, 2, 3]);
|
|
|
|
export function normalizeSymptomCode(value) {
|
|
const raw = String(value ?? '').trim();
|
|
if (HEALTH_SYMPTOM_CODES.includes(raw)) return raw;
|
|
const byLabel = Object.entries(HEALTH_SYMPTOM_LABELS).find(([, label]) => label === raw);
|
|
return byLabel ? byLabel[0] : null;
|
|
}
|
|
|
|
export function assertSymptomRecord({ code, severity, note = '' } = {}) {
|
|
const symptom = normalizeSymptomCode(code);
|
|
if (!symptom) {
|
|
return { ok: false, error: 'unknown_symptom' };
|
|
}
|
|
if (symptom === 'none') {
|
|
return { ok: true, code: 'none', severity: null, note: String(note ?? '').trim() || null };
|
|
}
|
|
const level = Number(severity);
|
|
if (!HEALTH_SYMPTOM_SEVERITIES.includes(level)) {
|
|
return { ok: false, error: 'invalid_severity' };
|
|
}
|
|
return { ok: true, code: symptom, severity: level, note: String(note ?? '').trim() || null };
|
|
}
|