feat: Add WallRepairActionDefinition and enhance GatewayProfileClient for improved database interactions

This commit is contained in:
2026-01-01 11:53:21 +00:00
parent cce57d0fea
commit 49942cea5e
4 changed files with 50 additions and 14 deletions
+1
View File
@@ -33,6 +33,7 @@ import {
TrainingActionDefinition, TrainingActionDefinition,
UprisingActionDefinition, UprisingActionDefinition,
VolunteerRecruitActionDefinition, VolunteerRecruitActionDefinition,
WallRepairActionDefinition,
} from '@sammo-ts/logic'; } from '@sammo-ts/logic';
import type { import type {
+12 -2
View File
@@ -1,5 +1,4 @@
import { createPostgresConnector } from '@sammo-ts/infra'; import { createPostgresConnector } from '@sammo-ts/infra';
import type { PrismaClient } from '@prisma/client';
export interface GatewayProfileGateOptions { export interface GatewayProfileGateOptions {
databaseUrl: string; databaseUrl: string;
@@ -18,12 +17,23 @@ const DEFAULT_CACHE_MS = 2000;
const isRunningStatus = (status: string | null | undefined): boolean => const isRunningStatus = (status: string | null | undefined): boolean =>
status === 'RUNNING'; status === 'RUNNING';
type GatewayProfileRow = {
status: string | null;
};
type GatewayProfileClient = {
findUnique(args: unknown): Promise<GatewayProfileRow | null>;
update(args: unknown): Promise<void>;
};
export const createGatewayProfileGate = async ( export const createGatewayProfileGate = async (
options: GatewayProfileGateOptions options: GatewayProfileGateOptions
): Promise<GatewayProfileGate> => { ): Promise<GatewayProfileGate> => {
const connector = createPostgresConnector({ url: options.databaseUrl }); const connector = createPostgresConnector({ url: options.databaseUrl });
await connector.connect(); await connector.connect();
const prisma = connector.prisma as PrismaClient; const prisma = connector.prisma as unknown as {
gatewayProfile: GatewayProfileClient;
};
let lastCheckedAt = 0; let lastCheckedAt = 0;
let cachedPause = false; let cachedPause = false;
@@ -37,6 +37,7 @@ import {
TrainingActionDefinition, TrainingActionDefinition,
UprisingActionDefinition, UprisingActionDefinition,
VolunteerRecruitActionDefinition, VolunteerRecruitActionDefinition,
WallRepairActionDefinition,
} from '@sammo-ts/logic'; } from '@sammo-ts/logic';
import { LogCategory, LogFormat, LogScope } from '@sammo-ts/logic'; import { LogCategory, LogFormat, LogScope } from '@sammo-ts/logic';
import { LiteHashDRBG } from '@sammo-ts/common'; import { LiteHashDRBG } from '@sammo-ts/common';
@@ -95,7 +95,7 @@ export interface GatewayProfileRepository {
const toIso = (value: Date | null): string | undefined => const toIso = (value: Date | null): string | undefined =>
value ? value.toISOString() : undefined; value ? value.toISOString() : undefined;
const mapProfile = (row: { type GatewayProfileRow = {
profileName: string; profileName: string;
profile: string; profile: string;
scenario: string; scenario: string;
@@ -116,7 +116,18 @@ const mapProfile = (row: {
meta: Prisma.JsonValue; meta: Prisma.JsonValue;
createdAt: Date; createdAt: Date;
updatedAt: Date; updatedAt: Date;
}): GatewayProfileRecord => ({ };
type GatewayProfileClient = {
findMany(args: unknown): Promise<GatewayProfileRow[]>;
findUnique(args: unknown): Promise<GatewayProfileRow | null>;
findFirst(args: unknown): Promise<GatewayProfileRow | null>;
upsert(args: unknown): Promise<GatewayProfileRow>;
update(args: unknown): Promise<GatewayProfileRow>;
updateMany(args: unknown): Promise<unknown>;
};
const mapProfile = (row: GatewayProfileRow): GatewayProfileRecord => ({
profileName: row.profileName, profileName: row.profileName,
profile: row.profile, profile: row.profile,
scenario: row.scenario, scenario: row.scenario,
@@ -146,20 +157,23 @@ export const createGatewayProfileRepository = (
prisma: PrismaClient prisma: PrismaClient
): GatewayProfileRepository => ({ ): GatewayProfileRepository => ({
async listProfiles(): Promise<GatewayProfileRecord[]> { async listProfiles(): Promise<GatewayProfileRecord[]> {
const rows = await prisma.gatewayProfile.findMany({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
const rows = await gatewayProfile.findMany({
orderBy: [{ profile: 'asc' }, { scenario: 'asc' }], orderBy: [{ profile: 'asc' }, { scenario: 'asc' }],
}); });
return rows.map(mapProfile); return rows.map(mapProfile);
}, },
async getProfile(profileName: string): Promise<GatewayProfileRecord | null> { async getProfile(profileName: string): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.findUnique({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
const row = await gatewayProfile.findUnique({
where: { profileName }, where: { profileName },
}); });
return row ? mapProfile(row) : null; return row ? mapProfile(row) : null;
}, },
async upsertProfile(input: GatewayProfileUpsertInput): Promise<GatewayProfileRecord> { async upsertProfile(input: GatewayProfileUpsertInput): Promise<GatewayProfileRecord> {
const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
const profileName = buildProfileName(input.profile, input.scenario); const profileName = buildProfileName(input.profile, input.scenario);
const row = await prisma.gatewayProfile.upsert({ const row = await gatewayProfile.upsert({
where: { profileName }, where: { profileName },
create: { create: {
profileName, profileName,
@@ -211,7 +225,8 @@ export const createGatewayProfileRepository = (
scheduledStartAt?: string | null; scheduledStartAt?: string | null;
} }
): Promise<GatewayProfileRecord | null> { ): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.update({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
const row = await gatewayProfile.update({
where: { profileName }, where: { profileName },
data: { data: {
status, status,
@@ -245,9 +260,13 @@ export const createGatewayProfileRepository = (
startedAt?: string | null; startedAt?: string | null;
completedAt?: string | null; completedAt?: string | null;
error?: string | null; error?: string | null;
commitSha?: string | null;
workspace?: string | null;
lastUsedAt?: string | null;
} }
): Promise<GatewayProfileRecord | null> { ): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.update({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
const row = await gatewayProfile.update({
where: { profileName }, where: { profileName },
data: { data: {
buildStatus: status, buildStatus: status,
@@ -285,7 +304,8 @@ export const createGatewayProfileRepository = (
return row ? mapProfile(row) : null; return row ? mapProfile(row) : null;
}, },
async listReservedToStart(now: Date): Promise<GatewayProfileRecord[]> { async listReservedToStart(now: Date): Promise<GatewayProfileRecord[]> {
const rows = await prisma.gatewayProfile.findMany({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
const rows = await gatewayProfile.findMany({
where: { where: {
status: 'RESERVED', status: 'RESERVED',
preopenAt: { preopenAt: {
@@ -296,14 +316,16 @@ export const createGatewayProfileRepository = (
return rows.map(mapProfile); return rows.map(mapProfile);
}, },
async findQueuedBuild(): Promise<GatewayProfileRecord | null> { async findQueuedBuild(): Promise<GatewayProfileRecord | null> {
const row = await prisma.gatewayProfile.findFirst({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
const row = await gatewayProfile.findFirst({
where: { buildStatus: 'QUEUED' }, where: { buildStatus: 'QUEUED' },
orderBy: { buildRequestedAt: 'asc' }, orderBy: { buildRequestedAt: 'asc' },
}); });
return row ? mapProfile(row) : null; return row ? mapProfile(row) : null;
}, },
async updateLastError(profileName: string, lastError: string | null): Promise<void> { async updateLastError(profileName: string, lastError: string | null): Promise<void> {
await prisma.gatewayProfile.update({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
await gatewayProfile.update({
where: { profileName }, where: { profileName },
data: { lastError }, data: { lastError },
}); });
@@ -313,7 +335,8 @@ export const createGatewayProfileRepository = (
workspace: string, workspace: string,
lastUsedAt: string lastUsedAt: string
): Promise<void> { ): Promise<void> {
await prisma.gatewayProfile.update({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
await gatewayProfile.update({
where: { profileName }, where: { profileName },
data: { data: {
buildWorkspace: workspace, buildWorkspace: workspace,
@@ -325,7 +348,8 @@ export const createGatewayProfileRepository = (
if (!profileNames.length) { if (!profileNames.length) {
return; return;
} }
await prisma.gatewayProfile.updateMany({ const gatewayProfile = prisma.gatewayProfile as unknown as GatewayProfileClient;
await gatewayProfile.updateMany({
where: { where: {
profileName: { in: profileNames }, profileName: { in: profileNames },
}, },