fix(team): preserve task projection cache shape
This commit is contained in:
parent
f5f22e50fb
commit
aa068efc68
2 changed files with 74 additions and 9 deletions
|
|
@ -736,16 +736,76 @@ function normalizePersistentTaskReadResult(
|
||||||
if (task.teamName !== teamName) return null;
|
if (task.teamName !== teamName) return null;
|
||||||
if (typeof task.id !== 'string') return null;
|
if (typeof task.id !== 'string') return null;
|
||||||
if (typeof task.subject !== 'string') return null;
|
if (typeof task.subject !== 'string') return null;
|
||||||
if (
|
const status =
|
||||||
task.status !== 'pending' &&
|
task.status === 'pending' ||
|
||||||
task.status !== 'in_progress' &&
|
task.status === 'in_progress' ||
|
||||||
task.status !== 'completed' &&
|
task.status === 'completed' ||
|
||||||
task.status !== 'deleted'
|
task.status === 'deleted'
|
||||||
) {
|
? task.status
|
||||||
return null;
|
: null;
|
||||||
}
|
if (!status) return null;
|
||||||
|
|
||||||
return { task };
|
return { task: restorePersistentTaskProjectionShape(task, teamName, status) };
|
||||||
|
}
|
||||||
|
|
||||||
|
function restorePersistentTaskProjectionShape(
|
||||||
|
task: Record<string, unknown>,
|
||||||
|
teamName: string,
|
||||||
|
status: string
|
||||||
|
): Record<string, unknown> {
|
||||||
|
const id = typeof task.id === 'string' ? task.id : '';
|
||||||
|
const subject = typeof task.subject === 'string' ? task.subject : '';
|
||||||
|
const displayId = task.displayId;
|
||||||
|
const reviewState = normalizeFallbackReviewState(task.reviewState, status);
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
displayId:
|
||||||
|
typeof displayId === 'string' && displayId.trim().length > 0
|
||||||
|
? displayId.trim()
|
||||||
|
: deriveTaskDisplayId(id),
|
||||||
|
subject,
|
||||||
|
description: typeof task.description === 'string' ? task.description : undefined,
|
||||||
|
descriptionTaskRefs: Array.isArray(task.descriptionTaskRefs)
|
||||||
|
? task.descriptionTaskRefs
|
||||||
|
: undefined,
|
||||||
|
activeForm: typeof task.activeForm === 'string' ? task.activeForm : undefined,
|
||||||
|
prompt: typeof task.prompt === 'string' ? task.prompt : undefined,
|
||||||
|
promptTaskRefs: Array.isArray(task.promptTaskRefs) ? task.promptTaskRefs : undefined,
|
||||||
|
owner: typeof task.owner === 'string' ? task.owner : undefined,
|
||||||
|
createdBy: typeof task.createdBy === 'string' ? task.createdBy : undefined,
|
||||||
|
status,
|
||||||
|
workIntervals: Array.isArray(task.workIntervals) ? task.workIntervals : undefined,
|
||||||
|
reviewIntervals: Array.isArray(task.reviewIntervals) ? task.reviewIntervals : undefined,
|
||||||
|
historyEvents: Array.isArray(task.historyEvents) ? task.historyEvents : undefined,
|
||||||
|
blocks: Array.isArray(task.blocks) ? task.blocks : undefined,
|
||||||
|
blockedBy: Array.isArray(task.blockedBy) ? task.blockedBy : undefined,
|
||||||
|
related: Array.isArray(task.related)
|
||||||
|
? (task.related as unknown[]).filter((id): id is string => typeof id === 'string')
|
||||||
|
: undefined,
|
||||||
|
createdAt: typeof task.createdAt === 'string' ? task.createdAt : undefined,
|
||||||
|
updatedAt: typeof task.updatedAt === 'string' ? task.updatedAt : undefined,
|
||||||
|
projectPath: typeof task.projectPath === 'string' ? task.projectPath : undefined,
|
||||||
|
comments: Array.isArray(task.comments) ? task.comments : undefined,
|
||||||
|
needsClarification:
|
||||||
|
task.needsClarification === 'lead' || task.needsClarification === 'user'
|
||||||
|
? task.needsClarification
|
||||||
|
: undefined,
|
||||||
|
reviewState,
|
||||||
|
deletedAt: undefined,
|
||||||
|
attachments: Array.isArray(task.attachments) ? task.attachments : undefined,
|
||||||
|
sourceMessageId:
|
||||||
|
typeof task.sourceMessageId === 'string' && task.sourceMessageId.trim()
|
||||||
|
? task.sourceMessageId.trim()
|
||||||
|
: undefined,
|
||||||
|
sourceMessage:
|
||||||
|
isRecord(task.sourceMessage) &&
|
||||||
|
typeof task.sourceMessage.text === 'string' &&
|
||||||
|
typeof task.sourceMessage.from === 'string' &&
|
||||||
|
typeof task.sourceMessage.timestamp === 'string'
|
||||||
|
? task.sourceMessage
|
||||||
|
: undefined,
|
||||||
|
teamName,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizePersistentTaskProjectionEntry(
|
function normalizePersistentTaskProjectionEntry(
|
||||||
|
|
|
||||||
|
|
@ -598,9 +598,11 @@ describe('team-fs-worker integration', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const firstWorker = createWorker(workerPath);
|
const firstWorker = createWorker(workerPath);
|
||||||
|
let firstTaskKeys: string[] = [];
|
||||||
try {
|
try {
|
||||||
const first = await callGetAllTasks(firstWorker, tasksBase, projectionCacheBase);
|
const first = await callGetAllTasks(firstWorker, tasksBase, projectionCacheBase);
|
||||||
expect(first.tasks[0]).toMatchObject({ teamName, subject: 'Persisted subject' });
|
expect(first.tasks[0]).toMatchObject({ teamName, subject: 'Persisted subject' });
|
||||||
|
firstTaskKeys = Object.keys(first.tasks[0] as Record<string, unknown>);
|
||||||
expect(first.diag?.cacheMisses).toBe(1);
|
expect(first.diag?.cacheMisses).toBe(1);
|
||||||
expect(first.diag?.persistentCacheWrites).toBe(1);
|
expect(first.diag?.persistentCacheWrites).toBe(1);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -611,6 +613,9 @@ describe('team-fs-worker integration', () => {
|
||||||
try {
|
try {
|
||||||
const second = await callGetAllTasks(secondWorker, tasksBase, projectionCacheBase);
|
const second = await callGetAllTasks(secondWorker, tasksBase, projectionCacheBase);
|
||||||
expect(second.tasks[0]).toMatchObject({ teamName, subject: 'Persisted subject' });
|
expect(second.tasks[0]).toMatchObject({ teamName, subject: 'Persisted subject' });
|
||||||
|
expect(Object.keys(second.tasks[0] as Record<string, unknown>)).toEqual(
|
||||||
|
firstTaskKeys
|
||||||
|
);
|
||||||
expect(second.diag?.cacheHits).toBe(0);
|
expect(second.diag?.cacheHits).toBe(0);
|
||||||
expect(second.diag?.cacheMisses).toBe(0);
|
expect(second.diag?.cacheMisses).toBe(0);
|
||||||
expect(second.diag?.persistentCacheLoads).toBe(1);
|
expect(second.diag?.persistentCacheLoads).toBe(1);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue