Skip to content

Konkuk-KUIT/OFF-Server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

246 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

OFF ํ”„๋กœ์ ํŠธ ๊ธฐ์ˆ  ๋ฌธ์„œ

ํ”„๋กœ์ ํŠธ ํŒŒํŠธ๋„ˆ ๋งค์นญ ํ”Œ๋žซํผ


๐Ÿ“š ๋ชฉ์ฐจ

  1. ๊ธฐ์ˆ  ์Šคํƒ
  2. ์„œ๋ฒ„ ์•„ํ‚คํ…์ฒ˜
  3. ERD (Entity Relationship Diagram)
  4. ์ฃผ์š” ๊ธฐ๋Šฅ
  5. ์™ธ๋ถ€ API ์—ฐ๋™

1. ๊ธฐ์ˆ  ์Šคํƒ

๐Ÿ”ง Backend

๋ถ„๋ฅ˜ ๊ธฐ์ˆ  ๋ฒ„์ „ ์šฉ๋„
Language Java 21 ๊ฐœ๋ฐœ ์–ธ์–ด
Framework Spring Boot 3.5.9 ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ
Build Tool Gradle - ๋นŒ๋“œ ๋ฐ ์˜์กด์„ฑ ๊ด€๋ฆฌ
ORM Spring Data JPA - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ
Database PostgreSQL - ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (AWS RDS)
Security JWT (JJWT) 0.12.5 ์ธ์ฆ/์ธ๊ฐ€
Spring Security Crypto - ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™” (BCrypt)
Validation Jakarta Validation - ์š”์ฒญ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ
Real-time WebSocket (STOMP) - ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…
Documentation Swagger (Springdoc) 2.8.5 API ๋ฌธ์„œํ™”

โ˜๏ธ Infrastructure & DevOps

๋ถ„๋ฅ˜ ๊ธฐ์ˆ  ์šฉ๋„
Cloud AWS EC2 ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„
AWS RDS (PostgreSQL) ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„
CI/CD GitHub Actions ์ž๋™ ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ
VCS Git / GitHub ๋ฒ„์ „ ๊ด€๋ฆฌ

๐Ÿ”— External APIs

API ์šฉ๋„ ๋ฒ„์ „
Google Gemini API AI ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ ๊ฒฌ์  ๋ฐ Task ์ž๋™ ์ƒ์„ฑ -
Toss Payments API ํŒŒํŠธ๋„ˆ ๋งค์นญ ๊ฒฐ์ œ -

๐Ÿ“ฆ ์ฃผ์š” Dependencies

// Core
- Spring Boot Starter Web
- Spring Boot Starter Data JPA
- Spring Boot Starter Validation
- Spring Boot Starter WebSocket

// Security
- JJWT (JWT ์ธ์ฆ)
- Spring Security Crypto (๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”)

// Database
- PostgreSQL Driver
- H2 Database (ํ…Œ์ŠคํŠธ์šฉ)

// Documentation
- Springdoc OpenAPI (Swagger)

// External Integration
- WebFlux (Toss Payments, Gemini API ์—ฐ๋™)

// Utilities
- Lombok (๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ ์ œ๊ฑฐ)
- Jackson (JSON ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”)

2. ์„œ๋ฒ„ ์•„ํ‚คํ…์ฒ˜

๐Ÿ—๏ธ ์ „์ฒด ์•„ํ‚คํ…์ฒ˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         Client Layer                         โ”‚
โ”‚                    (Web / Mobile App)                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚ HTTP/HTTPS
                             โ”‚ WebSocket
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Presentation Layer                      โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚              REST API Controllers                     โ”‚  โ”‚
โ”‚  โ”‚  - MemberController  - ProjectController             โ”‚  โ”‚
โ”‚  โ”‚  - ChatController    - PayController                 โ”‚  โ”‚
โ”‚  โ”‚  - PartnerMatchingController                         โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚            JWT Authentication Filter                  โ”‚  โ”‚
โ”‚  โ”‚       (JwtAuthenticationFilter)                      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       Business Layer                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                Service Components                     โ”‚  โ”‚
โ”‚  โ”‚  - MemberService      - ProjectService               โ”‚  โ”‚
โ”‚  โ”‚  - ChatService        - PayFacade/PayLogService      โ”‚  โ”‚
โ”‚  โ”‚  - PartnerMatchingService                            โ”‚  โ”‚
โ”‚  โ”‚  - NotificationService                               โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Persistence Layer                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚              JPA Repositories                         โ”‚  โ”‚
โ”‚  โ”‚  - MemberRepository  - ProjectRepository             โ”‚  โ”‚
โ”‚  โ”‚  - ChatRoomRepository                                โ”‚  โ”‚
โ”‚  โ”‚  - PartnerApplicationRepository                      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                  JPA Entities                         โ”‚  โ”‚
โ”‚  โ”‚  - Member  - Project  - ChatRoom  - PayLog          โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Database Layer                          โ”‚
โ”‚              PostgreSQL (AWS RDS)                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      External Services                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚  โ”‚ Gemini API   โ”‚  โ”‚Toss Paymentsโ”‚  โ”‚ AWS Services โ”‚     โ”‚
โ”‚  โ”‚ (AI ๊ฒฌ์ )    โ”‚  โ”‚   (๊ฒฐ์ œ)     โ”‚  โ”‚  (EC2/RDS)   โ”‚     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“‚ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ (Domain-Driven Design)

com.example.off
โ”‚
โ”œโ”€โ”€ common/                     # ๊ณตํ†ต ๋ชจ๋“ˆ
โ”‚   โ”œโ”€โ”€ config/                 # ์„ค์ • (PasswordConfig, FilterConfig)
โ”‚   โ”œโ”€โ”€ exception/              # ์˜ˆ์™ธ ์ฒ˜๋ฆฌ (OffException, OffControllerAdvice)
โ”‚   โ”œโ”€โ”€ response/               # ํ†ตํ•ฉ ์‘๋‹ต ํ˜•์‹ (BaseResponse, ResponseCode)
โ”‚   โ”œโ”€โ”€ jwt/                    # JWT ์ธ์ฆ (JwtTokenProvider, Filter)
โ”‚   โ”œโ”€โ”€ gemini/                 # Gemini API ์—ฐ๋™
โ”‚   โ”œโ”€โ”€ infra/                  # ์™ธ๋ถ€ ์ธํ”„๋ผ (TossPaymentsClient)
โ”‚   โ””โ”€โ”€ swagger/                # Swagger ์„ค์ •
โ”‚
โ”œโ”€โ”€ domain/                     # ๋„๋ฉ”์ธ ๊ณ„์ธต (DDD)
โ”‚   โ”œโ”€โ”€ member/                 # ํšŒ์› ๋„๋ฉ”์ธ
โ”‚   โ”‚   โ”œโ”€โ”€ Member.java         # ์—”ํ‹ฐํ‹ฐ
โ”‚   โ”‚   โ”œโ”€โ”€ controller/         # API ์ปจํŠธ๋กค๋Ÿฌ
โ”‚   โ”‚   โ”œโ”€โ”€ service/            # ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
โ”‚   โ”‚   โ”œโ”€โ”€ repository/         # ๋ฐ์ดํ„ฐ ์ ‘๊ทผ
โ”‚   โ”‚   โ””โ”€โ”€ dto/                # ๋ฐ์ดํ„ฐ ์ „์†ก ๊ฐ์ฒด
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ project/                # ํ”„๋กœ์ ํŠธ ๋„๋ฉ”์ธ
โ”‚   โ”‚   โ”œโ”€โ”€ Project.java
โ”‚   โ”‚   โ”œโ”€โ”€ controller/
โ”‚   โ”‚   โ”œโ”€โ”€ service/            # ๊ฒฌ์ , ํ™•์ •, Task ์ƒ์„ฑ
โ”‚   โ”‚   โ”œโ”€โ”€ repository/
โ”‚   โ”‚   โ””โ”€โ”€ dto/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ partnerRecruit/         # ํŒŒํŠธ๋„ˆ ๋ชจ์ง‘/๋งค์นญ ๋„๋ฉ”์ธ
โ”‚   โ”‚   โ”œโ”€โ”€ PartnerRecruit.java
โ”‚   โ”‚   โ”œโ”€โ”€ PartnerApplication.java
โ”‚   โ”‚   โ”œโ”€โ”€ controller/
โ”‚   โ”‚   โ”œโ”€โ”€ service/
โ”‚   โ”‚   โ””โ”€โ”€ dto/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ chat/                   # ์ฑ„ํŒ… ๋„๋ฉ”์ธ (WebSocket)
โ”‚   โ”‚   โ”œโ”€โ”€ ChatRoom.java
โ”‚   โ”‚   โ”œโ”€โ”€ Message.java
โ”‚   โ”‚   โ”œโ”€โ”€ controller/
โ”‚   โ”‚   โ”œโ”€โ”€ service/
โ”‚   โ”‚   โ””โ”€โ”€ dto/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ pay/                    # ๊ฒฐ์ œ ๋„๋ฉ”์ธ
โ”‚   โ”‚   โ”œโ”€โ”€ PayLog.java
โ”‚   โ”‚   โ”œโ”€โ”€ controller/
โ”‚   โ”‚   โ”œโ”€โ”€ service/            # PayLogService, PayFacade
โ”‚   โ”‚   โ””โ”€โ”€ dto/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ notification/           # ์•Œ๋ฆผ ๋„๋ฉ”์ธ
โ”‚   โ”œโ”€โ”€ task/                   # Task ๊ด€๋ฆฌ ๋„๋ฉ”์ธ
โ”‚   โ”œโ”€โ”€ projectMember/          # ํ”„๋กœ์ ํŠธ ๋ฉค๋ฒ„ ๋„๋ฉ”์ธ
โ”‚   โ””โ”€โ”€ role/                   # ์—ญํ•  ๋„๋ฉ”์ธ (PM, DEV, DES, MAR)
โ”‚
โ””โ”€โ”€ OffApplication.java         # ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

๐Ÿ”„ ์š”์ฒญ ์ฒ˜๋ฆฌ ํ๋ฆ„

1. Client Request
   โ†“
2. JwtAuthenticationFilter (JWT ๊ฒ€์ฆ โ†’ memberId ์ถ”์ถœ)
   โ†“
3. Controller (์š”์ฒญ ์ˆ˜์‹ , Validation)
   โ†“
4. Service (๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ)
   โ†“
5. Repository (๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ)
   โ†“
6. Entity (JPA ์˜์†์„ฑ ๊ด€๋ฆฌ)
   โ†“
7. Database (PostgreSQL)
   โ†“
8. Response (BaseResponse<T> ํ˜•์‹)
   โ†“
9. Client

๐ŸŽฏ ์„ค๊ณ„ ์›์น™

Layered Architecture + DDD

  • Presentation Layer: REST API, WebSocket
  • Business Layer: ๋„๋ฉ”์ธ๋ณ„ Service
  • Persistence Layer: JPA Repository
  • Database Layer: PostgreSQL

Entity ์„ค๊ณ„ ํŒจํ„ด

@Entity
@Getter
@NoArgsConstructor
public class Member {
    @Id @GeneratedValue
    private Long id;

    // Private constructor
    private Member(...) { ... }

    // Static factory method
    public static Member of(...) { ... }

    // Business logic methods
    public void updateNickname(...) { ... }
}

DTO ํŒจํ„ด

  • Request DTO: @NotNull, @NotBlank ๋“ฑ Validation
  • Response DTO: static of() factory method
  • ํ†ตํ•ฉ ์‘๋‹ต: BaseResponse<T>

์˜ˆ์™ธ ์ฒ˜๋ฆฌ

throw new OffException(ResponseCode.MEMBER_NOT_FOUND);
โ†“
@RestControllerAdvice
public class OffControllerAdvice {
    @ExceptionHandler(OffException.class)
    public ResponseEntity<BaseResponse<Void>> handle(...) { ... }
}

3. ERD

๐Ÿ“Š ์ฃผ์š” ์—”ํ‹ฐํ‹ฐ ๊ด€๊ณ„

erDiagram
    MEMBER ||--o{ PROJECT : creates
    MEMBER ||--o{ PROJECT_MEMBER : participates
    MEMBER ||--o{ PARTNER_APPLICATION : applies
    MEMBER ||--o{ CHAT_ROOM_MEMBER : joins
    MEMBER ||--o{ MESSAGE : sends
    MEMBER ||--o{ NOTIFICATION : receives
    MEMBER ||--o{ PORTFOLIO : has
    MEMBER }o--|| MEMBER_ROLE : has

    PROJECT ||--o{ PROJECT_MEMBER : has
    PROJECT ||--o{ PARTNER_RECRUIT : posts
    PROJECT ||--o{ CHAT_ROOM : belongs_to
    PROJECT ||--o{ TASK : contains

    PARTNER_RECRUIT ||--o{ PARTNER_APPLICATION : receives

    PARTNER_APPLICATION ||--o| PAY_LOG : payment_for

    CHAT_ROOM ||--o{ CHAT_ROOM_MEMBER : has
    CHAT_ROOM ||--o{ MESSAGE : contains

    TASK ||--o{ TO_DO : has

    PROJECT_MEMBER ||--o{ TASK : assigned_to
Loading

๐Ÿ“‹ ํ…Œ์ด๋ธ” ์ƒ์„ธ ์„ค๋ช…

๐Ÿ‘ค ํšŒ์› ๊ด€๋ จ

member

  • id (PK): ํšŒ์› ๊ณ ์œ  ID
  • email: ์ด๋ฉ”์ผ (๋กœ๊ทธ์ธ ID)
  • password: ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ (BCrypt)
  • nickname: ๋‹‰๋„ค์ž„
  • phone: ์ „ํ™”๋ฒˆํ˜ธ
  • profile_image: ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ URL
  • self_introduction: ์ž๊ธฐ์†Œ๊ฐœ
  • role: ์—ญํ•  (PM, DEV, DES, MAR)
  • project_count: ํ”„๋กœ์ ํŠธ ๊ฒฝํ—˜ ํšŸ์ˆ˜
  • is_working: ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ์ค‘ ์—ฌ๋ถ€
  • created_at, updated_at: ์ƒ์„ฑ/์ˆ˜์ • ์‹œ๊ฐ„

portfolio

  • portfolio_id (PK)
  • member_id (FK โ†’ member)
  • title: ํฌํŠธํด๋ฆฌ์˜ค ์ œ๋ชฉ
  • description: ์„ค๋ช…
  • url: ํฌํŠธํด๋ฆฌ์˜ค ๋งํฌ

๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ด€๋ จ

project

  • project_id (PK)
  • creator_id (FK โ†’ member): ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ์ž (๊ธฐํš์ž)
  • name: ํ”„๋กœ์ ํŠธ๋ช…
  • description: ์„ค๋ช…
  • requirement: ์š”๊ตฌ์‚ฌํ•ญ
  • introduction: ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ
  • total_estimate: ์ด ์˜ˆ์ƒ ๋น„์šฉ
  • start_date, end_date: ์‹œ์ž‘/์ข…๋ฃŒ์ผ
  • project_type: ํ”„๋กœ์ ํŠธ ํƒ€์ž…
  • status: ์ƒํƒœ (IN_PROGRESS, COMPLETED)

project_member

  • project_member_id (PK)
  • project_id (FK โ†’ project)
  • member_id (FK โ†’ member)
  • role: ํ”„๋กœ์ ํŠธ ๋‚ด ์—ญํ• 

๐Ÿค ํŒŒํŠธ๋„ˆ ๋ชจ์ง‘/๋งค์นญ

partner_recruit

  • partner_recruit_id (PK)
  • project_id (FK โ†’ project)
  • role: ๋ชจ์ง‘ ์—ญํ•  (DEV, DES, MAR)
  • number_of_person: ๋ชจ์ง‘ ์ธ์›
  • cost: 1์ธ๋‹น ๋น„์šฉ
  • recruit_status: ๋ชจ์ง‘ ์ƒํƒœ (OPEN, CLOSED)

partner_application

  • partner_application_id (PK)
  • partner_recruit_id (FK โ†’ partner_recruit)
  • member_id (FK โ†’ member): ์ง€์›์ž
  • application_status: ์ง€์› ์ƒํƒœ (WAITING, ACCEPT, REJECT)
  • is_from_project: ๊ธฐํš์ž ์ œ์•ˆ ์—ฌ๋ถ€ (true: ์ดˆ๋Œ€, false: ์ง€์›)

๐Ÿ’ฌ ์ฑ„ํŒ…

chat_room

  • chat_room_id (PK)
  • project_id (FK โ†’ project, nullable): ํ”„๋กœ์ ํŠธ ์ฑ„ํŒ…๋ฐฉ์ธ ๊ฒฝ์šฐ
  • chat_type: ์ฑ„ํŒ… ํƒ€์ž… (CONTACT: 1:1, PROJECT: ํ”„๋กœ์ ํŠธ)

chat_room_member

  • chat_room_member_id (PK)
  • chat_room_id (FK โ†’ chat_room)
  • member_id (FK โ†’ member)
  • last_read_at: ๋งˆ์ง€๋ง‰ ์ฝ์€ ์‹œ๊ฐ„

message

  • message_id (PK)
  • chat_room_id (FK โ†’ chat_room)
  • member_id (FK โ†’ member): ๋ฐœ์‹ ์ž
  • content: ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ
  • is_read: ์ฝ์Œ ์—ฌ๋ถ€

๐Ÿ’ณ ๊ฒฐ์ œ

pay_log

  • pay_log_id (PK)
  • order_id: Toss ์ฃผ๋ฌธ ID (UUID)
  • amount: ๊ฒฐ์ œ ๊ธˆ์•ก
  • status: ๊ฒฐ์ œ ์ƒํƒœ (READY, PAID, FAILED, CANCELED)
  • payment_key: Toss ๊ฒฐ์ œ ํ‚ค
  • payer_id (FK โ†’ member): ๊ฒฐ์ œ์ž (๊ธฐํš์ž)
  • partner_application_id (FK โ†’ partner_application)
  • project_member_id (FK โ†’ project_member): ๋งค์นญ ์™„๋ฃŒ ์‹œ ์ƒ์„ฑ

๐Ÿ”” ์•Œ๋ฆผ

notification

  • notification_id (PK)
  • member_id (FK โ†’ member): ์ˆ˜์‹ ์ž
  • message: ์•Œ๋ฆผ ๋ฉ”์‹œ์ง€
  • url: ์•Œ๋ฆผ ํด๋ฆญ ์‹œ ์ด๋™ URL
  • notification_type: ์•Œ๋ฆผ ํƒ€์ž… (INVITE, APPLICATION, PAY, PROJECT_COMPLETE)
  • is_read: ์ฝ์Œ ์—ฌ๋ถ€

โœ… Task ๊ด€๋ฆฌ

task

  • task_id (PK)
  • project_id (FK โ†’ project)
  • project_member_id (FK โ†’ project_member): ๋‹ด๋‹น์ž
  • name: Task ์ด๋ฆ„
  • description: Task ์„ค๋ช…

to_do

  • to_do_id (PK)
  • task_id (FK โ†’ task)
  • content: ToDo ๋‚ด์šฉ
  • is_done: ์™„๋ฃŒ ์—ฌ๋ถ€

4. ์ฃผ์š” ๊ธฐ๋Šฅ

๐ŸŽฏ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ํ๋ฆ„

1๏ธโƒฃ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ฐ ๊ฒฌ์ 

1. ๊ธฐํš์ž: ํ”„๋กœ์ ํŠธ ๊ฒฌ์  ์š”์ฒญ (POST /projects/estimate)
   โ†“
2. Gemini API ํ˜ธ์ถœ
   - ํ”„๋กœ์ ํŠธ ์„ค๋ช…/์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„
   - ์—ญํ• ๋ณ„ ๋น„์šฉ ์‚ฐ์ •
   - ์˜ˆ์ƒ ์ข…๋ฃŒ์ผ ๊ณ„์‚ฐ
   - ํŒŒํŠธ๋„ˆ ์ถ”์ฒœ
   - ์„œ๋น„์Šค ์š”์•ฝ ์ƒ์„ฑ
   โ†“
3. ๊ฒฌ์  ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜ (EstimateResponse)
   โ†“
4. ๊ธฐํš์ž: ํ”„๋กœ์ ํŠธ ํ™•์ • (POST /projects/confirm)
   โ†“
5. Project ์ƒ์„ฑ + PartnerRecruit ์ƒ์„ฑ + Task ์ž๋™ ์ƒ์„ฑ (Gemini)

2๏ธโƒฃ ํŒŒํŠธ๋„ˆ ๋งค์นญ

์‹œ๋‚˜๋ฆฌ์˜ค A: ํŒŒํŠธ๋„ˆ ์ง€์›

1. ํŒŒํŠธ๋„ˆ: ํ”„๋กœ์ ํŠธ ์ง€์› (POST /projects/{id}/applications)
   โ†“
2. PartnerApplication ์ƒ์„ฑ (status=WAITING)
   โ†“
3. ๊ธฐํš์ž์—๊ฒŒ ์•Œ๋ฆผ ์ „์†ก
   โ†“
4. ๊ธฐํš์ž: ๊ฒฐ์ œ ์ง„ํ–‰ (prepare โ†’ confirm)
   โ†“
5. ProjectMember ์ƒ์„ฑ + ๋งค์นญ ์™„๋ฃŒ

์‹œ๋‚˜๋ฆฌ์˜ค B: ๊ธฐํš์ž ์ดˆ๋Œ€

1. ๊ธฐํš์ž: ํŒŒํŠธ๋„ˆ ์ดˆ๋Œ€ (POST /projects/{id}/invitations)
   โ†“
2. PartnerApplication ์ƒ์„ฑ (isFromProject=true)
   โ†“
3. ํŒŒํŠธ๋„ˆ์—๊ฒŒ ์•Œ๋ฆผ ์ „์†ก
   โ†“
4. ํŒŒํŠธ๋„ˆ: ์ˆ˜๋ฝ (POST /invitations/{id}/accept)
   โ†“
5. ๊ธฐํš์ž์—๊ฒŒ ๊ฒฐ์ œ ์•Œ๋ฆผ
   โ†“
6. ๊ธฐํš์ž: ๊ฒฐ์ œ ์ง„ํ–‰
   โ†“
7. ProjectMember ์ƒ์„ฑ + ๋งค์นญ ์™„๋ฃŒ

3๏ธโƒฃ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… (WebSocket + STOMP)

1. ์ฒซ ๋ฉ”์‹œ์ง€ ์ „์†ก (POST /chat/rooms/first)
   - ChatRoom ์ƒ์„ฑ
   - ChatRoomMember 2๋ช… ์ถ”๊ฐ€
   - ChatType ์ž๋™ ๊ฒฐ์ • (CONTACT or PROJECT)
   โ†“
2. WebSocket ์—ฐ๊ฒฐ (/ws-stomp)
   โ†“
3. ๋ฉ”์‹œ์ง€ ๋ฐœํ–‰ (/pub/chat/message)
   โ†“
4. ๊ตฌ๋…์ž์—๊ฒŒ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ (/sub/chat/room/{roomId})
   โ†“
5. ์•ˆ ์ฝ์€ ๋ฉ”์‹œ์ง€ ์•Œ๋ฆผ (/queue/unread-status)

4๏ธโƒฃ Toss Payments ๊ฒฐ์ œ

1. ๊ธฐํš์ž: ๊ฒฐ์ œ ์ค€๋น„ (POST /payments/prepare)
   - PayLog ์ƒ์„ฑ (status=READY)
   - orderId, amount ๋ฐ˜ํ™˜
   โ†“
2. ํ”„๋ก ํŠธ: Toss ์œ„์ ฏ ์ดˆ๊ธฐํ™” (clientKey)
   โ†“
3. ์‚ฌ์šฉ์ž ๊ฒฐ์ œ ์ง„ํ–‰
   โ†“
4. Toss: successUrl๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ (paymentKey ์ „๋‹ฌ)
   โ†“
5. ํ”„๋ก ํŠธ: ๊ฒฐ์ œ ํ™•์ธ (POST /payments/confirm)
   - Toss API ์ตœ์ข… ์Šน์ธ ์š”์ฒญ
   - PayLog ์ƒํƒœ ์—…๋ฐ์ดํŠธ (PAID)
   - ProjectMember ์ƒ์„ฑ
   - ํŒŒํŠธ๋„ˆ์—๊ฒŒ ์•Œ๋ฆผ

๐Ÿ” ์ธ์ฆ/์ธ๊ฐ€

1. ๋กœ๊ทธ์ธ (POST /members/login)
   โ†“
2. JWT ํ† ํฐ ๋ฐœ๊ธ‰ (accessToken, refreshToken)
   โ†“
3. API ์š”์ฒญ ์‹œ Header: Authorization: Bearer {token}
   โ†“
4. JwtAuthenticationFilter
   - ํ† ํฐ ๊ฒ€์ฆ
   - memberId ์ถ”์ถœ
   - HttpServletRequest์— ์ €์žฅ
   โ†“
5. Controller์—์„œ memberId ์‚ฌ์šฉ

5. ์™ธ๋ถ€ API ์—ฐ๋™

๐Ÿค– Google Gemini API

์šฉ๋„:

  1. ํ”„๋กœ์ ํŠธ ๊ฒฌ์  ์ž๋™ ์‚ฐ์ •
  2. ํŒŒํŠธ๋„ˆ ์ถ”์ฒœ ๋ฐ ๋น„์šฉ ์ฐจ๋“ฑ ์‚ฐ์ •
  3. Task ๋ฐ ToDo ์ž๋™ ์ƒ์„ฑ
  4. ์„œ๋น„์Šค ์ƒ์„ธ ๊ธฐํš์•ˆ ์ƒ์„ฑ

๊ตฌํ˜„:

@Service
public class GeminiService {
    private final WebClient geminiWebClient;

    public String generateText(String prompt) {
        // Gemini API ํ˜ธ์ถœ
        // JSON ์‘๋‹ต ํŒŒ์‹ฑ
        // ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
    }
}

๐Ÿ’ณ Toss Payments API

์šฉ๋„: ํŒŒํŠธ๋„ˆ ๋งค์นญ ๊ฒฐ์ œ

ํ”Œ๋กœ์šฐ:

  1. ์ค€๋น„ ๋‹จ๊ณ„: PayLog ์ƒ์„ฑ (READY)
  2. ๊ฒฐ์ œ ๋‹จ๊ณ„: Toss ์œ„์ ฏ (ํด๋ผ์ด์–ธํŠธ)
  3. ์Šน์ธ ๋‹จ๊ณ„: Toss API ํ˜ธ์ถœ (์„œ๋ฒ„) โ†’ PAID

๊ตฌํ˜„:

@Component
public class TossPaymentsClient {
    private final WebClient tossWebClient;

    public TossPaymentConfirmResponse confirm(
        String paymentKey, String orderId, Long amount
    ) {
        // Toss API ์Šน์ธ ์š”์ฒญ
        // Basic Auth (secretKey)
    }
}

๐Ÿ“ˆ ์„ฑ๋Šฅ ์ตœ์ ํ™”

N+1 ์ฟผ๋ฆฌ ํ•ด๊ฒฐ

@Query("SELECT m FROM Member m " +
       "JOIN FETCH m.portfolios " +
       "WHERE m.id = :id")
Optional<Member> findByIdWithPortfolios(@Param("id") Long id);

JOIN FETCH ํ™œ์šฉ

@Query("SELECT crm FROM ChatRoomMember crm " +
       "JOIN FETCH crm.chatRoom cr " +
       "LEFT JOIN FETCH cr.project " +
       "JOIN FETCH crm.member " +
       "WHERE crm.member.id = :memberId")
List<ChatRoomMember> findAllByMember_IdAndChatRoom_ChatType(...);

๐Ÿš€ ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค

GitHub Actions CI/CD

on:
  push:
    branches: [ develop ]

jobs:
  build:
    - Gradle build
    - JAR ์ƒ์„ฑ

  deploy:
    - EC2์— JAR ๋ฐฐํฌ
    - ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • (.env)
    - systemd๋กœ ์•ฑ ์žฌ์‹œ์ž‘

ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ด€๋ฆฌ

  • ๋กœ์ปฌ: .env ํŒŒ์ผ
  • ๋ฐฐํฌ: GitHub Secrets โ†’ EC2 .env ์ž๋™ ์ƒ์„ฑ

๐Ÿ“ API ๋ช…์„ธ

Swagger UI: /swagger-ui/index.html

ํ†ตํ•ฉ ์‘๋‹ต ํ˜•์‹:

{
  "success": true,
  "code": 200,
  "message": "์š”์ฒญ์— ์„ฑ๊ณตํ•˜์˜€์Šต๋‹ˆ๋‹ค.",
  "data": { ... }
}

About

OFF Server Repository

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors