Skip to content

BE Request Weekly Matching Type

junseo2323 edited this page Sep 14, 2026 · 1 revision

BE ๊ฐœ๋ฐœ ์š”์ฒญ์„œ โ€” ๋งค์นญ ํ›„๋ณด๊ฐ€ "์ด๋ฒˆ ์ฃผ ๊ฒƒ"์ธ์ง€ ์•Œ๋ ค ์ฃผ์„ธ์š”

์ž‘์„ฑ: 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, ๋‹ค์Œ ์ฃผ ๊ทธ๋ฃน ์‹์œผ๋กœ ๋ฒˆ๊ฐˆ์•„ ๊ฐ‘๋‹ˆ๋‹ค. ์ด ๋ฌธ์„œ๋Š” ๊ทธ ์ „์ œ ์œ„์—์„œ ์”๋‹ˆ๋‹ค.


1. ๋งค์นญ ํ›„๋ณด ์‘๋‹ต์— ์ฃผ์ฐจ๋ฅผ ๋„ฃ์–ด ์ฃผ์„ธ์š” (P1)

์™œ โ€” ๊ฒฉ์ฃผ ์šด์˜์ด๋ฉด ๋งค์ฃผ ์ง€๋‚œ ์‚ฌ์ดํด ๋ฐ์ดํ„ฐ๊ฐ€ ๋”ธ๋ ค ์˜ต๋‹ˆ๋‹ค

๊ทธ๋ฃน ๋งค์นญ์ด ํ›„๋ณด ๊ทธ๋ฃน ์ˆ˜๋ฝ/๊ฑฐ์ ˆ ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๋€Œ๋ฉด์„œ(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 ์„ค๋ช…์—๋„ ์žˆ๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค ("ํ›„๋ณด ํ–‰์€ ์ง€๋‚œ ์ฃผ ๊ฒƒ๋„ ๋‚จ๊ธฐ ๋•Œ๋ฌธ์— ํ€ด์ฆˆ์…‹์œผ๋กœ ์ขํžˆ์ง€ ์•Š์œผ๋ฉด ์—ด๋žŒ ๊ถŒํ•œ์ด ์˜๊ตฌํžˆ ์—ด๋ฆฐ๋‹ค"). ๊ฐ™์€ ์„ฑ์งˆ์ด ๋งค์นญ ๊ฒฐ๊ณผ ํ™”๋ฉด์—๋„ ๊ทธ๋Œ€๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ FE๋Š” ์ด๋ ‡๊ฒŒ ์ถ”์ธกํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค

// 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 โ†’ 404 0004 (์™„์ฃผํ•œ 1:1 ํ€ด์ฆˆ์…‹์ด ์—†์Œ)
  • /matches/group โ†’ 10์ฃผ์ฐจ ๊ทธ๋ฃน ํ›„๋ณด 200

โ†’ ๋น„๊ต ๋Œ€์ƒ์ด ์—†์–ด FE๋Š” 10์ฃผ์ฐจ ๊ทธ๋ฃน ์นด๋“œ๋ฅผ ์ด๋ฒˆ ์ฃผ ๊ฒฐ๊ณผ๋กœ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ์— ์ฐธ์—ฌ๋„ ์•ˆ ํ–ˆ๋Š”๋ฐ "์ด๋ฒˆ์ฃผ ๋งค์นญ" ์นด๋“œ์— ์ง€๋‚œ ์ฃผ ๊ทธ๋ฃน์ด ๋œน๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ๋กœ, ์–ด๋“œ๋ฏผ์ด ๋‹ค์Œ ์ฃผ ํ€ด์ฆˆ์…‹์„ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘๋ฉด id ์ˆœ์„œ์™€ endDate ์ˆœ์„œ๊ฐ€ ์–ด๊ธ‹๋‚˜ ๋น„๊ต ์ž์ฒด๊ฐ€ ๊นจ์ง‘๋‹ˆ๋‹ค.

FE์—์„œ ์ž์ฒด ํ•ด๊ฒฐ์ด ์•ˆ ๋˜๋Š” ์ด์œ 

"์ด๋ฒˆ ์ฃผ ํ€ด์ฆˆ์…‹ id๋ฅผ ๋ฐ›์•„์„œ ๋Œ€์กฐํ•˜๋ฉด ๋˜์ง€ ์•Š๋‚˜" ๋ฅผ ๋จผ์ € ๊ฒ€ํ† ํ–ˆ๋Š”๋ฐ, ๋งค์นญ ๊ธฐ๊ฐ„์—๋Š” ๊ทธ ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • GET /quiz-sets/current-week โ†’ findCurrentWeekActive(now) โ†’ startDate <= now <= endDate
  • ๋งค์นญ ๋ฐฐ์น˜๋Š” ๋ชฉ 05:00์— endDate < now ์ธ ํ€ด์ฆˆ์…‹์„ ์žก์Šต๋‹ˆ๋‹ค(MatchingScheduler, findEndedQuizSetsWithoutCandidates)
  • ์ฆ‰ ํ€ด์ฆˆ์…‹์˜ endDate ๋Š” ๋ชฉ 05:00 ์ด์ „์ด์–ด์•ผ ํ•˜๊ณ , ๊ทธ๋ž˜์„œ ๋งค์นญยท๋Œ€ํ™” ๊ธฐ๊ฐ„์—๋Š” findCurrentWeekActive ๊ฐ€ ๋นˆ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค

๊ฒฐ๊ตญ ๋งค์นญ ๊ธฐ๊ฐ„์— "์ด๋ฒˆ ์ฃผ ํ€ด์ฆˆ์…‹์ด ๋ฌด์—‡์ธ์ง€" ๋ฌผ์–ด๋ณผ ๊ณณ์ด ์—†์Šต๋‹ˆ๋‹ค.

์š”์ฒญ โ€” year / month / week ๊ฐ€ ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค

MatchCandidateResponse ์™€ GroupCandidateResponse ์–‘์ชฝ์— ์ถ”๊ฐ€ํ•ด ์ฃผ์„ธ์š”.

// GET /api/v1/matches/1on1  ยท  GET /api/v1/matches/group
{
  "quizSetId": 10,
  "year": 2026,          // โ† ๋Œ€์ƒ ํ€ด์ฆˆ์…‹์˜ ์šด์˜ ์ฃผ
  "month": 9,
  "week": 2,
  ...
}

์ด ๋ชจ์–‘์„ ์„ ํ˜ธํ•˜๋Š” ์ด์œ : 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 ์ฑ„ํŒ… ๊ฐœ๋ฐฉ ์ดํ›„ ๋“ฑ)๋Š” ์„œ๋ฒ„ ํŒ๋‹จ์ด๋ผ, ๊ฐ’๋งŒ ์ฃผ์‹œ๋Š” ์ชฝ์„ ์šฐ์„ ์œผ๋กœ ์š”์ฒญ๋“œ๋ฆฝ๋‹ˆ๋‹ค.


2. ํ•œ ์ฃผ์— ํ€ด์ฆˆ์…‹์ด 2๊ฐœ๋ฉด 500 (ํ™•์ธ, P3)

์šด์˜์ด ํ•œ ์ฃผ ํ•œ ์ข…๋ฅ˜๋ผ ํ‰์ƒ์‹œ์—” ๋‹ฟ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ๋ง‰์•„ ๋‘๋Š” ๊ณณ์ด ์—†์–ด ๋‚จ๊ฒจ ๋‘ก๋‹ˆ๋‹ค.

  • 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 ์˜ ์ „์ œ๊ฐ€ ๊ตฌ์กฐ์ ์œผ๋กœ ์ฐธ์ด ๋ฉ๋‹ˆ๋‹ค. ์šด์˜ ์ „ํ™˜๊ธฐ์— ๋‘ ๊ฐœ๋ฅผ ๋‘ฌ์•ผ ํ•  ์ผ์ด ์žˆ๋Š”์ง€์— ๋”ฐ๋ผ ํŒ๋‹จ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.


3. ๊ทธ๋•Œ๊นŒ์ง€ FE๋Š”

  • quizSetId ํฌ๊ธฐ ๋น„๊ต๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์ด ๋‚ด๋ ค์˜ค๋ฉด ๊ทธ ํ•œ ์ค„๋งŒ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.
  • ยง1์˜ "์ด๋ฒˆ ์ฃผ ํ€ด์ฆˆ๋ฅผ ๊ฑด๋„ˆ๋›ด ํšŒ์›" ์ผ€์ด์Šค๋Š” ๊ณ ์น  ์ˆ˜๋‹จ์ด ์—†์–ด ๊ทธ๋Œ€๋กœ ๋‘ก๋‹ˆ๋‹ค.
  • ๊ทธ๋ฃน ๋งค์นญ ์—ฐ๋™(PR #174 ๋ฐ˜์˜)์€ ์ด ์š”์ฒญ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ์™„๋ฃŒํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์„œ๋Š” "์ง€๋‚œ ์‚ฌ์ดํด ํ›„๋ณด๊ฐ€ ์„ž์—ฌ ๋“ค์–ด์˜ค๋Š” ๊ฒƒ"๋งŒ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

4. ํšŒ์‹  ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ๋งค์นญ ํ›„๋ณด ์‘๋‹ต(/matches/1on1, /matches/group)์— ๋Œ€์ƒ ํ€ด์ฆˆ์…‹์˜ ์ฃผ์ฐจ๋ฅผ ๋„ฃ์–ด ์ฃผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
  • ๋ชจ์–‘์€ yearยทmonthยทweek(์„ ํ˜ธ) / quizSetEndDate / isCurrentWeek ์ค‘ ์–ด๋А ์ชฝ์ž…๋‹ˆ๊นŒ?
  • "์ด๋ฒˆ ์ฃผ๊ฐ€ ์•„๋‹ˆ๋ฉด 0004" ๋กœ ๋‹ซ๋Š” ๋ฐฉํ–ฅ๋„ ๊ฒ€ํ†  ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ? (์„ ํƒ)
  • ์–ด๋“œ๋ฏผ ํ€ด์ฆˆ์…‹ ์ƒ์„ฑ์— "ํ•œ ์šด์˜ ์ฃผ์— ํ•˜๋‚˜" ์ œ์•ฝ์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? (ยง2)
  • ์˜ˆ์ƒ ์ผ์ •

๋ถ€๋ก A. BE ์ชฝ ์ฐธ๊ณ  ์œ„์น˜

๋ฌด์—‡ ํŒŒ์ผ
ํƒ€์ž…๋ณ„ ์ตœ์‹  ์™„์ฃผ ํ€ด์ฆˆ์…‹ (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

๋ถ€๋ก B. FE ์ชฝ ์œ„์น˜

๋ฌด์—‡ ํŒŒ์ผ
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

Clone this wiki locally