Skip to content
Myukang edited this page Nov 9, 2023 · 10 revisions

설계

설계 목표

초기 구조

  • 해당 프로젝트의 첫 목표는 단기간 안에 서비스를 제공하는 것입니다.
  • 때문에, 멘토링에 필요하다고 생각하는 최소 기능을 목표로합니다.
  • 최소 기능 이후, 기능 확장 또한 필요하기 때문에 '확장 가능한 구조' 를 설계해야합니다.
  • 첫 개발인력인 @sungjpar @gulee 이외에 다른 인력이 오더라도 대체 가능한 프로젝트를 만들어야합니다.

최소 기능

  • 모든 유저는 멘토가 될 수 있습니다.
  • 멘토는 각자 프로필을 부여 받습니다.
  • 멘토의 프로필에는 각자의 분야를 해시태그로 표현할 수 있습니다.
  • 메인 페이지에서 DEVELOP, HOBBY 두 카테고리로 크게 분류할 수 있습니다.
  • 멘티는 멘토에게 멘토링을 예약할 수 있습니다.

추가 기능

  • 아래는 고려 중인 추가 기능사항들입니다.
  • 멘토링 예약 알림, 피드백 요청 등 알림 서비스
    • Slack bot을 이용하는 것이 가장 합리적이며, 권한 획득 이전에는 email을 통한 알림을 고려하고 있음.
    • 초창기에 둘다 없을 때는 운영자가 직접 뛰거나 (직접 슬랙 알림...), 멘티가 멘토에게 slack message로 요청하도록 권유
  • 멘토링 시간 지정
    • 42 Polar 에서 사용하였던 멘토링 시간대별 예약을 구현 (알림 서비스 이후에 등장하는 것이 좋아보입니다.)
  • 이전 42 구성원 유입
    • 초기의 구조는 42 내부 구성원만 사용할 수 있도록 작성할 것입니다.
    • 이후, 서비스가 활성화된다면 취업을 한 구성원들과도 닿을 수 있는 서비스로 발전하였으면 합니다.
    • 이를 위해서 42 계정의 권한이 없는 유저 또한 가입이 가능하도록 구조를 변경해야합니다.
  • 자기 소개 글 에디터 지원
    • 초기 구현에서는 자기 소개에 대해서 텍스트만 구성하도록 권장할 것입니다. 때문에 화려한 구성이 불가능합니다.
    • 이후에는 내부에 에디터를 탑재하고, 글, 그림, 영상 모두를 수용할 수 있도록 변경해야합니다.
  • 프로필 사진 변경 가능
    • 초기 구현에서는 intra profile 에 활용되는 이미지를 그대로 사용할 것입니다.
    • 이후 사용자가 원하는 profile image 를 사용할 수 있도록 이미지 서버 구성 및 수정 가능하도록 변경해야합니다.

DB 설계

ERD

manito 42의 DB 구조는 아래 ERD Cloud 를 통해서 보실 수 있습니다.

https://www.erdcloud.com/d/L8n7bayanfnsxNkmm

각 테이블 설명

users

  • 모든 유저의 정보를 담는 테이블입니다. 가입된 유저는 모두 해당 테이블의 레코드로 추가됩니다.
  • email, nickname, profile_image 은 42 intra와 동일하게 사용되며, 수정할 수 없습니다.
    • 내부 서비스이기 때문에 발생할 수 있는 혼란에 대해서 줄이기 위함입니다.
    • profile_image의 경우 추후 수정 가능 여부에 대해 검토할 것입니다.
  • is_mentor 를 통해 해당 유저가 멘토의 역할을 하는지 아닌지 판별합니다. is_mentor 가 활성화된 유저는 멘토용 프로필이 생성됩니다.
  • mentor_profiles 이 별도의 테이블로 구성되는 이유 중 하나는, 정규화 이외에도 이후 멘토링 카테고리별 멀티 프로필을 염두에 두고 있기 때문입니다.
  • role 의 경우 운영자를 판별하기 위한 용도입니다.
     enum UserRole {
       ADMIN = 'ADMIN',
        USER = 'USER',
    }

mentor_profiles

  • 모든 유저는 멘토가 될 수 있습니다. 멘토가 된 유저는 mentor_profiles 에 새 레코드가 추가됩니다.
  • 본인을 짧게 소개하는 short_description (프로필 카드 노출용)
  • 조금 더 장문으로 소개할 수 있는 description 이 있습니다.

mentee_feedbacks

  • 멘토링 이후 멘티가 멘토에게 작성하는 피드백입니다.
  • 멘티는 멘토에게 멘토링 후기를 작성할 수 있으며, 이는 content 에 긴 텍스트로 저장됩니다.
  • 멘토에 대한 평점 또한 저장되며, 0~5 점으로 부여합니다.

mentor_feedbacks

  • 멘토링 이후 멘토가 멘티에게 작성하는 피드백입니다.
  • 멘토는 멘티에게 멘토링 후기를 작성할 수 없습니다.
  • 단순히 해당 멘토링에 대한 평점만 남깁니다. 마찬가지로 0~5 점으로 부여됩니다.

hashtags

  • 멘토링의 성격을 구분하기 위해 존재합니다.
  • mentor_profiles, reservations 에 해당 프로필, 예약에 대해서 성격을 부여하는 역할을 합니다.

reservations

  • 멘토링 신청/성사에 활용되는 테이블입니다.

  • 멘티는 멘토의 프로필을 통해서 멘토링을 신청할 수 있습니다.

  • 멘토링은 시간 제약이 따로 없습니다.

    ReservationStatus {
      REQUEST = 'REQUEST', //멘티의 신청상태
      ACCEPT = 'ACCEPT', //멘토의 수락상태
      CANCEL = 'CANCEL', //멘토의 거절, 멘티의 신청취소, 
      MENTEE_FEEDBACK = 'MENTEE_FEEDBACK', //멘티가 피드백을 남긴 상태
      DONE = 'DONE' //멘토가 피드백남기고 멘토링이 끝난 상태
    }
  • 멘토링 예약시에 요청 메시지를 전달할 수 있으며 이는 request_message 에 긴 텍스트로 저장됩니다.

  • 이후 데이터 분류를 위해 category hashtag 를 반드시 reservation 에서 명시해야합니다.

categories

  • 데이터 분류를 위한 큰 분류입니다.
  • 서비스 초기에는 DEVELOP, HOBBY 두 가지의 카테고리만 존재할 예정이며, 이후 더 추가될 수 있습니다.

ORM

manito 42의 ORM은 Prisma를 활용하고 있습니다.

https://www.prisma.io/

  • 최근 TypeORM 과 npm downloads가 비등한 ORM 이며, Documentation이 훌륭하여 매력적으로 느꼈습니다.
  • 이러한 이유에서 TypeORM 과의 비교를 위해(학습 용도가 큽니다.) 채택하였습니다.

API 설계

manito 42의 API-SERVER 는 아래 제공된 명세를 기반으로 작성되어있습니다.

Swagger UI 를 통해서 확인해보세요.

https://manito42.github.io/api-docs/

AWS

Architecture

aws

VPC

  • 개발용 VPC, 배포용 VPC 구분되어있습니다.
  • 개발용 VPC 에서는 NAT 인스턴스를 직접 구축하여 사용하는 것 외에 다른 것은 없음 (비용 절감을 위함입니다.)
  • 주요 인스턴스들은 Private subnet 에 존재합니다. 따라서 외부에서 SSH 접속 등을 위해서는 Bastion host 를 거쳐 접속해야합니다.

CI/CD

  • Github action + CodeDeploy + S3 Bucket 사용 중입니다.
  • 배포 과정은 대략 아래와 같습니다.
  • Github action -> S3 Upload -> CodeDeploy -> Blue/Green Deploying..

RDS

  • 관련 Documentation
  • 현재는 RDS 하나만 사용하고 있습니다.(Replication 이나 추가 RDS 인스턴스는 존재하지 않습니다.)

ALB

  • HTTPS -> HTTP 및 Auto Scaling / 안정성 / CD 을 위해서 ALB를 사용하고 있습니다.

EFS

  • API 서버의 로그 영속적 저장을 위해 EFS 를 마운트하여 사용하고 있습니다.

프로젝트 디렉토리 구조

NestJS

.
├── prisma
├── src
│   ├── common
│   │   ├── decorators
│   │   ├── enums
│   │   ├── filters
│   │   ├── guards
│   │   ├── interceptors
│   │   ├── interfaces
│   │   ├── middlewares
│   │   └── pipes
│   ├── config
│   ├── database
│   │   ├── factories
│   │   ├── seeders
│   │   └── services
│   └── models
│   │   ├── category
│   │   │   ├── dto
│   │   │   │   ├── request
│   │   │   │   └── response
│   │   │   └── queries
│   │   └── ...
│   └── modules
│   │   ├── auth
│   │   ├── search
│   │   ├── home
│   │   └── ...
└── test

common

  • common 에는 프로젝트 전반에 사용되는 요소들이 위치합니다.

config

  • config 에는 프로젝트 내에서 사용되는 environment variable 을 관리하는 configuration module 들이 위치합니다.

database

  • database 에는 데이터베이스에 관련된 요소들이 위치합니다.
  • prisma.service, seeder factory 등이 그 예시입니다.

models

  • models 에는 DB model 의 입출력과 관련된 요소들, 이 모델들을 제어하는 service와 외부 api 역할을 책임지는 controller 가 위치합니다.
  • 내부적으로 사용하는 dto 에는 request response를 구분합니다. 이는 controller에서 들어오고 나가는 데이터 형식에 대해서 규정합니다.
    • 이는 타 모듈에서도 동일하게 작동합니다.
  • 중복되는 코드를 방지하기 위해서 db 쿼리에 사용되는 select, where 등을 처리하는 부분은 queries에 저장됩니다.

modules

  • modules 에는 이외의 모듈이 위치합니다. /auth /search /home 과 같이 models 들을 활용하지만 외부 API 에 등록된 경우에도 이와 같이 modules 에서 별도로 관리합니다.