feat: dynamic database storage size with PVC expansion

- Add dbStorageSize column to Application entity (default: 1Gi)
- Add dbStorageSize to CreateApplicationDto, frontend types
- Use dynamic storage size in K8s deployDatabase instead of hardcoded 5Gi
- Deploy page: storage size selector with +/- buttons (min 1GB, max 100GB)
- Auto-suggest storage based on DB dump file size (3x dump size, min 1GB)
- Show DB storage in Review step
- App detail: Database Storage section with expand button
- GET /applications/:id/db-storage — read current PVC size from K8s
- PATCH /applications/:id/db-storage — expand PVC (only increase, no shrink)
- PVC resize uses JSON patch on K8s API
This commit is contained in:
keyhan
2026-04-07 01:28:01 +03:30
parent e775b57421
commit ac489c88d8
8 changed files with 289 additions and 3 deletions
@@ -93,6 +93,48 @@ export class ApplicationsController {
};
}
@Get(':id/db-storage')
@ApiOperation({ summary: 'Get current database PVC storage size' })
async getDbStorage(@Param('id') id: string, @Request() req: any) {
const isStaff = req.user.role === UserRole.ADMIN || req.user.role === UserRole.TECHNICAL;
const app = await this.applicationsService.findOne(id, isStaff ? undefined : req.user.id);
if (app.databaseType === DatabaseType.NONE) {
throw new BadRequestException('This application does not have a database configured');
}
const currentSize = await this.kubernetesService.getDatabasePvcSize(app);
return { currentSize, savedSize: app.dbStorageSize || '1Gi' };
}
@Patch(':id/db-storage')
@ApiOperation({ summary: 'Resize (expand) database PVC storage' })
async resizeDbStorage(
@Param('id') id: string,
@Request() req: any,
@Body() body: { size: string },
) {
const isStaff = req.user.role === UserRole.ADMIN || req.user.role === UserRole.TECHNICAL;
const app = await this.applicationsService.findOne(id, isStaff ? undefined : req.user.id);
if (app.databaseType === DatabaseType.NONE) {
throw new BadRequestException('This application does not have a database configured');
}
if (!body.size || !/^\d+Gi$/.test(body.size)) {
throw new BadRequestException('Size must be in format like "1Gi", "5Gi", "10Gi"');
}
const result = await this.kubernetesService.resizeDatabasePvc(app, body.size);
if (result.success) {
// Update the saved size in the DB
await this.applicationsService.update(id, app.userId, { dbStorageSize: body.size } as any);
}
return result;
}
@Get()
@ApiOperation({ summary: 'List my applications' })
async findAll(@Request() req: any) {