119 lines
2.7 KiB
TypeScript
119 lines
2.7 KiB
TypeScript
import { writeFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import type { FieldDescription, JsonValue } from "@arco/clarizen-lib";
|
|
import type { EntityChoice } from "../metadata/picker.js";
|
|
import { formatFilterSummary, type EntityFilter } from "../query/filter.js";
|
|
import type { EntityRecord } from "../query/fetch-all.js";
|
|
import type { BulkUpdateResult } from "../update/bulk-field.js";
|
|
|
|
export interface RunLogEntry {
|
|
id: string;
|
|
displayName?: string;
|
|
status: "updated" | "error";
|
|
message?: string;
|
|
errorCode?: string;
|
|
}
|
|
|
|
export interface RunLog {
|
|
executedAt: string;
|
|
durationMs: number;
|
|
userId: string;
|
|
operation: {
|
|
typeName: string;
|
|
typeLabel?: string;
|
|
filter: string;
|
|
fieldName: string;
|
|
fieldLabel?: string;
|
|
fieldType?: string;
|
|
value: JsonValue;
|
|
};
|
|
summary: {
|
|
total: number;
|
|
updated: number;
|
|
errors: number;
|
|
};
|
|
results: RunLogEntry[];
|
|
}
|
|
|
|
export interface BuildRunLogParams {
|
|
startedAt: number;
|
|
userId: string;
|
|
entityChoice: EntityChoice;
|
|
entityFilter: EntityFilter;
|
|
field: FieldDescription;
|
|
fieldName: string;
|
|
parsedValue: JsonValue;
|
|
records: EntityRecord[];
|
|
result: BulkUpdateResult;
|
|
}
|
|
|
|
function logTimestamp(): string {
|
|
return new Date().toISOString().replace(/[:.]/g, "-");
|
|
}
|
|
|
|
export function buildRunLog(params: BuildRunLogParams): RunLog {
|
|
const {
|
|
startedAt,
|
|
userId,
|
|
entityChoice,
|
|
entityFilter,
|
|
field,
|
|
fieldName,
|
|
parsedValue,
|
|
records,
|
|
result,
|
|
} = params;
|
|
|
|
const errorsById = new Map(
|
|
result.errors.map((e) => [String(e.id), e] as const),
|
|
);
|
|
|
|
const results: RunLogEntry[] = records.map((record) => {
|
|
const id = String(record.id);
|
|
const error = errorsById.get(id);
|
|
|
|
if (error) {
|
|
return {
|
|
id,
|
|
displayName: record.displayName,
|
|
status: "error",
|
|
message: error.message,
|
|
errorCode: error.errorCode,
|
|
};
|
|
}
|
|
|
|
return {
|
|
id,
|
|
displayName: record.displayName,
|
|
status: "updated",
|
|
};
|
|
});
|
|
|
|
return {
|
|
executedAt: new Date().toISOString(),
|
|
durationMs: Date.now() - startedAt,
|
|
userId,
|
|
operation: {
|
|
typeName: entityChoice.typeName,
|
|
typeLabel: entityChoice.label,
|
|
filter: formatFilterSummary(entityFilter),
|
|
fieldName,
|
|
fieldLabel: field.label,
|
|
fieldType: field.type,
|
|
value: parsedValue,
|
|
},
|
|
summary: {
|
|
total: records.length,
|
|
updated: result.updated,
|
|
errors: result.errors.length,
|
|
},
|
|
results,
|
|
};
|
|
}
|
|
|
|
export function writeRunLog(log: RunLog, cwd = process.cwd()): string {
|
|
const filePath = resolve(cwd, `run-log-${logTimestamp()}.json`);
|
|
writeFileSync(filePath, JSON.stringify(log, null, 2), "utf-8");
|
|
return filePath;
|
|
}
|