Skip to content
This repository was archived by the owner on Dec 6, 2025. It is now read-only.

codeit-welive/welive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

827 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌳 Welive

Welive Logo

πŸ“Œ ν”„λ‘œμ νŠΈ μ†Œκ°œ

🌳 β€œν•¨κ»˜ μ‚¬λŠ” 곡간, ν•¨κ»˜ λ§Œλ“œλŠ” 관리.”
μœ„λ¦¬λΈŒ(Welive)λŠ” μž…μ£Όλ―Όκ³Ό 관리 단체가 ν•œμžλ¦¬μ—μ„œ μ†Œν†΅ν•˜κ³  문제λ₯Ό ν•΄κ²°ν•˜λ©°, 더 λ‚˜μ€ 곡동체λ₯Ό λ§Œλ“€μ–΄κ°€λŠ” μ•„νŒŒνŠΈ μƒν˜Έ 관리 ν”Œλž«νΌμž…λ‹ˆλ‹€.
λ‹Ήμ‹ μ˜ 일상이 더 νŽΈν•΄μ§€λŠ” κ·Έ μˆœκ°„κΉŒμ§€, μœ„λ¦¬λΈŒκ°€ ν•¨κ»˜ν•©λ‹ˆλ‹€.

πŸ”— 데λͺ¨ & μ£Όμš” 링크

πŸ›  기술 μŠ€νƒ

Backend

Node.js Express TypeScript Prisma PostgreSQL

Infra / DevOps

Docker GitHub Actions AWS EC2 AWS S3 Nginx

Testing & Quality

Jest Supertest ESLint Prettier

Frontend (ν˜‘μ—… / μ°Έκ³ )

Next.js


🧭 기술 μŠ€νƒ 채택 이유

Node.js + Express 5

  • λŒ€κ·œλͺ¨ μ„œλΉ„μŠ€μ—μ„œλ„ κ²€μ¦λœ κ²½λŸ‰ μ›Ή ν”„λ ˆμž„μ›Œν¬λ‘œ, λΌμš°νŒ…Β·λ―Έλ“€μ›¨μ–΄ 기반 ꡬ쑰λ₯Ό μ„Έλ°€ν•˜κ²Œ μ„€κ³„ν•˜κΈ° μš©μ΄ν•¨
  • 비동기 I/O 기반으둜 SSEΒ·Socket.io λ“± μ‹€μ‹œκ°„ κΈ°λŠ₯ κ΅¬ν˜„μ— 적합
  • Layered Architecture ꡬ성 μ‹œ Router β†’ Controller β†’ Service β†’ Repository 흐름을 κ°€μž₯ μœ μ—°ν•˜κ²Œ 섀계할 수 있음

TypeScript

  • 도메인 λ‹¨μœ„λ‘œ νƒ€μž…μ„ μ—„κ²©ν•˜κ²Œ μ •μ˜ν•΄ λŒ€κ·œλͺ¨ λͺ¨λ“ˆ κ°„ μ˜μ‘΄μ„±μ„ μ•ˆμ •μ μœΌλ‘œ μœ μ§€
  • DTOΒ·ValidatorΒ·Repository λ“± 계측 κ°„ 데이터 계약을 λͺ…ν™•νžˆ 보μž₯
  • Prisma와 κ²°ν•©ν•˜μ—¬ 컴파일 λ‹¨κ³„μ—μ„œ DB μŠ€ν‚€λ§ˆ 였λ₯˜λ₯Ό μ‘°κΈ° 감지할 수 있음

Prisma + PostgreSQL

  • Prisma의 μŠ€ν‚€λ§ˆ 기반 ORM은 λͺ¨λΈ λ³€κ²½ 및 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 관리가 직관적이며, λŒ€κ·œλͺ¨ ν…Œμ΄λΈ” 쑰인 κ΅¬μ‘°μ—μ„œλ„ νƒ€μž… μ•ˆμ „μ„±μ„ 제곡
  • PostgreSQL은 νŠΈλžœμž­μ…˜ 강도가 λ†’μ•„ Poll SchedulerΒ·μ•Œλ¦ΌΒ·λŒ€λŸ‰ CSV 처리 λ“± λ™μ‹œμ„± μš”κ΅¬μ— μ•ˆμ •μ μœΌλ‘œ λŒ€μ‘

Docker + Nginx

  • κ°œλ°œΒ·ν…ŒμŠ€νŠΈΒ·μš΄μ˜ ν™˜κ²½μ„ μ™„λ²½ν•˜κ²Œ λ™μΌν•˜κ²Œ μœ μ§€ν•  수 μžˆμ–΄ 배포 μ•ˆμ •μ„±μ΄ λ†’μŒ
  • Nginx Reverse Proxyλ₯Ό 톡해 SSL, 정적 μžμ› μ„œλΉ„μŠ€, CORS, 헀더 λ³΄μ•ˆ 등을 단일 μ§„μž…μ μ—μ„œ μ œμ–΄ κ°€λŠ₯
  • BE(μ»¨ν…Œμ΄λ„ˆ) + FE(PM2) μ‘°ν•©μœΌλ‘œ 초기 λ‘œλ”© μ‹œκ°„μ„ μ΅œμ ν™”ν•˜λ©΄μ„œλ„ CI/CD μžλ™ν™”μ— 유리

AWS(EC2, S3)

  • EC2λŠ” Docker ν™˜κ²½ 배포에 직관적이며 ν™•μž₯ 및 μœ μ§€λ³΄μˆ˜κ°€ 용이
  • S3λŠ” 이미지·정적 파일 μ €μž₯에 μ•ˆμ •μ μ΄λ©°, Presigned URL 기반 μ—…λ‘œλ“œλ‘œ λ³΄μ•ˆ μˆ˜μ€€μ„ 크게 높일 수 있음

GitHub Actions + GHCR

  • ν‘Έμ‹œ 이벀트 기반으둜 ν…ŒμŠ€νŠΈ β†’ λΉŒλ“œ β†’ 이미지 생성 β†’ μ„œλ²„ μžλ™ λ°°ν¬κΉŒμ§€ μ™„μ „ μžλ™ν™”
  • GHCR μ‚¬μš©μœΌλ‘œ 이미지 버전 관리 및 둀백이 μš©μ΄ν•˜λ©°, 사섀 λ ˆμ§€μŠ€νŠΈλ¦¬λ³΄λ‹€ 섀정이 λ‹¨μˆœ

Jest + Supertest

  • DB 연동 ν…ŒμŠ€νŠΈ, SSE 전달 ν…ŒμŠ€νŠΈ, μŠ€μΌ€μ€„λŸ¬ λ™μž‘κΉŒμ§€ 검증 κ°€λŠ₯ν•œ ꡬ쑰
  • ν…ŒμŠ€νŠΈ DBλ₯Ό λ³„λ„λ‘œ ꡬ성해 μ‹€μ œ Prisma νŠΈλžœμž­μ…˜ 흐름을 κ·ΈλŒ€λ‘œ μž¬ν˜„ κ°€λŠ₯

🧩 μ£Όμš” νŒ¨ν‚€μ§€ 채택 이유

  • Zod: DTO/Query/Paramsλ₯Ό μŠ€ν‚€λ§ˆ 기반으둜 톡합 κ΄€λ¦¬ν•˜μ—¬ 검증 일관성을 보μž₯
  • DOMPurify + jsdom: μ„œλ²„λ‹¨ Sanitization으둜 XSS 곡격 차단 (FEμ—μ„œ μ‘°μž‘ν•˜λ”λΌλ„ λ¬΄νš¨ν™”)
  • sharp: 이미지 λ¦¬μ‚¬μ΄μ¦ˆ 및 Magic Number 기반 MIME 검증을 ν†΅ν•œ 파일 μœ„μž₯ 곡격 λ°©μ§€
  • Limiter(직접 κ΅¬ν˜„): Poll μŠ€μΌ€μ€„λŸ¬ λ™μ‹œμ„± μ œμ–΄(단일 μ‹€ν–‰ 보μž₯)
  • Socket.io / SSE: μ±„νŒ… + μ‹€μ‹œκ°„ μ•Œλ¦Ό 각각의 νŠΉμ„±μ„ ν™œμš©ν•œ 이쀑 μ‹€μ‹œκ°„ 처리 ꡬ쑰

πŸš€ 핡심 κΈ°λŠ₯ μš”μ•½

  • μ—­ν•  기반 인증/승인 ν”„λ‘œμ„ΈμŠ€

    • μž…μ£Όλ―Ό Β· κ΄€λ¦¬μž Β· μŠˆνΌκ΄€λ¦¬μž λ“± 역할별 νšŒμ›κ°€μž…, 승인 μš”μ²­, 승인/거절 흐름
  • μž…μ£Όλ―Ό λͺ…λΆ€ 관리

    • CSV μ—…λ‘œλ“œ, 검색/필터링, νŽ˜μ΄μ§•, 일괄 정리 κΈ°λŠ₯ 제곡
  • 곡지사항 / 민원 / λŒ“κΈ€ μ‹œμŠ€ν…œ

    • CRUD, μΉ΄ν…Œκ³ λ¦¬, 쑰회수, λΉ„κ³΅κ°œ 처리, μˆ˜μ • μ œν•œ λ“± 운영 κΈ°λŠ₯ 포함
  • μ‹€μ‹œκ°„ μ•Œλ¦Ό μ‹œμŠ€ν…œ (SSE)

    • 민원/곡지/νˆ¬ν‘œ μƒνƒœ λ³€κ²½ μ‹œ μ¦‰μ‹œ μ•Œλ¦Ό 이벀트 전달
  • μ£Όλ―Ό νˆ¬ν‘œ μ‹œμŠ€ν…œ (Polls)

    • νˆ¬ν‘œκΆŒμž λ²”μœ„ μ„€μ •, μžλ™ μ˜€ν”ˆ/마감, μ‹€μ‹œκ°„ μ°Έμ—¬, κ²°κ³Ό μžλ™ 집계
  • 이벀트 μΊ˜λ¦°λ” (κ΄€λ¦¬μžμš©)

    • μ•„νŒŒνŠΈ λ‚΄ 일정 관리 및 곡지와 μ—°λ™λ˜λŠ” 이벀트 CRUD 제곡
  • μ‹€μ‹œκ°„ μ±„νŒ… (Socket.io)

    • μž…μ£Όλ―Όβ€“κ΄€λ¦¬μž κ°„ λΉ λ₯Έ μ‘λŒ€λ₯Ό μœ„ν•œ μ‹€μ‹œκ°„ λ©”μ‹œμ§• κΈ°λŠ₯
  • ν”„λ‘œν•„ 이미지 μ—…λ‘œλ“œ (S3 Presigned URL)

    • Magic Number 기반 κ²€μ¦μœΌλ‘œ μœ„μž₯ 파일 차단, μ•ˆμ „ν•œ 파일 처리
  • λ™μ‹œμ„± μ œμ–΄ 기반 μŠ€μΌ€μ€„λŸ¬ (Limiter)

    • Poll μžλ™ ν™œμ„±ν™”/만료 μ‹œ 단일 μ‹€ν–‰ 보μž₯ 및 경쟁 쑰건 λ°©μ§€

μœ„λ¦¬λΈŒλŠ” ν•™μŠ΅μš© μ˜ˆμ œκ°€ μ•„λ‹ˆλΌ, μ‹€μ œ μ•„νŒŒνŠΈ 관리 도메인을 κ³ λ €ν•œ
β€˜κΈ°λŠ₯Β·λ³΄μ•ˆΒ·ν™•μž₯μ„± μ€‘μ‹¬μ˜ μ‹€μ „ ν”„λ‘œμ νŠΈβ€™λ‘œ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

πŸ› μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜

flowchart LR
    subgraph CLIENT["Client"]
        A[Browser / Next.js]
    end

    subgraph PROXY["Nginx Reverse Proxy"]
        B[Nginx]
    end

    subgraph BACKEND["Backend (Node.js Β· Express 5)"]
        C[Router]
        D[Controller]
        E[Service]
        F[Repository]
        G[Prisma Client]
    end

    subgraph DATABASE["PostgreSQL (RDS)"]
        H[(PostgreSQL)]
    end

    subgraph STORAGE["AWS S3"]
        S3[S3 Bucket - Profile Images]
    end

    subgraph CICD["CI/CD Pipeline"]
        GA[GitHub Actions]
        GHCR[GHCR - Docker Image]
        EC2[EC2 - Docker Runtime]
    end

    %% Client -> Backend
    A --> B --> C
    C --> D --> E --> F --> G --> H

    %% File Upload
    E -->|Upload/Delete| S3

    %% CI/CD Flow
    GA --> GHCR --> EC2 --> B
Loading

πŸ—‚ Database ERD

Welive ERD

πŸ“Œ μ£Όμš” ν…Œμ΄λΈ” 관계 μš”μ•½

  • Apartments β†’ Residents : ν•œ μ•„νŒŒνŠΈμ—λŠ” μ—¬λŸ¬ μž…μ£Όλ―Όμ΄ μ†Œμ†
  • Residents β†’ Complaints / Notices / Comments : μž…μ£Όλ―Όμ΄ μž‘μ„±ν•œ λ―Όμ›Β·κ³΅μ§€Β·λŒ“κΈ€κ³Ό μ—°κ²°
  • Polls β†’ PollVotes : νˆ¬ν‘œ 1κ°œμ— μ—¬λŸ¬ νˆ¬ν‘œ 기둝이 쒅속
  • Complaints / Notices / Polls β†’ Events : λͺ¨λ“  μ£Όμš” ν™œλ™μ€ 이벀트 둜그둜 기둝
  • Events β†’ Notifications : μƒνƒœ λ³€κ²½ μ‹œ μ•Œλ¦Ό(SSE)둜 연동
  • Users β†’ Residents : μ£Όλ―Ό 계정과 μ‚¬μš©μž κ³„μ •μ˜ 1:1 λ§€ν•‘ ꡬ쑰

ERDλŠ” Prisma Schema 기반으둜 μžλ™ μƒμ„±λ˜λ©°,
κ΄€κ³„ν˜• λͺ¨λΈμ„ 톡해 κΆŒν•œ/μ—­ν•  기반 관리, μ‹€μ‹œκ°„ μ•Œλ¦Ό, νˆ¬ν‘œ μ‹œμŠ€ν…œ λ“±
μ£Όμš” κΈ°λŠ₯을 μΌκ΄€λœ ꡬ쑰둜 ν™•μž₯ν•  수 μžˆλ„λ‘ μ„€κ³„ν–ˆμŠ΅λ‹ˆλ‹€.

πŸ— μ‹œμŠ€ν…œ ꡬ쑰 (Layered Architecture)

μœ„λ¦¬λΈŒ λ°±μ—”λ“œλŠ” Express 5 기반의 Layered Architecture둜 κ΅¬μ„±λ˜μ–΄ 있으며,
각 λ ˆμ΄μ–΄κ°€ λͺ…ν™•ν•œ 역할을 가지도둝 섀계해 μœ μ§€λ³΄μˆ˜μ„±κ³Ό ν™•μž₯성을 λ†’μ˜€μŠ΅λ‹ˆλ‹€.

πŸ”Ή Layer ꡬ성

  • Router Layer

    • μš”μ²­ μ—”λ“œν¬μΈνŠΈ μ •μ˜ 및 λͺ¨λ“ˆ λ‹¨μœ„ λΌμš°νŒ… ꡬ성
    • 인증/인가, CSV 검증, Sanitization λ“± 곡톡 미듀웨어 적용 지점
  • Controller Layer

    • HTTP μš”μ²­/응닡 처리
    • μ„œλΉ„μŠ€ 호좜 μ „ μž…λ ₯κ°’ 검증(Zod) 및 μ˜ˆμ™Έ 흐름 ν†΅μ œ
    • Swagger μžλ™ λ¬Έμ„œν™” 주석 μœ„μΉ˜
  • Service Layer

    • λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 쀑심
    • κΆŒν•œ 검증, νŠΈλžœμž­μ…˜ 처리, 도메인 κ·œμΉ™ 적용
    • SSE μ•Œλ¦Ό 트리거, Poll μŠ€μΌ€μ€„λŸ¬ 호좜 λ“± 핡심 둜직 λ‹΄λ‹Ή
  • Repository Layer

    • Prisma 기반 λ°μ΄ν„°λ² μ΄μŠ€ μ ‘κ·Ό
    • λ³΅μž‘ν•œ 쿼리/쑰인/νŠΈλžœμž­μ…˜μ„ μΊ‘μŠν™”ν•˜μ—¬ Service와 뢄리
  • Prisma Client Layer

    • PostgreSQLκ³Ό 직접 톡신
    • νƒ€μž… 세이프티 제곡 및 μŠ€ν‚€λ§ˆ 기반 λͺ¨λΈ 관리

πŸ”Ή μΆ”κ°€ μ„œλΈŒ μ‹œμŠ€ν…œ

  • Input Sanitization (DOMPurify + jsdom)
    λŒ“κΈ€/곡지/민원 λ“± μ‚¬μš©μž μž…λ ₯ ν•„λ“œμ— λŒ€ν•΄ μ„œλ²„ λ‹¨μ—μ„œ HTML μ •ν™” μˆ˜ν–‰

  • Validation Layer (Zod)
    Params/Query/Bodyλ₯Ό μŠ€ν‚€λ§ˆ 기반으둜 톡합 κ²€μ¦ν•˜μ—¬ Controller에 λ„λ‹¬ν•˜κΈ° μ „ 데이터 무결성 보μž₯

  • SSE Notification Layer
    μ•Œλ¦Ό emitterλ₯Ό 별도 λͺ¨λ“ˆλ‘œ 뢄리해 Poll/민원/곡지 λ“±μ˜ 이벀트λ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ 전솑

  • Poll Scheduler (Limiter 기반 단일 μ‹€ν–‰ 보μž₯)
    Poll μžλ™ μ˜€ν”ˆ/만료λ₯Ό Cron + Limiter μ‘°ν•©μœΌλ‘œ κ΅¬ν˜„ν•΄ 경쟁 쑰건을 λ°©μ§€

  • Socket Layer (μ‹€μ‹œκ°„ μ±„νŒ…)
    μž…μ£Όλ―Όβ€“κ΄€λ¦¬μž κ°„ μ‹€μ‹œκ°„ λ©”μ‹œμ§•μ„ Socket.io둜 처리 (JWT 인증 미듀웨어 포함)

이 λ ˆμ΄μ–΄ κ΅¬μ‘°λŠ” 도메인 ν™•μž₯Β·ν…ŒμŠ€νŠΈΒ·λ³΄μ•ˆΒ·λ°°ν¬μ˜ λͺ¨λ“  κ³Όμ •μ—μ„œ μΌκ΄€λœ 흐름을 μœ μ§€ν•˜λ©°,
λŒ€κ·œλͺ¨ μ„œλΉ„μŠ€ ꡬ쑰둜 ν™•μž₯해도 μ•ˆμ •μ μœΌλ‘œ μœ μ§€λ  수 μžˆλ„λ‘ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

πŸ” λ³΄μ•ˆ 섀계 (Security Overview)

μœ„λ¦¬λΈŒλŠ” Express 5 기반 λ‹€μΈ΅ λ³΄μ•ˆ ꡬ쑰λ₯Ό μ μš©ν•΄
μž…λ ₯ 검증뢀터 파일 μ—…λ‘œλ“œ, 인증, μ„œλ²„ ν—€λ”κΉŒμ§€ μ „λ°˜μ μΈ λ³΄μ•ˆ 리슀크λ₯Ό μ΅œμ†Œν™”ν–ˆμŠ΅λ‹ˆλ‹€.

πŸ”Ή HTTP λ³΄μ•ˆ 헀더 & μ„œλ²„ 보호

  • helmet(CSP 적용): 슀크립트/이미지/ν”„λ ˆμž„ μ •μ±… κ°•ν™”λ‘œ XSSΒ·Clickjacking λ°©μ§€
  • X-Powered-By 제거, ETag λΉ„ν™œμ„±ν™”λ‘œ ν”„λ ˆμž„μ›Œν¬ λ…ΈμΆœ 및 캐싱 기반 곡격 μ™„ν™”
  • HPP(HTTP Parameter Pollution) 차단 적용

πŸ”Ή 인증 & κΆŒν•œ

  • JWT Access / Refresh Token ꡬ쑰
  • Refresh Token은 DB μƒνƒœ 관리 λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•΄ μž¬λ°œκΈ‰ μ‹œ κΈ°μ‘΄ 토큰 λ¬΄νš¨ν™”
  • λΌμš°ν„° λ‹¨μœ„λ‘œ μ—­ν•  기반 μ ‘κ·Ό μ œμ–΄(Role-based Access Control) 적용

πŸ”Ή CORS & Proxy ν™˜κ²½

  • Strict Origin 기반 CORS ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ
  • trust proxy μ„€μ •μœΌλ‘œ Nginx λ’€μ—μ„œ IP/ν”„λ‘œν† μ½œ 정보 μ •ν™•νžˆ νŒŒμ‹±

πŸ”Ή μž…λ ₯ 검증 & Sanitization

  • Zod μŠ€ν‚€λ§ˆ 기반 Params/Query/Body μ •ν˜•μ  검증
  • μ‚¬μš©μž μž…λ ₯값은 DOMPurify + jsdom 기반 μ„œλ²„λ‹¨ Sanitization으둜 XSS 차단
  • CSV μ—…λ‘œλ“œ μ‹œ μ •ν™•ν•œ ν—€λ”Β·νƒ€μž… 검증 및 전체 νŠΈλžœμž­μ…˜ 처리

πŸ”Ή 파일 μ—…λ‘œλ“œ λ³΄μ•ˆ

  • 이미지 μ—…λ‘œλ“œλŠ” ν™•μž₯μžκ°€ μ•„λ‹Œ Magic Number(MIME) 기반 검증
  • sharpλ₯Ό μ΄μš©ν•œ κ°•μ œ μž¬μΈμ½”λ”©(μž¬μ••μΆ•)으둜 β€œν΄λ¦¬κΈ€λ‘―(polyglot) νŒŒμΌβ€ 차단
    • 예: JPEG/PNG둜 μœ„μž₯ν•œ μŠ€ν¬λ¦½νŠΈΒ·μ‹€ν–‰νŒŒμΌ ν˜Όν•© νŽ˜μ΄λ‘œλ“œ κ°•μ œ 제거
  • μž¬μΈμ½”λ”© ν›„μ—λ§Œ Presigned URL 기반 S3 μ—…λ‘œλ“œ ν—ˆμš©
  • μœ„μž₯ 파일(예: PNG 헀더 + JS νŽ˜μ΄λ‘œλ“œ) μ¦‰μ‹œ κ±°λΆ€

πŸ”Ή Rate Limiting & μ„œλ²„ 보호

  • express-rate-limit: IP λ‹¨μœ„ μš”μ²­ μ œν•œ 적용
  • JSON Body μ‚¬μ΄μ¦ˆ μ œν•œ(2MB), URL-encoded μ œν•œ

πŸ”Ή μ‹€μ‹œκ°„ 톡신 보호

  • SSE μ•Œλ¦Ό: JWT 기반 인증
  • Socket.io μ±„νŒ…: Connection middleware둜 인증 ν›„ μ†ŒμΌ“ 확립

πŸ”Ή μ—λŸ¬/λ‘œκΉ…

  • Pino 기반 ꡬ쑰적 λ‘œκΉ…
  • κΈ€λ‘œλ²Œ μ—λŸ¬ ν•Έλ“€λŸ¬λ‘œ λ‚΄λΆ€ μŠ€νƒ μˆ¨κΉ€ & μΌκ΄€λœ μ—λŸ¬ 응닡 포맷 μœ μ§€

μž…λ ₯ 검증, Sanitization, μž¬μΈμ½”λ”© 기반 파일 λ³΄μ•ˆ, JWT 인증, CSP λ“±
μ—¬λŸ¬ λ³΄μ•ˆ 계측을 μ μš©ν•˜μ—¬ μ•ˆμ •μ„±κ³Ό 신뒰성을 κ°•ν™”ν–ˆμŠ΅λ‹ˆλ‹€.

🚒 CI/CD & 배포 ꡬ쑰

μœ„λ¦¬λΈŒλŠ” Docker 기반 ν”„λ‘œλ•μ…˜ ν™˜κ²½ + GitHub Actions μžλ™ 배포 νŒŒμ΄ν”„λΌμΈμ„ κ΅¬μΆ•ν•˜μ—¬
개발 β†’ λΉŒλ“œ β†’ ν…ŒμŠ€νŠΈ β†’ 배포의 μ „ 과정을 μžλ™ν™”ν–ˆμŠ΅λ‹ˆλ‹€.

πŸ”Ή CI/CD 흐름

  1. GitHub Actions(CI)

    • PR/commit μ‹œ μžλ™μœΌλ‘œ ν…ŒμŠ€νŠΈ μ‹€ν–‰(Jest)
    • νƒ€μž… 체크/ESLint 검사 톡해 ν’ˆμ§ˆ μœ μ§€
    • λͺ¨λ“  ν…ŒμŠ€νŠΈ 톡과 μ‹œ Docker 이미지 λΉŒλ“œ
  2. GHCR(GitHub Container Registry)

    • λΉŒλ“œλœ Docker 이미지λ₯Ό νƒœκ·Έ λ²„μ „μœΌλ‘œ μ—…λ‘œλ“œ
    • 이미지 버전 관리 및 둀백이 용이
  3. GitHub Actions(CD) – EC2 μžλ™ 배포

    • SSHλ₯Ό 톡해 EC2에 접속
    • μ΅œμ‹  이미지 Pull
    • docker-compose.prod.yaml 기반으둜 μ»¨ν…Œμ΄λ„ˆ μž¬κΈ°λ™
    • ν™˜κ²½ λ³€μˆ˜ 파일(.env.prod) μžλ™ 생성/동기화
  4. EC2(Docker Runtime)

    • Backend μ»¨ν…Œμ΄λ„ˆ 단일 μ‹€ν–‰
    • 둜그 관리(Pino 파일 μ €μž₯), ν—¬μŠ€μ²΄ν¬ 포함
  5. Nginx Reverse Proxy

    • μš”μ²­ λΌμš°νŒ…: FE β†’ / (Next.js) / BE β†’ /api
    • Cloudflare Origin 볡원, gzip μ••μΆ•, CORS/λ³΄μ•ˆ 헀더 일괄 관리
    • SSL(TLS) 쒅단 처리

πŸ”Ή 배포 ꡬ쑰 μš”μ•½

flowchart LR
    Dev[Developer Push] --> GA[GitHub Actions]
    GA --> Test[Tests & Lint]
    GA --> Build[Docker Build]
    Build --> GHCR[Push to GHCR]
    GHCR --> Deploy[GA Deploy Script]
    Deploy --> EC2[(EC2)]
    EC2 --> DC[Docker Compose Up]
    DC --> Nginx[Nginx Reverse Proxy]
    Nginx --> Backend[Backend Container]
Loading

πŸ”Ή μ£Όμš” νŠΉμ§•

  • μ™„μ „ μžλ™ 배포: Git push만으둜 ν…ŒμŠ€νŠΈ β†’ λΉŒλ“œ β†’ λ°°ν¬κΉŒμ§€ μžλ™ 처리
  • ν™˜κ²½ 뢄리: .env, .env.test, .env.production 뢄리 λ‘œλ“œ
  • 선택적 재배포: API λ³€κ²½ 없이 νŠΉμ • λͺ¨λ“ˆλ§Œ 재배포 κ°€λŠ₯
  • μ—λŸ¬ λ°©μ§€ μž₯치: Swagger 미생성 μ‹œ μ„œλ²„ 기동 차단, ν”„λ‘μ‹œ/포트 μžλ™ 검증
  • 운영 μ•ˆμ •μ„± κ°•ν™”: Docker 이미지 기반으둜 λ™μΌν•œ μ‹€ν–‰ ν™˜κ²½ 보μž₯

πŸ“‚ 디렉터리 ꡬ쑰 (μš”μ•½)

ν”„λ‘œμ νŠΈλŠ” Layered Architecture + 도메인 λͺ¨λ“ˆ ꡬ쑰둜 κ΅¬μ„±λ˜μ–΄ 있으며,
핡심 μ±…μž„ λ‹¨μœ„κ°€ λͺ…ν™•ν•˜κ²Œ λΆ„λ¦¬λ˜μ–΄ μœ μ§€λ³΄μˆ˜μ„±κ³Ό ν™•μž₯성을 λ†’μ˜€μŠ΅λ‹ˆλ‹€.

welive/
β”œβ”€β”€ infra/ # Docker, nginx, 배포 μ„€μ •
β”‚ β”œβ”€β”€ docker/
β”‚ └── nginx/
β”‚
β”œβ”€β”€ prisma/ # Prisma μŠ€ν‚€λ§ˆ 및 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜
β”‚ β”œβ”€β”€ schema.prisma
β”‚ └── migrations/
β”‚
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ core/ # μ•± μ½”μ–΄ (envΒ·loggerΒ·middlewaresΒ·sseΒ·socket λ“±)
β”‚ β”œβ”€β”€ modules/ # 도메인 λͺ¨λ“ˆ (auth, residents, polls, notices λ“±)
β”‚ β”œβ”€β”€ jobs/ # Poll Scheduler
β”‚ β”œβ”€β”€ @types/ # κΈ€λ‘œλ²Œ νƒ€μž… ν™•μž₯
β”‚ └── index.ts # μ„œλ²„ μ—”νŠΈλ¦¬ν¬μΈνŠΈ
β”‚
β”œβ”€β”€ tests/ # Core / Modules / Scheduler 톡합 ν…ŒμŠ€νŠΈ
β”‚ β”œβ”€β”€ core/
β”‚ β”œβ”€β”€ modules/
β”‚ └── jobs/
β”‚
β”œβ”€β”€ swagger/ # μžλ™ μƒμ„±λœ Swagger JSON
β”œβ”€β”€ scripts/ # Swagger 생성 λ“± 슀크립트
└── package.json

πŸ“Œ ꡬ쑰 νŠΉμ§•

  • core: 인증/CORS/Sanitize/Error ν•Έλ“€λŸ¬, SSE, Socket, Limiter λ“± 곡톡 μ‹œμŠ€ν…œ λ ˆμ΄μ–΄
  • modules: Router β†’ Controller β†’ Service β†’ Repository β†’ Prisma ꡬ쑰λ₯Ό λ”°λ₯΄λŠ” 도메인 λ‹¨μœ„ κ΅¬ν˜„
  • jobs: Poll μžλ™ μ˜€ν”ˆ/만료 μŠ€μΌ€μ€„λŸ¬
  • tests: μ‹€μ œ DB 기반 톡합 ν…ŒμŠ€νŠΈ (ν…ŒμŠ€νŠΈμš© DB μžλ™ μ΄ˆκΈ°ν™”)

βš™οΈ μ‹€ν–‰ κ°€μ΄λ“œ (Run & Setup Guide)

1) ν™˜κ²½ λ³€μˆ˜ μ„€μ • (.env)

.env.example νŒŒμΌμ„ μ°Έκ³ ν•΄ 개발/ν…ŒμŠ€νŠΈ/운영 ν™˜κ²½μ— 맞게 .env, .env.test, .env.production을 κ΅¬μ„±ν•©λ‹ˆλ‹€.

# DATABASE
DATABASE_URL=postgresql://<user>:<password>@localhost:5432/welive

# SERVER
PORT=3001
FE_PORT=3000
CORS_ORIGIN=http://localhost:3000

# JWT / AUTH
ACCESS_TOKEN_SECRET=your_access_token_secret
REFRESH_TOKEN_SECRET=your_refresh_token_secret
PASSWORD_PEPPER=your_pepper

# AWS S3
AWS_REGION=ap-northeast-2
AWS_S3_BUCKET_NAME=your_bucket
AWS_S3_BASE_URL=https://your_bucket.s3.ap-northeast-2.amazonaws.com

2) νŒ¨ν‚€μ§€ μ„€μΉ˜

npm install

3) λ°μ΄ν„°λ² μ΄μŠ€ μ΄ˆκΈ°ν™” (Prisma)

개발/ν…ŒμŠ€νŠΈ ν™˜κ²½ λͺ¨λ‘ Prisma μŠ€ν‚€λ§ˆ 기반으둜 μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.

npm run prisma:migrate      # λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ + μ‹œλ“œ 전체 μˆ˜ν–‰
npm run prisma:generate     # Prisma Client 생성
npm run prisma:reset        # 개발 DB μ΄ˆκΈ°ν™”
npm run prisma:studio       # DB UI (μ›Ή)

ν…ŒμŠ€νŠΈ ν™˜κ²½μ—μ„œ DB μ΄ˆκΈ°ν™”:

npm run test:reset
npm run test:migrate

4) 개발 μ„œλ²„ μ‹€ν–‰

λ°±μ—”λ“œ/ν”„λ‘ νŠΈλ₯Ό λ™μ‹œμ— κ°œλ°œν•˜κΈ° μœ„ν•œ 슀크립트 포함.

npm run dev        # BE + FE λ™μ‹œ μ‹€ν–‰
npm run dev:be     # λ°±μ—”λ“œ 단독 μ‹€ν–‰
npm run dev:fe     # ν”„λ‘ νŠΈ 단독 μ‹€ν–‰

5) ν…ŒμŠ€νŠΈ μ‹€ν–‰

ν…ŒμŠ€νŠΈ ν™˜κ²½(.env.test)이 μžλ™ λ‘œλ“œλ˜λ©°,
ν…ŒμŠ€νŠΈμš© DBλŠ” λ§€ μ‹€ν–‰λ§ˆλ‹€ μ΄ˆκΈ°ν™”λ©λ‹ˆλ‹€.

npm test            # 전체 ν…ŒμŠ€νŠΈ
npm run test:watch  # λ³€κ²½ 감지
npm run test:cov    # 컀버리지

6) λΉŒλ“œ

npm run build

λΉŒλ“œ ν›„ κ²°κ³ΌλŠ” dist/에 μƒμ„±λ˜λ©° tsc-alias둜 경둜 aliasκ°€ μžλ™ λ³€ν™˜λ©λ‹ˆλ‹€.

7) ν”„λ‘œλ•μ…˜ μ‹€ν–‰

  • λ°±μ—”λ“œ: Docker 기반 (EC2)
  • ν”„λ‘ νŠΈμ—”λ“œ: PM2 기반 Next.js μ‹€ν–‰
npm start        # BE + FE
npm run start:be # λ°±μ—”λ“œλ§Œ
npm run start:fe # ν”„λ‘ νŠΈλ§Œ

쀑지:

npm run stop

ν…ŒμŠ€νŠΈ/운영 DB ν˜Όμš©μ„ λ°©μ§€ν•˜κΈ° μœ„ν•΄
.env.testμ—λŠ” 운영 DB 정보λ₯Ό μ ˆλŒ€ μ €μž₯ν•˜μ§€ μ•Šλ„λ‘ μ„€κ³„λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

✨ μ£Όμš” κ΅¬ν˜„ ν•˜μ΄λΌμ΄νŠΈ (Key Implementations)

πŸ”Ή 1) μ—­ν•  기반 인증/인가 ꡬ쑰 (RBAC)

  • JWT Access/Refresh Token + DB 기반 Refresh μƒνƒœ 관리
  • SUPER_ADMIN / ADMIN / USER 3단 역할을 λΌμš°ν„° λ‹¨μœ„λ‘œ μ œμ–΄
  • 승인 λŒ€κΈ°/거절/μΆ”κ°€ 정보 ν•„μš” λ“± μž…μ£Όλ―Ό μƒνƒœ 흐름을 μƒμ„Έν•˜κ²Œ λͺ¨λΈλ§

πŸ”Ή 2) μ‹€μ‹œκ°„ μ•Œλ¦Ό μ‹œμŠ€ν…œ (SSE)

  • λ―Όμ›Β·κ³΅μ§€Β·νˆ¬ν‘œ λ“± μ£Όμš” 이벀트 λ°œμƒ μ‹œ μ¦‰μ‹œ μ•Œλ¦Ό 전솑
  • SSE μ „μ—­ Emitter λͺ¨λ“ˆν™” β†’ μ„œλΉ„μŠ€ λ ˆμ΄μ–΄μ—μ„œ 단일 API둜 μ‚¬μš©
  • ν”„λ‘ νŠΈλŠ” μ•Œλ¦Ό Store와 μ—°κ²°λ˜μ–΄ μ‹€μ‹œκ°„ UI 반영

πŸ”Ή 3) Poll μŠ€μΌ€μ€„λŸ¬ (μžλ™ μ˜€ν”ˆ/마감)

  • Cron 기반 μžλ™ μŠ€μΌ€μ€„λŸ¬ κ΅¬ν˜„
  • Limiter(직접 κ΅¬ν˜„) 둜 단일 μ‹€ν–‰ 보μž₯ β†’ 쀑볡 처리/경쟁 쑰건 제거
  • 만료 μ‹œμ μ— μžλ™ 집계 + μ•Œλ¦ΌκΉŒμ§€ 일괄 처리

πŸ”Ή 4) 파일 μ—…λ‘œλ“œ λ³΄μ•ˆ 섀계

  • ν™•μž₯자 기반이 μ•„λ‹Œ Magic Number(MIME) 검증
  • sharp μž¬μΈμ½”λ”©μœΌλ‘œ 폴리글둯(polyglot) 파일 곡격 차단
  • Presigned URL λ°©μ‹μœΌλ‘œ S3 직접 μ—…λ‘œλ“œ

πŸ”Ή 5) HTML Sanitization & μž…λ ₯ 검증

  • μ„œλ²„λ‹¨ DOMPurify + jsdom으둜 XSS λ°©μ§€
  • Zod μŠ€ν‚€λ§ˆ 기반으둜 Params/Query/Body 톡합 검증
  • 검증(Zod) β†’ Sanitize β†’ Controller νλ¦„μœΌλ‘œ μ „ 계측 보호

πŸ”Ή 6) Socket.io 기반 μ‹€μ‹œκ°„ μ±„νŒ…

  • JWT 인증 λ―Έλ“€μ›¨μ–΄λ‘œ μ‚¬μš©μž 검증
  • κ΄€λ¦¬μž ↔ μž…μ£Όλ―Ό κ°„ λΉ λ₯Έ μ‘λŒ€ ꡬ쑰 확립
  • λ©”μ‹œμ§€ μ €μž₯, 읽음 처리, μ±„νŒ…λ°© λ‹¨μœ„ 관리

πŸ”Ή 7) CSV 기반 μž…μ£Όλ―Ό λͺ…λΆ€ μ—…λ‘œλ“œ

  • CSV 헀더/νƒ€μž… μ •ν™• 검증
  • λŒ€λŸ‰ μ—…λ‘œλ“œ μ‹œ 전체λ₯Ό 단일 νŠΈλžœμž­μ…˜μœΌλ‘œ 처리
  • 잘λͺ»λœ λ°μ΄ν„°λŠ” line λ‹¨μœ„λ‘œ μ¦‰μ‹œ 였λ₯˜ 제곡

πŸ”Ή 8) ν…ŒμŠ€νŠΈ μ½”λ“œ & μ•ˆμ •μ„±

  • 전체 도메인 λͺ¨λ“ˆ 톡합 ν…ŒμŠ€νŠΈ ꡬ성 (Jest + Supertest)
  • ν…ŒμŠ€νŠΈ ν™˜κ²½ μ „μš© DB(setupTestDB) μžλ™ μ΄ˆκΈ°ν™”
  • SchedulerΒ·SSE μ΄λ²€νŠΈκΉŒμ§€ λ…λ¦½μ μœΌλ‘œ 검증 κ°€λŠ₯ν•˜λ„λ‘ ꡬ쑰화

πŸ”Ή 9) μ•ˆμ •μ μΈ 운영 ν™˜κ²½

  • Swagger 미생성 μ‹œ μ„œλ²„ λΆ€νŒ… 차단
  • healthcheck 기반 Docker μ»¨ν…Œμ΄λ„ˆ μƒνƒœ 확인
  • Nginx + Cloudflare Origin Restore + gzip μ••μΆ• μ‘°ν•©

λ³Έ ν”„λ‘œμ νŠΈλŠ” Layered Architecture, 도메인 기반 섀계, ν…ŒμŠ€νŠΈΒ·λ³΄μ•ˆΒ·λ°°ν¬ μžλ™ν™”λ₯Ό λͺ¨λ‘ κ°–μΆ˜
μ‹€μ œ 운영 μˆ˜μ€€μ˜ λ°±μ—”λ“œ μ•„ν‚€ν…μ²˜λ₯Ό λͺ©ν‘œλ‘œ κ΅¬ν˜„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ λͺ¨λ“ˆ μ±…μž„ 뢄리, μŠ€ν”„λ¦°νŠΈ λ‹¨μœ„ 일정 관리, GitHub PR 기반 ν˜‘μ—…μœΌλ‘œ
μ‹€μ œ νŒ€ 개발 흐름에 맞좘 운영 ν”„λ‘œμ„ΈμŠ€λ₯Ό μœ μ§€ν–ˆμŠ΅λ‹ˆλ‹€.

πŸ“Ž 뢀둝 & μ‚°μΆœλ¬Ό (Official Project Documents)

μ•„λž˜ λ¬Έμ„œλŠ” ν”„λ‘œμ νŠΈμ˜ μ „ 과정을 μ •λ¦¬ν•œ ꡬ글 λ…μŠ€ 기반 곡식 μ‚°μΆœλ¬Όμž…λ‹ˆλ‹€.

Note

μƒλ‹¨μ˜ β€œπŸ”— 데λͺ¨ & μ£Όμš” λ§ν¬β€λŠ” μ‹€ν–‰ κ°€λŠ₯ν•œ μ„œλΉ„μŠ€/μ½”λ“œ μ ‘κ·Όμš©,
λ³Έ μ„Ήμ…˜μ€ ν”„λ‘œμ νŠΈ μ§„ν–‰ 전체λ₯Ό 닀룬 정식 λ¬Έμ„œ μ‚°μΆœλ¬Ό λͺ¨μŒμž…λ‹ˆλ‹€.

About

Codeit1Team Welive

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages