refactor(data): 收口关系表运行时数据源
Some checks failed
Deploy Production / Build, push, deploy, verify (push) Has been cancelled
Some checks failed
Deploy Production / Build, push, deploy, verify (push) Has been cancelled
- 移除已迁移业务 AppData 运行时 fallback,改走领域 API 和关系表快读 - 补齐需求产品负责人、版本计划任务 JSON 和成员 username 回填迁移 - 统一治理字典入口,并补充 AI provider、数据源契约和领域服务测试 Co-Authored-By: Codex GPT-5 <codex@openai.com>
This commit is contained in:
66
apps/web/lib/no-business-appdata-runtime-source.test.ts
Normal file
66
apps/web/lib/no-business-appdata-runtime-source.test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import test from 'node:test';
|
||||
|
||||
function source(path: string) {
|
||||
return readFileSync(join(process.cwd(), path), 'utf8');
|
||||
}
|
||||
|
||||
const migratedBusinessStores = [
|
||||
['stores/useProductStore.ts', 'products-overview'],
|
||||
['stores/useRequirementStore.ts', 'requirements'],
|
||||
['stores/useVersionPlanStore.ts', 'version-plans'],
|
||||
['stores/useDevTaskStore.ts', 'dev-tasks'],
|
||||
['stores/useTestCaseStore.ts', 'test-cases'],
|
||||
['stores/useBugStore.ts', 'bugs'],
|
||||
['stores/useTaskCategoryStore.ts', 'task-categories'],
|
||||
['stores/useTaskWorklogStore.ts', 'task-worklogs'],
|
||||
['stores/useWorkActivityStore.ts', 'work-activities'],
|
||||
] as const;
|
||||
|
||||
test('migrated business stores do not read or write AppData documents at runtime', () => {
|
||||
for (const [file, key] of migratedBusinessStores) {
|
||||
const text = source(file);
|
||||
|
||||
assert.doesNotMatch(text, new RegExp(`loadServerData<[^>]*>\\('${key}'`), `${file} must not read ${key}`);
|
||||
assert.doesNotMatch(text, new RegExp(`loadServerData\\([^)]*'${key}'`), `${file} must not read ${key}`);
|
||||
assert.doesNotMatch(text, new RegExp(`saveServerData\\('${key}'`), `${file} must not write ${key}`);
|
||||
assert.doesNotMatch(text, /\.catch\(loadStored\)/, `${file} must not fall back to legacy AppData reads`);
|
||||
}
|
||||
});
|
||||
|
||||
test('only explicit legacy config stores keep AppData access', () => {
|
||||
assert.match(source('stores/useMemberStore.ts'), /saveServerData\('members'/);
|
||||
assert.match(source('stores/useMemberStore.ts'), /loadServerData<[^>]+>\('members'/);
|
||||
assert.match(source('stores/useOvertimeStore.ts'), /loadServerData<[^>]+>\('overtime'/);
|
||||
});
|
||||
|
||||
test('read-only Xiaobao AppData archive keys are not used by runtime stores', () => {
|
||||
for (const file of ['stores/useXiaobaoRiskStore.ts', 'stores/useXiaobaoWarningReadStore.ts']) {
|
||||
const text = source(file);
|
||||
|
||||
assert.doesNotMatch(text, /loadServerData<[^>]+>\('xiaobao-risk-snapshots'/, `${file} must not read Xiaobao snapshots AppData`);
|
||||
assert.doesNotMatch(text, /loadServerData<[^>]+>\('xiaobao-risk-insights'/, `${file} must not read Xiaobao insights AppData`);
|
||||
assert.doesNotMatch(text, /loadServerData<[^>]+>\('xiaobao-warning-views'/, `${file} must not read Xiaobao warning read-state AppData`);
|
||||
assert.doesNotMatch(text, /saveServerData\('xiaobao-risk-snapshots'/, `${file} must not write Xiaobao snapshots AppData`);
|
||||
assert.doesNotMatch(text, /saveServerData\('xiaobao-risk-insights'/, `${file} must not write Xiaobao insights AppData`);
|
||||
assert.doesNotMatch(text, /saveServerData\('xiaobao-warning-views'/, `${file} must not write Xiaobao warning read-state AppData`);
|
||||
}
|
||||
});
|
||||
|
||||
test('auth reads member identities from the member domain API instead of members AppData', () => {
|
||||
const text = source('stores/useAuthStore.ts');
|
||||
|
||||
assert.match(text, /listMembersDomain/);
|
||||
assert.doesNotMatch(text, /loadServerData<[^>]+>\('members'/);
|
||||
assert.doesNotMatch(text, /from '@\/lib\/server-data'/);
|
||||
});
|
||||
|
||||
test('member store keeps members AppData as config only, not member identity fallback', () => {
|
||||
const text = source('stores/useMemberStore.ts');
|
||||
|
||||
assert.doesNotMatch(text, /cached\.members/);
|
||||
assert.doesNotMatch(text, /members: get\(\)\.members,/);
|
||||
assert.match(text, /saveServerData\('members', \{ departments: state\.departments, members: \[\], roles: state\.roles, passwordRule: state\.passwordRule \}\)/);
|
||||
});
|
||||
Reference in New Issue
Block a user