💪 슬롯 오픈·매칭 (멘토 흐름)
Status: Draft · Layer: 💪 멘토 · Updated: 2026-05-13
관련 결정: 3A 강사 페르소나 · 3E 운영 모델 · 5A 예약 · 3F 일반 멘토
📡 API: 멘토 · 예약
🗄️ Data: 3. Schedule · 4. Reservation · 8. Mentor System
현재 코드: apps/partner/src/pages/schedule-page.tsx
1. 배경
멘토는 30분 단위 슬롯을 자유롭게 오픈. 회원 예약이 들어오면 자동 매칭 (이전 멘토 우선). 멘토 본인은 매칭에 직접 개입하지 않고 슬롯 ON/OFF만 관리.
기존 schedule-page.tsx는 60분 슬롯 + 자유 매칭 모델. 30분 단위·자동 매칭·48h/6h 변경 룰 적용 필요.
2. 정책서 락된 사항
슬롯 모델 (5A + 3E)
- 멘토 = 30분 단위로 가능 시간 ON/OFF
- 1시간 = 2 슬롯 (방 A 30분 + 방 B 30분)
- 멘토는 고정 슬롯 ❌ (회원이 고정, 멘토는 자유)
- 본인이 원할 때 슬롯 오픈/닫음 (배달기사형)
이전 멘토 우선 매칭 (5A)
- 회원의 고정 슬롯에 그 멘토 슬롯 오픈 시 → 자동 우선 매칭
- 다른 회원 가로채기 ❌
슬롯 변경/취소 룰 (3E + 2D)
- 48h 전: 무료 (멘토 패널티 ❌)
- 48h-6h 전: 멘토 등급 영향 ❌ (단, 잦으면 평가)
- 6h 이내 본인 취소: 회원 회차 +1 보상, 멘토 등급 패널티, 정산 차감
Pro 인증 멘토 (4A + 3H)
- Pro 인증 = 자격증 + 본사 심사 통과
- Pro 인증 시 단가 자율 권한 (별도 PRD)
- 회원에게 “Pro 인증” 배지 노출
의무 슬롯 (Phase 1, 3E)
- Phase 1 (1-3호점): 본사 코어 12명 = 피크 시간 의무 슬롯 (주 N시간)
- Phase 2+: 점차 약화, 자율 ↑
3. 현재 코드 vs 새 시스템
| 영역 | 현재 (schedule-page.tsx) |
새 시스템 |
|---|---|---|
| 슬롯 단위 | 60분 (start_time + end_time) | 30분 (start_at만, 30분 고정) |
| 슬롯 모델 | TimeSlot | MentorBlock |
| 매칭 | 회원이 trainer 직접 선택 | AI 자동 매칭 (멘토는 수동 ❌) |
| 변경 룰 | 단순 삭제 | 48h/6h 차등 + 패널티 |
| 의무 슬롯 | 모델 없음 | Phase 1 = 주 N시간 의무 |
| 매칭 알림 | 없음 | 회원 매칭 시 푸시 |
| 회원 정보 미리보기 | 없음 | 매칭 시 회원 프로필·이력 노출 |
4. 멘토 시나리오
4.1 슬롯 오픈
캘린더 페이지 진입 → 4주 보기 → 30분 단위 그리드
[화] [10:00] [10:30] [11:00] [11:30] ... [19:00] [19:30] [20:00]
○ ○ ✓ ✓
○ = open (매칭 대기)
✓ = 매칭됨 (회원 이름 hover 표시)
공백 = 닫힘 (default)
클릭 = 토글:
- 닫힘 → open
- open → 닫힘 (48h 전 가능)
- 매칭됨 → 비활성 (운영 매니저만 변경)
4.2 매칭 알림
📩 푸시: "5/15 (화) 19:30 회원 김OO 매칭됨"
[회원 프로필 보기] [확인]
- 회원 프로필: 이름, 나이, 운동 경력, 이전 진행 멘토 (재예약 N회차 표시)
- 직전 인계 메모 (다른 멘토 → 본인) 자동 노출
4.3 슬롯 변경 (멘토 본인 사정)
[슬롯 클릭: 5/15 19:30 - 매칭됨]
─────────────────
회원 김OO 매칭 중
[변경 신청]
- 48h 전 = 자동 처리 (회원 알림 + 다른 멘토 매칭)
- 48h-6h = 운영 매니저 검토 (잦으면 평가)
- 6h 이내 = 회원 회차 +1 보상, 본인 등급·정산 패널티
사유: [_______]
[취소 신청]
4.4 의무 슬롯 (Phase 1 코어 멘토)
이번 주 의무 슬롯: 주 12시간 (피크 6-10pm 우선)
현재 등록: 14시간 ✅ (2시간 초과)
미달 시 = 코어 멘토 인센티브 ↓
월요일 19:00-22:00 (3h)
화요일 19:00-22:00 (3h)
수요일 19:00-21:00 (2h)
...
Phase 2+에서는 자율 (의무 ❌).
4.5 멘토가 매칭에 개입할 수 없는 사항
- 회원 선택 ❌ (AI가 알아서 매칭)
- 회원 거부 ❌ (등급 평가 영향)
- 단가 협상 ❌ (Pro 인증 시만 본사 한도 내 자율)
→ 슬롯만 열어두면 시스템이 회원·결제·정산 다 처리.
5. 화면 요구사항
5.1 슬롯 캘린더 (/schedule)
컴포넌트: schedule-page.tsx 재작성
2026년 5월 (4주 보기)
────────────────────────────────────────
월 화 수 목 금 토 일
06:00 [ ] [ ] [ ] [ ] [ ] [ ] [ ]
06:30 [ ] [ ] [ ] [ ] [ ] [ ] [ ]
...
19:00 [✓] [✓] [✓] [ ] [ ] [ ] [ ] ← ✓ 회원 매칭
19:30 [✓] [○] [✓] [ ] [ ] [ ] [ ] ← ○ open, 매칭 대기
20:00 [○] [○] [○] [ ] [ ] [ ] [ ]
...
범례:
공백 = 닫힘
[○] = open (매칭 대기, 클릭 = 닫기)
[✓] = 매칭됨 (회원 정보 표시)
[🔒] = 변경 불가 (6h 이내 등)
[의무 슬롯 확인] [반복 슬롯 일괄 설정]
5.2 반복 슬롯 일괄 설정
매주 반복 슬롯
────────────────────
[월] 19:00-22:00 (6 슬롯)
[화] 19:00-22:00 (6 슬롯)
[수] 19:00-21:00 (4 슬롯)
저장 시 다음 4주 자동 반복 등록.
[설정]
5.3 매칭된 슬롯 상세
2026-05-15 (화) 19:30 - 20:00
─────────────────
회원 김OO (32세)
재예약: 4회차 (이전 멘토 = 본인)
운동 경력: 6개월
주요 목표: 체형 개선·근력
컨디션 메모: 주 2회 운동 안정
📋 직전 인계 (5/8, 박멘토):
"코어 약함, 데드 시 허리 보호 필요"
[세션 진입 (T-15분 알림)] [변경 신청]
5.4 매칭 알림 화면
📩 새 매칭 (3건)
──────────────────
🆕 5/15 (화) 19:30 - 김OO (4회차, 본인 이전 멘토)
🆕 5/15 (화) 20:00 - 이OO (첫 매칭)
🆕 5/16 (수) 19:00 - 박OO (2회차)
[전체 확인]
5.5 변경 신청
슬롯 변경 신청
──────────────────
대상: 5/15 (화) 19:30 (회원 김OO)
현재까지 남은 시간: 48시간 ← 48h 전이면 자유
사유:
[📌 부득이한 사유]
[📌 일정 변경]
[📌 기타]
[_____ 상세]
자동 처리:
- 48h 전 = 회원에게 알림 + 다른 멘토 자동 매칭
- 본인 등급 영향 ❌
[신청]
6h 이내 = 패널티 경고:
⚠️ 6시간 이내 취소
- 회원 회차 +1 보상 발급
- 멘토 등급 -1 (Top → Pro)
- 이번 격주 정산 -1세션 차감
정말 진행하시겠습니까?
[취소 신청] [뒤로]
6. 데이터 모델
type MentorBlockStatus = 'open' | 'assigned' | 'completed' | 'cancelled'
interface MentorBlock {
id: string
mentorId: string
startAt: string // 30분 단위 (정각 또는 30분)
status: MentorBlockStatus
assignedSessionId?: string
assignedAt?: string
cancelledAt?: string
cancellationReason?: string
penaltyApplied?: boolean // 6h 이내 취소 시 true
}
interface MentorRecurringSlot { // 반복 슬롯 설정
mentorId: string
weekday: 0 | 1 | 2 | 3 | 4 | 5 | 6
hour: number
minute: 0 | 30
active: boolean
}
interface MentorObligationStatus { // Phase 1 의무 슬롯
mentorId: string
period: string // 주 단위
requiredHours: number // 의무
registeredHours: number // 실제 등록
status: 'meeting' | 'shortage' | 'exceeded'
}
interface MentorCancellation {
id: string
mentorId: string
blockId: string
cancelledAt: string
cancelledAtRelativeToSession: 'before_48h' | '48h_to_6h' | 'within_6h'
reason: string
penaltyApplied: boolean
memberCompensationCredits: number // 회원에게 발급된 보상 회차
payoutDeduction: number // 정산 차감액
}
interface AssignedSessionPreview {
sessionId: string
startAt: string
member: {
id: string
name: string
age?: number
rebookCount: number // 본 멘토와의 이전 진행 수
experienceLevel?: string
goals?: string[]
}
aiRecommendation?: AIRecommendation
lastHandover?: { mentorId: string, mentorName: string, text: string, date: string }
}
7. API 통신
7.1 새 엔드포인트
GET /api/mentors/me/blocks?from=YYYY-MM-DD&to=YYYY-MM-DD
Response: MentorBlock[]
POST /api/mentors/me/blocks
Body: { startAt }
Response: MentorBlock
POST /api/mentors/me/blocks/bulk
Body: { weekday, hour, minute, weeks } // 반복 등록
Response: MentorBlock[]
DELETE /api/mentors/me/blocks/:id
Response: {
success: boolean,
cancellationCategory: 'before_48h' | '48h_to_6h' | 'within_6h',
penaltyApplied: boolean,
memberCompensation?: { credits: number }
}
GET /api/mentors/me/obligation
Response: MentorObligationStatus // Phase 1만
GET /api/mentors/me/today
Response: AssignedSessionPreview[]
GET /api/mentors/me/assignment-notifications?since=:timestamp
Response: { matches: AssignedSessionPreview[] }
7.2 응답 예시
// DELETE /api/mentors/me/blocks/block_xxx
{
"success": true,
"cancellationCategory": "48h_to_6h",
"penaltyApplied": false,
"memberCompensation": null,
"newMentorMatched": true // 회원에게 다른 멘토 자동 매칭됨
}
// 6h 이내일 경우
{
"success": true,
"cancellationCategory": "within_6h",
"penaltyApplied": true,
"memberCompensation": { "credits": 1 },
"payoutDeduction": 20000,
"tierImpact": "Pro → Verified (보류)"
}
8. 엣지 케이스
| 케이스 | 처리 |
|---|---|
| 멘토 동시 두 슬롯 등록 시도 (같은 시각) | 시스템이 차단 (1 슬롯 = 30분 = 1 회원) |
| 30분 이상 슬롯 (60분 한 회원에게) | 불가 — 30분 단위만 |
| 의무 슬롯 미달 (Phase 1 코어) | 인센티브 ↓ + 운영 매니저 통보 |
| 슬롯 변경 후 회원 매칭 못 찾음 | 그 회원은 자동 매칭 큐로 → 다른 멘토 시도 |
| 멘토가 회원 거부 시도 (등급 우려) | UI에서 차단 — 거부 기능 ❌ |
| 본사 의무 슬롯과 본인 일정 충돌 | 본사가 우선 (자동 등록 차단 가능) |
| 같은 시간에 두 회원 매칭됐는데 한 명 노쇼 | 다른 회원과는 정상 진행. 노쇼 회원은 회차 차감 |
| 멘토가 슬롯 오픈하지 않은 시간에 회원 요청 | 매칭 실패 → 다른 멘토 |
9. 측정 지표
| 지표 | 목표 |
|---|---|
| 슬롯 오픈 → 매칭 비율 | ≥ 70% |
| 멘토 취소율 (전체) | ≤ 5% |
| 6h 이내 취소 | ≤ 1% |
| 의무 슬롯 달성률 (Phase 1) | ≥ 95% |
| 이전 멘토 매칭 (회원의 고정 슬롯 우선) | ≥ 80% |
10. 구현 작업 분해
10.1 페이지 개편
src/pages/schedule-page.tsx— 30분 단위 그리드 재작성src/pages/notifications-page.tsx(신규) — 매칭 알림 모음
10.2 컴포넌트
src/components/SlotGrid.tsx— 30분 그리드 (요일·시간)src/components/RecurringSlotEditor.tsx— 반복 슬롯 설정src/components/CancellationModal.tsx— 변경 사유·룰 표시src/components/AssignedSessionCard.tsx— 매칭 슬롯 상세src/components/ObligationBadge.tsx— 의무 슬롯 진행률
10.3 서비스 / 스토어
src/services/schedule.ts— 슬롯 CRUD + 반복 등록src/services/notifications.ts— 매칭 알림src/store/usePartnerStore.ts— schedule·assignments·obligation
10.4 타입
packages/api-types/src/mentor-schedule.ts— 위 정의
| 2026-05-13 | 초안 |
| 2026-05-13 | 정책서 4개 cross-ref + 현재 코드 비교 + 5 시나리오 + 5 화면 + API·작업 분해 상세화 |