Files
memind/health-publish-guard.mjs
T
john f96fdcb3b9 feat(health): add P0 health channel kernel and encrypted health zone.
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>
2026-09-09 18:04:26 +08:00

78 lines
2.5 KiB
JavaScript

import { HEALTH_CATEGORY_CODE, HEALTH_PUBLISH_POLICY } from './health-feature.mjs';
export const HEALTH_ALLOWED_ACCESS_MODES = Object.freeze(['password', 'login_required']);
export const HEALTH_SHARE_FORBIDDEN_COLUMNS = Object.freeze([
'raw_payload',
'source_ref',
'ocr_text',
]);
export const HEALTH_SHARE_FORBIDDEN_DATASETS = Object.freeze([
'health_observations',
'health_observation_drafts',
'health_documents',
]);
export function isHealthPublishPolicy(publishPolicy, categoryCode) {
return (
String(publishPolicy ?? '') === HEALTH_PUBLISH_POLICY
|| String(categoryCode ?? '') === HEALTH_CATEGORY_CODE
);
}
export function assertHealthPublicationAllowed({
categoryCode = null,
publishPolicy = null,
accessMode,
password = '',
existingPasswordHash = null,
} = {}) {
if (!isHealthPublishPolicy(publishPolicy, categoryCode)) {
return { ok: true, skipped: true };
}
const mode = String(accessMode ?? '').trim();
if (mode === 'public') {
const error = Object.assign(new Error('健康区禁止完全公开发布'), {
code: 'health_public_forbidden',
});
throw error;
}
if (!HEALTH_ALLOWED_ACCESS_MODES.includes(mode)) {
const error = Object.assign(new Error('健康区仅允许口令或登录访问'), {
code: 'health_access_mode_forbidden',
});
throw error;
}
if (mode === 'password') {
const hasPassword = String(password ?? '').trim().length > 0;
const hasHash = Boolean(existingPasswordHash);
if (!hasPassword && !hasHash) {
const error = Object.assign(new Error('健康区发布必须设置口令'), {
code: 'health_password_required',
});
throw error;
}
}
return { ok: true, skipped: false, accessMode: mode };
}
export function assertHealthShareDatasetPolicy({ datasetName, columns = {} } = {}) {
const name = String(datasetName ?? '').trim();
if (HEALTH_SHARE_FORBIDDEN_DATASETS.includes(name)) {
const error = Object.assign(new Error('健康分享页不得直连原始健康 dataset'), {
code: 'health_share_raw_dataset_forbidden',
});
throw error;
}
const readColumns = Array.isArray(columns.read) ? columns.read : [];
const forbidden = readColumns.filter((column) => HEALTH_SHARE_FORBIDDEN_COLUMNS.includes(column));
if (forbidden.length > 0) {
const error = Object.assign(new Error(`健康分享页不得暴露字段:${forbidden.join(', ')}`), {
code: 'health_share_column_forbidden',
});
throw error;
}
return { ok: true };
}