Skip to content

QnoteAITeam/nestjs-api-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

18 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

QnoteAI NestJS API ์„œ๋ฒ„

QnoteAI์˜ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋Š” NestJS๋กœ ๊ตฌ์ถ•๋œ RESTful API ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.
์ฃผ์š” ๊ธฐ๋Šฅ์€ ์‚ฌ์šฉ์ž ์ธ์ฆ, ์ผ๊ธฐ/ํƒœ๊ทธ/์Šค์ผ€์ค„ ๊ด€๋ฆฌ, AI ๊ธฐ๋ฐ˜ ์ฑ—, ๊ทธ๋ฆฌ๊ณ  ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์—”ํ‹ฐํ‹ฐ ๊ด€๋ฆฌ์ž…๋‹ˆ๋‹ค.


ํด๋” ๋ฐ ์ฃผ์š” ํŒŒ์ผ ๊ตฌ์กฐ

  • /src
    • main.ts : ์•ฑ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ, ๊ธ€๋กœ๋ฒŒ ํŒŒ์ดํ”„, Swagger ๋ฌธ์„œ ์ž๋™ํ™”
    • app.module.ts : ์ „์—ญ ๋ชจ๋“ˆ, TypeORM/Config ๋ชจ๋“ˆ ๋ฐ ์ฃผ์š” feature module ๋“ฑ๋ก
    • users/, diaries/, tags/, chat-messages/, chat-sessions/, schedules/, user-passwords/ : ๊ฐ ๋„๋ฉ”์ธ๋ณ„ ๋ชจ๋“ˆ ๋ฐ ์—”ํ‹ฐํ‹ฐ
  • ๋„์ปค ๋ฐ ํ™˜๊ฒฝ์„ค์ •
    • docker-compose.*.yaml, dockerfile.*, .env ๋“ฑ

๋” ๋งŽ์€ ๊ตฌ์กฐ๋Š” ํด๋” ๊ตฌ์กฐ ๋ฐ”๋กœ๋ณด๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๊ธฐ์ˆ  ์Šคํƒ ๋ฐ ํ™˜๊ฒฝ

  • Framework: NestJS
  • Database: MySQL (TypeORM ์‚ฌ์šฉ)
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜: dotenv ๋ฐ ConfigModule์„ ํ†ตํ•œ ๊ด€๋ฆฌ
  • Swagger: API ๋ฌธ์„œ ์ž๋™ ์ƒ์„ฑ ๋ฐ ์ œ๊ณต (/api ์—”๋“œํฌ์ธํŠธ)
  • ํ…Œ์ŠคํŠธ: Jest

TypeORM ์—ฐ๊ฒฐ ๋ฐฉ์‹

TypeORM์€ app.module.ts์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

  • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ธฐ๋ฐ˜์œผ๋กœ DB ์ •๋ณด ์ฃผ์ž…
  • ์—”ํ‹ฐํ‹ฐ ์ž๋™ ๋กœ๋“œ: entities: [__dirname + '/**/*.entity{.ts,.js}']
  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋ฐ ๋™๊ธฐํ™” ์ง€์› (synchronize: true, ๊ฐœ๋ฐœํ™˜๊ฒฝ์—์„œ๋งŒ ๊ถŒ์žฅ)
  • ์˜ˆ์‹œ:
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.DB_DOCKER_NAME,
      port: parseInt(process.env.DB_PORT!),
      username: 'root',
      password: process.env.DB_ROOT_PW,
      database: process.env.DB_NAME,
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    })

API ๋ฌธ์„œ

  • Swagger ๊ธฐ๋ฐ˜์˜ ์ž๋™ ๋ฌธ์„œํ™”(localhost:3000/api)
  • JWT Bearer ์ธ์ฆ ๋ฐฉ์‹ ์ง€์›

์‹คํ–‰ ๋ฐฉ๋ฒ• (์š”์•ฝ)

  1. ์˜์กด์„ฑ ์„ค์น˜
    npm install
  2. ํ™˜๊ฒฝ๋ณ€์ˆ˜(.env) ์„ค์ •
  3. ์„œ๋ฒ„ ์‹คํ–‰
    npm run start:dev
  4. API ๋ฌธ์„œ ๋ณด๊ธฐ

๊ธฐํƒ€

  • ์ฝ”๋“œ ์Šคํƒ€์ผ: ESLint, Prettier ์ ์šฉ
  • Docker/Docker Compose ์ง€์›
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ: /test ๋””๋ ‰ํ† ๋ฆฌ

โœจ ์ฃผ์š” API ์—”๋“œํฌ์ธํŠธ

๋Œ€๋ถ€๋ถ„์˜ ์—”๋“œํฌ์ธํŠธ๋Š” JWT ์ธ์ฆ์ด ํ•„์š”ํ•˜๋ฉฐ, Swagger ๋ฌธ์„œ(/api)์—์„œ ์ƒ์„ธ ์ŠคํŽ™์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1. Auth (์ธ์ฆ)

  • POST /auth/login : ์ด๋ฉ”์ผ+๋น„๋ฐ€๋ฒˆํ˜ธ ๋กœ๊ทธ์ธ (Access/Refresh Token ๋ฐœ๊ธ‰)
  • POST /auth/restore : refreshToken์œผ๋กœ accessToken ์žฌ๋ฐœ๊ธ‰
  • POST /auth/oauth : OAuth ๋กœ๊ทธ์ธ (Google ๋“ฑ)
  • GET /auth/profile : ๋‚ด ํ”„๋กœํ•„ ์ •๋ณด ์กฐํšŒ (JWT ํ•„์š”)
  • POST /auth/register : ํšŒ์›๊ฐ€์ž…

2. User (์‚ฌ์šฉ์ž)

  • GET /users : ์ „์ฒด ์œ ์ € ๋ชฉ๋ก ์กฐํšŒ (๊ด€๋ฆฌ์ž์šฉ)
  • GET /users/my : ๋‚ด ์ •๋ณด ์กฐํšŒ (JWT ํ•„์š”)

3. Diary (์ผ๊ธฐ)

  • POST /diaries : ์ผ๊ธฐ ์ƒ์„ฑ
  • GET /diaries : ๋‚ด ์ผ๊ธฐ ๋ชฉ๋ก ์กฐํšŒ (ํŽ˜์ด์ง•)
  • GET /diaries/recent : ์ตœ๊ทผ N๊ฐœ์˜ ์ผ๊ธฐ ์กฐํšŒ
  • GET /diaries/recent/one : ๊ฐ€์žฅ ์ตœ๊ทผ ์ผ๊ธฐ ์กฐํšŒ
  • GET /diaries/:id : ํŠน์ • ์ผ๊ธฐ ์ƒ์„ธ ์กฐํšŒ
  • PUT /diaries/:id : ์ผ๊ธฐ ์ˆ˜์ •
  • DELETE /diaries/:id : ์ผ๊ธฐ ์‚ญ์ œ

4. Schedule (์ผ์ •)

  • GET /schedules : ๋‚ด ์ผ์ • ์ „์ฒด ์กฐํšŒ
  • GET /schedules/:id : ์ผ์ • ๋‹จ๊ฑด ์กฐํšŒ
  • POST /schedules : ์ผ์ • ์ƒ์„ฑ
  • PUT /schedules/:id : ์ผ์ • ์ˆ˜์ •
  • DELETE /schedules/:id : ์ผ์ • ์‚ญ์ œ

5. AI/Chat (OpenAI ์—ฐ๋™)

  • POST /openai/send-message : ์ฑ—๋ด‡(AI)์—๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „์†ก, ๋‹ต๋ณ€ ๋ฐ›๊ธฐ
  • POST /openai/metadata : ์ผ๊ธฐ ๋‚ด์šฉ ๊ธฐ๋ฐ˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ(๊ฐ์ • ๋“ฑ) ์ถ”์ถœ
  • POST /openai/summary/content : ์ผ๊ธฐ ์š”์•ฝ ์ƒ์„ฑ
  • GET /openai/predict/recent : ์ตœ๊ทผ ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์˜ˆ์ธก ์‘๋‹ต

6. ChatSession (์ฑ— ์„ธ์…˜)

  • GET /sessions/recent : ์ตœ๊ทผ ์ฑ— ์„ธ์…˜ ๋ชฉ๋ก ์กฐํšŒ

๐Ÿ”‘ Auth(์ธ์ฆ) ์‹œ์Šคํ…œ ์š”์•ฝ

  • ๋ฐฉ์‹: JWT ๊ธฐ๋ฐ˜ (Access, Refresh Token), Passport.js(Local, JWT), OAuth(Google ๋“ฑ)
  • AccessToken: 3์‹œ๊ฐ„ ์œ ํšจ, Bearer ๋ฐฉ์‹์œผ๋กœ ์ „๋‹ฌ
  • RefreshToken: 7์ผ ์œ ํšจ, accessToken ์žฌ๋ฐœ๊ธ‰์— ์‚ฌ์šฉ
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”: bcrypt ์‚ฌ์šฉ, SALT ์ ์šฉ
  • ์ฃผ์š” ๋กœ์ง
    • ํšŒ์›๊ฐ€์ž…/๋กœ๊ทธ์ธ ์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฒ€์ฆ ๋ฐ JWT ํ† ํฐ ๋ฐœ๊ธ‰
    • ๋ชจ๋“  ์ธ์ฆ์ด ํ•„์š”ํ•œ API์—์„œ JwtAuthGuard ์ ์šฉ
    • ํ† ํฐ ๋งŒ๋ฃŒ/์˜ค๋ฅ˜์‹œ ์ ์ ˆํ•œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ฐ˜ํ™˜
    • OAuth ๋กœ๊ทธ์ธ(๊ตฌ๊ธ€ ๋“ฑ) ์ง€์›, ์™ธ๋ถ€ ํ† ํฐ ๊ฒ€์ฆ ํ›„ ์ž์ฒด ํ† ํฐ ๋ฐœ๊ธ‰
// Auth Module (์ผ๋ถ€ ์˜ˆ์‹œ)
JwtModule.register({
  secret: process.env.JWT_SECRET_KEY,
  signOptions: { expiresIn: '3h' },
});
// JWT Strategy (์ผ๋ถ€ ์˜ˆ์‹œ)
super({
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKey: process.env.JWT_SECRET_KEY!,
});
  • ๊ด€๋ จ ํŒŒ์ผ
    • src/auth/auth.module.ts
    • src/auth/auth.service.ts
    • src/auth/jwt.strategy.ts
    • src/users/user.entity.ts, src/user-passwords/user-password.entity.ts

์ตœ๊ทผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ๊ด€๊ณ„๋„

image


๐Ÿ” ์ฐธ๊ณ 

๋ณธ ์š”์•ฝ์€ ๋Œ€ํ‘œ API์™€ ์ธ์ฆ ๋กœ์ง์„ ์ค‘์‹ฌ์œผ๋กœ ์ •๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๋” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ ๋ฐ ์„ธ๋ถ€ ๊ตฌํ˜„์€ ์ฝ”๋“œ์™€ Swagger ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

About

๐Ÿš€ NestJS backend with MySQL and Docker Compose setup. Includes local auth with JWT.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages