Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Server] 관리 페이지와 api 구현 #197

Merged
merged 16 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"axios": "^1.6.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"cookie-parser": "^1.4.6",
"nest-winston": "^1.9.4",
"pg": "^8.11.3",
"redis": "^4.6.11",
Expand Down
15 changes: 13 additions & 2 deletions server/redis/redis.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DynamicModule, Global, Module } from '@nestjs/common';
import { RedisClientType, createClient } from 'redis';
import { RedisService } from './redis.service';

/**
* RedisModule은 NestJS 애플리케이션에서 Redis 클라이언트를 설정하고 관리하는데 사용되는 모듈이다.
Expand Down Expand Up @@ -64,8 +65,18 @@ export class RedisModule {
*/
return {
module: RedisModule,
providers: [redisProvider, redisPubProvider, redisSubProvider],
exports: [redisProvider, redisPubProvider, redisSubProvider],
providers: [
redisProvider,
redisPubProvider,
redisSubProvider,
RedisService,
],
exports: [
redisProvider,
redisPubProvider,
redisSubProvider,
RedisService,
],
};
}
}
21 changes: 21 additions & 0 deletions server/redis/redis.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Inject, Injectable } from '@nestjs/common';
import { RedisClientType } from 'redis';

@Injectable()
export class RedisService {
constructor(
@Inject('REDIS_SUB_CLIENT')
private readonly redisSubscriber: RedisClientType,
@Inject('REDIS_PUB_CLIENT')
private readonly redisPublisher: RedisClientType,
) {}

subscribeToChannel(channel: string, callback: Function) {
this.redisSubscriber.subscribe(channel, (message) => {
callback(message);
});
}
publishToChannel(channel: string, message: string) {
this.redisPublisher.publish(channel, message);
}
}
20 changes: 20 additions & 0 deletions server/src/admin/admin.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AdminController } from './admin.controller';
import { AdminService } from './admin.service';

describe('AdminController', () => {
let controller: AdminController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AdminController],
providers: [AdminService],
}).compile();

controller = module.get<AdminController>(AdminController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
59 changes: 59 additions & 0 deletions server/src/admin/admin.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
Controller,
Get,
Req,
Res,
UnauthorizedException,
} from '@nestjs/common';
import { Response } from 'express';
import { RedisService } from 'redis/redis.service';
import { UserId } from 'src/users/decorator/userId.decorator';
import { channels } from './const/channels.const';

@Controller('admin')
export class AdminController {
constructor(private readonly redisService: RedisService) {}

@Get('events')
sse(@Req() req, @Res() res: Response, @UserId() userId: number) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();

if (userId !== 1) {
throw new UnauthorizedException('관리자가 아닙니다.');
}

const changeFormat = (channel, message) => {
const result = { channel, message };
return JSON.stringify(result);
};

res.write(`data: ${changeFormat('notice', 'Server connected')}\n\n`);
channels.forEach((channel) => {
this.redisService.subscribeToChannel(channel, (message) => {
res.write(`data: ${changeFormat(channel, message)}\n\n`);
});
});

req.on('close', () => {
res.end();
});
}
@Get('generate')
generate(@UserId() userId: number) {
if (userId !== 1) {
throw new UnauthorizedException('관리자가 아닙니다.');
}
this.redisService.publishToChannel('channel', 'processAiResult');
}

@Get('category')
category(@UserId() userId: number) {
if (userId !== 1) {
throw new UnauthorizedException('관리자가 아닙니다.');
}
this.redisService.publishToChannel('channel', 'processCategory');
}
}
9 changes: 9 additions & 0 deletions server/src/admin/admin.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { AdminController } from './admin.controller';
import { AdminService } from './admin.service';

@Module({
controllers: [AdminController],
providers: [AdminService],
})
export class AdminModule {}
18 changes: 18 additions & 0 deletions server/src/admin/admin.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AdminService } from './admin.service';

describe('AdminService', () => {
let service: AdminService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AdminService],
}).compile();

service = module.get<AdminService>(AdminService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
4 changes: 4 additions & 0 deletions server/src/admin/admin.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';

@Injectable()
export class AdminService {}
7 changes: 7 additions & 0 deletions server/src/admin/const/channels.const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const channels = [
'channel',
'sharedChecklist',
'ai_result',
'httpLog',
'wsLog',
];
Loading