feat: refactor database client types and update related logic across game engine modules

This commit is contained in:
2025-12-30 12:40:55 +00:00
parent 4de688d642
commit cc78319948
10 changed files with 560 additions and 117 deletions
-1
View File
@@ -12,7 +12,6 @@
"typecheck": "tsc -b" "typecheck": "tsc -b"
}, },
"dependencies": { "dependencies": {
"@prisma/client": "^7.2.0",
"@sammo-ts/common": "workspace:*", "@sammo-ts/common": "workspace:*",
"@sammo-ts/infra": "workspace:*", "@sammo-ts/infra": "workspace:*",
"@sammo-ts/logic": "workspace:*", "@sammo-ts/logic": "workspace:*",
+10 -8
View File
@@ -1,6 +1,9 @@
import type { Prisma } from '@prisma/client'; import {
createPostgresConnector,
import { createPostgresConnector } from '@sammo-ts/infra'; type InputJsonValue,
type TurnEngineDatabaseClient,
type TurnEngineEventCreateManyInput,
} from '@sammo-ts/infra';
import { import {
buildScenarioBootstrap, buildScenarioBootstrap,
type ScenarioBootstrapWarning, type ScenarioBootstrapWarning,
@@ -37,8 +40,7 @@ export interface ScenarioSeedResult {
warnings: ScenarioBootstrapWarning[]; warnings: ScenarioBootstrapWarning[];
} }
const asJson = (value: unknown): Prisma.InputJsonValue => const asJson = (value: unknown): InputJsonValue => value as InputJsonValue;
value as Prisma.InputJsonValue;
const resolveGeneralAge = ( const resolveGeneralAge = (
startYear: number | null, startYear: number | null,
@@ -53,8 +55,8 @@ const resolveGeneralAge = (
const buildEventRows = ( const buildEventRows = (
rows: unknown[], rows: unknown[],
targetOverride?: string targetOverride?: string
): Prisma.EventCreateManyInput[] => { ): TurnEngineEventCreateManyInput[] => {
const result: Prisma.EventCreateManyInput[] = []; const result: TurnEngineEventCreateManyInput[] = [];
for (const row of rows) { for (const row of rows) {
if (!Array.isArray(row)) { if (!Array.isArray(row)) {
@@ -123,7 +125,7 @@ export const seedScenarioToDatabase = async (
await connector.connect(); await connector.connect();
try { try {
const prisma = connector.prisma; const prisma = connector.prisma as TurnEngineDatabaseClient;
if (options.resetTables ?? true) { if (options.resetTables ?? true) {
await prisma.event.deleteMany(); await prisma.event.deleteMany();
+41 -28
View File
@@ -1,6 +1,16 @@
import type { Prisma } from '@prisma/client'; import {
createPostgresConnector,
import { createPostgresConnector } from '@sammo-ts/infra'; type InputJsonValue,
type TurnEngineCityUpdateInput,
type TurnEngineDatabaseClient,
type TurnEngineGeneralCreateManyInput,
type TurnEngineGeneralUpdateInput,
type TurnEngineLogEntryCreateManyInput,
type TurnEngineNationUpdateInput,
type TurnEngineTroopCreateManyInput,
type TurnEngineTroopUpdateInput,
type TurnEngineWorldStateUpdateInput,
} from '@sammo-ts/infra';
import { finalizeLogEntry, type LogEntryDraft } from '@sammo-ts/logic'; import { finalizeLogEntry, type LogEntryDraft } from '@sammo-ts/logic';
import type { TurnDaemonHooks } from '../lifecycle/types.js'; import type { TurnDaemonHooks } from '../lifecycle/types.js';
@@ -12,8 +22,7 @@ export interface DatabaseTurnHooks {
close(): Promise<void>; close(): Promise<void>;
} }
const asJson = (value: unknown): Prisma.InputJsonValue => const asJson = (value: unknown): InputJsonValue => value as InputJsonValue;
value as Prisma.InputJsonValue;
const toCode = (value: string | null | undefined): string => const toCode = (value: string | null | undefined): string =>
value && value !== 'None' ? value : 'None'; value && value !== 'None' ? value : 'None';
@@ -28,7 +37,7 @@ const readMetaNumber = (
const buildGeneralUpdate = ( const buildGeneralUpdate = (
general: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['generals'][number] general: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['generals'][number]
): Prisma.GeneralUpdateInput => ({ ): TurnEngineGeneralUpdateInput => ({
name: general.name, name: general.name,
nationId: general.nationId, nationId: general.nationId,
cityId: general.cityId, cityId: general.cityId,
@@ -62,7 +71,7 @@ const buildGeneralUpdate = (
const buildGeneralCreate = ( const buildGeneralCreate = (
general: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['generals'][number] general: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['generals'][number]
): Prisma.GeneralCreateManyInput => ({ ): TurnEngineGeneralCreateManyInput => ({
id: general.id, id: general.id,
name: general.name, name: general.name,
nationId: general.nationId, nationId: general.nationId,
@@ -97,13 +106,13 @@ const buildGeneralCreate = (
const buildCityUpdate = ( const buildCityUpdate = (
city: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['cities'][number] city: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['cities'][number]
): Prisma.CityUpdateInput => { ): TurnEngineCityUpdateInput => {
const meta = city.meta as Record<string, unknown>; const meta = city.meta as Record<string, unknown>;
const trust = readMetaNumber(meta, 'trust'); const trust = readMetaNumber(meta, 'trust');
const trade = readMetaNumber(meta, 'trade'); const trade = readMetaNumber(meta, 'trade');
const region = readMetaNumber(meta, 'region'); const region = readMetaNumber(meta, 'region');
const data: Prisma.CityUpdateInput = { const data: TurnEngineCityUpdateInput = {
name: city.name, name: city.name,
nationId: city.nationId, nationId: city.nationId,
level: city.level, level: city.level,
@@ -139,7 +148,7 @@ const buildCityUpdate = (
const buildNationUpdate = ( const buildNationUpdate = (
nation: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['nations'][number] nation: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['nations'][number]
): Prisma.NationUpdateInput => ({ ): TurnEngineNationUpdateInput => ({
name: nation.name, name: nation.name,
color: nation.color, color: nation.color,
capitalCityId: nation.capitalCityId, capitalCityId: nation.capitalCityId,
@@ -152,14 +161,14 @@ const buildNationUpdate = (
const buildTroopUpdate = ( const buildTroopUpdate = (
troop: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['troops'][number] troop: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['troops'][number]
): Prisma.TroopUpdateInput => ({ ): TurnEngineTroopUpdateInput => ({
nationId: troop.nationId, nationId: troop.nationId,
name: troop.name, name: troop.name,
}); });
const buildTroopCreate = ( const buildTroopCreate = (
troop: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['troops'][number] troop: ReturnType<InMemoryTurnWorld['consumeDirtyState']>['troops'][number]
): Prisma.TroopCreateManyInput => ({ ): TurnEngineTroopCreateManyInput => ({
troopLeaderId: troop.id, troopLeaderId: troop.id,
nationId: troop.nationId, nationId: troop.nationId,
name: troop.name, name: troop.name,
@@ -168,7 +177,7 @@ const buildTroopCreate = (
const buildLogCreateData = ( const buildLogCreateData = (
entry: LogEntryDraft, entry: LogEntryDraft,
context: { year: number; month: number; at: Date } context: { year: number; month: number; at: Date }
): Prisma.LogEntryCreateManyInput | null => { ): TurnEngineLogEntryCreateManyInput | null => {
const record = finalizeLogEntry(entry, { const record = finalizeLogEntry(entry, {
year: context.year, year: context.year,
month: context.month, month: context.month,
@@ -201,6 +210,7 @@ export const createDatabaseTurnHooks = async (
// 턴 처리 결과를 DB에 반영하는 훅을 만든다. // 턴 처리 결과를 DB에 반영하는 훅을 만든다.
const connector = createPostgresConnector({ url: databaseUrl }); const connector = createPostgresConnector({ url: databaseUrl });
await connector.connect(); await connector.connect();
const prisma = connector.prisma as TurnEngineDatabaseClient;
const hooks: TurnDaemonHooks = { const hooks: TurnDaemonHooks = {
flushChanges: async () => { flushChanges: async () => {
@@ -215,14 +225,15 @@ export const createDatabaseTurnHooks = async (
createdTroops, createdTroops,
} = world.consumeDirtyState(); } = world.consumeDirtyState();
await connector.prisma.worldState.update({ const worldStateUpdate: TurnEngineWorldStateUpdateInput = {
currentYear: state.currentYear,
currentMonth: state.currentMonth,
tickSeconds: state.tickSeconds,
meta: asJson(state.meta),
};
await prisma.worldState.update({
where: { id: state.id }, where: { id: state.id },
data: { data: worldStateUpdate,
currentYear: state.currentYear,
currentMonth: state.currentMonth,
tickSeconds: state.tickSeconds,
meta: asJson(state.meta),
},
}); });
const createdIds = new Set( const createdIds = new Set(
@@ -233,12 +244,12 @@ export const createDatabaseTurnHooks = async (
); );
if (createdGenerals.length > 0) { if (createdGenerals.length > 0) {
await connector.prisma.general.createMany({ await prisma.general.createMany({
data: createdGenerals.map(buildGeneralCreate), data: createdGenerals.map(buildGeneralCreate),
}); });
} }
if (createdTroops.length > 0) { if (createdTroops.length > 0) {
await connector.prisma.troop.createMany({ await prisma.troop.createMany({
data: createdTroops.map(buildTroopCreate), data: createdTroops.map(buildTroopCreate),
}); });
} }
@@ -247,19 +258,19 @@ export const createDatabaseTurnHooks = async (
...generals ...generals
.filter((general) => !createdIds.has(general.id)) .filter((general) => !createdIds.has(general.id))
.map((general) => .map((general) =>
connector.prisma.general.update({ prisma.general.update({
where: { id: general.id }, where: { id: general.id },
data: buildGeneralUpdate(general), data: buildGeneralUpdate(general),
}) })
), ),
...cities.map((city) => ...cities.map((city) =>
connector.prisma.city.update({ prisma.city.update({
where: { id: city.id }, where: { id: city.id },
data: buildCityUpdate(city), data: buildCityUpdate(city),
}) })
), ),
...nations.map((nation) => ...nations.map((nation) =>
connector.prisma.nation.update({ prisma.nation.update({
where: { id: nation.id }, where: { id: nation.id },
data: buildNationUpdate(nation), data: buildNationUpdate(nation),
}) })
@@ -267,7 +278,7 @@ export const createDatabaseTurnHooks = async (
...troops ...troops
.filter((troop) => !createdTroopIds.has(troop.id)) .filter((troop) => !createdTroopIds.has(troop.id))
.map((troop) => .map((troop) =>
connector.prisma.troop.update({ prisma.troop.update({
where: { troopLeaderId: troop.id }, where: { troopLeaderId: troop.id },
data: buildTroopUpdate(troop), data: buildTroopUpdate(troop),
}) })
@@ -283,11 +294,13 @@ export const createDatabaseTurnHooks = async (
const payload = logs const payload = logs
.map((entry) => buildLogCreateData(entry, logContext)) .map((entry) => buildLogCreateData(entry, logContext))
.filter( .filter(
(entry): entry is Prisma.LogEntryCreateManyInput => (
entry
): entry is TurnEngineLogEntryCreateManyInput =>
Boolean(entry) Boolean(entry)
); );
if (payload.length > 0) { if (payload.length > 0) {
await connector.prisma.logEntry.createMany({ await prisma.logEntry.createMany({
data: payload, data: payload,
}); });
} }
+12 -56
View File
@@ -1,6 +1,8 @@
import type { Prisma } from '@prisma/client'; import {
createPostgresConnector,
import { createPostgresConnector } from '@sammo-ts/infra'; type InputJsonValue,
type TurnEngineDatabaseClient,
} from '@sammo-ts/infra';
export interface ReservedTurnEntry { export interface ReservedTurnEntry {
action: string; action: string;
@@ -22,8 +24,7 @@ const DEFAULT_TURN_ACTION = '휴식';
const DEFAULT_GENERAL_TURNS = 30; const DEFAULT_GENERAL_TURNS = 30;
const DEFAULT_NATION_TURNS = 12; const DEFAULT_NATION_TURNS = 12;
const asJson = (value: unknown): Prisma.InputJsonValue => const asJson = (value: unknown): InputJsonValue => value as InputJsonValue;
value as Prisma.InputJsonValue;
const isRecord = (value: unknown): value is Record<string, unknown> => const isRecord = (value: unknown): value is Record<string, unknown> =>
value !== null && typeof value === 'object' && !Array.isArray(value); value !== null && typeof value === 'object' && !Array.isArray(value);
@@ -81,50 +82,10 @@ const buildTurnListFromRows = (
const buildNationKey = (nationId: number, officerLevel: number): string => const buildNationKey = (nationId: number, officerLevel: number): string =>
`${nationId}:${officerLevel}`; `${nationId}:${officerLevel}`;
interface PrismaReservedTurnClient { type ReservedTurnDatabaseClient = Pick<
generalTurn: { TurnEngineDatabaseClient,
findMany(args?: unknown): Promise< 'generalTurn' | 'nationTurn'
Array<{ >;
generalId: number;
turnIdx: number;
actionCode: string;
arg: unknown;
}>
>;
deleteMany(args: { where: { generalId: number } }): Promise<unknown>;
createMany(args: {
data: Array<{
generalId: number;
turnIdx: number;
actionCode: string;
arg: Prisma.InputJsonValue;
}>;
}): Promise<unknown>;
};
nationTurn: {
findMany(args?: unknown): Promise<
Array<{
nationId: number;
officerLevel: number;
turnIdx: number;
actionCode: string;
arg: unknown;
}>
>;
deleteMany(args: {
where: { nationId: number; officerLevel: number };
}): Promise<unknown>;
createMany(args: {
data: Array<{
nationId: number;
officerLevel: number;
turnIdx: number;
actionCode: string;
arg: Prisma.InputJsonValue;
}>;
}): Promise<unknown>;
};
}
export class InMemoryReservedTurnStore { export class InMemoryReservedTurnStore {
private readonly generalTurns = new Map<number, ReservedTurnEntry[]>(); private readonly generalTurns = new Map<number, ReservedTurnEntry[]>();
@@ -135,7 +96,7 @@ export class InMemoryReservedTurnStore {
private readonly maxNationTurns: number; private readonly maxNationTurns: number;
constructor( constructor(
private readonly prisma: PrismaClientOrAdapter, private readonly prisma: ReservedTurnDatabaseClient,
options: { maxGeneralTurns: number; maxNationTurns: number } options: { maxGeneralTurns: number; maxNationTurns: number }
) { ) {
this.maxGeneralTurns = options.maxGeneralTurns; this.maxGeneralTurns = options.maxGeneralTurns;
@@ -305,18 +266,13 @@ export class InMemoryReservedTurnStore {
} }
} }
type PrismaClientOrAdapter = ReturnType<
typeof createPostgresConnector
>['prisma'] &
PrismaReservedTurnClient;
export const createReservedTurnStore = async ( export const createReservedTurnStore = async (
options: ReservedTurnStoreOptions options: ReservedTurnStoreOptions
): Promise<ReservedTurnStoreHandle> => { ): Promise<ReservedTurnStoreHandle> => {
const connector = createPostgresConnector({ url: options.databaseUrl }); const connector = createPostgresConnector({ url: options.databaseUrl });
await connector.connect(); await connector.connect();
const store = new InMemoryReservedTurnStore( const store = new InMemoryReservedTurnStore(
connector.prisma as PrismaClientOrAdapter, connector.prisma as ReservedTurnDatabaseClient,
{ {
maxGeneralTurns: options.maxGeneralTurns ?? DEFAULT_GENERAL_TURNS, maxGeneralTurns: options.maxGeneralTurns ?? DEFAULT_GENERAL_TURNS,
maxNationTurns: options.maxNationTurns ?? DEFAULT_NATION_TURNS, maxNationTurns: options.maxNationTurns ?? DEFAULT_NATION_TURNS,
+17 -17
View File
@@ -1,13 +1,13 @@
import type { import {
City as PrismaCity, createPostgresConnector,
Diplomacy as PrismaDiplomacy, type JsonValue,
General as PrismaGeneral, type TurnEngineCityRow,
Nation as PrismaNation, type TurnEngineDatabaseClient,
Prisma, type TurnEngineDiplomacyRow,
Troop as PrismaTroop, type TurnEngineGeneralRow,
} from '@prisma/client'; type TurnEngineNationRow,
type TurnEngineTroopRow,
import { createPostgresConnector } from '@sammo-ts/infra'; } from '@sammo-ts/infra';
import type { import type {
City, City,
Nation, Nation,
@@ -126,7 +126,7 @@ const alignToPreviousTick = (base: Date, tickMinutes: number): Date => {
return new Date(nextTick.getTime() - tickMinutes * 60_000); return new Date(nextTick.getTime() - tickMinutes * 60_000);
}; };
const mapScenarioConfig = (raw: Prisma.JsonValue): ScenarioConfig => { const mapScenarioConfig = (raw: JsonValue): ScenarioConfig => {
const parsed = zScenarioConfig.safeParse(raw); const parsed = zScenarioConfig.safeParse(raw);
if (!parsed.success) { if (!parsed.success) {
throw new Error(`world_state.config is invalid: ${parsed.error.message}`); throw new Error(`world_state.config is invalid: ${parsed.error.message}`);
@@ -134,7 +134,7 @@ const mapScenarioConfig = (raw: Prisma.JsonValue): ScenarioConfig => {
return parsed.data; return parsed.data;
}; };
const mapGeneralRow = (row: PrismaGeneral): TurnGeneral => ({ const mapGeneralRow = (row: TurnEngineGeneralRow): TurnGeneral => ({
id: row.id, id: row.id,
name: row.name, name: row.name,
nationId: row.nationId, nationId: row.nationId,
@@ -179,7 +179,7 @@ const mapGeneralRow = (row: PrismaGeneral): TurnGeneral => ({
recentWarTime: row.recentWarTime ?? null, recentWarTime: row.recentWarTime ?? null,
}); });
const mapCityRow = (row: PrismaCity): City => ({ const mapCityRow = (row: TurnEngineCityRow): City => ({
id: row.id, id: row.id,
name: row.name, name: row.name,
nationId: row.nationId, nationId: row.nationId,
@@ -206,7 +206,7 @@ const mapCityRow = (row: PrismaCity): City => ({
}, },
}); });
const mapNationRow = (row: PrismaNation): Nation => ({ const mapNationRow = (row: TurnEngineNationRow): Nation => ({
id: row.id, id: row.id,
name: row.name, name: row.name,
color: row.color, color: row.color,
@@ -223,14 +223,14 @@ const mapNationRow = (row: PrismaNation): Nation => ({
}, },
}); });
const mapDiplomacyRow = (row: PrismaDiplomacy): ScenarioDiplomacy => ({ const mapDiplomacyRow = (row: TurnEngineDiplomacyRow): ScenarioDiplomacy => ({
fromNationId: row.srcNationId, fromNationId: row.srcNationId,
toNationId: row.destNationId, toNationId: row.destNationId,
state: row.stateCode, state: row.stateCode,
durationMonths: row.term, durationMonths: row.term,
}); });
const mapTroopRow = (row: PrismaTroop): Troop => ({ const mapTroopRow = (row: TurnEngineTroopRow): Troop => ({
id: row.troopLeaderId, id: row.troopLeaderId,
nationId: row.nationId, nationId: row.nationId,
name: row.name, name: row.name,
@@ -242,7 +242,7 @@ export const loadTurnWorldFromDatabase = async (
const connector = createPostgresConnector({ url: options.databaseUrl }); const connector = createPostgresConnector({ url: options.databaseUrl });
await connector.connect(); await connector.connect();
try { try {
const prisma = connector.prisma; const prisma = connector.prisma as TurnEngineDatabaseClient;
const worldState = await prisma.worldState.findFirst(); const worldState = await prisma.worldState.findFirst();
if (!worldState) { if (!worldState) {
throw new Error('world_state row is required to start turn daemon.'); throw new Error('world_state row is required to start turn daemon.');
+22 -2
View File
@@ -6,11 +6,31 @@ import { seedScenarioToDatabase } from '../src/scenario/scenarioSeeder.js';
const scenarioId = 1010; const scenarioId = 1010;
const databaseUrl = await resolveDatabaseUrl(); const databaseUrl = await resolveDatabaseUrl();
type ScenarioSeederPrismaClient = {
$queryRawUnsafe(query: string): Promise<unknown>;
nation: {
count(): Promise<number>;
};
city: {
count(): Promise<number>;
};
general: {
count(): Promise<number>;
};
diplomacy: {
count(): Promise<number>;
findFirst(args: {
where: { srcNationId: number; destNationId: number };
}): Promise<{ stateCode: string } | null>;
};
};
const canConnectToDatabase = async (url: string): Promise<boolean> => { const canConnectToDatabase = async (url: string): Promise<boolean> => {
const connector = createPostgresConnector({ url }); const connector = createPostgresConnector({ url });
try { try {
await connector.connect(); await connector.connect();
await connector.prisma.$queryRawUnsafe('SELECT 1'); const prisma = connector.prisma as ScenarioSeederPrismaClient;
await prisma.$queryRawUnsafe('SELECT 1');
return true; return true;
} catch { } catch {
return false; return false;
@@ -32,7 +52,7 @@ describeDb('scenario database seed', () => {
const connector = createPostgresConnector({ url: databaseUrl }); const connector = createPostgresConnector({ url: databaseUrl });
await connector.connect(); await connector.connect();
try { try {
const prisma = connector.prisma; const prisma = connector.prisma as ScenarioSeederPrismaClient;
const [ const [
nationCount, nationCount,
cityCount, cityCount,
+4 -1
View File
@@ -1,6 +1,7 @@
import fastify from 'fastify'; import fastify from 'fastify';
import cors from '@fastify/cors'; import cors from '@fastify/cors';
import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify'; import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
import type { PrismaClient } from '@prisma/client';
import { import {
createPostgresConnector, createPostgresConnector,
createRedisConnector, createRedisConnector,
@@ -24,7 +25,9 @@ export const createGatewayApiServer = async () => {
await postgres.connect(); await postgres.connect();
await redis.connect(); await redis.connect();
const users = createPostgresUserRepository(postgres.prisma); const users = createPostgresUserRepository(
postgres.prisma as PrismaClient
);
const sessions = new RedisGatewaySessionService(redis.client, { const sessions = new RedisGatewaySessionService(redis.client, {
keyPrefix: config.redisKeyPrefix, keyPrefix: config.redisKeyPrefix,
sessionTtlSeconds: config.sessionTtlSeconds, sessionTtlSeconds: config.sessionTtlSeconds,
+1
View File
@@ -2,3 +2,4 @@ export * from './postgres.js';
export * from './db.js'; export * from './db.js';
export * from './logRepository.js'; export * from './logRepository.js';
export * from './redis.js'; export * from './redis.js';
export * from './turnEngineDb.js';
+13 -4
View File
@@ -1,14 +1,23 @@
import { Prisma, PrismaClient } from '@prisma/client'; import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg'; import { PrismaPg } from '@prisma/adapter-pg';
import { Pool } from 'pg'; import { Pool } from 'pg';
export type PostgresLogLevel = 'query' | 'info' | 'warn' | 'error';
export type PostgresLogOption =
| PostgresLogLevel
| {
emit: 'stdout' | 'event';
level: PostgresLogLevel;
};
export interface PostgresConfig { export interface PostgresConfig {
url: string; url: string;
log?: Prisma.PrismaClientOptions['log']; log?: PostgresLogOption[];
} }
export interface PostgresConnector { export interface PostgresConnector<TClient = unknown> {
readonly prisma: PrismaClient; readonly prisma: TClient;
connect(): Promise<void>; connect(): Promise<void>;
disconnect(): Promise<void>; disconnect(): Promise<void>;
} }
+440
View File
@@ -0,0 +1,440 @@
export type JsonValue =
| null
| boolean
| number
| string
| JsonValue[]
| { [key: string]: JsonValue };
export type InputJsonValue = JsonValue;
export interface TurnEngineWorldStateRow {
id: number;
scenarioCode: string;
currentYear: number;
currentMonth: number;
tickSeconds: number;
config: JsonValue;
meta: JsonValue;
updatedAt?: Date | null;
}
export interface TurnEngineGeneralRow {
id: number;
name: string;
nationId: number;
cityId: number;
troopId: number;
leadership: number;
strength: number;
intel: number;
experience: number;
dedication: number;
officerLevel: number;
personalCode: string | null;
specialCode: string | null;
special2Code: string | null;
horseCode: string | null;
weaponCode: string | null;
bookCode: string | null;
itemCode: string | null;
injury: number;
gold: number;
rice: number;
crew: number;
crewTypeId: number;
train: number;
atmos: number;
age: number;
npcState: number;
meta: JsonValue;
turnTime: Date;
recentWarTime: Date | null;
}
export interface TurnEngineCityRow {
id: number;
name: string;
nationId: number;
level: number;
population: number;
populationMax: number;
agriculture: number;
agricultureMax: number;
commerce: number;
commerceMax: number;
security: number;
securityMax: number;
supplyState: number;
frontState: number;
defence: number;
defenceMax: number;
wall: number;
wallMax: number;
meta: JsonValue;
trust: number;
trade: number;
region: number;
}
export interface TurnEngineNationRow {
id: number;
name: string;
color: string;
capitalCityId: number | null;
gold: number;
rice: number;
tech: number;
level: number;
typeCode: string;
meta: JsonValue;
}
export interface TurnEngineDiplomacyRow {
srcNationId: number;
destNationId: number;
stateCode: number;
term: number;
}
export interface TurnEngineTroopRow {
troopLeaderId: number;
nationId: number;
name: string;
}
export interface TurnEngineEventRow {
id: number;
targetCode: string;
priority: number;
condition: JsonValue;
action: JsonValue;
meta: JsonValue;
}
export interface TurnEngineGeneralTurnRow {
generalId: number;
turnIdx: number;
actionCode: string;
arg: JsonValue;
}
export interface TurnEngineNationTurnRow {
nationId: number;
officerLevel: number;
turnIdx: number;
actionCode: string;
arg: JsonValue;
}
export interface TurnEngineWorldStateUpdateInput {
currentYear: number;
currentMonth: number;
tickSeconds: number;
meta: InputJsonValue;
}
export interface TurnEngineWorldStateCreateInput {
scenarioCode: string;
currentYear: number;
currentMonth: number;
tickSeconds: number;
config: InputJsonValue;
meta: InputJsonValue;
}
export interface TurnEngineGeneralUpdateInput {
name: string;
nationId: number;
cityId: number;
troopId: number | null;
leadership: number;
strength: number;
intel: number;
experience: number;
dedication: number;
officerLevel: number;
injury: number;
gold: number;
rice: number;
crew: number;
crewTypeId: number;
train: number;
atmos: number;
age: number;
npcState: number;
horseCode: string;
weaponCode: string;
bookCode: string;
itemCode: string;
personalCode: string;
specialCode: string;
special2Code: string;
meta: InputJsonValue;
turnTime: Date;
recentWarTime: Date | null;
}
export interface TurnEngineGeneralCreateManyInput {
id: number;
name: string;
nationId: number;
cityId: number;
troopId?: number | null;
npcState: number;
leadership: number;
strength: number;
intel: number;
experience?: number;
dedication?: number;
officerLevel: number;
injury?: number;
gold: number;
rice: number;
crew?: number;
crewTypeId: number;
train?: number;
atmos?: number;
age: number;
horseCode: string;
weaponCode: string;
bookCode: string;
itemCode: string;
personalCode: string;
specialCode: string;
special2Code: string;
meta: InputJsonValue;
turnTime: Date;
recentWarTime?: Date | null;
affinity?: number | null;
bornYear?: number;
deadYear?: number;
picture?: string | null;
lastTurn?: InputJsonValue;
penalty?: InputJsonValue;
}
export interface TurnEngineCityUpdateInput {
name: string;
nationId: number;
level: number;
population: number;
populationMax: number;
agriculture: number;
agricultureMax: number;
commerce: number;
commerceMax: number;
security: number;
securityMax: number;
supplyState: number;
frontState: number;
defence: number;
defenceMax: number;
wall: number;
wallMax: number;
meta: InputJsonValue;
trust?: number;
trade?: number;
region?: number;
}
export interface TurnEngineCityCreateManyInput {
id: number;
name: string;
level: number;
nationId: number;
supplyState: number;
frontState: number;
population: number;
populationMax: number;
agriculture: number;
agricultureMax: number;
commerce: number;
commerceMax: number;
security: number;
securityMax: number;
trust: number;
trade: number;
defence: number;
defenceMax: number;
wall: number;
wallMax: number;
region: number;
conflict: InputJsonValue;
meta: InputJsonValue;
}
export interface TurnEngineNationUpdateInput {
name: string;
color: string;
capitalCityId: number | null;
gold: number;
rice: number;
level: number;
typeCode: string;
meta: InputJsonValue;
}
export interface TurnEngineNationCreateManyInput {
id: number;
name: string;
color: string;
capitalCityId: number | null;
gold: number;
rice: number;
tech: number;
level: number;
typeCode: string;
meta: InputJsonValue;
}
export interface TurnEngineTroopUpdateInput {
nationId: number;
name: string;
}
export interface TurnEngineTroopCreateManyInput {
troopLeaderId: number;
nationId: number;
name: string;
}
export interface TurnEngineDiplomacyCreateManyInput {
srcNationId: number;
destNationId: number;
stateCode: number;
term: number;
meta: InputJsonValue;
}
export interface TurnEngineEventCreateManyInput {
targetCode: string;
priority: number;
condition: InputJsonValue;
action: InputJsonValue;
meta: InputJsonValue;
}
export interface TurnEngineLogEntryCreateManyInput {
scope: string;
category: string;
subType: string | null;
year: number;
month: number;
text: string;
generalId: number | null;
nationId: number | null;
userId: number | null;
meta: InputJsonValue;
createdAt?: Date;
}
export interface TurnEngineDatabaseClient {
worldState: {
findFirst(args?: unknown): Promise<TurnEngineWorldStateRow | null>;
update(args: {
where: { id: number };
data: TurnEngineWorldStateUpdateInput;
}): Promise<unknown>;
create(args: {
data: TurnEngineWorldStateCreateInput;
}): Promise<unknown>;
deleteMany(args?: unknown): Promise<unknown>;
};
general: {
findMany(args?: unknown): Promise<TurnEngineGeneralRow[]>;
createMany(args: {
data: TurnEngineGeneralCreateManyInput[];
}): Promise<unknown>;
update(args: {
where: { id: number };
data: TurnEngineGeneralUpdateInput;
}): Promise<unknown>;
deleteMany(args?: unknown): Promise<unknown>;
};
city: {
findMany(args?: unknown): Promise<TurnEngineCityRow[]>;
createMany(args: {
data: TurnEngineCityCreateManyInput[];
}): Promise<unknown>;
update(args: {
where: { id: number };
data: TurnEngineCityUpdateInput;
}): Promise<unknown>;
deleteMany(args?: unknown): Promise<unknown>;
};
nation: {
findMany(args?: unknown): Promise<TurnEngineNationRow[]>;
createMany(args: {
data: TurnEngineNationCreateManyInput[];
}): Promise<unknown>;
update(args: {
where: { id: number };
data: TurnEngineNationUpdateInput;
}): Promise<unknown>;
deleteMany(args?: unknown): Promise<unknown>;
};
diplomacy: {
findMany(args?: unknown): Promise<TurnEngineDiplomacyRow[]>;
createMany(args: {
data: TurnEngineDiplomacyCreateManyInput[];
}): Promise<unknown>;
deleteMany(args?: unknown): Promise<unknown>;
};
troop: {
findMany(args?: unknown): Promise<TurnEngineTroopRow[]>;
createMany(args: {
data: TurnEngineTroopCreateManyInput[];
}): Promise<unknown>;
update(args: {
where: { troopLeaderId: number };
data: TurnEngineTroopUpdateInput;
}): Promise<unknown>;
deleteMany(args?: unknown): Promise<unknown>;
};
event: {
findMany(args?: unknown): Promise<TurnEngineEventRow[]>;
createMany(args: {
data: TurnEngineEventCreateManyInput[];
}): Promise<unknown>;
deleteMany(args?: unknown): Promise<unknown>;
};
logEntry: {
createMany(args: {
data: TurnEngineLogEntryCreateManyInput[];
}): Promise<unknown>;
};
generalTurn: {
findMany(args?: {
where?: { generalId?: number };
orderBy?: { turnIdx: 'asc' | 'desc' }[];
}): Promise<TurnEngineGeneralTurnRow[]>;
deleteMany(args: { where: { generalId: number } }): Promise<unknown>;
createMany(args: {
data: Array<{
generalId: number;
turnIdx: number;
actionCode: string;
arg: InputJsonValue;
}>;
}): Promise<unknown>;
};
nationTurn: {
findMany(args?: {
where?: { nationId?: number; officerLevel?: number };
orderBy?: { turnIdx: 'asc' | 'desc' }[];
}): Promise<TurnEngineNationTurnRow[]>;
deleteMany(args: {
where: { nationId: number; officerLevel: number };
}): Promise<unknown>;
createMany(args: {
data: Array<{
nationId: number;
officerLevel: number;
turnIdx: number;
actionCode: string;
arg: InputJsonValue;
}>;
}): Promise<unknown>;
};
}