feat: GamePrisma를 사용하여 데이터베이스 클라이언트 및 관련 타입 정의 업데이트

This commit is contained in:
2026-01-05 15:13:59 +00:00
parent c3b6833172
commit b1f2523fa3
7 changed files with 47 additions and 216 deletions
+11 -112
View File
@@ -1,6 +1,6 @@
import { z } from 'zod'; import { z } from 'zod';
import type { GameSessionTokenPayload } from '@sammo-ts/common'; import type { GameSessionTokenPayload } from '@sammo-ts/common';
import type { DatabaseClient as InfraDatabaseClient, RedisConnector } from '@sammo-ts/infra'; import type { DatabaseClient as InfraDatabaseClient, RedisConnector, GamePrisma } from '@sammo-ts/infra';
import type { TurnDaemonTransport } from './daemon/transport.js'; import type { TurnDaemonTransport } from './daemon/transport.js';
import type { BattleSimTransport } from './battleSim/transport.js'; import type { BattleSimTransport } from './battleSim/transport.js';
@@ -26,119 +26,18 @@ export const zWorldStateMeta = z.object({
}); });
export type WorldStateMeta = z.infer<typeof zWorldStateMeta>; export type WorldStateMeta = z.infer<typeof zWorldStateMeta>;
export interface WorldStateRow { export type WorldStateRow = GamePrisma.WorldStateGetPayload<{}>;
scenarioCode: string; export type GeneralRow = GamePrisma.GeneralGetPayload<{}>;
currentYear: number; export type GeneralTurnRow = GamePrisma.GeneralTurnGetPayload<{}>;
currentMonth: number; export type NationTurnRow = GamePrisma.NationTurnGetPayload<{}>;
tickSeconds: number; export type CityRow = GamePrisma.CityGetPayload<{}>;
config: unknown; export type NationRow = GamePrisma.NationGetPayload<{}>;
meta: unknown; export type TroopRow = GamePrisma.TroopGetPayload<{}>;
updatedAt: Date;
}
export interface GeneralRow { export type JsonValue = GamePrisma.JsonValue;
id: number; export type InputJsonValue = GamePrisma.InputJsonValue;
userId: string | null;
name: string;
nationId: number;
cityId: number;
troopId: number;
leadership: number;
strength: number;
intel: number;
experience: number;
dedication: number;
officerLevel: number;
personalCode: string;
specialCode: string;
special2Code: string;
horseCode: string;
weaponCode: string;
bookCode: string;
itemCode: string;
injury: number;
gold: number;
rice: number;
crew: number;
crewTypeId: number;
train: number;
atmos: number;
age: number;
npcState: number;
picture: string | null;
meta: unknown;
}
export interface GeneralTurnRow { export type DatabaseClient = InfraDatabaseClient;
id: number;
generalId: number;
turnIdx: number;
actionCode: string;
arg: unknown;
}
export interface NationTurnRow {
id: number;
nationId: number;
officerLevel: number;
turnIdx: number;
actionCode: string;
arg: unknown;
}
export interface CityRow {
id: number;
name: string;
nationId: number;
level: number;
population: number;
populationMax: number;
agriculture: number;
agricultureMax: number;
commerce: number;
commerceMax: number;
security: number;
securityMax: number;
trust: number;
trade: number;
supplyState: number;
frontState: number;
defence: number;
defenceMax: number;
wall: number;
wallMax: number;
region: number;
meta: unknown;
}
export interface NationRow {
id: number;
name: string;
color: string;
capitalCityId: number | null;
gold: number;
rice: number;
tech: number;
level: number;
typeCode: string;
meta: unknown;
}
export interface TroopRow {
troopLeaderId: number;
nationId: number;
name: string;
}
export type DatabaseClient = InfraDatabaseClient<
WorldStateRow,
GeneralRow,
CityRow,
NationRow,
GeneralTurnRow,
NationTurnRow,
TroopRow
>;
export interface GameApiContext { export interface GameApiContext {
db: DatabaseClient; db: DatabaseClient;
+5 -4
View File
@@ -2,6 +2,7 @@ import type {
DatabaseClient, DatabaseClient,
GeneralTurnRow, GeneralTurnRow,
NationTurnRow, NationTurnRow,
InputJsonValue,
} from '../context.js'; } from '../context.js';
export const DEFAULT_TURN_ACTION = '휴식'; export const DEFAULT_TURN_ACTION = '휴식';
@@ -10,13 +11,13 @@ export const MAX_NATION_TURNS = 12;
export interface ReservedTurnEntry { export interface ReservedTurnEntry {
action: string; action: string;
args: Record<string, unknown>; args: InputJsonValue;
} }
export interface ReservedTurnView { export interface ReservedTurnView {
index: number; index: number;
action: string; action: string;
args: Record<string, unknown>; args: InputJsonValue;
} }
const isRecord = (value: unknown): value is Record<string, unknown> => const isRecord = (value: unknown): value is Record<string, unknown> =>
@@ -25,8 +26,8 @@ const isRecord = (value: unknown): value is Record<string, unknown> =>
const normalizeAction = (action: string | null | undefined): string => const normalizeAction = (action: string | null | undefined): string =>
action && action.length > 0 ? action : DEFAULT_TURN_ACTION; action && action.length > 0 ? action : DEFAULT_TURN_ACTION;
const normalizeArgs = (args: unknown): Record<string, unknown> => const normalizeArgs = (args: unknown): InputJsonValue =>
isRecord(args) ? args : {}; isRecord(args) ? (args as InputJsonValue) : {};
const createDefaultEntry = (): ReservedTurnEntry => ({ const createDefaultEntry = (): ReservedTurnEntry => ({
action: DEFAULT_TURN_ACTION, action: DEFAULT_TURN_ACTION,
+10 -10
View File
@@ -18,7 +18,7 @@ const buildDb = () => {
const generalTurns = new Map<number, GeneralTurnRow[]>(); const generalTurns = new Map<number, GeneralTurnRow[]>();
const nationTurns = new Map<string, NationTurnRow[]>(); const nationTurns = new Map<string, NationTurnRow[]>();
const db: DatabaseClient = { const db = {
worldState: { worldState: {
findFirst: async () => null, findFirst: async () => null,
}, },
@@ -32,13 +32,13 @@ const buildDb = () => {
findUnique: async () => null, findUnique: async () => null,
}, },
generalTurn: { generalTurn: {
findMany: async ({ where }) => generalTurns.get(where.generalId) ?? [], findMany: async ({ where }: any) => generalTurns.get(where.generalId) ?? [],
deleteMany: async ({ where }) => { deleteMany: async ({ where }: any) => {
generalTurns.delete(where.generalId); generalTurns.delete(where.generalId);
return {}; return {};
}, },
createMany: async ({ data }) => { createMany: async ({ data }: any) => {
const rows = data.map((row, index) => ({ const rows = data.map((row: any, index: number) => ({
id: index + 1, id: index + 1,
generalId: row.generalId, generalId: row.generalId,
turnIdx: row.turnIdx, turnIdx: row.turnIdx,
@@ -53,14 +53,14 @@ const buildDb = () => {
}, },
}, },
nationTurn: { nationTurn: {
findMany: async ({ where }) => findMany: async ({ where }: any) =>
nationTurns.get(`${where.nationId}:${where.officerLevel}`) ?? [], nationTurns.get(`${where.nationId}:${where.officerLevel}`) ?? [],
deleteMany: async ({ where }) => { deleteMany: async ({ where }: any) => {
nationTurns.delete(`${where.nationId}:${where.officerLevel}`); nationTurns.delete(`${where.nationId}:${where.officerLevel}`);
return {}; return {};
}, },
createMany: async ({ data }) => { createMany: async ({ data }: any) => {
const rows = data.map((row, index) => ({ const rows = data.map((row: any, index: number) => ({
id: index + 1, id: index + 1,
nationId: row.nationId, nationId: row.nationId,
officerLevel: row.officerLevel, officerLevel: row.officerLevel,
@@ -76,7 +76,7 @@ const buildDb = () => {
return {}; return {};
}, },
}, },
}; } as unknown as DatabaseClient;
return { db }; return { db };
}; };
+5
View File
@@ -8,6 +8,11 @@ export * from './config.js';
export * from './context.js'; export * from './context.js';
export * from './router.js'; export * from './router.js';
export * from './server.js'; export * from './server.js';
export { GatewayPrisma } from '@sammo-ts/infra';
export type JsonObject = GatewayPrisma.JsonObject;
export type JsonArray = GatewayPrisma.JsonArray;
export * from './orchestrator/profileRepository.js';
export * from './orchestrator/gatewayOrchestrator.js';
export * from './auth/userRepository.js'; export * from './auth/userRepository.js';
export * from './auth/passwordHasher.js'; export * from './auth/passwordHasher.js';
export * from './auth/inMemoryUserRepository.js'; export * from './auth/inMemoryUserRepository.js';
+1 -1
View File
@@ -1,5 +1,5 @@
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client'; import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '../../../gateway-api/src/router'; import type { AppRouter } from '@sammo-ts/gateway-api';
const getSessionToken = (): string | null => { const getSessionToken = (): string | null => {
if (typeof window === 'undefined') { if (typeof window === 'undefined') {
+3 -1
View File
@@ -33,7 +33,9 @@
"@sammo-ts/game-engine": ["../../app/game-engine/src/index.ts"], "@sammo-ts/game-engine": ["../../app/game-engine/src/index.ts"],
"@sammo-ts/game-engine/*": ["../../app/game-engine/src/*"], "@sammo-ts/game-engine/*": ["../../app/game-engine/src/*"],
"@sammo-ts/game-api": ["../../app/game-api/src/index.ts"], "@sammo-ts/game-api": ["../../app/game-api/src/index.ts"],
"@sammo-ts/game-api/*": ["../../app/game-api/src/*"] "@sammo-ts/game-api/*": ["../../app/game-api/src/*"],
"@sammo-ts/gateway-api": ["../../app/gateway-api/src/index.ts"],
"@sammo-ts/gateway-api/*": ["../../app/gateway-api/src/*"]
} }
}, },
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
+12 -88
View File
@@ -1,89 +1,13 @@
export interface DatabaseClient< import type { GamePrisma, GamePrismaClient } from './gamePrisma.js';
WorldStateRow = unknown,
GeneralRow = unknown, export interface DatabaseClient {
CityRow = unknown, $transaction: GamePrismaClient['$transaction'];
NationRow = unknown, $queryRaw: GamePrismaClient['$queryRaw'];
GeneralTurnRow = unknown, worldState: GamePrisma.WorldStateDelegate;
NationTurnRow = unknown, general: GamePrisma.GeneralDelegate;
TroopRow = unknown city: GamePrisma.CityDelegate;
> { nation: GamePrisma.NationDelegate;
$transaction<T = unknown>( generalTurn: GamePrisma.GeneralTurnDelegate;
queries: Array<Promise<T>> nationTurn: GamePrisma.NationTurnDelegate;
): Promise<T[]>; troop: GamePrisma.TroopDelegate;
$queryRaw<T = unknown>(
query: TemplateStringsArray,
...values: unknown[]
): Promise<T>;
worldState: {
findFirst(args?: unknown): Promise<WorldStateRow | null>;
};
general: {
findUnique(args: { where: { id: number } }): Promise<GeneralRow | null>;
findFirst(args: {
where: { userId?: string; npcState?: number | { gt: number } };
select?: { name?: boolean; picture?: boolean };
}): Promise<GeneralRow | null>;
findMany(args: {
where?: { nationId?: number };
}): Promise<GeneralRow[]>;
count(args?: {
where?: { npcState?: number | { gt: number } };
}): Promise<number>;
update(args: {
where: { id: number };
data: Partial<GeneralRow>;
}): Promise<GeneralRow>;
updateMany(args: {
where: { troopId?: number };
data: Partial<GeneralRow>;
}): Promise<unknown>;
};
city: {
findUnique(args: { where: { id: number } }): Promise<CityRow | null>;
};
nation: {
findUnique(args: { where: { id: number } }): Promise<NationRow | null>;
count(args?: { where?: { level?: { gt: number } } }): Promise<number>;
};
generalTurn: {
findMany(args: {
where: { generalId: number };
orderBy?: { turnIdx: 'asc' | 'desc' }[];
}): Promise<GeneralTurnRow[]>;
deleteMany(args: { where: { generalId: number } }): Promise<unknown>;
createMany(args: {
data: Array<{
generalId: number;
turnIdx: number;
actionCode: string;
arg: unknown;
}>;
}): Promise<unknown>;
};
nationTurn: {
findMany(args: {
where: { nationId: number; officerLevel: number };
orderBy?: { turnIdx: 'asc' | 'desc' }[];
}): Promise<NationTurnRow[]>;
deleteMany(args: {
where: { nationId: number; officerLevel: number };
}): Promise<unknown>;
createMany(args: {
data: Array<{
nationId: number;
officerLevel: number;
turnIdx: number;
actionCode: string;
arg: unknown;
}>;
}): Promise<unknown>;
};
troop: {
findUnique(args: {
where: { troopLeaderId: number };
}): Promise<TroopRow | null>;
deleteMany(args: {
where: { troopLeaderId: number };
}): Promise<unknown>;
};
} }