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

This commit is contained in:
smueller
2026-06-26 13:11:28 +02:00
parent d29a02f2a4
commit 49a98ee31d
81 changed files with 1462 additions and 53 deletions

View File

@@ -1,14 +1,19 @@
import {
Body,
Controller,
Get,
HttpCode,
HttpStatus,
Param,
ParseUUIDPipe,
Post,
UseGuards,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { z } from 'zod';
import type { NodeListResponse, NodeSummary } from '@hexahost/contracts';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { SessionGuard } from '../auth/guards/session.guard';
import { ZodValidationPipe } from '../common/pipes/zod-validation.pipe';
@@ -20,6 +25,12 @@ const createNodeRequestSchema = z.object({
name: z.string().min(1).max(64),
hostname: z.string().min(1).max(255),
maxServers: z.number().int().min(1).max(1000).optional(),
maxRamMb: z.number().int().min(2048).max(1048576).optional(),
platformRamMb: z.number().int().min(512).max(65536).optional(),
});
const maintenanceRequestSchema = z.object({
enabled: z.boolean(),
});
@ApiTags('admin')
@@ -28,6 +39,13 @@ const createNodeRequestSchema = z.object({
export class AdminNodesController {
constructor(private readonly adminNodesService: AdminNodesService) {}
@Get()
@ApiOperation({ summary: 'List game nodes (super admin only)' })
list(@CurrentUser() user: { roles: string[] }): Promise<NodeListResponse> {
this.adminNodesService.assertSuperAdmin(user.roles);
return this.adminNodesService.listNodes();
}
@Post()
@HttpCode(HttpStatus.CREATED)
@ApiOperation({ summary: 'Register a new game node (super admin only)' })
@@ -42,4 +60,28 @@ export class AdminNodesController {
body as Parameters<AdminNodesService['createNode']>[0],
);
}
@Post(':id/drain')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Drain a game node (super admin only)' })
drain(
@CurrentUser() user: { roles: string[] },
@Param('id', ParseUUIDPipe) id: string,
): Promise<NodeSummary> {
this.adminNodesService.assertSuperAdmin(user.roles);
return this.adminNodesService.requestDrain(id);
}
@Post(':id/maintenance')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Toggle maintenance mode for a node (super admin only)' })
maintenance(
@CurrentUser() user: { roles: string[] },
@Param('id', ParseUUIDPipe) id: string,
@Body(new ZodValidationPipe(maintenanceRequestSchema)) body: unknown,
): Promise<NodeSummary> {
this.adminNodesService.assertSuperAdmin(user.roles);
const input = body as z.infer<typeof maintenanceRequestSchema>;
return this.adminNodesService.setMaintenance(id, input.enabled);
}
}