feat: enhance API and query handling with Redis caching; add QueryGuard for query validation; refactor services to utilize RedisClient for improved performance

This commit is contained in:
Boris D
2025-10-10 10:51:52 +03:00
parent 45db65cec8
commit ca134414b0
20 changed files with 228 additions and 64 deletions

View File

@ -9,12 +9,14 @@ import { DatabaseManagerController } from "./database/database.manager.controlle
import { DatabaseManagerService } from "./database/database.manager.service";
import { DatabaseNodeService } from "./databaseNode/database.node.service";
import { ApiModule } from "src/api/api.module";
import { RedisModule } from "src/redis/redis.module";
@Module({
imports: [
forwardRef(() => ProjectModule),
forwardRef(() => MigrationModule),
forwardRef(() => ApiModule),
forwardRef(() => RedisModule),
TypeOrmModule.forFeature([Database, DatabaseNode, Project]),
],
controllers: [DatabaseManagerController],

View File

@ -1,4 +1,4 @@
import { Injectable } from "@nestjs/common";
import { Inject, Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Database } from "../entities/database.entity";
import { Repository } from "typeorm";
@ -6,6 +6,7 @@ import { ProjectService } from "src/project/project.service";
import { DatabaseEncryptionService } from "../database.encryption.service";
import { DatabaseNodeService } from "../databaseNode/database.node.service";
import * as mysql from "mysql2/promise";
import { RedisClient } from "src/redis/redis.service";
@Injectable()
export class DatabaseManagerService extends DatabaseEncryptionService {
@ -13,7 +14,9 @@ export class DatabaseManagerService extends DatabaseEncryptionService {
@InjectRepository(Database)
private databaseRepository: Repository<Database>,
private readonly projectService: ProjectService,
private readonly databaseNodeService: DatabaseNodeService
private readonly databaseNodeService: DatabaseNodeService,
@Inject(RedisClient)
private readonly redisClient: RedisClient
) {
super();
}
@ -64,6 +67,14 @@ export class DatabaseManagerService extends DatabaseEncryptionService {
throw new Error("Project not found");
}
const cached = await this.redisClient.get(
`db_conn_opts_${projectId}_${queryUser}`
);
if (cached) {
return cached;
}
const database = await this.databaseRepository.findOne({
where: { project: { id: project.id } },
relations: ["node"],
@ -73,7 +84,7 @@ export class DatabaseManagerService extends DatabaseEncryptionService {
throw new Error("Database not found");
}
return {
const connectionOptions = {
host: database.node.host,
port: database.node.port,
user: queryUser ? database.q_username : database.c_username,
@ -82,6 +93,14 @@ export class DatabaseManagerService extends DatabaseEncryptionService {
idleTimeout: 150e3,
connectTimeout: 2e3,
};
await this.redisClient.set(
`db_conn_opts_${projectId}_${queryUser}`,
connectionOptions,
300
);
return connectionOptions;
}
async createDatabase(projectId: string): Promise<Database> {