feat: 외교 문서 변경을 입력 원장과 함께 감사 이력으로 저장

This commit is contained in:
2026-09-16 05:46:11 +00:00
parent 8faab62866
commit b9d9b63b14
15 changed files with 576 additions and 45 deletions
@@ -20,6 +20,18 @@ export const prunePreviousAuditBatch = async (
if (!lock?.locked) return { status: 'busy', deleted: 0 };
const world = await tx.worldState.findFirst({ orderBy: { id: 'asc' }, select: { meta: true } });
if (asRecord(world?.meta).serverId !== expectedServerId) return { status: 'identityChanged', deleted: 0 };
const diplomacyEvents = await tx.playAuditDiplomacyEvent.findMany({
where: { serverId: { not: expectedServerId } },
orderBy: { sequence: 'asc' },
take: AUDIT_RETENTION_BATCH_SIZE,
select: { id: true },
});
if (diplomacyEvents.length) {
const deleted = await tx.playAuditDiplomacyEvent.deleteMany({
where: { id: { in: diplomacyEvents.map((row) => row.id) } },
});
return { status: 'progress', deleted: deleted.count };
}
const policies = await tx.playAuditPolicy.findMany({
where: { serverId: { not: expectedServerId } },
orderBy: { id: 'asc' },
@@ -215,4 +215,37 @@ integration('bounded previous-season audit retention', () => {
expect(await prunePreviousAuditBatch(db, 'policy-active')).toEqual({ status: 'complete', deleted: 0 });
expect(await db.playAuditPolicy.findUnique({ where: { id: 'active-policy' } })).not.toBeNull();
});
it('prunes diplomacy history in bounded batches without touching the active season', async () => {
await db.playAuditMonth.deleteMany();
await db.playAuditPolicy.deleteMany();
await db.playAuditDiplomacyEvent.deleteMany();
await db.worldState.updateMany({ data: { meta: { serverId: 'diplomacy-active' } } });
const row = (id: string, serverId: string, ordinal: number) => ({
id,
serverId,
ordinal,
executionId: 'fixture',
nationA: 1,
nationB: 2,
srcNationId: 1,
destNationId: 2,
category: 'DOCUMENT',
source: 'API',
eventType: 'LETTER_PROPOSED',
year: 190,
month: 1,
hash: id,
});
await db.playAuditDiplomacyEvent.createMany({
data: [
...Array.from({ length: 201 }, (_, index) => row(`old-diplomacy-${index}`, 'old-diplomacy', index + 1)),
row('active-diplomacy', 'diplomacy-active', 1),
],
});
expect(await prunePreviousAuditBatch(db, 'diplomacy-active')).toEqual({ status: 'progress', deleted: 200 });
expect(await prunePreviousAuditBatch(db, 'diplomacy-active')).toEqual({ status: 'progress', deleted: 1 });
expect(await prunePreviousAuditBatch(db, 'diplomacy-active')).toEqual({ status: 'complete', deleted: 0 });
expect(await db.playAuditDiplomacyEvent.findUnique({ where: { id: 'active-diplomacy' } })).not.toBeNull();
await db.playAuditDiplomacyEvent.deleteMany();
});
});