feat: add ranking and hall of fame features

- Implemented new routes for Best General and Hall of Fame views in the frontend.
- Created BestGeneralView and HallOfFameView components to display rankings based on game data.
- Added new database models for RankData and HallOfFame to store ranking information.
- Introduced ranking types and hall of fame types in common types for better type safety.
- Developed ranking router to handle fetching of best general and hall of fame data.
- Updated database schema with migrations to include new tables for rank data and hall of fame.
- Enhanced the main view with links to the new ranking features.
This commit is contained in:
2026-01-29 18:18:35 +00:00
parent 19c359d0b2
commit 9fff671c2f
16 changed files with 1217 additions and 2 deletions
+12 -1
View File
@@ -321,6 +321,14 @@ const applySanctionsPatch = (current: UserSanctions, patch: SanctionsPatch): Use
const buildAdminPassword = (): string => randomBytes(6).toString('hex');
const buildServerId = (profileName: string, now: Date): string => {
const year = String(now.getFullYear()).slice(-2);
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const suffix = randomBytes(2).toString('hex');
return `${profileName}_${year}${month}${day}_${suffix}`;
};
// 프로필 메타를 안전하게 읽고, 패치를 병합한다.
const readMetaObject = (value: unknown): Record<string, unknown> => {
if (!value || typeof value !== 'object') {
@@ -881,11 +889,13 @@ export const adminRouter = router({
}
const season = nextSeasonIdx ?? baseSeason ?? 1;
const seedNow = new Date();
const serverId = buildServerId(updatedProfile.profileName, seedNow);
await seedProfileDatabase({
databaseUrl,
scenarioId: input.install.scenarioId,
tickSeconds: input.install.turnTermMinutes * 60,
now: new Date(),
now: seedNow,
installOptions: {
turnTermMinutes: input.install.turnTermMinutes,
sync: input.install.sync,
@@ -897,6 +907,7 @@ export const adminRouter = router({
tournamentTrig: input.install.tournamentTrig,
joinMode: input.install.joinMode,
season,
serverId,
autorunUser: input.install.autorunUser
? {
limitMinutes: input.install.autorunUser.limitMinutes,