Add AdminId decorator for extracting adminId from requests; refactor AdminController to utilize new decorator for fetching admin details and restaurant-specific admins; update AdminService to handle admin creation and retrieval by restaurant; remove unused role and permission entities for cleaner architecture.
This commit is contained in:
@@ -6,12 +6,10 @@ import { Role } from '../../roles/entities/role.entity';
|
||||
import { Restaurant } from '../../restaurants/entities/restaurant.entity';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { CacheService } from '../../utils/cache.service';
|
||||
import { AdminDetailTransformer, AdminDetailResponse } from '../transformers/admin-detail.transformer';
|
||||
import { CreateMyRestaurantAdminDto } from '../dto/create-my-restaurant-admin.dto';
|
||||
|
||||
@Injectable()
|
||||
export class AdminService {
|
||||
private readonly ADMIN_PERMISSIONS_KEY = 'admin-perms';
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Admin)
|
||||
private readonly adminRepository: EntityRepository<Admin>,
|
||||
@@ -23,24 +21,44 @@ export class AdminService {
|
||||
return this.adminRepository.findOne({ phone });
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<AdminDetailResponse | null> {
|
||||
const admin = await this.adminRepository.findOne({ id }, { populate: ['role', 'role.permissions', 'restaurant'] });
|
||||
async findById(id: string): Promise<Admin | null> {
|
||||
const admin = await this.adminRepository.findOne({ id }, { populate: ['roles', 'roles.role'] });
|
||||
return admin;
|
||||
}
|
||||
|
||||
if (!admin) {
|
||||
return null;
|
||||
async findAllByRestaurantId(restId: string): Promise<Admin[]> {
|
||||
return this.adminRepository.find({ roles: { restaurant: { id: restId } } }, { populate: ['roles', 'roles.role'] });
|
||||
}
|
||||
|
||||
async createAdminForMyRestaurant(restId: string, dto: CreateMyRestaurantAdminDto) {
|
||||
const { phone, firstName, lastName, roleId } = dto;
|
||||
const currentAdmin = await this.adminRepository.findOne({
|
||||
phone,
|
||||
roles: { role: { id: roleId }, restaurant: { id: restId } },
|
||||
});
|
||||
if (currentAdmin) {
|
||||
return currentAdmin;
|
||||
}
|
||||
|
||||
return AdminDetailTransformer.transform(admin);
|
||||
}
|
||||
async findAll(): Promise<Admin[]> {
|
||||
return this.adminRepository.findAll();
|
||||
const role = await this.em.findOne(Role, { id: roleId });
|
||||
if (!role) throw new Error('Role not found');
|
||||
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
||||
if (!restaurant) throw new Error('Restaurant not found');
|
||||
const admin = this.adminRepository.create({ phone, firstName, lastName, roles: [{ role, restaurant }] });
|
||||
await this.em.persistAndFlush(admin);
|
||||
return admin;
|
||||
}
|
||||
|
||||
async create(data: { phone: string; firstName?: string; lastName?: string; roleId: string; restId: string }) {
|
||||
async createRestaurantBySuperAdmin(data: {
|
||||
phone: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
roleId: string;
|
||||
restId: string;
|
||||
}) {
|
||||
const { phone, firstName, lastName, roleId, restId } = data;
|
||||
|
||||
// check existing
|
||||
const existing = await this.adminRepository.findOne({ phone, restaurant: { id: restId } });
|
||||
const existing = await this.adminRepository.findOne({ phone, roles: { restaurant: { id: restId } } });
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
@@ -52,64 +70,8 @@ export class AdminService {
|
||||
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
||||
if (!restaurant) throw new Error('Restaurant not found');
|
||||
|
||||
const admin = this.adminRepository.create({ phone, firstName, lastName, role, restaurant });
|
||||
const admin = this.adminRepository.create({ phone, firstName, lastName, roles: [{ role, restaurant }] });
|
||||
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: unknown = 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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user