Phase4
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 9s
CI / Go — node-agent tests (push) Failing after 9s
CI / Go — edge-gateway build (push) Successful in 13s

This commit is contained in:
smueller
2026-06-26 12:32:27 +02:00
parent 9b061c3ee7
commit 4262464cd5
101 changed files with 4024 additions and 74 deletions

View File

@@ -0,0 +1,102 @@
import { z } from 'zod';
export const backupStatusSchema = z.enum([
'PENDING',
'RUNNING',
'AVAILABLE',
'FAILED',
'DELETED',
]);
export const backupTypeSchema = z.enum([
'MANUAL',
'SCHEDULED',
'PRE_RESTORE',
'PRE_WORLD_REPLACE',
]);
export const backupRestoreStatusSchema = z.enum([
'PENDING',
'RUNNING',
'COMPLETED',
'FAILED',
]);
export const backupResponseSchema = z.object({
id: z.string().uuid(),
serverId: z.string().uuid(),
type: backupTypeSchema,
status: backupStatusSchema,
s3Key: z.string().nullable(),
sizeBytes: z.string().nullable(),
sha256: z.string().nullable(),
label: z.string().nullable(),
failureReason: z.string().nullable(),
createdAt: z.string().datetime(),
completedAt: z.string().datetime().nullable(),
expiresAt: z.string().datetime().nullable(),
});
export const backupListResponseSchema = z.object({
backups: z.array(backupResponseSchema),
});
export const createBackupRequestSchema = z.object({
label: z.string().max(128).optional(),
});
export const backupActionResponseSchema = z.object({
backup: backupResponseSchema,
jobId: z.string().optional(),
});
export const backupDownloadUrlResponseSchema = z.object({
downloadUrl: z.string().url(),
expiresAt: z.string().datetime(),
});
export const restoreBackupRequestSchema = z.object({
confirm: z.literal(true, {
errorMap: () => ({ message: 'Restore must be explicitly confirmed' }),
}),
});
export const backupRestoreResponseSchema = z.object({
restore: z.object({
id: z.string().uuid(),
serverId: z.string().uuid(),
backupId: z.string().uuid(),
safetyBackupId: z.string().uuid().nullable(),
status: backupRestoreStatusSchema,
failureReason: z.string().nullable(),
createdAt: z.string().datetime(),
completedAt: z.string().datetime().nullable(),
}),
jobId: z.string().optional(),
});
export const backupScheduleSchema = z.object({
enabled: z.boolean(),
intervalHours: z.number().int().min(1).max(168),
retentionCount: z.number().int().min(1).max(50),
nextRunAt: z.string().datetime().nullable(),
lastRunAt: z.string().datetime().nullable(),
});
export const updateBackupScheduleSchema = z.object({
enabled: z.boolean().optional(),
intervalHours: z.number().int().min(1).max(168).optional(),
retentionCount: z.number().int().min(1).max(50).optional(),
});
export type BackupStatus = z.infer<typeof backupStatusSchema>;
export type BackupType = z.infer<typeof backupTypeSchema>;
export type BackupResponse = z.infer<typeof backupResponseSchema>;
export type BackupListResponse = z.infer<typeof backupListResponseSchema>;
export type CreateBackupRequest = z.infer<typeof createBackupRequestSchema>;
export type BackupActionResponse = z.infer<typeof backupActionResponseSchema>;
export type BackupDownloadUrlResponse = z.infer<typeof backupDownloadUrlResponseSchema>;
export type RestoreBackupRequest = z.infer<typeof restoreBackupRequestSchema>;
export type BackupRestoreResponse = z.infer<typeof backupRestoreResponseSchema>;
export type BackupSchedule = z.infer<typeof backupScheduleSchema>;
export type UpdateBackupSchedule = z.infer<typeof updateBackupScheduleSchema>;

View File

@@ -113,3 +113,44 @@ export {
type OperatorEntry,
type PlayerListResponse,
} from './players';
export {
backupStatusSchema,
backupTypeSchema,
backupRestoreStatusSchema,
backupResponseSchema,
backupListResponseSchema,
createBackupRequestSchema,
backupActionResponseSchema,
backupDownloadUrlResponseSchema,
restoreBackupRequestSchema,
backupRestoreResponseSchema,
backupScheduleSchema,
updateBackupScheduleSchema,
type BackupStatus,
type BackupType,
type BackupResponse,
type BackupListResponse,
type CreateBackupRequest,
type BackupActionResponse,
type BackupDownloadUrlResponse,
type RestoreBackupRequest,
type BackupRestoreResponse,
type BackupSchedule,
type UpdateBackupSchedule,
} from './backups';
export {
worldSummarySchema,
worldInfoResponseSchema,
initiateWorldUploadSchema,
worldUploadInitResponseSchema,
worldUploadResponseSchema,
worldDownloadUrlResponseSchema,
type WorldSummary,
type WorldInfoResponse,
type InitiateWorldUpload,
type WorldUploadInitResponse,
type WorldUploadResponse,
type WorldDownloadUrlResponse,
} from './worlds';

View File

@@ -8,6 +8,8 @@ export const gameServerStatusSchema = z.enum([
'STARTING',
'RUNNING',
'STOPPING',
'BACKING_UP',
'RESTORING',
'ERROR',
'DELETING',
'DELETED',
@@ -53,6 +55,7 @@ export const serverResponseSchema = z.object({
hostPort: z.number().int().nullable(),
containerId: z.string().nullable(),
dataPath: z.string().nullable(),
activeWorldName: z.string(),
ramMb: z.number().int(),
createdAt: z.string().datetime(),
updatedAt: z.string().datetime(),

View File

@@ -0,0 +1,59 @@
import { z } from 'zod';
export const worldSummarySchema = z.object({
name: z.string(),
path: z.string(),
sizeBytes: z.string(),
hasLevelDat: z.boolean(),
});
export const worldInfoResponseSchema = z.object({
activeWorldName: z.string(),
worlds: z.array(worldSummarySchema),
});
export const initiateWorldUploadSchema = z.object({
worldName: z
.string()
.min(1)
.max(64)
.regex(/^[a-zA-Z0-9_-]+$/, 'Invalid world name'),
});
export const worldUploadInitResponseSchema = z.object({
uploadId: z.string().uuid(),
uploadUrl: z.string().url(),
expiresAt: z.string().datetime(),
s3Key: z.string(),
});
export const worldUploadResponseSchema = z.object({
id: z.string().uuid(),
serverId: z.string().uuid(),
status: z.enum([
'PENDING',
'UPLOADING',
'VALIDATING',
'READY',
'COMPLETED',
'FAILED',
]),
worldName: z.string(),
sizeBytes: z.string().nullable(),
failureReason: z.string().nullable(),
createdAt: z.string().datetime(),
completedAt: z.string().datetime().nullable(),
});
export const worldDownloadUrlResponseSchema = z.object({
downloadUrl: z.string().url(),
expiresAt: z.string().datetime(),
backupId: z.string().uuid(),
});
export type WorldSummary = z.infer<typeof worldSummarySchema>;
export type WorldInfoResponse = z.infer<typeof worldInfoResponseSchema>;
export type InitiateWorldUpload = z.infer<typeof initiateWorldUploadSchema>;
export type WorldUploadInitResponse = z.infer<typeof worldUploadInitResponseSchema>;
export type WorldUploadResponse = z.infer<typeof worldUploadResponseSchema>;
export type WorldDownloadUrlResponse = z.infer<typeof worldDownloadUrlResponseSchema>;