feat(deploy): remove cluster allocation section from app creation

Drop the admin-only "cluster assignment" UI from the resources &
config step of the deploy wizard and the related backend override.
App placement is now always decided automatically by the allocator.

- frontend: remove cluster/pool selection block, review-step cluster
  row, clusterMode state, public cluster/pool queries, and clusterId/
  poolId from CreateApplicationDto
- backend: drop clusterId/poolId override from the create DTO and
  simplify ApplicationsService.create to always auto-allocate; widen
  selectClusterForApplication param to keep the fallback path working

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
keyhan
2026-06-19 11:58:30 +03:30
parent 5fd2a9883a
commit dbc169206f
6 changed files with 10 additions and 260 deletions
@@ -9,7 +9,6 @@ import { Application } from './entities/application.entity';
import { CreateApplicationDto, UpdateApplicationDto } from './dto/application.dto';
import { ClustersService } from '../clusters/clusters.service';
import {
UserRole,
DatabaseType,
CustomDomainStatus,
AppRuntime,
@@ -57,39 +56,17 @@ export class ApplicationsService {
throw new BadRequestException('Failed to generate a unique subdomain. Please try again.');
}
async create(userId: string, dto: CreateApplicationDto, userRole?: string): Promise<Application> {
async create(userId: string, dto: CreateApplicationDto): Promise<Application> {
dto = normalizeCreateApplicationDto(dto);
const productType = dto.productType ?? ProductType.APPLICATION;
// End users and technical staff cannot influence placement; only admins may manually assign.
const isAdmin = userRole === UserRole.ADMIN;
if (!isAdmin) {
if (dto.clusterId || dto.poolId) {
this.logger.warn(`Non-admin user ${userId} attempted manual cluster/pool selection - ignoring`);
}
dto.clusterId = undefined;
dto.poolId = undefined;
}
let clusterId = dto.clusterId;
let poolId = dto.poolId;
let allocationLogId: string | undefined;
if (isAdmin && clusterId) {
await this.clustersService.findOne(clusterId);
this.logger.log(`Manual cluster assignment for app "${dto.name}" -> cluster ${clusterId}`);
} else {
const allocationDto = { ...dto };
if (poolId) {
allocationDto.poolId = poolId;
}
const allocation = await this.clustersService.selectClusterForApplication(allocationDto, userId);
clusterId = allocation.cluster.id;
poolId = allocation.pool?.id || (isAdmin ? poolId : undefined);
allocationLogId = allocation.allocationLogId;
if (!clusterId) {
throw new BadRequestException('No eligible cluster available for this application');
}
// Placement is always decided automatically by the allocator.
const allocation = await this.clustersService.selectClusterForApplication(dto, userId);
const clusterId = allocation.cluster.id;
const poolId = allocation.pool?.id;
const allocationLogId = allocation.allocationLogId;
if (!clusterId) {
throw new BadRequestException('No eligible cluster available for this application');
}
// Generate database credentials if a database is requested