73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Delete,
|
|
Get,
|
|
Param,
|
|
Patch,
|
|
Post,
|
|
Query,
|
|
UseGuards,
|
|
} from '@nestjs/common';
|
|
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
|
import { UserRole } from '../../database/entities/user.entity';
|
|
import { AdminGuard } from '../../common/guards/admin.guard';
|
|
import { Roles } from '../../common/decorators/roles.decorator';
|
|
import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe';
|
|
import {
|
|
CreateUserDtoSchema,
|
|
ListUsersQueryDtoSchema,
|
|
UpdateUserRoleDtoSchema,
|
|
UserIdParamDtoSchema,
|
|
} from './dto/admin.dto';
|
|
import { AdminService } from './admin.service';
|
|
|
|
/**
|
|
* All admin handlers use Zod validation via `ZodValidationPipe` and an
|
|
* INLINE body/param/query type. Using inline types (rather than class
|
|
* metatypes) avoids the Nest class-transformer pass which would otherwise
|
|
* overwrite the raw body before our pipe sees it.
|
|
*/
|
|
|
|
@ApiTags('admin')
|
|
@ApiBearerAuth()
|
|
@Controller('api/v1/admin')
|
|
@UseGuards(AdminGuard)
|
|
@Roles('admin')
|
|
export class AdminController {
|
|
constructor(private readonly admin: AdminService) {}
|
|
|
|
@Get('users')
|
|
@ApiOperation({ summary: 'List all users (admin only)' })
|
|
list(
|
|
@Query(new ZodValidationPipe(ListUsersQueryDtoSchema))
|
|
query: { limit?: number; cursor?: string; role?: UserRole },
|
|
) {
|
|
return this.admin.listUsers(query);
|
|
}
|
|
|
|
@Patch('users/:id')
|
|
@ApiOperation({ summary: 'Update a user role (admin only)' })
|
|
update(
|
|
@Param(new ZodValidationPipe(UserIdParamDtoSchema)) params: { id: string },
|
|
@Body(new ZodValidationPipe(UpdateUserRoleDtoSchema)) body: { role: UserRole },
|
|
) {
|
|
return this.admin.updateUserRole(params.id, body.role);
|
|
}
|
|
|
|
@Delete('users/:id')
|
|
@ApiOperation({ summary: 'Delete a user (admin only)' })
|
|
async remove(
|
|
@Param(new ZodValidationPipe(UserIdParamDtoSchema)) params: { id: string },
|
|
): Promise<void> {
|
|
await this.admin.deleteUser(params.id);
|
|
}
|
|
|
|
@Post('users')
|
|
@ApiOperation({ summary: 'Create a user (admin only)' })
|
|
create(
|
|
@Body(new ZodValidationPipe(CreateUserDtoSchema)) body: { username: string; password: string; role: UserRole },
|
|
) {
|
|
return this.admin.createUser(body.username, body.password, body.role);
|
|
}
|
|
} |