task logs: migrate from filesystem to postgresql; refactor sidecars into submodules
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
import { mkdir } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { getTaskLogsDir } from '@@/data-path';
|
||||
import { db, schema } from 'officerdb';
|
||||
import type { TaskInfo } from '@@/api/chat-types';
|
||||
|
||||
type ChatMessage =
|
||||
@@ -18,46 +16,41 @@ type ChatMessage =
|
||||
| { role: 'error'; text: string };
|
||||
|
||||
type TaskLog = {
|
||||
userId: number;
|
||||
taskName: string;
|
||||
taskDirName: string;
|
||||
entryName: string;
|
||||
entryType: 'file' | 'directory';
|
||||
provider: string;
|
||||
model: string;
|
||||
startedAt: string;
|
||||
completedAt: string | null;
|
||||
startedAt: Date;
|
||||
messages: ChatMessage[];
|
||||
};
|
||||
|
||||
type LogEntry = {
|
||||
email: string;
|
||||
filePath: string;
|
||||
userId: number;
|
||||
log: TaskLog;
|
||||
};
|
||||
|
||||
const activeLogs = new Map<string, LogEntry>();
|
||||
let logCounter = 0;
|
||||
|
||||
export function createTaskLog(email: string, taskInfo: TaskInfo, provider: string, model: string): string {
|
||||
export function createTaskLog(userId: number, taskInfo: TaskInfo, provider: string, model: string): string {
|
||||
const logId = `log_${Date.now()}_${++logCounter}`;
|
||||
const dir = getTaskLogsDir(email);
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
const filename = `${timestamp}-${taskInfo.taskDirName}.json`;
|
||||
const filePath = join(dir, filename);
|
||||
|
||||
const log: TaskLog = {
|
||||
userId,
|
||||
taskName: taskInfo.taskName,
|
||||
taskDirName: taskInfo.taskDirName,
|
||||
entryName: taskInfo.entryName,
|
||||
entryType: taskInfo.entryType,
|
||||
provider,
|
||||
model,
|
||||
startedAt: new Date().toISOString(),
|
||||
completedAt: null,
|
||||
startedAt: new Date(),
|
||||
messages: [],
|
||||
};
|
||||
|
||||
activeLogs.set(logId, { email, filePath, log });
|
||||
activeLogs.set(logId, { userId, log });
|
||||
return logId;
|
||||
}
|
||||
|
||||
@@ -82,11 +75,24 @@ export async function finalizeLog(logId: string) {
|
||||
const entry = activeLogs.get(logId);
|
||||
if (!entry) return;
|
||||
|
||||
entry.log.completedAt = new Date().toISOString();
|
||||
const { log } = entry;
|
||||
const lastMessage = log.messages[log.messages.length - 1];
|
||||
const isError = lastMessage?.role === 'result' ? lastMessage.isError : lastMessage?.role === 'error';
|
||||
|
||||
try {
|
||||
await mkdir(join(entry.filePath, '..'), { recursive: true });
|
||||
await Bun.write(entry.filePath, JSON.stringify(entry.log, null, 2));
|
||||
await db.insert(schema.taskLogs).values({
|
||||
userId: log.userId,
|
||||
taskName: log.taskName,
|
||||
taskDirName: log.taskDirName,
|
||||
entryName: log.entryName,
|
||||
entryType: log.entryType,
|
||||
provider: log.provider,
|
||||
model: log.model,
|
||||
isError: !!isError,
|
||||
messages: log.messages,
|
||||
startedAt: log.startedAt,
|
||||
completedAt: new Date(),
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('[task-logger] Failed to write log:', err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user