Enhance AdminService with caching for admin permissions and add UtilsModule to AdminModule imports

This commit is contained in:
2025-11-17 23:59:57 +03:30
parent e699a961be
commit 607e2ec2cf
2 changed files with 66 additions and 1 deletions
+6 -1
View File
@@ -12,11 +12,16 @@ import { RoleService } from './providers/role.service';
import { RoleController } from './controllers/role.controller';
import { PermissionService } from './providers/permission.service';
import { PermissionController } from './controllers/permission.controller';
import { UtilsModule } from '../utils/utils.module';
@Module({
providers: [AdminService, AdminRepository, RoleService, PermissionService],
controllers: [AdminController, RoleController, PermissionController],
imports: [MikroOrmModule.forFeature([Admin, Role, Permission, RolePermission]), JwtModule],
imports: [
MikroOrmModule.forFeature([Admin, Role, Permission, RolePermission]),
JwtModule,
UtilsModule,
],
exports: [AdminService, AdminRepository, RoleService, PermissionService],
})
export class AdminModule {}
@@ -5,13 +5,17 @@ import { Admin } from '../entities/admin.entity';
import { Role } from '../entities/role.entity';
import { Restaurant } from '../../restaurants/entities/restaurant.entity';
import { EntityManager } from '@mikro-orm/postgresql';
import { CacheService } from '../../utils/cache.service';
@Injectable()
export class AdminService {
private readonly ADMIN_PERMISSIONS_KEY = 'admin-perms';
constructor(
@InjectRepository(Admin)
private readonly adminRepository: EntityRepository<Admin>,
private readonly em: EntityManager,
private readonly cacheService: CacheService,
) {}
async findByPhone(phone: string): Promise<Admin | null> {
@@ -45,4 +49,60 @@ export class AdminService {
await this.em.persistAndFlush(admin);
return admin;
}
/**
* Get admin permissions from cache or database
* @param adminId - The admin ID
* @param restId - The restaurant ID
* @returns Array of permission names (string[])
*/
async getAdminPermissions(adminId: string, restId: string): Promise<string[]> {
const cacheKey = `${this.ADMIN_PERMISSIONS_KEY}:${adminId}:${restId}`;
// Try to get from cache first
const cachedPermissions = await this.cacheService.get<string>(cacheKey);
if (cachedPermissions) {
try {
const parsed = JSON.parse(cachedPermissions);
// Ensure it's an array of strings
if (Array.isArray(parsed) && parsed.every((p): p is string => typeof p === 'string')) {
return parsed;
}
// If invalid format, continue to fetch from DB
} catch {
// If parsing fails, continue to fetch from DB
}
}
// If not in cache, fetch from database
const admin = await this.adminRepository.findOne(
{ id: adminId, restaurant: { id: restId } },
{ populate: ['role', 'role.permissions'] },
);
if (!admin || !admin.role) {
return [];
}
// Extract permission names as array of strings
const permissions = await admin.role.permissions.loadItems();
const permissionNames: string[] = permissions
.map(p => p.name)
.filter((name): name is string => typeof name === 'string');
// Store in cache as JSON stringified array of strings (1 hour TTL)
await this.cacheService.set(cacheKey, JSON.stringify(permissionNames), 3600);
return permissionNames;
}
/**
* Invalidate admin permissions cache
* @param adminId - The admin ID
* @param restId - The restaurant ID
*/
async invalidateAdminPermissionsCache(adminId: string, restId: string): Promise<void> {
const cacheKey = `${this.ADMIN_PERMISSIONS_KEY}:${adminId}:${restId}`;
await this.cacheService.del(cacheKey);
}
}