refactor(data): 收口关系表运行时数据源
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:
2026-07-09 14:59:49 +08:00
parent 1e6fb0c7aa
commit 2e595c7e72
98 changed files with 2938 additions and 1441 deletions

View File

@@ -43,9 +43,10 @@ interface OvertimeState {
deleteReason: (id: string) => void;
}
async function loadStored(): Promise<{ records: OvertimeRecord[]; reasons: DictItem[] } | null> {
async function loadStoredReasons(): Promise<DictItem[] | null> {
try {
return await loadServerData<{ records: OvertimeRecord[]; reasons: DictItem[] }>('overtime');
const stored = await loadServerData<{ records?: OvertimeRecord[]; reasons?: DictItem[] }>('overtime');
return Array.isArray(stored?.reasons) ? stored.reasons : null;
} catch {}
return null;
}
@@ -58,15 +59,15 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
fetchRecords: async (options) => {
if (!options?.force && get().loaded && Date.now() - lastOvertimeFetchAt < SERVER_DATA_CACHE_MS) return;
const [cached, domainRecords] = await Promise.all([
loadStored(),
const [storedReasons, domainRecords] = await Promise.all([
loadStoredReasons(),
listOvertimeRecordsDomain().catch(() => null),
]);
if (!options?.force && get().loaded && Date.now() - lastOvertimeFetchAt < SERVER_DATA_CACHE_MS) return;
lastOvertimeFetchAt = Date.now();
set({
records: domainRecords && domainRecords.length > 0 ? domainRecords : cached?.records ?? MOCK_RECORDS,
reasons: cached?.reasons ?? PRESET_REASONS,
records: domainRecords ?? MOCK_RECORDS,
reasons: storedReasons ?? PRESET_REASONS,
loaded: true,
});
},
@@ -84,15 +85,11 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
set({ records, loaded: true });
scheduleSaveWithOptimisticRollback({
save: async () => {
try {
const created = await createOvertimeRecordDomain(record);
set({
records: get().records.map((item) => (item.id === record.id ? { ...record, ...created } : item)),
loaded: true,
});
} catch {
await saveOvertimeFallback(records, get().reasons);
}
const created = await createOvertimeRecordDomain(record);
set({
records: get().records.map((item) => (item.id === record.id ? { ...record, ...created } : item)),
loaded: true,
});
},
expected: records,
getCurrent: () => get().records,
@@ -113,11 +110,7 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
set({ records, loaded: true });
scheduleSaveWithOptimisticRollback({
save: async () => {
try {
await updateOvertimeRecordDomain(id, records.find((record) => record.id === id) ?? {});
} catch {
await saveOvertimeFallback(records, get().reasons);
}
await updateOvertimeRecordDomain(id, records.find((record) => record.id === id) ?? {});
},
expected: records,
getCurrent: () => get().records,
@@ -131,11 +124,7 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
set({ records, loaded: true });
scheduleSaveWithOptimisticRollback({
save: async () => {
try {
await deleteOvertimeRecordDomain(id);
} catch {
await saveOvertimeFallback(records, get().reasons);
}
await deleteOvertimeRecordDomain(id);
},
expected: records,
getCurrent: () => get().records,
@@ -149,7 +138,7 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
const reasons = [...previous, item];
set({ reasons, loaded: true });
scheduleSaveWithOptimisticRollback({
save: () => saveServerData('overtime', { records: get().records, reasons }),
save: () => saveOvertimeReasons(reasons),
expected: reasons,
getCurrent: () => get().reasons,
rollback: () => set({ reasons: previous, loaded: true }),
@@ -161,7 +150,7 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
const reasons = previous.map((r) => r.id === id ? { ...r, name } : r);
set({ reasons, loaded: true });
scheduleSaveWithOptimisticRollback({
save: () => saveServerData('overtime', { records: get().records, reasons }),
save: () => saveOvertimeReasons(reasons),
expected: reasons,
getCurrent: () => get().reasons,
rollback: () => set({ reasons: previous, loaded: true }),
@@ -173,7 +162,7 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
const reasons = previous.filter((r) => r.id !== id);
set({ reasons, loaded: true });
scheduleSaveWithOptimisticRollback({
save: () => saveServerData('overtime', { records: get().records, reasons }),
save: () => saveOvertimeReasons(reasons),
expected: reasons,
getCurrent: () => get().reasons,
rollback: () => set({ reasons: previous, loaded: true }),
@@ -181,6 +170,6 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
},
}));
async function saveOvertimeFallback(records: OvertimeRecord[], reasons: DictItem[]) {
await saveServerData('overtime', { records, reasons });
async function saveOvertimeReasons(reasons: DictItem[]) {
await saveServerData('overtime', { records: [], reasons });
}