Files
core2026/app/game-engine/src/turn/yearbookPersistence.ts
T

76 lines
2.4 KiB
TypeScript

import { createHash } from 'node:crypto';
import type { GamePrisma, InputJsonValue } from '@sammo-ts/infra';
import { LogCategory, LogScope } from '@sammo-ts/logic';
import type { PendingYearbookSnapshot } from './types.js';
const asJson = (value: unknown): InputJsonValue => value as InputJsonValue;
const computeHash = (payload: unknown): string => createHash('sha256').update(JSON.stringify(payload)).digest('hex');
export const persistYearbookSnapshot = async (
transaction: GamePrisma.TransactionClient,
snapshot: PendingYearbookSnapshot
): Promise<void> => {
const [historyRows, actionRows] = await Promise.all([
transaction.logEntry.findMany({
where: {
scope: LogScope.SYSTEM,
category: LogCategory.HISTORY,
year: snapshot.year,
month: snapshot.month,
},
orderBy: { id: 'desc' },
select: { text: true },
}),
transaction.logEntry.findMany({
where: {
scope: LogScope.SYSTEM,
category: LogCategory.ACTION,
year: snapshot.year,
month: snapshot.month,
},
orderBy: { id: 'desc' },
select: { text: true },
}),
]);
const globalHistory = historyRows.map((row) => row.text);
const globalAction = actionRows.map((row) => row.text);
const hash = computeHash({
map: snapshot.map,
nations: snapshot.nations,
globalHistory,
globalAction,
});
await transaction.yearbookHistory.upsert({
where: {
profileName_year_month_sourceId: {
profileName: snapshot.serverId,
year: snapshot.year,
month: snapshot.month,
sourceId: snapshot.sourceId,
},
},
update: {
map: asJson(snapshot.map),
nations: asJson(snapshot.nations),
globalHistory: asJson(globalHistory),
globalAction: asJson(globalAction),
hash,
},
create: {
profileName: snapshot.serverId,
sourceId: snapshot.sourceId,
year: snapshot.year,
month: snapshot.month,
map: asJson(snapshot.map),
nations: asJson(snapshot.nations),
globalHistory: asJson(globalHistory),
globalAction: asJson(globalAction),
hash,
},
});
};