feat: add dynasty management features including list and detail views

- Implemented `OldNation`, `OldGeneral`, and `Emperor` models in Prisma schema.
- Created API routes for fetching dynasty lists and details.
- Developed frontend views for displaying dynasty list and detail information.
- Enhanced in-memory world to track deleted nation snapshots during unification.
- Added functionality to settle dynasty information after unification events.
This commit is contained in:
2026-01-29 19:09:17 +00:00
parent c4a5361fc6
commit d3277f204a
12 changed files with 1095 additions and 1 deletions
+73 -1
View File
@@ -12,7 +12,7 @@ import {
type TurnEngineTroopUpdateInput,
type TurnEngineWorldStateUpdateInput,
} from '@sammo-ts/infra';
import { finalizeLogEntry, type LogEntryDraft } from '@sammo-ts/logic';
import { finalizeLogEntry, LogCategory, LogScope, type LogEntryDraft } from '@sammo-ts/logic';
import { asRecord, type RankDataType } from '@sammo-ts/common';
import type { TurnDaemonHooks } from '../lifecycle/types.js';
@@ -316,6 +316,7 @@ export const createDatabaseTurnHooks = async (
deletedTroops,
deletedGenerals,
deletedNations,
deletedNationSnapshots,
diplomacy,
logs,
createdGenerals,
@@ -335,6 +336,77 @@ export const createDatabaseTurnHooks = async (
data: worldStateUpdate,
});
const meta = asRecord(state.meta);
const serverId =
typeof meta.serverId === 'string' && meta.serverId.trim() ? meta.serverId.trim() : 'default';
if (deletedNationSnapshots.length > 0) {
const nationIds = deletedNationSnapshots.map((snapshot) => snapshot.nation.id);
const historyRows = await prisma.logEntry.findMany({
where: {
nationId: { in: nationIds },
scope: LogScope.NATION,
category: LogCategory.HISTORY,
},
orderBy: { id: 'asc' },
select: { nationId: true, text: true },
});
const historyMap = new Map<number, string[]>();
for (const row of historyRows) {
const bucket = historyMap.get(row.nationId ?? 0) ?? [];
bucket.push(row.text);
historyMap.set(row.nationId ?? 0, bucket);
}
await Promise.all(
deletedNationSnapshots.map((snapshot) =>
prisma.oldNation.upsert({
where: {
serverId_nation: {
serverId,
nation: snapshot.nation.id,
},
},
update: {
data: {
nation: snapshot.nation.id,
name: snapshot.nation.name,
color: snapshot.nation.color,
type: snapshot.nation.typeCode,
level: snapshot.nation.level,
gold: snapshot.nation.gold,
rice: snapshot.nation.rice,
power: snapshot.nation.power,
capitalCityId: snapshot.nation.capitalCityId,
generals: snapshot.generalIds,
history: historyMap.get(snapshot.nation.id) ?? [],
meta: snapshot.nation.meta ?? {},
},
date: snapshot.removedAt,
},
create: {
serverId,
nation: snapshot.nation.id,
data: {
nation: snapshot.nation.id,
name: snapshot.nation.name,
color: snapshot.nation.color,
type: snapshot.nation.typeCode,
level: snapshot.nation.level,
gold: snapshot.nation.gold,
rice: snapshot.nation.rice,
power: snapshot.nation.power,
capitalCityId: snapshot.nation.capitalCityId,
generals: snapshot.generalIds,
history: historyMap.get(snapshot.nation.id) ?? [],
meta: snapshot.nation.meta ?? {},
},
date: snapshot.removedAt,
},
})
)
);
}
const createdIds = new Set(createdGenerals.map((general) => general.id));
const createdNationIds = new Set(createdNations.map((nation) => nation.id));
const createdTroopIds = new Set(createdTroops.map((troop) => troop.id));