From 49942cea5e0cd9de4f489704fd1999c9819e1773 Mon Sep 17 00:00:00 2001 From: Hide_D Date: Thu, 1 Jan 2026 11:53:21 +0000 Subject: [PATCH] feat: Add WallRepairActionDefinition and enhance GatewayProfileClient for improved database interactions --- app/game-api/src/turns/commandTable.ts | 1 + .../src/turn/gatewayProfileGate.ts | 14 +++++- .../src/turn/reservedTurnHandler.ts | 1 + .../src/orchestrator/profileRepository.ts | 48 ++++++++++++++----- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/app/game-api/src/turns/commandTable.ts b/app/game-api/src/turns/commandTable.ts index 8eaac53..9b3b407 100644 --- a/app/game-api/src/turns/commandTable.ts +++ b/app/game-api/src/turns/commandTable.ts @@ -33,6 +33,7 @@ import { TrainingActionDefinition, UprisingActionDefinition, VolunteerRecruitActionDefinition, + WallRepairActionDefinition, } from '@sammo-ts/logic'; import type { diff --git a/app/game-engine/src/turn/gatewayProfileGate.ts b/app/game-engine/src/turn/gatewayProfileGate.ts index 7c6c242..af5df80 100644 --- a/app/game-engine/src/turn/gatewayProfileGate.ts +++ b/app/game-engine/src/turn/gatewayProfileGate.ts @@ -1,5 +1,4 @@ import { createPostgresConnector } from '@sammo-ts/infra'; -import type { PrismaClient } from '@prisma/client'; export interface GatewayProfileGateOptions { databaseUrl: string; @@ -18,12 +17,23 @@ const DEFAULT_CACHE_MS = 2000; const isRunningStatus = (status: string | null | undefined): boolean => status === 'RUNNING'; +type GatewayProfileRow = { + status: string | null; +}; + +type GatewayProfileClient = { + findUnique(args: unknown): Promise; + update(args: unknown): Promise; +}; + export const createGatewayProfileGate = async ( options: GatewayProfileGateOptions ): Promise => { const connector = createPostgresConnector({ url: options.databaseUrl }); await connector.connect(); - const prisma = connector.prisma as PrismaClient; + const prisma = connector.prisma as unknown as { + gatewayProfile: GatewayProfileClient; + }; let lastCheckedAt = 0; let cachedPause = false; diff --git a/app/game-engine/src/turn/reservedTurnHandler.ts b/app/game-engine/src/turn/reservedTurnHandler.ts index 71d3b1b..aa0d955 100644 --- a/app/game-engine/src/turn/reservedTurnHandler.ts +++ b/app/game-engine/src/turn/reservedTurnHandler.ts @@ -37,6 +37,7 @@ import { TrainingActionDefinition, UprisingActionDefinition, VolunteerRecruitActionDefinition, + WallRepairActionDefinition, } from '@sammo-ts/logic'; import { LogCategory, LogFormat, LogScope } from '@sammo-ts/logic'; import { LiteHashDRBG } from '@sammo-ts/common'; diff --git a/app/gateway-api/src/orchestrator/profileRepository.ts b/app/gateway-api/src/orchestrator/profileRepository.ts index 5a8ff5e..bd22407 100644 --- a/app/gateway-api/src/orchestrator/profileRepository.ts +++ b/app/gateway-api/src/orchestrator/profileRepository.ts @@ -95,7 +95,7 @@ export interface GatewayProfileRepository { const toIso = (value: Date | null): string | undefined => value ? value.toISOString() : undefined; -const mapProfile = (row: { +type GatewayProfileRow = { profileName: string; profile: string; scenario: string; @@ -116,7 +116,18 @@ const mapProfile = (row: { meta: Prisma.JsonValue; createdAt: Date; updatedAt: Date; -}): GatewayProfileRecord => ({ +}; + +type GatewayProfileClient = { + findMany(args: unknown): Promise; + findUnique(args: unknown): Promise; + findFirst(args: unknown): Promise; + upsert(args: unknown): Promise; + update(args: unknown): Promise; + updateMany(args: unknown): Promise; +}; + +const mapProfile = (row: GatewayProfileRow): GatewayProfileRecord => ({ profileName: row.profileName, profile: row.profile, scenario: row.scenario, @@ -146,20 +157,23 @@ export const createGatewayProfileRepository = ( prisma: PrismaClient ): GatewayProfileRepository => ({ async listProfiles(): Promise { - const rows = await prisma.gatewayProfile.findMany({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + const rows = await gatewayProfile.findMany({ orderBy: [{ profile: 'asc' }, { scenario: 'asc' }], }); return rows.map(mapProfile); }, async getProfile(profileName: string): Promise { - const row = await prisma.gatewayProfile.findUnique({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + const row = await gatewayProfile.findUnique({ where: { profileName }, }); return row ? mapProfile(row) : null; }, async upsertProfile(input: GatewayProfileUpsertInput): Promise { + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; const profileName = buildProfileName(input.profile, input.scenario); - const row = await prisma.gatewayProfile.upsert({ + const row = await gatewayProfile.upsert({ where: { profileName }, create: { profileName, @@ -211,7 +225,8 @@ export const createGatewayProfileRepository = ( scheduledStartAt?: string | null; } ): Promise { - const row = await prisma.gatewayProfile.update({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + const row = await gatewayProfile.update({ where: { profileName }, data: { status, @@ -245,9 +260,13 @@ export const createGatewayProfileRepository = ( startedAt?: string | null; completedAt?: string | null; error?: string | null; + commitSha?: string | null; + workspace?: string | null; + lastUsedAt?: string | null; } ): Promise { - const row = await prisma.gatewayProfile.update({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + const row = await gatewayProfile.update({ where: { profileName }, data: { buildStatus: status, @@ -285,7 +304,8 @@ export const createGatewayProfileRepository = ( return row ? mapProfile(row) : null; }, async listReservedToStart(now: Date): Promise { - const rows = await prisma.gatewayProfile.findMany({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + const rows = await gatewayProfile.findMany({ where: { status: 'RESERVED', preopenAt: { @@ -296,14 +316,16 @@ export const createGatewayProfileRepository = ( return rows.map(mapProfile); }, async findQueuedBuild(): Promise { - const row = await prisma.gatewayProfile.findFirst({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + const row = await gatewayProfile.findFirst({ where: { buildStatus: 'QUEUED' }, orderBy: { buildRequestedAt: 'asc' }, }); return row ? mapProfile(row) : null; }, async updateLastError(profileName: string, lastError: string | null): Promise { - await prisma.gatewayProfile.update({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + await gatewayProfile.update({ where: { profileName }, data: { lastError }, }); @@ -313,7 +335,8 @@ export const createGatewayProfileRepository = ( workspace: string, lastUsedAt: string ): Promise { - await prisma.gatewayProfile.update({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + await gatewayProfile.update({ where: { profileName }, data: { buildWorkspace: workspace, @@ -325,7 +348,8 @@ export const createGatewayProfileRepository = ( if (!profileNames.length) { return; } - await prisma.gatewayProfile.updateMany({ + const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient; + await gatewayProfile.updateMany({ where: { profileName: { in: profileNames }, },