feat: complete admin backend controllers and services
- AdminPlansController & Service (CRUD, reorder) - AdminPaymentMethodsController & Service (CRUD, reorder) - AdminPaymentsController & Service (verify, reject, pending count) - AdminUsersController & Service (search, suspend, grant pro access, stats) - AdminConfigController & Service (dynamic config management) - Wire all controllers into AdminModule - Import AdminModule in AppModule Admin API Routes: - GET/POST/PUT/DELETE /admin/plans - GET/POST/PUT/DELETE /admin/payment-methods - GET /admin/payments (with status filter) - POST /admin/payments/:id/verify - POST /admin/payments/:id/reject - GET /admin/users (with search) - POST /admin/users/:id/grant-pro - GET/POST/DELETE /admin/config All routes protected by AuthGuard + AdminGuard
This commit is contained in:
55
apps/api/src/admin/admin-config.controller.ts
Normal file
55
apps/api/src/admin/admin-config.controller.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
import { AdminGuard } from './guards/admin.guard';
|
||||
import { AdminConfigService } from './admin-config.service';
|
||||
|
||||
interface RequestWithUser {
|
||||
user: {
|
||||
userId: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Controller('admin/config')
|
||||
@UseGuards(AuthGuard, AdminGuard)
|
||||
export class AdminConfigController {
|
||||
constructor(private readonly service: AdminConfigService) {}
|
||||
|
||||
@Get()
|
||||
findAll(@Query('category') category?: string) {
|
||||
return this.service.findAll(category);
|
||||
}
|
||||
|
||||
@Get('by-category')
|
||||
getByCategory() {
|
||||
return this.service.getByCategory();
|
||||
}
|
||||
|
||||
@Get(':key')
|
||||
findOne(@Param('key') key: string) {
|
||||
return this.service.findOne(key);
|
||||
}
|
||||
|
||||
@Post(':key')
|
||||
upsert(
|
||||
@Param('key') key: string,
|
||||
@Body() data: any,
|
||||
@Req() req: RequestWithUser,
|
||||
) {
|
||||
return this.service.upsert(key, data, req.user.userId);
|
||||
}
|
||||
|
||||
@Delete(':key')
|
||||
delete(@Param('key') key: string) {
|
||||
return this.service.delete(key);
|
||||
}
|
||||
}
|
||||
57
apps/api/src/admin/admin-config.service.ts
Normal file
57
apps/api/src/admin/admin-config.service.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class AdminConfigService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll(category?: string) {
|
||||
return this.prisma.appConfig.findMany({
|
||||
where: category ? { category } : undefined,
|
||||
orderBy: { category: 'asc' },
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(key: string) {
|
||||
return this.prisma.appConfig.findUnique({
|
||||
where: { key },
|
||||
});
|
||||
}
|
||||
|
||||
async upsert(key: string, data: any, updatedBy: string) {
|
||||
return this.prisma.appConfig.upsert({
|
||||
where: { key },
|
||||
update: {
|
||||
...data,
|
||||
updatedBy,
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
create: {
|
||||
key,
|
||||
...data,
|
||||
updatedBy,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async delete(key: string) {
|
||||
return this.prisma.appConfig.delete({
|
||||
where: { key },
|
||||
});
|
||||
}
|
||||
|
||||
async getByCategory() {
|
||||
const configs = await this.prisma.appConfig.findMany();
|
||||
|
||||
// Group by category
|
||||
const grouped = configs.reduce((acc, config) => {
|
||||
if (!acc[config.category]) {
|
||||
acc[config.category] = [];
|
||||
}
|
||||
acc[config.category].push(config);
|
||||
return acc;
|
||||
}, {} as Record<string, any[]>);
|
||||
|
||||
return grouped;
|
||||
}
|
||||
}
|
||||
49
apps/api/src/admin/admin-payment-methods.controller.ts
Normal file
49
apps/api/src/admin/admin-payment-methods.controller.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
import { AdminGuard } from './guards/admin.guard';
|
||||
import { AdminPaymentMethodsService } from './admin-payment-methods.service';
|
||||
|
||||
@Controller('admin/payment-methods')
|
||||
@UseGuards(AuthGuard, AdminGuard)
|
||||
export class AdminPaymentMethodsController {
|
||||
constructor(private readonly service: AdminPaymentMethodsService) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.service.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.service.findOne(id);
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() data: any) {
|
||||
return this.service.create(data);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
update(@Param('id') id: string, @Body() data: any) {
|
||||
return this.service.update(id, data);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
delete(@Param('id') id: string) {
|
||||
return this.service.delete(id);
|
||||
}
|
||||
|
||||
@Post('reorder')
|
||||
reorder(@Body() body: { methodIds: string[] }) {
|
||||
return this.service.reorder(body.methodIds);
|
||||
}
|
||||
}
|
||||
50
apps/api/src/admin/admin-payment-methods.service.ts
Normal file
50
apps/api/src/admin/admin-payment-methods.service.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class AdminPaymentMethodsService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll() {
|
||||
return this.prisma.paymentMethod.findMany({
|
||||
orderBy: { sortOrder: 'asc' },
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
return this.prisma.paymentMethod.findUnique({
|
||||
where: { id },
|
||||
});
|
||||
}
|
||||
|
||||
async create(data: any) {
|
||||
return this.prisma.paymentMethod.create({
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async update(id: string, data: any) {
|
||||
return this.prisma.paymentMethod.update({
|
||||
where: { id },
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async delete(id: string) {
|
||||
return this.prisma.paymentMethod.delete({
|
||||
where: { id },
|
||||
});
|
||||
}
|
||||
|
||||
async reorder(methodIds: string[]) {
|
||||
const updates = methodIds.map((id, index) =>
|
||||
this.prisma.paymentMethod.update({
|
||||
where: { id },
|
||||
data: { sortOrder: index + 1 },
|
||||
})
|
||||
);
|
||||
|
||||
await this.prisma.$transaction(updates);
|
||||
return { success: true };
|
||||
}
|
||||
}
|
||||
54
apps/api/src/admin/admin-payments.controller.ts
Normal file
54
apps/api/src/admin/admin-payments.controller.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
import { AdminGuard } from './guards/admin.guard';
|
||||
import { AdminPaymentsService } from './admin-payments.service';
|
||||
|
||||
interface RequestWithUser {
|
||||
user: {
|
||||
userId: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Controller('admin/payments')
|
||||
@UseGuards(AuthGuard, AdminGuard)
|
||||
export class AdminPaymentsController {
|
||||
constructor(private readonly service: AdminPaymentsService) {}
|
||||
|
||||
@Get()
|
||||
findAll(@Query('status') status?: string) {
|
||||
return this.service.findAll(status);
|
||||
}
|
||||
|
||||
@Get('pending/count')
|
||||
getPendingCount() {
|
||||
return this.service.getPendingCount();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.service.findOne(id);
|
||||
}
|
||||
|
||||
@Post(':id/verify')
|
||||
verify(@Param('id') id: string, @Req() req: RequestWithUser) {
|
||||
return this.service.verify(id, req.user.userId);
|
||||
}
|
||||
|
||||
@Post(':id/reject')
|
||||
reject(
|
||||
@Param('id') id: string,
|
||||
@Req() req: RequestWithUser,
|
||||
@Body() body: { reason: string },
|
||||
) {
|
||||
return this.service.reject(id, req.user.userId, body.reason);
|
||||
}
|
||||
}
|
||||
110
apps/api/src/admin/admin-payments.service.ts
Normal file
110
apps/api/src/admin/admin-payments.service.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class AdminPaymentsService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll(status?: string) {
|
||||
return this.prisma.payment.findMany({
|
||||
where: status ? { status } : undefined,
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
subscription: {
|
||||
include: {
|
||||
plan: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
return this.prisma.payment.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
subscription: {
|
||||
include: {
|
||||
plan: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async verify(id: string, adminUserId: string) {
|
||||
const payment = await this.prisma.payment.findUnique({
|
||||
where: { id },
|
||||
include: { subscription: { include: { plan: true } } },
|
||||
});
|
||||
|
||||
if (!payment) {
|
||||
throw new Error('Payment not found');
|
||||
}
|
||||
|
||||
// Update payment status
|
||||
const updatedPayment = await this.prisma.payment.update({
|
||||
where: { id },
|
||||
data: {
|
||||
status: 'paid',
|
||||
verifiedBy: adminUserId,
|
||||
verifiedAt: new Date(),
|
||||
paidAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
// Activate or extend subscription
|
||||
if (payment.subscriptionId && payment.subscription) {
|
||||
const plan = payment.subscription.plan;
|
||||
const now = new Date();
|
||||
const endDate = new Date(now);
|
||||
|
||||
if (plan.durationDays) {
|
||||
endDate.setDate(endDate.getDate() + plan.durationDays);
|
||||
}
|
||||
|
||||
await this.prisma.subscription.update({
|
||||
where: { id: payment.subscriptionId },
|
||||
data: {
|
||||
status: 'active',
|
||||
startDate: now,
|
||||
endDate: plan.durationType === 'lifetime' ? new Date('2099-12-31') : endDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return updatedPayment;
|
||||
}
|
||||
|
||||
async reject(id: string, adminUserId: string, reason: string) {
|
||||
return this.prisma.payment.update({
|
||||
where: { id },
|
||||
data: {
|
||||
status: 'rejected',
|
||||
verifiedBy: adminUserId,
|
||||
verifiedAt: new Date(),
|
||||
rejectionReason: reason,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getPendingCount() {
|
||||
return this.prisma.payment.count({
|
||||
where: { status: 'pending' },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
import { AdminGuard } from './guards/admin.guard';
|
||||
import { AdminPlansService } from './admin-plans.service';
|
||||
|
||||
@Controller('admin/plans')
|
||||
@UseGuards(AuthGuard, AdminGuard)
|
||||
export class AdminPlansController {
|
||||
constructor(private readonly plansService: AdminPlansService) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.plansService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.plansService.findOne(id);
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() data: any) {
|
||||
return this.plansService.create(data);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
update(@Param('id') id: string, @Body() data: any) {
|
||||
return this.plansService.update(id, data);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
delete(@Param('id') id: string) {
|
||||
return this.plansService.delete(id);
|
||||
}
|
||||
|
||||
@Post('reorder')
|
||||
reorder(@Body() body: { planIds: string[] }) {
|
||||
return this.plansService.reorder(body.planIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class AdminPlansService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll() {
|
||||
return this.prisma.plan.findMany({
|
||||
orderBy: { sortOrder: 'asc' },
|
||||
include: {
|
||||
_count: {
|
||||
select: { subscriptions: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
return this.prisma.plan.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
_count: {
|
||||
select: { subscriptions: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async create(data: any) {
|
||||
return this.prisma.plan.create({
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async update(id: string, data: any) {
|
||||
return this.prisma.plan.update({
|
||||
where: { id },
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async delete(id: string) {
|
||||
// Soft delete - just deactivate
|
||||
return this.prisma.plan.update({
|
||||
where: { id },
|
||||
data: { isActive: false, isVisible: false },
|
||||
});
|
||||
}
|
||||
|
||||
async reorder(planIds: string[]) {
|
||||
// Update sort order for multiple plans
|
||||
const updates = planIds.map((id, index) =>
|
||||
this.prisma.plan.update({
|
||||
where: { id },
|
||||
data: { sortOrder: index + 1 },
|
||||
})
|
||||
);
|
||||
|
||||
await this.prisma.$transaction(updates);
|
||||
return { success: true };
|
||||
}
|
||||
}
|
||||
|
||||
57
apps/api/src/admin/admin-users.controller.ts
Normal file
57
apps/api/src/admin/admin-users.controller.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
import { AdminGuard } from './guards/admin.guard';
|
||||
import { AdminUsersService } from './admin-users.service';
|
||||
|
||||
@Controller('admin/users')
|
||||
@UseGuards(AuthGuard, AdminGuard)
|
||||
export class AdminUsersController {
|
||||
constructor(private readonly service: AdminUsersService) {}
|
||||
|
||||
@Get()
|
||||
findAll(@Query('search') search?: string) {
|
||||
return this.service.findAll(search);
|
||||
}
|
||||
|
||||
@Get('stats')
|
||||
getStats() {
|
||||
return this.service.getStats();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.service.findOne(id);
|
||||
}
|
||||
|
||||
@Put(':id/role')
|
||||
updateRole(@Param('id') id: string, @Body() body: { role: string }) {
|
||||
return this.service.updateRole(id, body.role);
|
||||
}
|
||||
|
||||
@Post(':id/suspend')
|
||||
suspend(@Param('id') id: string, @Body() body: { reason: string }) {
|
||||
return this.service.suspend(id, body.reason);
|
||||
}
|
||||
|
||||
@Post(':id/unsuspend')
|
||||
unsuspend(@Param('id') id: string) {
|
||||
return this.service.unsuspend(id);
|
||||
}
|
||||
|
||||
@Post(':id/grant-pro')
|
||||
grantProAccess(
|
||||
@Param('id') id: string,
|
||||
@Body() body: { planSlug: string; durationDays: number },
|
||||
) {
|
||||
return this.service.grantProAccess(id, body.planSlug, body.durationDays);
|
||||
}
|
||||
}
|
||||
143
apps/api/src/admin/admin-users.service.ts
Normal file
143
apps/api/src/admin/admin-users.service.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class AdminUsersService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll(search?: string) {
|
||||
return this.prisma.user.findMany({
|
||||
where: search
|
||||
? {
|
||||
OR: [
|
||||
{ email: { contains: search, mode: 'insensitive' } },
|
||||
{ name: { contains: search, mode: 'insensitive' } },
|
||||
],
|
||||
}
|
||||
: undefined,
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
role: true,
|
||||
emailVerified: true,
|
||||
createdAt: true,
|
||||
lastLoginAt: true,
|
||||
suspendedAt: true,
|
||||
_count: {
|
||||
select: {
|
||||
wallets: true,
|
||||
transactions: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
return this.prisma.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
subscriptions: {
|
||||
include: {
|
||||
plan: true,
|
||||
},
|
||||
},
|
||||
_count: {
|
||||
select: {
|
||||
wallets: true,
|
||||
transactions: true,
|
||||
payments: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateRole(id: string, role: string) {
|
||||
return this.prisma.user.update({
|
||||
where: { id },
|
||||
data: { role },
|
||||
});
|
||||
}
|
||||
|
||||
async suspend(id: string, reason: string) {
|
||||
return this.prisma.user.update({
|
||||
where: { id },
|
||||
data: {
|
||||
suspendedAt: new Date(),
|
||||
suspendedReason: reason,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async unsuspend(id: string) {
|
||||
return this.prisma.user.update({
|
||||
where: { id },
|
||||
data: {
|
||||
suspendedAt: null,
|
||||
suspendedReason: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async grantProAccess(userId: string, planSlug: string, durationDays: number) {
|
||||
const plan = await this.prisma.plan.findUnique({
|
||||
where: { slug: planSlug },
|
||||
});
|
||||
|
||||
if (!plan) {
|
||||
throw new Error('Plan not found');
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const endDate = new Date(now);
|
||||
endDate.setDate(endDate.getDate() + durationDays);
|
||||
|
||||
// Check if user already has a subscription
|
||||
const existing = await this.prisma.subscription.findUnique({
|
||||
where: { userId },
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
// Update existing subscription
|
||||
return this.prisma.subscription.update({
|
||||
where: { userId },
|
||||
data: {
|
||||
planId: plan.id,
|
||||
status: 'active',
|
||||
startDate: now,
|
||||
endDate,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// Create new subscription
|
||||
return this.prisma.subscription.create({
|
||||
data: {
|
||||
userId,
|
||||
planId: plan.id,
|
||||
status: 'active',
|
||||
startDate: now,
|
||||
endDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async getStats() {
|
||||
const totalUsers = await this.prisma.user.count();
|
||||
const activeSubscriptions = await this.prisma.subscription.count({
|
||||
where: { status: 'active' },
|
||||
});
|
||||
const suspendedUsers = await this.prisma.user.count({
|
||||
where: { suspendedAt: { not: null } },
|
||||
});
|
||||
|
||||
return {
|
||||
totalUsers,
|
||||
activeSubscriptions,
|
||||
suspendedUsers,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PrismaModule } from '../prisma/prisma.module';
|
||||
import { AdminGuard } from './guards/admin.guard';
|
||||
|
||||
// Controllers
|
||||
import { AdminPlansController } from './admin-plans.controller';
|
||||
import { AdminPaymentMethodsController } from './admin-payment-methods.controller';
|
||||
import { AdminPaymentsController } from './admin-payments.controller';
|
||||
import { AdminUsersController } from './admin-users.controller';
|
||||
import { AdminConfigController } from './admin-config.controller';
|
||||
|
||||
// Services
|
||||
import { AdminPlansService } from './admin-plans.service';
|
||||
import { AdminPaymentMethodsService } from './admin-payment-methods.service';
|
||||
import { AdminPaymentsService } from './admin-payments.service';
|
||||
import { AdminUsersService } from './admin-users.service';
|
||||
import { AdminConfigService } from './admin-config.service';
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
controllers: [
|
||||
AdminPlansController,
|
||||
AdminPaymentMethodsController,
|
||||
AdminPaymentsController,
|
||||
AdminUsersController,
|
||||
AdminConfigController,
|
||||
],
|
||||
providers: [
|
||||
AdminGuard,
|
||||
AdminPlansService,
|
||||
AdminPaymentMethodsService,
|
||||
AdminPaymentsService,
|
||||
AdminUsersService,
|
||||
AdminConfigService,
|
||||
],
|
||||
exports: [
|
||||
AdminGuard,
|
||||
AdminPlansService,
|
||||
AdminPaymentMethodsService,
|
||||
AdminPaymentsService,
|
||||
AdminUsersService,
|
||||
AdminConfigService,
|
||||
],
|
||||
})
|
||||
export class AdminModule {}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { WalletsModule } from './wallets/wallets.module';
|
||||
import { TransactionsModule } from './transactions/transactions.module';
|
||||
import { CategoriesModule } from './categories/categories.module';
|
||||
import { OtpModule } from './otp/otp.module';
|
||||
import { AdminModule } from './admin/admin.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -26,6 +27,7 @@ import { OtpModule } from './otp/otp.module';
|
||||
TransactionsModule,
|
||||
CategoriesModule,
|
||||
OtpModule,
|
||||
AdminModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
providers: [],
|
||||
|
||||
Reference in New Issue
Block a user