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 μ—μ„œ λ³„λ„λ‘œ κ΄€λ¦¬ν•©λ‹ˆλ‹€.