-
Notifications
You must be signed in to change notification settings - Fork 0
BE Request Weekly Matching Type
์์ฑ: 2026-09-14 ยท FE ๋ด๋น: @junseo2323 ๋์:
ditto-develop/ditto-server๊ด๋ จ: Frontend-Group-Matching-Guide (์ด์ #171 ยท PR #174) ยท BE ๊ฐ๋ฐ ์์ฒญ์ โ ๋งค์นญ ํ๋ณด ์๊ฐ๋ ธํธ ์ด๋ ๊ถํ ยท FE ๋ธ๋์นfeat/s3-migration์์ฒญ 2๊ฑด ยท [ํ์ฅ] + [ํ์ธ] ยท P1
| # | ํญ๋ชฉ | ํ๊ทธ | ์ฐ์ | ์ง๊ธ ์ํ |
|---|---|---|---|---|
| 1 | ๋งค์นญ ํ๋ณด ์๋ต์ ๊ทธ ํด์ฆ์ ์ ์ฃผ์ฐจ๋ฅผ ๋ฃ์ด ์ฃผ์ธ์ | ํ์ฅ | P1 | FE๊ฐ quizSetId ํฌ๊ธฐ๋ก ์ถ์ธก ์ค โ ํ๋ฆฌ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค
|
| 2 | ์ด๋๋ฏผ์ด ํ ์ฃผ์ ํด์ฆ์
์ 2๊ฐ ๋ง๋ค๋ฉด /quiz-progress/current ๊ฐ 500์
๋๋ค |
ํ์ธ | P3 | ์์ฑ ์ ๋ง์ง ์์ |
์ ์ : ์ด์์ ํ ์ฃผ์ ํ ์ข ๋ฅ์ ๋๋ค โ ์ด๋ฒ ์ฃผ 1:1, ๋ค์ ์ฃผ ๊ทธ๋ฃน ์์ผ๋ก ๋ฒ๊ฐ์ ๊ฐ๋๋ค. ์ด ๋ฌธ์๋ ๊ทธ ์ ์ ์์์ ์๋๋ค.
๊ทธ๋ฃน ๋งค์นญ์ด ํ๋ณด ๊ทธ๋ฃน ์๋ฝ/๊ฑฐ์ ๋ฐฉ์์ผ๋ก ๋ฐ๋๋ฉด์(PR #174) FE๋ ํ์์ ๋ ์๋ํฌ์ธํธ๋ฅผ ๊ฐ์ด ํธ์ถํฉ๋๋ค.
GET /api/v1/matches/1on1 โ findLatestCompletedQuizSet(memberId, ONE_TO_ONE)
GET /api/v1/matches/group โ findLatestCompletedQuizSet(memberId, GROUP)
๋ ๋ค "๋ด๊ฐ ์ต๊ทผ ์์ฃผํ <ํ์ > ํด์ฆ์ " ์ ํ์ ๋ณ๋ก ๋ ๋ฆฝํด์ ์ฐพ์ต๋๋ค. ์ฃผ์ฐจ๋ฅผ ๋ณด์ง ์์ต๋๋ค. ๊ทธ๋์ ๊ฒฉ์ฃผ๋ก ๋ฒ๊ฐ์ ๊ฐ๋ ์ด์์์๋ ๋งค์ฃผ, ๋ฐ๋ ํ์ ์๋ํฌ์ธํธ๊ฐ ์ง๋ ์ฌ์ดํด ํ๋ณด๋ฅผ 200์ผ๋ก ๋๋ ค์ค๋๋ค.
10์ฃผ์ฐจ = ๊ทธ๋ฃน โ 11์ฃผ์ฐจ = 1:1 ์ธ ๊ฒฝ์ฐ 11์ฃผ์ฐจ ๋งค์นญ ๊ธฐ๊ฐ์
/matches/1on1โ 11์ฃผ์ฐจ ํ๋ณด โ/matches/groupโ 10์ฃผ์ฐจ ํ๋ณดโ ๏ธ (์๋ต ์ ํ ๊ทธ๋ฃน์myStatus: PENDING์ผ๋ก, ์๋ฝํ๋ ๊ทธ๋ฃน์ACCEPTED/isFormed๋ก ๊ณ์ ๋ด๋ ค์ต๋๋ค. ๊ฑฐ์ ํ ๊ฒ๋ง ๋น ์ง๋๋ค)
ํ๋ณด ํ์ด ์ง๋ ์ฃผ ๊ฒ๋ ๋จ๋๋ค๋ ๊ฑด PR #173 ์ค๋ช ์๋ ์๋ ๋ด์ฉ์ ๋๋ค ("ํ๋ณด ํ์ ์ง๋ ์ฃผ ๊ฒ๋ ๋จ๊ธฐ ๋๋ฌธ์ ํด์ฆ์ ์ผ๋ก ์ขํ์ง ์์ผ๋ฉด ์ด๋ ๊ถํ์ด ์๊ตฌํ ์ด๋ฆฐ๋ค"). ๊ฐ์ ์ฑ์ง์ด ๋งค์นญ ๊ฒฐ๊ณผ ํ๋ฉด์๋ ๊ทธ๋๋ก ๋ํ๋ฉ๋๋ค.
// src/app/home/MainSection.tsx
// quizSetId ๊ฐ ํฐ ์ชฝ์ด ์ด๋ฒ ์ฃผ์ผ ๊ฒ์ด๋ค โ ์ด๋๊น์ง๋ ์ถ์ธก
const groupIsThisWeek =
groupResult !== null &&
(candidateResult === null ||
Number(groupResult.quizSetId) >= Number(candidateResult.quizSetId));์๋ฒ์ ์ ๋ณธ ๊ธฐ์ค์ quizSet.endDate DESC ์ธ๋ฐ ์๋ต์ endDate ๊ฐ ์์ด ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋น๊ตํ ์ ์์ต๋๋ค.
์ด๋ฒ ์ฃผ ํด์ฆ๋ฅผ ๊ฑด๋๋ด ํ์์ ๋๋ค.
10์ฃผ์ฐจ(๊ทธ๋ฃน) ์์ฃผ ยท ํ๋ณด์ ์๋ต ์ ํจ โ 11์ฃผ์ฐจ(1:1) ํด์ฆ๋ฅผ ์ ํ 11์ฃผ์ฐจ ๋งค์นญ ๊ธฐ๊ฐ:
/matches/1on1โ 4040004(์์ฃผํ 1:1 ํด์ฆ์ ์ด ์์)/matches/groupโ 10์ฃผ์ฐจ ๊ทธ๋ฃน ํ๋ณด 200โ ๋น๊ต ๋์์ด ์์ด FE๋ 10์ฃผ์ฐจ ๊ทธ๋ฃน ์นด๋๋ฅผ ์ด๋ฒ ์ฃผ ๊ฒฐ๊ณผ๋ก ๊ทธ๋ฆฝ๋๋ค. ์ด๋ฒ ์ฃผ์ ์ฐธ์ฌ๋ ์ ํ๋๋ฐ "์ด๋ฒ์ฃผ ๋งค์นญ" ์นด๋์ ์ง๋ ์ฃผ ๊ทธ๋ฃน์ด ๋น๋๋ค.
๋ ๋ฒ์งธ๋ก, ์ด๋๋ฏผ์ด ๋ค์ ์ฃผ ํด์ฆ์
์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋๋ฉด id ์์์ endDate ์์๊ฐ ์ด๊ธ๋
๋น๊ต ์์ฒด๊ฐ ๊นจ์ง๋๋ค.
"์ด๋ฒ ์ฃผ ํด์ฆ์ id๋ฅผ ๋ฐ์์ ๋์กฐํ๋ฉด ๋์ง ์๋" ๋ฅผ ๋จผ์ ๊ฒํ ํ๋๋ฐ, ๋งค์นญ ๊ธฐ๊ฐ์๋ ๊ทธ ๊ฐ์ ๋ฐ์ ์ ์์ต๋๋ค.
-
GET /quiz-sets/current-weekโfindCurrentWeekActive(now)โstartDate <= now <= endDate - ๋งค์นญ ๋ฐฐ์น๋ ๋ชฉ 05:00์
endDate < now์ธ ํด์ฆ์ ์ ์ก์ต๋๋ค(MatchingScheduler,findEndedQuizSetsWithoutCandidates) - ์ฆ ํด์ฆ์
์
endDate๋ ๋ชฉ 05:00 ์ด์ ์ด์ด์ผ ํ๊ณ , ๊ทธ๋์ ๋งค์นญยท๋ํ ๊ธฐ๊ฐ์๋findCurrentWeekActive๊ฐ ๋น ๋ฐฐ์ด์ ๋๋ค
๊ฒฐ๊ตญ ๋งค์นญ ๊ธฐ๊ฐ์ "์ด๋ฒ ์ฃผ ํด์ฆ์ ์ด ๋ฌด์์ธ์ง" ๋ฌผ์ด๋ณผ ๊ณณ์ด ์์ต๋๋ค.
MatchCandidateResponse ์ GroupCandidateResponse ์์ชฝ์ ์ถ๊ฐํด ์ฃผ์ธ์.
์ด ๋ชจ์์ ์ ํธํ๋ ์ด์ : FE๋ ํ ์ง์
๋ ์ด๋ฏธ GET /api/v1/system/state ๋ฅผ ๋ถ๋ฅด๊ณ ์๊ณ ,
๊ทธ ์๋ต์ด { year, month, week, period } ์
๋๋ค. ๊ฐ์ ํค๋ก ์ค๋ฉด ์ถ๊ฐ ์์ฒญ ์์ด ํ ์ค ๋น๊ต๋ก ๋๋ฉ๋๋ค.
์๋ฒ์๋ OperationWeek.containing(...) ์ด ์ด๋ฏธ ์์ผ๋ CurrentWeekQuizSetsResponse ์ ๊ฐ์ ๋ฐฉ์์ด๋ฉด ๋ฉ๋๋ค.
๋์๋ ๊ด์ฐฎ์ต๋๋ค. ํธํ์ ์ชฝ์ผ๋ก ์ฃผ์๋ฉด FE๊ฐ ๋ง์ถ๊ฒ ์ต๋๋ค.
// (๋์ a) ํด์ฆ์
์ข
๋ฃ ์๊ฐ โ ์๋ฒ๊ฐ ์ ๋ ฌ์ ์ฐ๋ ๊ฐ ๊ทธ๋๋ก
{ "quizSetId": 10, "quizSetEndDate": "2026-09-09 23:59:59", ... }
// (๋์ b) ์๋ฒ๊ฐ ์์ ํ์
{ "quizSetId": 10, "isCurrentWeek": true, ... }๋๋ ์์ ์ ๋ด๋ ค์ฃผ๊ธฐ: ๋์ ํด์ฆ์
์ด ์ด๋ฒ ์ฃผ๊ฐ ์๋๋ฉด 0004 ๋ก ๋ซ์ ์ฃผ์
๋ FE๋ ๊น๋ํฉ๋๋ค.
๋ค๋ง ๋งค์นญ ๊ธฐ๊ฐ์ด ์ฃผ ๊ฒฝ๊ณ๋ฅผ ์ด๋ป๊ฒ ๋๋์ง(๊ธ 00:00 ์ฑํ
๊ฐ๋ฐฉ ์ดํ ๋ฑ)๋ ์๋ฒ ํ๋จ์ด๋ผ,
๊ฐ๋ง ์ฃผ์๋ ์ชฝ์ ์ฐ์ ์ผ๋ก ์์ฒญ๋๋ฆฝ๋๋ค.
์ด์์ด ํ ์ฃผ ํ ์ข ๋ฅ๋ผ ํ์์์ ๋ฟ์ง ์์ต๋๋ค. ๋ค๋ง ๋ง์ ๋๋ ๊ณณ์ด ์์ด ๋จ๊ฒจ ๋ก๋๋ค.
-
AdminQuizService.createQuizSet์validatePeriodWithinOneWeek๋ง ๋ด ๋๋ค โ ๊ธฐ๊ฐ์ด ํ ์ด์ ์ฃผ ์์ธ์ง๋ง ๋ณด๊ณ , ๊ฐ์ ์ฃผ์ ํด์ฆ์ ์ด ์ด๋ฏธ ์๋์ง๋ ๋ณด์ง ์์ต๋๋ค. -
๊ทธ ์ํ์์ ํ์์ด ๋ ํด์ฆ์ ์ ๋ชจ๋ ๋ตํ๋ฉด(
validateNotCompleted๋ ๊ทธ ํด์ฆ์ ์ฌ์์ฃผ๋ง ๋ง์ต๋๋ค)quiz_progressํ์ด 2๊ฐ ์๊ธฐ๊ณ , -
GET /api/v1/quiz-progress/current๊ฐ ๋ถ๋ฅด๋findActiveProgress๊ฐif (progresses.size > 1) { log.error { "ํ ์ฃผ์ ์ฌ๋ฌ ํด์ฆ์ ์ ์ฐธ์ฌํ ์ฌ์ฉ์ ๋ฐ๊ฒฌ: ..." } throw ErrorException(ErrorCode.INTERNAL_ERROR) // 500 / 9999 }
๋ก 500 ์ ๋์ง๋๋ค.
์ฆ์: FE๋ ์ด ์ค๋ฅ๋ฅผ ์ผ์ผ ์งํ ์ํ๋ฅผ ๋ชป ์ฝ์ต๋๋ค โ ํด์ฆ๋ฅผ ๋ค ํผ ์ฌ๋์ด
"์์ง ์ ํผ ์ฌ๋"์ผ๋ก ๋ณด์
๋๋ค(์ฐธ์ฌ ์๋ฃ ์นด๋ ๋์ ์์ ์นด๋, ์ฐธ์ฌ์ ์ 0).
ํ๋ณต์ POST /quiz-progress/reset(ํด์ฆ ํ๋ฉด "์๋ก ํ๊ธฐ") ๋ฟ์ธ๋ฐ ์ด๋ฒ ์ฃผ ๋ต๋ณ์ ์ ๋ถ ์ง์๋๋ค.
์์ฒญ: ์ด๋๋ฏผ ํด์ฆ์
์์ฑ ์ "๊ฐ์ ์ด์ ์ฃผ์ ์ด๋ฏธ ํด์ฆ์
์ด ์์ผ๋ฉด ๊ฑฐ๋ถ"๋ฅผ ๋ฃ์ด ์ฃผ์๋ฉด,
findActiveProgress ์ ์ ์ ๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ์ฐธ์ด ๋ฉ๋๋ค. ์ด์ ์ ํ๊ธฐ์ ๋ ๊ฐ๋ฅผ ๋ฌ์ผ ํ ์ผ์ด
์๋์ง์ ๋ฐ๋ผ ํ๋จ ๋ถํ๋๋ฆฝ๋๋ค.
-
quizSetIdํฌ๊ธฐ ๋น๊ต๋ฅผ ์ ์งํฉ๋๋ค. ๊ฐ์ด ๋ด๋ ค์ค๋ฉด ๊ทธ ํ ์ค๋ง ๋ฐ๊ฟ๋๋ค. - ยง1์ "์ด๋ฒ ์ฃผ ํด์ฆ๋ฅผ ๊ฑด๋๋ด ํ์" ์ผ์ด์ค๋ ๊ณ ์น ์๋จ์ด ์์ด ๊ทธ๋๋ก ๋ก๋๋ค.
- ๊ทธ๋ฃน ๋งค์นญ ์ฐ๋(PR #174 ๋ฐ์)์ ์ด ์์ฒญ๊ณผ ๋ฌด๊ดํ๊ฒ ์๋ฃํด ๋์์ต๋๋ค. ์ด ๋ฌธ์๋ "์ง๋ ์ฌ์ดํด ํ๋ณด๊ฐ ์์ฌ ๋ค์ด์ค๋ ๊ฒ"๋ง ๋ค๋ฃน๋๋ค.
- ๋งค์นญ ํ๋ณด ์๋ต(
/matches/1on1,/matches/group)์ ๋์ ํด์ฆ์ ์ ์ฃผ์ฐจ๋ฅผ ๋ฃ์ด ์ฃผ์ค ์ ์์ต๋๊น? - ๋ชจ์์
yearยทmonthยทweek(์ ํธ) /quizSetEndDate/isCurrentWeek์ค ์ด๋ ์ชฝ์ ๋๊น? - "์ด๋ฒ ์ฃผ๊ฐ ์๋๋ฉด
0004" ๋ก ๋ซ๋ ๋ฐฉํฅ๋ ๊ฒํ ๊ฐ๋ฅํฉ๋๊น? (์ ํ) - ์ด๋๋ฏผ ํด์ฆ์ ์์ฑ์ "ํ ์ด์ ์ฃผ์ ํ๋" ์ ์ฝ์ ๋ฃ์ ์ ์์ต๋๊น? (ยง2)
- ์์ ์ผ์
| ๋ฌด์ | ํ์ผ |
|---|---|
ํ์
๋ณ ์ต์ ์์ฃผ ํด์ฆ์
(endDate DESC, ์ฃผ์ฐจ ๋ฌด๊ด) |
domain/.../quiz/repository/querydsl/QuizSetRepositoryImpl.kt โ findLatestCompletedQuizSet
|
| ํ๋ณด ์๋ต DTO |
api/.../match/dto/MatchCandidateResponse.kt ยท GroupCandidateResponse.kt
|
| ํ๋ณด ์กฐํ ์๋น์ค |
api/.../match/service/MatchCandidateService.kt ยท GroupCandidateService.kt
|
| ์ด๋ฒ ์ฃผ ํ์ฑ ํด์ฆ์ (๋งค์นญ ๊ธฐ๊ฐ์ ๋น ๋ฐฐ์ด) |
QuizSetRepositoryImpl.findCurrentWeekActive (startDate <= now <= endDate) |
๋งค์นญ ๋ฐฐ์น (๋ชฉ 05:00, endDate < now) |
api/.../match/scheduler/MatchingScheduler.kt |
| ์ด์ ์ฃผ ๊ณ์ฐ |
domain/.../system/OperationWeek.kt โ containing(...)
|
| ํ ์ฃผ ์งํ ํ์ (500 ์ง์ ) |
api/.../quiz/service/QuizProgressService.kt โ findActiveProgress
|
| ์ด๋๋ฏผ ํด์ฆ์ ์์ฑ ๊ฒ์ฆ |
api/.../admin/quiz/...AdminQuizService.kt โ validatePeriodWithinOneWeek
|
| ๋ฌด์ | ํ์ผ |
|---|---|
| 1:1/๊ทธ๋ฃน ๋ถ๊ธฐ (์ถ์ธก ์ง์ ) |
src/app/home/MainSection.tsx โ groupIsThisWeek
|
| ํ์ฌ ์ฃผ์ฐจยท๊ธฐ๊ฐ |
src/shared/lib/api/externalApi.ts โ getExternalSystemState (year/month/week/period) |
| ํ๋ณด ์กฐํ |
src/shared/lib/api/externalApi.ts โ getExternalMatchCandidates / getExternalGroupCandidates
|
| ์๋ต ํ์ |
src/features/matching/api/matchingApi.ts โ GetMatchCandidatesResponse / GetGroupCandidatesResponse
|
| ์งํ ์กฐํ |
src/shared/lib/api/externalApi.ts โ getExternalQuizProgress
|
| E2E |
cypress/e2e/matching-profile/00-entry.cy.ts ยท 03-result-group.cy.ts
|