feat: 로그 시스템 구현 및 관련 클래스 추가

This commit is contained in:
2025-12-29 08:40:01 +00:00
parent e0eb768e2e
commit 27cc016804
13 changed files with 630 additions and 11 deletions
+45 -1
View File
@@ -1,6 +1,7 @@
import type { Prisma } from '@prisma/client';
import { createPostgresConnector } from '@sammo-ts/infra';
import { finalizeLogEntry, type LogEntryDraft } from '@sammo-ts/logic';
import type { TurnDaemonHooks } from '../lifecycle/types.js';
import type { InMemoryTurnWorld } from './inMemoryWorld.js';
@@ -85,6 +86,34 @@ const buildNationUpdate = (
meta: asJson(nation.meta),
});
const buildLogCreateData = (
entry: LogEntryDraft,
context: { year: number; month: number; at: Date }
): Prisma.LogEntryCreateManyInput | null => {
const record = finalizeLogEntry(entry, {
year: context.year,
month: context.month,
at: context.at,
});
if (!record) {
return null;
}
return {
scope: record.scope,
category: record.category,
subType: record.subType ?? null,
year: record.year,
month: record.month,
text: record.text,
generalId: record.generalId ?? null,
nationId: record.nationId ?? null,
userId: record.userId ?? null,
meta: asJson(record.meta ?? {}),
createdAt: record.createdAt,
};
};
export const createDatabaseTurnHooks = async (
databaseUrl: string,
world: InMemoryTurnWorld
@@ -130,7 +159,22 @@ export const createDatabaseTurnHooks = async (
]);
if (logs.length > 0) {
// TODO: API 서버 연동 전까지는 로그를 별도 처리하지 않는다.
const logContext = {
year: state.currentYear,
month: state.currentMonth,
at: state.lastTurnTime,
};
const payload = logs
.map((entry) => buildLogCreateData(entry, logContext))
.filter(
(entry): entry is Prisma.LogEntryCreateManyInput =>
Boolean(entry)
);
if (payload.length > 0) {
await connector.prisma.logEntry.createMany({
data: payload,
});
}
}
},
};
+4 -4
View File
@@ -1,4 +1,4 @@
import type { City, Nation, TurnSchedule } from '@sammo-ts/logic';
import type { City, LogEntryDraft, Nation, TurnSchedule } from '@sammo-ts/logic';
import { getNextTurnAt } from '@sammo-ts/logic';
import type { TurnCheckpoint } from '../lifecycle/types.js';
@@ -17,7 +17,7 @@ export interface GeneralTurnResult {
city?: City;
nation?: Nation | null;
nextTurnAt?: Date;
logs?: string[];
logs?: LogEntryDraft[];
}
export interface GeneralTurnHandler {
@@ -85,7 +85,7 @@ export class InMemoryTurnWorld {
private readonly dirtyGeneralIds = new Set<number>();
private readonly dirtyCityIds = new Set<number>();
private readonly dirtyNationIds = new Set<number>();
private readonly logs: string[] = [];
private readonly logs: LogEntryDraft[] = [];
private checkpoint?: TurnCheckpoint;
private state: TurnWorldState;
@@ -242,7 +242,7 @@ export class InMemoryTurnWorld {
generals: TurnGeneral[];
cities: City[];
nations: Nation[];
logs: string[];
logs: LogEntryDraft[];
} {
const generals = Array.from(this.dirtyGeneralIds)
.map((id) => this.generals.get(id))