Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(timeout 5 npx tsx src/index.ts)"
]
}
}
117 changes: 117 additions & 0 deletions 도얏/week2/mission_queries.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
-- =============================================
-- UMC 2주차 미션 쿼리 (제공해주신 로직 + 1주차 ERD 스키마 반영)
-- =============================================

-- =============================================
-- 1. 내가 진행중/진행 완료한 미션 목록 조회 (페이징 포함)
-- =============================================
SELECT
m.c_mis_id AS mission_id,
s.c_sto_name AS store_name,
m.c_mis_title AS mission_title,
m.c_mis_reward AS point,
mm.c_mm_status AS mission_status,
mm.c_mm_created AS started_at,
mm.c_mm_updated AS completed_at
FROM t_member_mission mm
JOIN t_mission m ON mm.c_mm_mission_id = m.c_mis_id
JOIN t_store s ON m.c_mis_store_id = s.c_sto_id
WHERE mm.c_mm_member_id = 1 -- 로그인한 유저 id
AND mm.c_mm_status = 'CHALLENGING' -- 진행중: 'CHALLENGING' / 진행완료: 'COMPLETE'
ORDER BY mm.c_mm_created DESC
LIMIT 10 OFFSET 0; -- 1페이지: OFFSET 0, 2페이지: OFFSET 10

-- 진행완료 탭으로 바꿀 때는 status 조건만 변경
-- AND mm.c_mm_status = 'COMPLETE'


-- =============================================
-- 2. 리뷰 작성 쿼리 (사진 제외)
-- =============================================
INSERT INTO t_review (
c_rev_member_id,
c_rev_store_id,
c_rev_content,
c_rev_score,
c_rev_created,
c_rev_updated
)
SELECT
mm.c_mm_member_id,
m.c_mis_store_id,
'너무 맛있어요! 포인트도 받고 좋았습니다.', -- 실제로는 유저가 입력한 내용
4.5, -- 실제로는 유저가 선택한 별점
NOW(),
NOW()
FROM t_member_mission mm
JOIN t_mission m ON mm.c_mm_mission_id = m.c_mis_id
WHERE mm.c_mm_member_id = 1 -- 로그인한 유저 id (본인 미션만 작성 가능)
AND mm.c_mm_mission_id = 1 -- 리뷰 작성할 미션 id
AND mm.c_mm_status = 'COMPLETE'; -- 완료된 미션만 리뷰 작성 가능

-- 리뷰 작성 후 해당 가게의 평균 별점 업데이트
-- (참고: 현재 ERD의 t_store에는 별점 컬럼이 없으나, 'c_sto_score' 컬럼이 있다고 가정)
/*
UPDATE t_store s
SET c_sto_score = (
SELECT AVG(r.c_rev_score)
FROM t_review r
WHERE r.c_rev_store_id = s.c_sto_id
)
WHERE s.c_sto_id = (
SELECT m.c_mis_store_id
FROM t_mission m
WHERE m.c_mis_id = 1
);
*/


-- =============================================
-- 3. 홈 화면 - 현재 선택된 지역에서 도전 가능한 미션 목록 (페이징 포함)
-- =============================================

-- 3-1. 현재 지역 완료 미션 수 (상단 7/10 표시용)
SELECT COUNT(*) AS complete_count
FROM t_member_mission mm
JOIN t_mission m ON mm.c_mm_mission_id = m.c_mis_id
JOIN t_store s ON m.c_mis_store_id = s.c_sto_id
WHERE mm.c_mm_member_id = 1 -- 로그인한 유저 id
AND s.c_sto_region_id = 1 -- 현재 선택된 지역 id
AND mm.c_mm_status = 'COMPLETE';

-- 3-2. 현재 지역에서 도전 가능한 미션 목록 (아직 도전 안 한 미션)
SELECT
m.c_mis_id AS mission_id,
s.c_sto_name AS store_name,
fc.c_fc_name AS category,
m.c_mis_title AS mission_title,
m.c_mis_reward AS point,
m.c_mis_deadline AS deadline
FROM t_mission m
JOIN t_store s ON m.c_mis_store_id = s.c_sto_id
JOIN t_food_category fc ON s.c_sto_fc_id = fc.c_fc_id
WHERE s.c_sto_region_id = 1 -- 현재 선택된 지역 id
AND s.c_sto_status = 'OPEN' -- 상점 오픈 상태 가정
AND m.c_mis_id NOT IN ( -- 내가 이미 도전중이거나 완료한 미션 제외
SELECT c_mm_mission_id
FROM t_member_mission
WHERE c_mm_member_id = 1 -- 로그인한 유저 id
)
ORDER BY m.c_mis_created DESC
LIMIT 10 OFFSET 0; -- 1페이지: OFFSET 0, 2페이지: OFFSET 10


-- =============================================
-- 4. 마이페이지 화면 쿼리
-- =============================================
SELECT
u.c_mem_nickname AS nickname,
u.c_mem_social_id AS email, -- 이메일 전용 컬럼 부재로 소셜 계정 ID 매핑
u.c_mem_phone_num AS phone,
u.c_mem_profile_image_url AS profile_img,
u.c_mem_point AS point,
COUNT(r.c_rev_id) AS review_count -- 작성한 리뷰 수
FROM t_member u
LEFT JOIN t_review r ON r.c_rev_member_id = u.c_mem_id
WHERE u.c_mem_id = 1 -- 로그인한 유저 id
GROUP BY u.c_mem_id;
107 changes: 107 additions & 0 deletions 도얏/week3/WEEK3_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@

---

# 미션 서비스 API 명세서

## 1. 회원 관련 API

### **[POST] 회원가입**
* **Endpoint**: `/users/signup`
* **Request Header**: `Content-Type: application/json`
* **Request Body**:
```json
{
"email": "string",
"password": "string",
"name": "string",
"gender": "integer",
"birth": "string",
"address": "string"
}
```
* **설명**: 새로운 사용자 계정을 생성합니다.

### **[POST] 선호 조사 내역 저장**
* **Endpoint**: `/users/preferences`
* **Request Header**: `Authorization: Bearer {token}`, `Content-Type: application/json`
* **Request Body**:
```json
{
"category_ids": [1, 2, 3]
}
```
* **설명**: 회원가입 후 사용자의 관심 카테고리 정보를 저장합니다.

---

## 2. 홈 및 미션 관리 API

### **[GET] 홈 화면: 내가 받은 미션 조회**
* **Endpoint**: `/members/me/missions/active`
* **Request Header**: `Authorization: Bearer {token}`
* **Query String**: `page=0&size=10`
* **설명**: 홈 화면에서 현재 사용자가 할당받거나 진행 중인 미션 목록을 조회합니다.

### **[GET] 미션 목록 조회 (수행 중 / 완료)**
* **Endpoint**: `/members/me/missions`
* **Request Header**: `Authorization: Bearer {token}`
* **Query String**:
* `status`: `CHALLENGING` (수행 중) 또는 `COMPLETE` (완료)
* `page`: 페이지 번호
* **설명**: 사용자의 미션 수행 기록을 상태별로 필터링하여 조회합니다.

### **[POST] 미션 도전하기 (성공 누르기)**
* **Endpoint**: `/members/me/missions/{missionId}`
* **Path Variable**: `missionId` (도전할 미션의 ID)
* **Request Header**: `Authorization: Bearer {token}`
* **설명**: 특정 미션을 수행하기 시작하거나 완료를 요청합니다.

---

## 3. 지도 및 가게 관련 API

### **[GET] 지역별 가게 리스트 조회**
* **Endpoint**: `/regions/{regionId}/stores`
* **Path Variable**: `regionId` (지역 ID)
* **Query String**: `last_store_id=10&size=10`
* **설명**: 특정 지역에 등록된 가게들의 목록을 조회합니다.

### **[GET] 가게 정보 및 미션 조회**
* **Endpoint**: `/stores/{storeId}`
* **Path Variable**: `storeId` (가게 ID)
* **설명**: 특정 가게의 상세 정보와 해당 가게에서 진행 가능한 미션 목록을 조회합니다.

---

## 4. 마이페이지 및 리뷰 API

### **[POST] 리뷰 작성하기**
* **Endpoint**: `/members/me/missions/{memberMissionId}/reviews`
* **Path Variable**: `memberMissionId` (완료된 미션 수행 기록 ID)
* **Request Header**: `Authorization: Bearer {token}`
* **Request Body**:
```json
{
"content": "string",
"score": "float",
"image_url": "string"
}
```
* **설명**: 완료된 미션에 대해 가게 리뷰와 별점을 작성합니다.

### **[GET] 내 포인트 조회**
* **Endpoint**: `/members/me/points`
* **Request Header**: `Authorization: Bearer {token}`
* **설명**: 사용자가 현재 보유한 총 포인트와 적립 내역을 확인합니다.

---

## 핵심 비즈니스 로직

### **지역 보너스 포인트 자동 지급**
* **적용 대상 API**: `POST /members/me/missions/{missionId}` (미션 완료 처리 시)
* **로직 상세**:
1. 사용자가 미션을 완료할 때마다 해당 가게의 `region_id`를 확인합니다.
2. 서버 내부에서 해당 사용자가 동일 지역에서 완료한 미션의 총개수를 카운트합니다.
3. **모든 지역마다 누적 완료 미션이 10개가 될 때마다 1000 point를 즉시 지급**합니다.
4. 보너스 지급 시 사용자에게 알림을 발송합니다.
3 changes: 3 additions & 0 deletions 도얏/week4/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
dist/
.env
Loading