필라테스 공정 대기 예약 API 문서
1. 공통 기준
- 대상: 웹 서비스
- 회원 인증: 휴대폰 본인 확인 후 발급된 회원 인증 정보 사용
- 원장 인증: 원장 로그인 방식은 확인 필요이며, 인증된 원장만 자신의 기구 필라테스 스튜디오 데이터에 접근한다. (FR-001)
- 날짜·시각: 모든 날짜·시각은 시간대를 포함한 절대 시각으로 저장·응답한다. (NFR-004)
- 성공 응답:
2xx상태 코드와 결과 데이터를 반환한다. - 오류 응답 형식 예시:
{
"error": {
"code": "CLASS_FULL",
"message": "방금 다른 회원의 예약이 확정되어 자리가 마감되었습니다.",
"action": "대기 신청을 할 수 있습니다."
}
}
- 개인정보: 회원은 본인 정보와 본인 예약·대기 신청만 조회할 수 있다. 원장은 자신의 기구 필라테스 스튜디오에 등록된 회원·수업·기록만 조회·처리할 수 있다. (FR-001, NFR-007)
2. 원장 접근과 기구 필라테스 스튜디오 식별
원장 운영 화면 정보 조회 (FR-001)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 인증된 기구 필라테스 스튜디오 운영 화면에 들어가도록 한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/studio |
성공 응답
{
"studio": {
"id": "studio_001",
"name": "OO 필라테스"
},
"owner": {
"id": "owner_001",
"name": "김원장"
}
}
사용자가 이해할 수 있는 오류 상황
- 로그인이 필요합니다.
- 원장 권한이 없어 운영 화면을 볼 수 없습니다.
- 현재 선택한 기구 필라테스 스튜디오 정보를 찾을 수 없습니다.
- 다른 기구 필라테스 스튜디오의 정보에는 접근할 수 없습니다.
완료 조건
- 원장은 자신의 기구 필라테스 스튜디오에 속한 회원, 수업, 예약, 대기 신청, 회원권 이력만 조회한다.
3. 회원·회원권 초기 등록
회원과 회원권 등록 (FR-002, FR-017)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 기존 회원과 서비스 밖에서 판매한 회원권 정보를 등록한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/members |
요청값
{
"memberName": "홍길동",
"phoneNumber": "01012345678",
"membershipPass": {
"name": "20회 회원권",
"totalCount": 20,
"remainingCount": 18,
"startDate": "2026-09-01",
"endDate": "2026-12-31"
}
}
성공 응답
{
"member": {
"id": "member_001",
"name": "홍길동",
"phoneNumber": "01012345678"
},
"membershipPass": {
"id": "pass_001",
"name": "20회 회원권",
"totalCount": 20,
"remainingCount": 18,
"startDate": "2026-09-01",
"endDate": "2026-12-31"
},
"registeredAt": "2026-09-01T09:00:00+09:00"
}
사용자가 이해할 수 있는 오류 상황
- 이미 같은 휴대폰 번호로 등록된 회원이 있습니다.
- 잔여 횟수는 총 횟수보다 많을 수 없습니다.
- 회원권 시작일과 만료일을 다시 확인해 주세요.
- 회원 이름, 휴대폰 번호, 회원권 정보를 모두 입력해 주세요.
회원 정보와 회원권 수정 (FR-002, FR-017, FR-020)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 회원 정보 또는 회원권 정보를 수정하고 수정 이유를 남긴다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | PATCH /api/owner/members/{memberId} |
요청값
{
"memberName": "홍길동",
"membershipPass": {
"id": "pass_001",
"remainingCount": 19,
"endDate": "2027-01-31"
},
"reason": "원장 수기 기록 확인 후 잔여 횟수 조정"
}
성공 응답
{
"memberId": "member_001",
"updatedFields": ["membershipPass.remainingCount", "membershipPass.endDate"],
"adjustmentHistoryId": "adjustment_001",
"updatedAt": "2026-09-02T10:00:00+09:00"
}
사용자가 이해할 수 있는 오류 상황
- 수정 이유를 입력해 주세요.
- 수정할 회원 또는 회원권을 찾을 수 없습니다.
- 잔여 횟수 값이 올바르지 않습니다.
- 다른 기구 필라테스 스튜디오의 회원 정보는 수정할 수 없습니다.
회원별 회원권과 회원권 이력 조회 (FR-017, FR-019)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 회원의 회원권 잔여 횟수와 차감·복구·조정 이력을 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/members/{memberId}/membership-history |
요청값
- 경로값:
memberId - 선택 쿼리값:
from,to,type
성공 응답
{
"member": {
"id": "member_001",
"name": "홍길동"
},
"membershipPasses": [
{
"id": "pass_001",
"name": "20회 회원권",
"totalCount": 20,
"remainingCount": 17,
"startDate": "2026-09-01",
"endDate": "2026-12-31"
}
],
"histories": [
{
"id": "history_001",
"type": "cancellation_deduction",
"changeCount": -1,
"beforeRemainingCount": 18,
"afterRemainingCount": 17,
"reason": "12시간 이내 취소",
"processedBy": "owner_001",
"processedAt": "2026-09-10T14:00:00+09:00",
"sourceHistoryId": null
}
]
}
사용자가 이해할 수 있는 오류 상황
- 회원 정보를 찾을 수 없습니다.
- 이 회원의 회원권 이력을 볼 권한이 없습니다.
- 조회 기간 형식이 올바르지 않습니다.
4. 회원 휴대폰 본인 확인
인증번호 발송 (FR-003)
| 항목 | 내용 |
|---|---|
| 목적 | 등록된 회원의 휴대폰 번호로 인증번호를 문자 발송한다. |
| 인증 | 인증 불필요 |
| HTTP 방식·경로 | POST /api/member/phone-auth/request |
요청값
{
"phoneNumber": "01012345678",
"returnPath": "/classes",
"vacancyOfferToken": null
}
성공 응답
{
"requestId": "phone_auth_001",
"expiresAt": "2026-09-01T10:05:00+09:00",
"maskedPhoneNumber": "010-1234-5678"
}
사용자가 이해할 수 있는 오류 상황
- 등록되지 않은 휴대폰 번호입니다. 원장에게 회원 등록을 요청해 주세요.
- 인증번호를 너무 자주 요청했습니다. 잠시 후 다시 시도해 주세요.
- 문자 발송에 실패했습니다. 잠시 후 다시 요청해 주세요.
- 휴대폰 번호 형식을 확인해 주세요.
인증번호 확인 (FR-003)
| 항목 | 내용 |
|---|---|
| 목적 | 회원이 입력한 인증번호를 확인하고 회원용 화면 접근을 허용한다. |
| 인증 | 인증 불필요 |
| HTTP 방식·경로 | POST /api/member/phone-auth/verify |
요청값
{
"requestId": "phone_auth_001",
"verificationCode": "123456"
}
성공 응답
{
"member": {
"id": "member_001",
"name": "홍길동"
},
"authenticated": true,
"returnPath": "/classes"
}
사용자가 이해할 수 있는 오류 상황
- 인증번호가 맞지 않습니다.
- 인증번호 유효 시간이 지났습니다. 새 인증번호를 요청해 주세요.
- 인증번호 입력 가능 횟수를 초과했습니다. 잠시 후 다시 시도해 주세요.
- 인증 요청 정보를 찾을 수 없습니다.
5. 수업 등록과 정원 관리
수업 등록 (FR-004, UIR-009)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 수업명, 날짜·시각, 정원, 예약·대기 신청 가능 상태를 등록한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/classes |
요청값
{
"name": "기구 필라테스 그룹",
"startAt": "2026-09-10T19:00:00+09:00",
"endAt": "2026-09-10T19:50:00+09:00",
"capacity": 8,
"reservationAvailable": true,
"waitlistAvailable": true
}
성공 응답
{
"class": {
"id": "class_001",
"name": "기구 필라테스 그룹",
"startAt": "2026-09-10T19:00:00+09:00",
"endAt": "2026-09-10T19:50:00+09:00",
"capacity": 8,
"freeCancellationDeadlineAt": "2026-09-10T07:00:00+09:00",
"reservationAvailable": true,
"waitlistAvailable": true
}
}
사용자가 이해할 수 있는 오류 상황
- 정원은 5명에서 15명 사이로 입력해 주세요.
- 수업 종료 시각은 시작 시각보다 늦어야 합니다.
- 날짜와 시간을 입력해 주세요.
수업 수정 (FR-004, FR-016, UIR-009)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 수업 정보와 신청 가능 상태를 수정하고 대기 제안 진행 여부를 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | PATCH /api/owner/classes/{classId} |
요청값
{
"capacity": 10,
"reservationAvailable": true,
"waitlistAvailable": true,
"changeReason": "기구 추가 설치"
}
성공 응답
{
"class": {
"id": "class_001",
"capacity": 10,
"confirmedReservationCount": 8,
"waitlistCount": 2,
"activeVacancyOfferCount": 1
},
"notice": "수락 대기 중인 대기 제안 1건이 있습니다."
}
사용자가 이해할 수 있는 오류 상황
- 현재 예약 확정 인원보다 정원을 적게 설정할 수 없습니다.
- 수락 대기 또는 승인 대기 중인 대기 제안이 있어 변경 영향을 확인해 주세요.
- 이미 시작한 수업은 기본 정보 수정이 제한됩니다.
원장용 날짜별 수업·예약 인원·대기 현황 조회 (FR-004, FR-016, UIR-007)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 날짜별 수업과 예약·대기·빈자리 처리 현황을 한눈에 본다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/classes?date=2026-09-10 |
성공 응답
{
"date": "2026-09-10",
"classes": [
{
"id": "class_001",
"name": "기구 필라테스 그룹",
"startAt": "2026-09-10T19:00:00+09:00",
"capacity": 8,
"confirmedReservationCount": 7,
"pendingApprovalCount": 1,
"waitlistCount": 3,
"vacancyOfferStatus": "awaiting_response"
}
]
}
사용자가 이해할 수 있는 오류 상황
- 날짜 형식을 확인해 주세요.
- 조회할 수업이 없습니다.
- 운영 화면을 볼 권한이 없습니다.
6. 회원용 수업 조회·예약·대기 신청
회원용 수업 목록 조회 (FR-005, UIR-004)
| 항목 | 내용 |
|---|---|
| 목적 | 회원이 날짜별 수업, 예약 가능 여부, 대기 신청 가능 여부를 확인한다. |
| 인증 | 회원 인증 필요 |
| HTTP 방식·경로 | GET /api/member/classes?from=2026-09-01&to=2026-09-30 |
성공 응답
{
"classes": [
{
"id": "class_001",
"name": "기구 필라테스 그룹",
"startAt": "2026-09-10T19:00:00+09:00",
"endAt": "2026-09-10T19:50:00+09:00",
"capacity": 8,
"confirmedReservationCount": 7,
"reservationAvailable": true,
"waitlistAvailable": true,
"estimatedWaitlistOrder": null
}
]
}
사용자가 이해할 수 있는 오류 상황
- 휴대폰 본인 확인 후 수업 목록을 볼 수 있습니다.
- 조회 기간을 확인해 주세요.
- 이미 시작했거나 마감된 수업은 새 예약을 할 수 없습니다.
자리가 있는 수업 예약 (FR-006)
| 항목 | 내용 |
|---|---|
| 목적 | 회원이 정원에 여유가 있는 수업을 예약한다. |
| 인증 | 회원 인증 필요 |
| HTTP 방식·경로 | POST /api/member/classes/{classId}/reservations |
요청값
{}
성공 응답
{
"reservation": {
"id": "reservation_001",
"classId": "class_001",
"status": "confirmed",
"reservedAt": "2026-09-01T10:00:00+09:00",
"freeCancellationDeadlineAt": "2026-09-10T07:00:00+09:00"
},
"membershipPassStatus": {
"remainingCount": 18,
"deductionStatus": "확인 필요"
}
}
사용자가 이해할 수 있는 오류 상황
- 방금 다른 회원의 예약이 확정되어 자리가 마감되었습니다. 대기 신청을 할 수 있습니다.
- 이미 같은 수업을 예약했습니다.
- 이미 같은 수업에 대기 신청한 상태입니다.
- 회원권 횟수가 부족하거나 만료되었습니다. 일반 예약 처리 방식은 확인 필요입니다.
- 예약 가능한 시간이 지났습니다.
대기 신청과 대기 순번 부여 (FR-007)
| 항목 | 내용 |
|---|---|
| 목적 | 만석인 수업에 회원이 대기 신청하고 본인의 대기 순번을 확인한다. |
| 인증 | 회원 인증 필요 |
| HTTP 방식·경로 | POST /api/member/classes/{classId}/waitlist-requests |
요청값
{}
성공 응답
{
"waitlistRequest": {
"id": "waitlist_001",
"classId": "class_001",
"myWaitlistOrder": 2,
"totalWaitlistCount": 2,
"requestedAt": "2026-09-01T10:05:00+09:00"
}
}
사용자가 이해할 수 있는 오류 상황
- 이미 이 수업을 예약했습니다.
- 이미 이 수업에 대기 신청했습니다.
- 현재 자리가 생겨 수업 상태가 바뀌었습니다. 수업 정보를 다시 확인해 주세요.
- 대기 신청이 마감된 수업입니다.
내 예약·대기 현황 조회 (FR-008, UIR-005)
| 항목 | 내용 |
|---|---|
| 목적 | 회원이 본인의 예약, 승인 대기, 취소, 대기 순번, 수락 마감 시각을 확인한다. |
| 인증 | 회원 인증 필요 |
| HTTP 방식·경로 | GET /api/member/my-schedule |
성공 응답
{
"reservations": [
{
"id": "reservation_001",
"className": "기구 필라테스 그룹",
"startAt": "2026-09-10T19:00:00+09:00",
"status": "confirmed",
"freeCancellationDeadlineAt": "2026-09-10T07:00:00+09:00"
}
],
"waitlistRequests": [
{
"id": "waitlist_001",
"className": "기구 필라테스 그룹",
"myWaitlistOrder": 2,
"totalWaitlistCount": 3,
"vacancyOfferStatus": "awaiting_response",
"responseDeadlineAt": "2026-09-10T17:30:00+09:00"
}
]
}
사용자가 이해할 수 있는 오류 상황
- 휴대폰 본인 확인이 필요합니다.
- 변경되었거나 휴강된 수업입니다. 수업 상태를 확인해 주세요.
7. 예약 취소와 회원권 처리
예약 취소와 취소 사유 제출 (FR-009)
| 항목 | 내용 |
|---|---|
| 목적 | 회원이 모든 취소에서 취소 사유를 제출하고 예약을 취소한다. |
| 인증 | 회원 인증 필요 |
| HTTP 방식·경로 | POST /api/member/reservations/{reservationId}/cancellations |
요청값
{
"reasonType": "health",
"reasonDetail": "감기 증상이 있어 수업 참여가 어렵습니다."
}
reasonType 예시: late, health, personal, other
성공 응답
{
"cancellation": {
"id": "cancellation_001",
"reservationId": "reservation_001",
"cancelledAt": "2026-09-10T10:00:00+09:00",
"isWithinFreeCancellationDeadline": false,
"membershipProcessingStatus": "owner_action_required"
},
"vacancyProcessingStarted": true
}
사용자가 이해할 수 있는 오류 상황
- 취소 사유를 선택해 주세요.
- 이미 취소된 예약입니다.
- 처리 중인 취소 요청이 있습니다.
- 취소할 수 없는 수업 상태입니다.
- 승인 대기 예약을 취소하면 보류 중인 좌석도 함께 해제됩니다.
취소 횟수 차감 또는 미차감 처리 (FR-010)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 12시간 이내 취소에 대해 차감 또는 미차감을 결정하고 이유를 기록한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/cancellations/{cancellationId}/membership-processing |
요청값
{
"decision": "no_deduction",
"reason": "회원의 건강 사유 확인"
}
decision 값: deduct, no_deduction
성공 응답
{
"cancellationId": "cancellation_001",
"decision": "no_deduction",
"membershipHistory": {
"id": "history_010",
"type": "exception_restore",
"beforeRemainingCount": 17,
"afterRemainingCount": 18,
"sourceHistoryId": "history_009"
},
"processedAt": "2026-09-10T10:20:00+09:00"
}
사용자가 이해할 수 있는 오류 상황
- 처리 이유를 입력해 주세요.
- 무료 취소 마감 시각 이전 취소는 기본 미차감 처리됩니다.
- 이미 처리된 취소입니다.
- 복구할 기존 회원권 이력을 찾을 수 없습니다.
- 같은 취소에 대한 예외 복구가 이미 처리되었습니다.
8. 빈자리 제안과 순차 문자 안내
빈자리 발생에 따른 대기 제안 생성 (FR-011)
이 기능은 예약 취소, 승인 대기 좌석 해제, 원장 조정 등으로 빈자리가 생길 때 자동 실행한다.
| 항목 | 내용 |
|---|---|
| 목적 | 대기 순번이 가장 빠른 회원에게 빈자리를 제안한다. |
| 인증 | 시스템 처리 |
| HTTP 방식·경로 | POST /api/internal/classes/{classId}/vacancy-offers |
요청값
{
"vacancySource": "cancellation",
"sourceId": "cancellation_001"
}
성공 응답
{
"vacancyOffer": {
"id": "offer_001",
"waitlistRequestId": "waitlist_001",
"status": "awaiting_response",
"responseDeadlineAt": "2026-09-10T17:30:00+09:00"
},
"messageRequested": true
}
사용자가 이해할 수 있는 오류 상황
- 대기 신청한 회원이 없어 빈자리만 표시합니다.
- 이미 이 빈자리에 대한 수락 대기 또는 승인 대기 처리가 있습니다.
- 같은 회원에게 같은 수업의 대기 제안을 중복으로 만들 수 없습니다.
순차 문자 안내 발송 결과 저장 (FR-012)
| 항목 | 내용 |
|---|---|
| 목적 | 대기 제안의 문자 수락 링크 발송 결과를 기록하고 원장이 확인하게 한다. |
| 인증 | 시스템 처리 |
| HTTP 방식·경로 | POST /api/internal/vacancy-offers/{vacancyOfferId}/messages |
요청값
{
"messageType": "vacancy_offer",
"responseDeadlineAt": "2026-09-10T17:30:00+09:00"
}
성공 응답
{
"vacancyOfferId": "offer_001",
"message": {
"id": "message_001",
"status": "sent",
"requestedAt": "2026-09-10T16:30:00+09:00",
"providerMessageId": "provider_message_001"
}
}
사용자가 이해할 수 있는 오류 상황
- 문자 발송에 실패했습니다. 실패 코드와 재시도 횟수를 기록합니다.
- 문자 수신 번호를 확인할 수 없습니다.
- 재발송할지 다음 대기 회원에게 넘길지는 확인 필요입니다.
- 최종 발송 실패 상태는 원장 화면에서 확인할 수 있습니다.
응답 마감 처리와 다음 대기 회원 안내 (FR-013)
이 기능은 수락 대기 중인 대기 제안의 응답 마감 시각에 자동 실행한다.
| 항목 | 내용 |
|---|---|
| 목적 | 무응답 대기 제안을 만료 처리하고 다음 대기 순번 회원에게 안내한다. |
| 인증 | 시스템 처리 |
| HTTP 방식·경로 | POST /api/internal/vacancy-offers/{vacancyOfferId}/expire |
요청값
{}
성공 응답
{
"expiredVacancyOffer": {
"id": "offer_001",
"status": "expired",
"expiredAt": "2026-09-10T17:30:00+09:00"
},
"nextVacancyOffer": {
"id": "offer_002",
"status": "awaiting_response",
"responseDeadlineAt": "2026-09-10T17:40:00+09:00"
}
}
사용자가 이해할 수 있는 오류 상황
- 이미 수락·거절·만료 처리된 대기 제안입니다.
- 동시에 수락 요청이 들어온 경우 먼저 확정된 처리 결과를 적용합니다.
- 수업 시작 시각 이후 응답 마감 기준은 확인 필요입니다.
- 서비스 재시작 후에도 아직 처리되지 않은 응답 마감 건을 다시 확인합니다.
9. 빈자리 수락·거절과 원장 최종 예약 승인
문자 링크의 빈자리 제안 조회 (FR-014, UIR-006)
| 항목 | 내용 |
|---|---|
| 목적 | 회원이 문자 링크에서 수업 정보와 수락 가능 시간을 확인한다. |
| 인증 | 문자 링크 확인 후 필요 시 휴대폰 본인 확인 |
| HTTP 방식·경로 | GET /api/member/vacancy-offers/{offerToken} |
성공 응답
{
"vacancyOffer": {
"id": "offer_001",
"className": "기구 필라테스 그룹",
"startAt": "2026-09-10T19:00:00+09:00",
"responseDeadlineAt": "2026-09-10T17:30:00+09:00",
"status": "awaiting_response"
},
"requiresPhoneAuth": false
}
사용자가 이해할 수 있는 오류 상황
- 링크 유효 시간이 지났습니다.
- 이미 처리된 빈자리 제안입니다. 현재 처리 결과를 확인해 주세요.
- 이 링크는 다른 회원이 사용할 수 없습니다.
- 링크 정보가 올바르지 않습니다.
빈자리 수락 또는 거절 (FR-014)
| 항목 | 내용 |
|---|---|
| 목적 | 회원이 문자 링크에서 빈자리 수락 또는 이번 제안 거절을 선택한다. |
| 인증 | 회원 인증 필요 및 유효한 문자 링크 필요 |
| HTTP 방식·경로 | POST /api/member/vacancy-offers/{offerToken}/response |
요청값
{
"response": "accept"
}
response 값: accept, decline
성공 응답: 수락
{
"vacancyOfferId": "offer_001",
"response": "accept",
"reservationStatus": "pending_owner_approval",
"ownerApprovalRequired": true,
"notice": "원장 확인 후 예약이 최종 확정됩니다."
}
성공 응답: 거절
{
"vacancyOfferId": "offer_001",
"response": "decline",
"status": "declined",
"nextVacancyOfferStarted": true
}
사용자가 이해할 수 있는 오류 상황
- 응답 가능 시간이 지났습니다.
- 이미 응답한 빈자리 제안입니다.
- 다른 회원의 문자 링크로는 응답할 수 없습니다.
- 회원권 횟수가 부족하거나 만료되어도 수락은 가능하며 원장 확인 대상으로 표시합니다.
원장 최종 예약 승인 또는 반려 (FR-015, UIR-010)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 빈자리 수락 건의 회원권 상태, 예외 여부 등을 확인한 뒤 예약을 승인하거나 반려한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/vacancy-offers/{vacancyOfferId}/approval |
요청값
{
"decision": "approve",
"reason": "회원권 1회 잔여 확인"
}
decision 값: approve, reject
성공 응답
{
"vacancyOfferId": "offer_001",
"decision": "approve",
"reservation": {
"id": "reservation_002",
"status": "confirmed"
},
"seatHold": {
"status": "released"
},
"membershipProcessingStatus": "확인 필요"
}
사용자가 이해할 수 있는 오류 상황
- 이미 승인 또는 반려 처리된 요청입니다.
- 승인 대기 중인 좌석 보류 시간이 끝났습니다.
- 해당 수업의 정원이 이미 찼습니다.
- 회원권 횟수가 부족합니다. 승인 시 잔여 횟수를 음수로 허용할지, 먼저 회원권 정보를 조정할지는 확인 필요입니다.
- 원장 승인 대기 좌석의 보류 만료 시간과 미응답 처리 기준은 확인 필요입니다.
원장용 승인 대기 목록 조회 (FR-015, UIR-010)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 승인 대기 중인 빈자리 수락 건과 좌석 보류 상태를 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/vacancy-offers?status=pending_owner_approval |
성공 응답
{
"vacancyOffers": [
{
"id": "offer_001",
"memberName": "홍길동",
"className": "기구 필라테스 그룹",
"acceptedAt": "2026-09-10T17:10:00+09:00",
"membershipPassStatus": "insufficient",
"seatHoldExpiresAt": null
}
]
}
사용자가 이해할 수 있는 오류 상황
- 승인 대기 중인 요청이 없습니다.
- 운영 권한이 필요합니다.
10. 수업별 처리 과정과 출결·노쇼 관리
수업별 예약·대기 처리 과정 조회 (FR-016, UIR-002)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 수업별 예약, 취소, 대기 신청, 대기 제안, 문자 발송, 응답, 승인 과정을 시간순으로 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/classes/{classId}/activity |
성공 응답
{
"class": {
"id": "class_001",
"name": "기구 필라테스 그룹",
"startAt": "2026-09-10T19:00:00+09:00"
},
"activities": [
{
"occurredAt": "2026-09-10T16:20:00+09:00",
"type": "cancellation_created",
"memberName": "김회원",
"summary": "건강 사유로 예약을 취소했습니다."
},
{
"occurredAt": "2026-09-10T16:21:00+09:00",
"type": "vacancy_offer_sent",
"memberName": "홍길동",
"summary": "대기 순번 1번 회원에게 문자 안내를 발송했습니다."
}
]
}
사용자가 이해할 수 있는 오류 상황
- 수업 정보를 찾을 수 없습니다.
- 이 수업의 처리 기록을 볼 권한이 없습니다.
출결 상태 기록 (FR-018)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 수업 후 예약 회원의 출석, 지각 출석, 노쇼, 보류 상태를 기록한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/classes/{classId}/attendance |
요청값
{
"records": [
{
"reservationId": "reservation_001",
"attendanceStatus": "attended"
},
{
"reservationId": "reservation_002",
"attendanceStatus": "no_show",
"reason": "연락 없이 불참"
}
]
}
attendanceStatus 값: attended, late_attended, no_show, pending
성공 응답
{
"classId": "class_001",
"savedCount": 2,
"attendanceRecordedAt": "2026-09-10T20:00:00+09:00"
}
사용자가 이해할 수 있는 오류 상황
- 수업에 연결된 예약만 출결 처리할 수 있습니다.
- 출석 상태를 선택해 주세요.
- 이미 확정된 출결을 수정하려면 수정 이유를 남겨 주세요.
- 노쇼 횟수에 따른 대기 순번 제한 여부는 확인 필요입니다.
회원별 이용·예외·노쇼 기록 조회 (FR-018, FR-019, UIR-008)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 회원별 예약·취소·예외 승인·출결·노쇼 이력을 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/members/{memberId}/activity |
성공 응답
{
"member": {
"id": "member_001",
"name": "홍길동",
"noShowCount": 2
},
"summary": {
"confirmedReservationCount": 12,
"cancellationCount": 3,
"exceptionApprovalCount": 1,
"noShowCount": 2
},
"activities": [
{
"occurredAt": "2026-09-10T20:00:00+09:00",
"type": "no_show",
"className": "기구 필라테스 그룹",
"reason": "연락 없이 불참"
}
]
}
사용자가 이해할 수 있는 오류 상황
- 회원 정보를 찾을 수 없습니다.
- 다른 기구 필라테스 스튜디오의 회원 기록은 볼 수 없습니다.
11. 오류 수정·조정 이력
오류 수정 및 회원권 조정 처리 (FR-020)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 잘못된 예약·출결·회원권 처리 결과를 수정하고 원본 이력과 수정 이유를 남긴다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/adjustments |
요청값
{
"targetType": "membership_history",
"targetId": "history_001",
"adjustmentType": "restore_count",
"changeCount": 1,
"reason": "중복 차감 확인 후 복구"
}
성공 응답
{
"adjustment": {
"id": "adjustment_001",
"targetType": "membership_history",
"targetId": "history_001",
"sourceHistoryId": "history_001",
"changeCount": 1,
"reason": "중복 차감 확인 후 복구",
"processedAt": "2026-09-11T09:00:00+09:00"
}
}
사용자가 이해할 수 있는 오류 상황
- 수정 이유를 입력해 주세요.
- 수정 대상 기록을 찾을 수 없습니다.
- 이미 취소되거나 복구된 기록은 원본을 삭제하지 않고 새 조정 이력으로 처리합니다.
- 원본 이력 연결이 필요한 조정인데 연결 대상이 없습니다.
오류 수정·조정 이력 조회 (FR-020, UIR-011)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 오류 수정과 회원권 조정의 처리자, 시각, 전후 값을 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/adjustments |
선택 쿼리값
memberIdclassIdfromtotargetType
성공 응답
{
"adjustments": [
{
"id": "adjustment_001",
"targetType": "membership_history",
"targetId": "history_001",
"sourceHistoryId": "history_001",
"beforeValue": 17,
"afterValue": 18,
"reason": "중복 차감 확인 후 복구",
"processedBy": "owner_001",
"processedAt": "2026-09-11T09:00:00+09:00"
}
]
}
사용자가 이해할 수 있는 오류 상황
- 조회 기간을 확인해 주세요.
- 조정 이력이 없습니다.
- 운영 권한이 필요합니다.
12. 휴강 처리
수업 휴강 처리 (FR-021)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 수업을 휴강으로 변경하고 해당 수업의 예약·대기·대기 제안 상태를 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/classes/{classId}/cancellation |
요청값
{
"reason": "원장 건강 사유",
"memberNotificationRequired": true
}
성공 응답
{
"classId": "class_001",
"classStatus": "cancelled",
"affectedReservationCount": 7,
"affectedWaitlistCount": 3,
"activeVacancyOfferCount": 1,
"notice": "휴강에 따른 회원권 처리와 안내 기준은 운영 정책 설정이 필요합니다."
}
사용자가 이해할 수 있는 오류 상황
- 이미 휴강 처리된 수업입니다.
- 시작된 수업의 휴강 처리는 기록 확인이 필요합니다.
- 휴강 시 회원권 복구, 문자 안내, 승인 대기 좌석 해제 기준은 확인 필요입니다.
13. 운영 정책 설정
운영 정책 설정은 이어서 만들 범위다. 다만 현재 확정된 운영 규칙과 확인 필요 항목을 저장할 수 있도록 설계한다. (FR-022)
운영 정책 조회 (FR-022)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 기구 필라테스 스튜디오의 취소·대기·문자·휴강 기준을 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/operating-policy |
성공 응답
{
"freeCancellationHours": 12,
"waitlistResponseRules": {
"atLeastTwoHoursBeforeClassMinutes": 60,
"withinTwoHoursBeforeClassMinutes": 10
},
"policyStatus": {
"approvalSeatHoldMinutes": "확인 필요",
"messageFailureHandling": "확인 필요",
"generalReservationInsufficientPassHandling": "확인 필요",
"classStartResponseDeadlineHandling": "확인 필요"
}
}
사용자가 이해할 수 있는 오류 상황
- 운영 정책을 볼 권한이 없습니다.
- 아직 설정되지 않은 정책 항목이 있습니다.
운영 정책 변경 (FR-022)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 확정된 운영 정책을 변경하고 변경 이력을 남긴다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | PATCH /api/owner/operating-policy |
요청값
{
"approvalSeatHoldMinutes": 30,
"messageFailureHandling": "owner_review",
"classStartResponseDeadlineHandling": "limit_to_class_start",
"changeReason": "시험 운영 후 기준 확정"
}
성공 응답
{
"updatedPolicy": {
"approvalSeatHoldMinutes": 30,
"messageFailureHandling": "owner_review",
"classStartResponseDeadlineHandling": "limit_to_class_start"
},
"updatedAt": "2026-09-15T09:00:00+09:00"
}
사용자가 이해할 수 있는 오류 상황
- 변경 이유를 입력해 주세요.
- 이미 진행 중인 대기 제안에는 새 정책을 바로 적용할 수 없습니다.
- 확정되지 않은 정책값입니다.
14. 스튜디오용 월 구독료 결제
회원의 회원권 결제·충전은 서비스 밖에서 처리한다. 이 항목은 원장이 서비스 이용료를 결제하는 기능이며 이어서 만들 범위다. (FR-023)
구독 상태 조회 (FR-023)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 현재 월 구독 상태와 다음 결제 정보를 확인한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | GET /api/owner/subscription |
성공 응답
{
"subscription": {
"status": "inactive",
"planName": null,
"nextBillingDate": null,
"paymentMethod": null
},
"pricing": "확인 필요"
}
사용자가 이해할 수 있는 오류 상황
- 구독 정보를 찾을 수 없습니다.
- 결제 상태를 확인할 수 없습니다. 잠시 후 다시 시도해 주세요.
월 구독 결제 시작 또는 변경 (FR-023)
| 항목 | 내용 |
|---|---|
| 목적 | 원장이 기구 필라테스 스튜디오용 월 구독료 결제를 시작하거나 결제 수단을 변경한다. |
| 인증 | 원장 인증 필요 |
| HTTP 방식·경로 | POST /api/owner/subscription/checkout |
요청값
{
"planId": "monthly_standard",
"paymentMethodId": "결제업체_결제수단_ID"
}
성공 응답
{
"subscription": {
"status": "active",
"planId": "monthly_standard",
"nextBillingDate": "2026-10-01"
}
}
사용자가 이해할 수 있는 오류 상황
- 월 구독 가격과 결제 업체는 확인 필요입니다.
- 결제 수단을 확인할 수 없습니다.
- 결제에 실패했습니다. 결제 수단을 확인해 주세요.
- 결제 실패 시 이용 제한 기준은 확인 필요입니다.
15. 화면과 API 연결
| 화면 | 연결 API | 관련 요구사항 |
|---|---|---|
| 회원 화면 | 회원용 수업 목록, 내 예약·대기 현황, 예약, 대기 신청, 취소, 빈자리 수락 API | UIR-001, FR-005~FR-009, FR-014 |
| 수업별 화면 | 날짜별 수업 현황, 수업별 처리 과정, 출결 API | UIR-002, FR-004, FR-016, FR-018 |
| 회원용 휴대폰 인증 화면 | 인증번호 발송·확인 API | UIR-003, FR-003 |
| 회원용 수업 목록·예약·대기 신청 화면 | 수업 목록, 예약, 대기 신청 API | UIR-004, FR-005~FR-007 |
| 회원용 내 예약·대기 순번·취소 화면 | 내 예약·대기 현황, 예약 취소 API | UIR-005, FR-008~FR-010 |
| 문자 링크에서 여는 빈자리 수락 화면 | 빈자리 제안 조회, 수락·거절 API | UIR-006, FR-014 |
| 원장용 날짜별 수업·예약 인원·대기 현황 화면 | 날짜별 수업 현황, 수업별 처리 과정 API | UIR-007, FR-004, FR-011~FR-016 |
| 원장용 회원별 회원권 횟수·취소 예외·노쇼 기록 화면 | 회원·회원권 이력, 취소 처리, 출결, 회원 활동 조회 API | UIR-008, FR-010, FR-017~FR-019 |
| 원장용 수업 등록·수정 화면 | 수업 등록·수정 API | UIR-009, FR-004, FR-021 |
| 원장용 빈자리 수락 승인 화면 | 승인 대기 목록, 최종 승인·반려 API | UIR-010, FR-015 |
| 원장용 오류 수정·조정 이력 화면 | 오류 수정, 조정 이력 조회 API | UIR-011, FR-020 |
| 원장용 회원·회원권 초기 등록 화면 | 회원·회원권 등록·수정 API | UIR-012, FR-002, FR-017 |
16. 구현 기준
정원·중복 처리 (NFR-002)
- 예약 확정과 원장 최종 예약 승인은 처리 시점에 정원을 다시 확인한다.
- 같은 회원은 같은 수업에 예약과 대기 신청을 동시에 가질 수 없다.
- 같은 빈자리에 수락 대기 또는 승인 대기 대기 제안은 한 건만 존재해야 한다.
- 취소, 수락, 응답 마감이 동시에 발생해도 하나의 최종 상태만 저장한다.
예약 작업과 장애 복구 (NFR-003)
- 응답 마감 처리, 문자 발송 결과 확인, 다음 대기 회원 안내는 서비스 재시작 후에도 처리되지 않은 건을 찾아 다시 실행한다.
- 문자 발송 요청, 대기 제안 생성, 예약 확정 결과는 중복 실행되어도 같은 결과가 반복 저장되지 않게 한다.
- 대기 순번, 대기 제안, 예약 상태 변경은 처리 시각과 함께 남긴다.
보안과 개인정보 (NFR-005, NFR-006, NFR-007)
- 인증번호는 유효 시간, 입력 횟수 제한, 재전송 제한을 둔다.
- 문자 수락 링크는 특정 회원과 특정 대기 제안에만 연결한다.
- 문자 수락 링크는 응답 마감 시각 이후 사용할 수 없다.
- 회원 화면에는 다른 회원의 이름, 휴대폰 번호, 대기 신청 시각을 표시하지 않는다.
- 원장은 자신이 관리하는 기구 필라테스 스튜디오 데이터에만 접근한다.
원본 이력과 회원권 데이터 일치 (NFR-008, NFR-009)
- 회원권 차감, 예외 복구, 오류 수정은 기존 기록을 삭제하거나 덮어쓰지 않고 새 회원권 이력으로 남긴다.
- 예외 복구와 오류 수정은 반드시 대상 원본 이력을 연결한다.
- 각 회원권의 잔여 횟수는 회원권 이력의 변경값 합계와 일치해야 한다.
문자 발송 추적과 조회 성능 (NFR-010, NFR-012)
- 순차 문자 안내마다 발송 요청 시각, 메시지 ID, 발송 상태, 실패 코드, 재시도 횟수를 저장한다.
- 원장 화면은 날짜별 수업 현황, 회원별 이력, 수업별 처리 과정을 실제 운영 중 확인 가능한 속도로 조회할 수 있어야 한다.
- 대량 이력 조회는 기간과 회원 조건으로 나누어 조회할 수 있어야 한다.
모바일 사용성과 접근성 (NFR-001, NFR-011)
- 회원 화면은 휴대폰 웹 환경에서 한 손으로 예약, 취소, 대기 신청, 빈자리 수락을 완료할 수 있어야 한다.
- 중요한 상태는 색상만으로 구분하지 않고 텍스트로 함께 표시한다.
- 버튼에는 명확한 행동 문구를 사용한다.
예:예약하기,대기 신청하기,빈자리 수락,이번 제안 거절,원장 승인 - 응답 마감 시각, 무료 취소 마감 시각, 예약 확정 여부는 날짜와 시각을 함께 표시한다.