fix(platform): apply production hardening from audit plan

Close billing, tenancy, migration, build, and CI/CD gaps identified in the
audit: wallet/gateway guards, full-UUID namespaces, idempotent migrations with
base schema, stateful service stability, safer Dockerfiles/git builds, and
platform chart hardening (Redis auth, RollingUpdate, backups, Swagger off).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
keyhan
2026-07-02 19:35:07 +03:30
parent 34c110be6a
commit 22359be40e
55 changed files with 4883 additions and 381 deletions
@@ -22,6 +22,7 @@ import {
detectRuntimeFromArchive,
} from '../build/runtime-detector';
import { SourceStorageService } from '../storage/source-storage.service';
import { userIdSlug } from '../kubernetes/k8s-workload.util';
import * as os from 'os';
@Injectable()
@@ -67,6 +68,18 @@ export class ApplicationsService {
dto = normalizeCreateApplicationDto(dto);
const productType = dto.productType ?? ProductType.APPLICATION;
// WordPress only runs on MySQL/MariaDB — reject PostgreSQL/Mongo/none up
// front instead of failing at runtime inside the WordPress container.
if (dto.runtime === AppRuntime.WORDPRESS) {
if (!dto.databaseType || dto.databaseType === DatabaseType.NONE) {
dto.databaseType = DatabaseType.MYSQL;
} else if (![DatabaseType.MYSQL, DatabaseType.MARIADB].includes(dto.databaseType)) {
throw new BadRequestException(
`WordPress requires a MySQL or MariaDB database — "${dto.databaseType}" is not supported.`,
);
}
}
// Placement is always decided automatically by the allocator.
const allocation = await this.clustersService.selectClusterForApplication(dto, userId);
const clusterId = allocation.cluster.id;
@@ -96,7 +109,7 @@ export class ApplicationsService {
const baseLabel = dto.name;
const subdomain = customDomain
? `${this.toDnsLabel(baseLabel)}-${this.toDnsLabel(userId.split('-')[0])}`
? `${this.toDnsLabel(baseLabel)}-${this.toDnsLabel(userIdSlug(userId).slice(0, 12))}`
: await this.generateRandomSubdomain(baseLabel);
const platformDomain = this.configService.get('platform.domain') || 'apps.cloudhost.ir';