Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9951a09
springboot 프로젝트 생성
dasolit Nov 23, 2024
57b5ec8
DB 설정 및 엔티티 추가
dasolit Nov 25, 2024
dac05f7
엔티티 수정
dasolit Nov 26, 2024
bb2ee21
설문조사 생성 커밋
dasolit Nov 27, 2024
0165417
설문조사 등록 수정, 공통 응답 추가
dasolit Dec 4, 2024
4a522aa
설문조사 수정 완료
dasolit Dec 4, 2024
fa627a5
사용하지 않는 import 문 제거
dasolit Dec 4, 2024
2d65878
설문 응답 제출 완료
dasolit Dec 4, 2024
8edc2b7
설문 등답 조회 완료, advanced 미구현.. 작업 진행 중
dasolit Dec 4, 2024
6337f23
answer service 확인용 로그 제거
dasolit Dec 4, 2024
faac8c4
swagger 의존성 및 설정 추가
dasolit Dec 5, 2024
ca3e682
readme 작성
dasolit Dec 5, 2024
d1215b8
스웨거 설명 수정
dasolit Dec 7, 2024
bee16aa
스웨거 기본 값 수정
dasolit Dec 7, 2024
9fde5b6
readme 수정
dasolit Dec 7, 2024
1d2ea83
멀티 모듈 생성
dasolit Dec 12, 2024
83f00ce
멀티 모듈로 변경
dasolit Dec 16, 2024
6f3935a
모듈에 맞게 소스 코드 분리, api 모듈 service 주입 처리 중
dasolit Dec 16, 2024
e3f159e
api 모듈 service error 수정, jpa repo에 @repository 어노테이션 추가
dasolit Dec 16, 2024
ce9cddf
is delete 값 삭제
dasolit Dec 28, 2024
0b75c6c
Update README.md
dasolit Mar 5, 2025
9c63167
Update README.md
dasolit Mar 5, 2025
f5854c6
Update README.md
dasolit Mar 5, 2025
201aa11
Update README.md
dasolit Mar 5, 2025
e9cc27b
Update README.md
dasolit Mar 5, 2025
68db4b7
Update README.md
dasolit Mar 5, 2025
d0315ad
수정 완료
dasolit Mar 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
295 changes: 180 additions & 115 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,115 +1,180 @@
# 이너써클 BE 온보딩 프로젝트

## 온보딩 프로젝트의 목적

- 공통된 내용과 기술스택을 이용한 기술 경험 수준 평가
- 최대한 과거에 경험 해보시지 못한 주제를 선정하여 기술적으로 챌린지 하실 수 있게끔 구성
- 점수를 매기거나 합격과 불합격을 구분하는 목적은 아님.
- 서로가 서로에게 도움 줄 수 있는 각자의 강점을 파악하기 위하여 진행
- 꼼꼼한 요구사항 분석과 문서화
- 새로운 기술적 접근 방식
- 안정적인 아키텍처 구성

## Introduction

- “설문조사 서비스"를 구현하려고 합니다.
- “온보딩 프로젝트 기능 요구사항"을 구현해 주시기 바랍니다.
- 온보딩 프로젝트 기능 요구 사항 및 기술 요구사항이 충족되지 않은 결과물은 코드레벨 평가를 진행하지 않습니다.
- 아래의 “코드레벨 평가항목"으로 코드를 평가합니다.
- “설문조사 서비스"의 API 명세를 함께 제출해주세요.
- 우대사항은 직접 구현하지 않더라도 README에 적용 방법 등을 구체적으로 명시해주시는 것으로 대체 할 수 있습니다.

## 온보딩 프로젝트 기능 요구사항

### 개요

- “설문조사 서비스”는 설문조사 양식을 만들고, 만들어진 양식을 기반으로 응답을 받을 수 있는 서비스입니다. (e.g. Google Forms, Tally, Typeform)
- 설문조사 양식은 [설문조사 이름], [설문조사 설명], [설문 받을 항목]의 구성으로 이루어져있습니다.
- [설문 받을 항목]은 [항목 이름], [항목 설명], [항목 입력 형태], [항목 필수 여부]의 구성으로 이루어져있습니다.
- [항목 입력 형태]는 [단답형], [장문형], [단일 선택 리스트], [다중 선택 리스트]의 구성으로 이루어져있습니다.


### 1. 설문조사 생성 API

- 요청 값에는 [설문조사 이름], [설문조사 설명], [설문 받을 항목]이 포함됩니다.
- [설문 받을 항목]은 [항목 이름], [항목 설명], [항목 입력 형태], [항목 필수 여부]의 구성으로 이루어져있습니다.
- [항목 입력 형태]는 [단답형], [장문형], [단일 선택 리스트], [다중 선택 리스트]의 구성으로 이루어져있습니다.
- [단일 선택 리스트], [다중 선택 리스트]의 경우 선택 할 수 있는 후보를 요청 값에 포함하여야 합니다.
- [설문 받을 항목]은 1개 ~ 10개까지 포함 할 수 있습니다.


### 2. 설문조사 수정 API

- 요청 값에는 [설문조사 이름], [설문조사 설명], [설문 받을 항목]이 포함됩니다.
- [설문 받을 항목]은 [항목 이름], [항목 설명], [항목 입력 형태], [항목 필수 여부]의 구성으로 이루어져있습니다.
- [항목 입력 형태]는 [단답형], [장문형], [단일 선택 리스트], [다중 선택 리스트]의 구성으로 이루어져있습니다.
- [단일 선택 리스트], [다중 선택 리스트]의 경우 선택 할 수 있는 후보를 요청 값에 포함하여야 합니다.
- [설문 받을 항목]이 추가/변경/삭제 되더라도 기존 응답은 유지되어야 합니다.


### 3. 설문조사 응답 제출 API

- 요청 값에는 [설문 받을 항목]에 대응되는 응답 값이 포함됩니다.
- 응답 값은 설문조사의 [설문 받을 항목]과 일치해야만 응답 할 수 있습니다.


### 4. 설문조사 응답 조회 API

- 요청 값에는 [설문조사 식별자]가 포함됩니다.
- 해당 설문조사의 전체 응답을 조회합니다.
- **(Advanced)** 설문 응답 항목의 이름과 응답 값을 기반으로 검색 할 수 있습니다.

<br/>

> 💡 주어진 요구사항 이외의 추가 기능 구현에 대한 제약은 없으며, 새롭게 구현한 기능이 있을 경우 README 파일에 기재 해주세요.

<br/>

## 기술 요구 사항

- JAVA 11 이상 또는 Kotlin 사용
- Spring Boot 사용
- Gradle 기반의 프로젝트
- 온보딩 프로젝트 기능 요구사항은 서버(백엔드)에서 구현/처리
- 구현을 보여줄 수 있는 화면(프론트엔드)은 구현 금지
- DB는 인메모리 RDBMS(예: h2)를 사용하며 DB 컨트롤은 JPA로 구현. (NoSQL 사용 X)
- API의 HTTP Method는 자유롭게 선택해주세요.
- 에러 응답, 에러 코드는 자유롭게 정의해주세요.
- 외부 라이브러리 및 오픈소스 사용 가능 (단, README 파일에 사용한 오픈 소스와 사용 목적을 명확히 명시해 주세요.)

## 코드레벨 평가 항목

온보딩 프로젝트는 다음 내용을 고려하여 평가 하게 됩니다.

- 프로젝트 구성 방법 및 관련된 시스템 아키텍처 설계 방법이 적절한가?
- 작성한 애플리케이션 코드의 가독성이 좋고 의도가 명확한가?
- e.g. 불필요한(사용되지) 않는 코드의 존재 여부, 일정한 코드 컨벤션 등
- 작성한 테스트 코드는 적절한 범위의 테스트를 수행하고 있는가?
- e.g. 유닛/통합 테스트 등
- Spring Boot의 기능을 적절히 사용하고 있는가?
- 예외 처리(Exception Handling)은 적절히 수행하고 있는가?

## 우대사항

- 프로젝트 구성 추가 요건: 멀티 모듈 구성 및 모듈간 의존성 제약
- Back-end 추가 요건
- 트래픽이 많고, 저장되어 있는 데이터가 많음을 염두에 둔 구현
- 다수의 서버, 인스턴스에서 동작할 수 있음을 염두에 둔 구현
- 동시성 이슈가 발생할 수 있는 부분을 염두에 둔 구현

## 온보딩 프로젝트 제출 방식

### 소스코드

- 본 Repository에 main 브랜치를 포크하여 작업을 시작합니다.
- SpringBoot 프로젝트를 신규로 설정하고, 개인별로 main 브랜치에 PR을 공개적으로 먼저 작성한 후에 작업을 시작합니다.
- 이때 PR에는 WIP 레이블을 붙여서 작업 중임을 알게 해주세요.
- 코드를 마무리해서 리뷰받을 준비가 되면 WIP 레이블을 제거하고, Needs Review 레이블을 추가해주세요.
- 피드백을 받은 후 추가 작업을 진행할 때는 WIP 레이블을 다시 추가하고 Needs Review 레이블을 제거해주세요.
- 최소 기능 단위로 완성할 때 마다 커밋합니다.

### 기능 점검을 위한 빌드 결과물

빌드 결과물을 Executable jar 형태로 만들어 위 Branch에 함께 업로드 하시고, README에 다운로드 링크 정보를 넣어주시기 바랍니다. GitHub의 용량 문제로 업로드가 안되는 경우 다른 곳(개인 구글 드라이브 등)에 업로드 한 후 해당 다운로드 링크 정보를 README에 넣어주셔도 됩니다.

해당 파일을 다운로드 및 실행(e.g. java -jar project.jar)하여 요구 사항 기능 검증을 진행하게 됩니다. 해당 파일을 다운로드할 수 없거나 실행 시 에러가 발생하는 경우에는 기능 점검을 진행하지 않습니다. 온보딩 프로젝트 제출 전 해당 실행 파일 다운로드 및 정상 동작 여부를 체크해 주시기 바랍니다.
# [IC2_BE] 최다솔 - 설문조사 서비스 과제
# API 요청 & JSON 예시 (단일 블록)

## (1) 설문조사 생성 [POST] /api/v1/survey
```json
{
"name": "고객 만족도 조사",
"description": "서비스 이용 고객들의 만족도 파악용 설문입니다.",
"items": [
{
"id": null,
"name": "이름",
"description": "사용자의 이름을 입력해주세요.",
"isRequired": true,
"type": "SHORT",
"options": []
},
{
"id": null,
"name": "가장 만족스러운 기능은?",
"description": "서비스 기능 중 가장 마음에 드는 것을 선택해주세요.",
"isRequired": false,
"type": "SINGLE",
"options": [
"속도",
"가격",
"디자인"
]
}
]
}
```

## (2) 설문조사 수정 [PUT] /api/v1/survey/{surveyId}
```json
{
"name": "고객 만족도 조사 (수정됨)",
"description": "조사 설명이 변경되었습니다.",
"items": [
{
"id": 1,
"name": "이름(수정)",
"description": "이름 질문을 수정했습니다.",
"isRequired": true,
"type": "SHORT",
"options": []
},
{
"id": null,
"name": "가격 만족도",
"description": "새로운 질문을 추가했습니다.",
"isRequired": false,
"type": "MULTI",
"options": [
"비싸다",
"적절하다",
"싸다"
]
}
]
}
```
## (3-1) 설문 응답 제출 #1 [POST] /api/v1/answer/{surveyId}
```json
{
"surveyId": 1,
"answerItemList": [
{
"itemId": 1,
"type": "SHORT",
"answer": "홍길동",
"option": null,
"optionList": null
},
{
"itemId": 2,
"type": "SINGLE",
"answer": null,
"option": "디자인",
"optionList": null
}
]
}
```
## (3-2) 설문 응답 제출 #2 [POST] /api/v1/answer/{surveyId}
```json
{
"surveyId": 1,
"answerItemList": [
{
"itemId": 1,
"type": "SHORT",
"answer": "김철수",
"option": null,
"optionList": null
},
{
"itemId": 3,
"type": "MULTI",
"answer": null,
"option": null,
"optionList": [
"적절하다",
"싸다"
]
}
]
}
```
## (4) 설문 응답 조회 [GET] /api/v1/answer/{surveyId}
```json
[
{
"answerId": 10,
"surveyId": 1,
"answerItemList": [
{
"itemId": 1,
"type": "SHORT",
"answer": "홍길동",
"option": null,
"optionList": null
},
{
"itemId": 2,
"type": "SINGLE",
"answer": null,
"option": "디자인",
"optionList": null
}
]
},
{
"answerId": 11,
"surveyId": 1,
"answerItemList": [
{
"itemId": 1,
"type": "SHORT",
"answer": "김철수",
"option": null,
"optionList": null
},
{
"itemId": 3,
"type": "MULTI",
"answer": null,
"option": null,
"optionList": [
"적절하다",
"싸다"
]
}
]
}
]
```

# Jar

[다운로드](https://drive.google.com/file/d/1lU3XsaXOGsfxZ_4c9vgLcKVX4KbXEsyB/view?usp=sharing)


## 2. 트래픽이 많고, 저장되어 있는 데이터가 많음을 염두에 둔 구현

- **대규모 데이터 분산**:
설문 응답(`Answer`)이 기하급수적으로 늘어날 수 있으므로, 테이블 **파티셔닝**(예: 날짜 기준 파티션) 또는 **샤딩**(수평 분할) 전략을 고려했습니다. 이를 통해 특정 파티션/샤드에만 쿼리를 수행하여 조회·저장 성능을 향상

- **인덱스(Index) 최적화**:
`survey_id`, `question_id` 필드 등에 필수 인덱스를 설정하여, 설문·질문·응답 간 조인을 빠르게 처리, 또한, **카디널리티(Cardinality) 분석**을 통해 불필요한 인덱스는 제거하고, 필요한 인덱스만 유지하여 DB 오버헤드 감소

- **캐싱(Caching) & 무중단 스케일링**:
Redis 등 **인메모리 캐시**를 도입하여 자주 조회되는 설문조사 정보를 캐싱하며, 응답 제출 시 캐시 무효화(Invalidate) 정책을 적용, Docker/Kubernetes 환경에서 컨테이너 수를 유연하게 조절해 **서비스 무중단 확장**도 고려


## 3. 다수의 서버, 인스턴스에서 동작할 수 있음을 염두에 둔 구현

- **동시성 및 분산 락 고려**:
여러 서버에서 동시에 같은 설문에 응답이 몰릴 수 있으므로, **Optimistic Lock**(버전 필드) 또는 **Pessimistic Lock**(`for update`) 적용
필요 시 **Redis 기반 분산 락**(Redisson 등)을 사용해 응답 중복 처리나 데이터 정합성 이슈를 해결할 수 있음
3 changes: 3 additions & 0 deletions survey/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/gradlew text eol=lf
*.bat text eol=crlf
*.jar binary
Loading