출처: 약나루 API Swagger UI (http://118.131.251.206:39080/swagger-ui/index.html) 의 OpenAPI 3.1 문서 /v3/api-docs, 2026.09.23 스냅샷. 설명문은 Swagger 원문을 그대로 옮겼고, 이 문서에서 덧붙인 해석은 [결론]·콜아웃에만 있음. 서버 주소는 실증(dev) 환경이며 개발용(dev) 태그는 운영(prod)에 존재하지 않음.
/api/v1 로 시작 (헬스 체크 / 제외)405 COMMON_005POST …/delete · 수정 POST …/update · 상태 변경 POST …/update-status 처럼 동사 접미사로 구분{board}(faq | qna) 뿐/detail?id=, /detail?code=), 수정·삭제는 본문의 식별자 필드(prescriptionId, addressId, pharmacyCode, postId 등)page(0부터) + perPage → Spring Data Page 형태(content, totalElements, totalPages, number, size, last…). 일부 앱 목록은 배열2026-09-11, 2026-09-11T10:15:30.123), 금액은 숫자(원){"success": true, "data": …}
// data 가 없는 작업은 {"success": true} 만{"success": false,
"error": {"code": "AUTH_001", "message": "인증이 필요합니다."}}| code | HTTP | 의미 |
|---|---|---|
| COMMON_001 | 400 | 잘못된 요청(필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) |
| COMMON_002 | 500 | 서버 내부 오류 |
| COMMON_003 | 404 | 리소스 없음 / 존재하지 않는 경로 |
| COMMON_004 | 500 | 메일 발송 실패(임시 비밀번호) |
| COMMON_005 | 405 | 지원하지 않는 메서드(PATCH/PUT/DELETE) |
| AUTH_001 | 401 | 인증 필요(토큰 없음) |
| AUTH_002 | 401 | 아이디 또는 비밀번호 불일치 |
| AUTH_003 | 401 | 토큰 만료 |
| AUTH_004 | 401 | 유효하지 않은 토큰 |
| AUTH_005 | 403 | 권한 없음(역할 부족, 다른 종류 토큰, 타인 자원, 정지·검토대기 계정) |
| MEMBER_001 | 404 | 회원 없음 |
| MEMBER_002 | 409 | 이미 가입된 이메일 |
| MEMBER_003 | 409 | 이미 가입된 본인인증(DI) |
| MEMBER_004 | 403 | 탈퇴한 회원/계정 |
| MEMBER_005 | 400 | 추천인 코드 무효 |
둘 다 Authorization: Bearer {accessToken} 헤더로 보내며, access 토큰 30분 / refresh 토큰 14일. 서로 다른 종류의 토큰으로 호출하면 403 AUTH_005.
| 토큰 | 발급 | userType / role | 사용처 |
|---|---|---|---|
| 앱 회원 토큰 | POST /api/v1/auth/login | USER / USER | 앱의 회원 API 에만 사용. 관리자 API(/api/v1/admin/**)에는 쓸 수 없음 |
| 관리자 토큰 | POST /api/v1/admin/auth/login | ADMIN / SYSTEM_ADMIN(운영자) · PHARMACY_ADMIN(약사) | 관리자 API + 일부 관리자 전용 오퍼레이션(앱 설정 갱신·푸시 발송·자격 승인/반려). 약사는 처방전·주문·매출·대시보드에서 자기에게 매핑된 약국 데이터만 조회(백엔드 scope 자동) |
처방전 1건 = 주문 1건. 앱은 POST /api/v1/prescriptions 로 접수(01)하고, 이후 상태 전이는 약사(관리자웹 POST /api/v1/admin/prescriptions/update)와 회원(POST /api/v1/prescriptions/update-status)이 나눠 수행함. 상태 변경 시 회원에게 FCM 푸시가 자동 발송됨.
단계별 진입 시각은 readyAt(02) · paidAt(04) · preparedAt(05) · inTransitAt(06) · deliveredAt(07) · pickedUpAt(010) 로 PrescriptionView 에 기록됨. 수령 방식 receiveType: onLine 택배배송 / offLine 방문수령.
| 대상 | 코드 |
|---|---|
| 약 배송 자격 | I 심사중 → S 승인(택배 이용 가능) / R 반려(재신청 가능). 자격 유형 ltc65plus 65세 이상 장기요양등급자 · disabled 장애인 · infectiousDisease 감염병 환자 · rareDisease 희귀질환자 |
| 회원 상태 | ACTIVE 정상 / DORMANT 휴면 / SUSPENDED 정지 / WITHDRAWN 탈퇴 |
| 관리자 계정 | PENDING 검토대기(로그인 차단) / ACTIVE / SUSPENDED / WITHDRAWN |
| 건강샵 주문 | PAID 결제 완료 → SHIPPING 배송 중 → DELIVERED 배송 완료 (주문번호 SO-YYYYMMDD-###, 상품 코드 HP-###) |
| Q&A | WAITING 답변대기 / ANSWERED 답변완료 (응답은 한글 라벨) |
| 앱 설정 플래그 | up_* 강제 업데이트 · agree_* 약관 재동의 · popup_* 팝업 · server_* 서버 점검 — 값은 yes/no |
화면 ID 는 앱 화면기획서·관리자웹 화면기획서와 동일함.
| 흐름 | 화면 | 호출 순서 |
|---|---|---|
| 앱 부팅 → 로그인 | Loading → A-001 로그인 | GET /app/setting?platform= → POST /auth/login → POST /push/subscribe(FCM) · 만료 시 POST /auth/refresh |
| 회원가입 | A-010 약관 → A-020 정보 입력 | POST /members/check-id · /check-email · /check-di(NICE DI) · /check-recommend → POST /members/signup → POST /members/me/update-push |
| 처방전 접수 (택배) | O-001 → O-010 배송지 → P-001 약국 → P-020 촬영 → P-025 확인 | GET /eligibility/latest(택배 가능 판단) → GET /addresses · POST /pharmacies/check-delivery → GET /pharmacies?gpsX&gpsY → POST /prescriptions/upload-image → POST /prescriptions/qr-callback(OCR 결과) → POST /prescriptions(01 발송) |
| 약사 조제·배송 | AW-110 처방전 관리 · AW-111 크게보기 | GET /admin/prescriptions → GET /admin/prescriptions/detail?id= → GET /admin/drug-master/lookup?code= · GET /admin/substitute-medicines/lookup → POST /admin/prescriptions/update-partner-info(OCR 보정) → POST /admin/prescriptions/update(02 조제가능·약제비 → 05/06 · 송장) |
| 회원 결제·수령 | O-050 주문 내역 → O-040 상세 | GET /orders → GET /orders/detail?id= → POST /prescriptions/update-status(04 결제완료 / 010 수령완료) |
| 약 배송 자격 | D-001 자격 신청 · AW-140 심사 | POST /eligibility/documents?documentTypes=(multipart) → 관리자 GET /admin/eligibility → POST /admin/eligibility/approve / /reject → 회원 푸시 |
| 건강샵 주문 | SH-001 → SH-003 장바구니 → SH-004 주문 확인 → SH-005 토스 결제 | GET /shop/products · GET /shop/settings(배송비 정책) → 토스 결제창(WebView) → POST /shop/orders/create → 관리자 POST /admin/shop/orders/update-status(PAID→SHIPPING→DELIVERED) → GET /shop/orders |
| 약사 가입·승인 | AW-001 → /signup · AW-160 약국 관리 | GET /pharmacist/check-id → POST /pharmacist/signup(PENDING + 약국 자동 생성) → 운영자 POST /admin/pharmacies/approve / /reject → POST /admin/auth/login |
| 게시판 | N-001 공지 · N-020 FAQ · N-030 문의 / AW-300~330 | 앱 GET /bbs/notices · /faqs · /faq-categories · POST /bbs/qnas ↔ 관리자 POST /admin/bbs/notices · /faqs · /qnas/answer · /{board}-categories/create |
앱(React Native) 회원용 + 공개 API. 앱 화면 ID 와 소스 파일명은 Swagger 설명 원문 그대로임.
서버 기동 확인용. 배포 스크립트나 로드밸런서가 호출하며 인증이 필요 없다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | / | 서버 상태 확인 | 로그인 불필요 |
서비스명, 상태(UP), 서버 현재 시각을 돌려준다. DB 연결은 확인하지 않으며(그건 /actuator/health), 프로세스가 요청을 받는지만 본다. 로그인 불필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 회원 로그인·토큰 갱신·로그아웃. 여기서 발급한 토큰은 회원용(userType=USER)이며 관리자 API(/api/v1/admin/**)에는 쓸 수 없다. 모두 로그인 없이 호출한다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/auth/login | 회원 로그인 | 로그인 불필요 |
| POST | /api/v1/auth/logout | 로그아웃 | 로그인 불필요 |
| POST | /api/v1/auth/refresh | 토큰 갱신 | 로그인 불필요 |
앱 로그인 화면(SignIn)과 생체인증/PIN 재로그인(BiometricAuth, PinInput)에서 호출한다. 아이디(memId)와 비밀번호(memPass)를 검증해 access 토큰(30분)과 refresh 토큰(14일), 내 정보(myInfo)를 함께 돌려준다. 아이디·비밀번호 불일치는 AUTH_002, 탈퇴 회원은 MEMBER_004. 로그인 불필요.
application/json — LoginRequest회원(RN 앱) 로그인 요청 — POST /api/v1/auth/login
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 회원 로그인 아이디 — 회원가입(POST /api/v1/members/signup) 시 지정 예: hong1234 |
| memPass | string | 필수 | 비밀번호 (평문, TLS 구간 전송) 예: ******** |
object (로그인 성공)
{
"success": true,
"data": {
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMiIsInVzZXJUeXBlIjoiVVNFUiJ9.xxxxx",
"refreshToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMiIsInR5cCI6InJlZnJlc2gifQ.yyyyy",
"expiresIn": 1800,
"myInfo": {
"id": 12,
"memId": "hong123",
"memEmail": "hong@example.com",
"memName": "홍길동",
"memBirth": "1990-01-15",
"memGender": "1",
"memTel": "010-1234-5678",
"memPush": "Y",
"memState": "ACTIVE",
"roles": [
"USER"
]
}
}
}오류 응답: 401 아이디 또는 비밀번호 불일치 · 403 탈퇴한 회원 · 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
서버는 stateless JWT 라 아무 것도 저장하지 않고 성공만 돌려준다. 앱은 이 호출 후 로컬 토큰을 지우고, 기기 푸시를 끊으려면 /api/v1/push/unsubscribe 를 함께 호출한다. 로그인 불필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 네트워크 계층이 access 토큰 만료(401)를 받으면 자동으로 호출한다. refresh 토큰을 검증해 새 access/refresh 토큰 쌍과 내 정보를 다시 발급한다. 위조되었거나 만료된 refresh 토큰은 AUTH_004. 로그인 불필요(본문 refreshToken 만 사용).
application/json — RefreshRequest회원 토큰 갱신 요청 — POST /api/v1/auth/refresh
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| refreshToken | string | 필수 | 갱신 토큰 — POST /api/v1/auth/login 응답의 refreshToken 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJob25nMTIzNCIsInR5cCI6InJlZnJlc2gifQ.7LmP… |
{"success":true,"data":…} — data: TokenResponse (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 회원가입·중복확인·비밀번호 재설정(로그인 불필요)과 내 정보 조회/수정, 비밀번호 변경, 광고 수신동의, 탈퇴(회원 토큰 필요).
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/members/check-di | 본인인증 DI 중복 확인 | 로그인 불필요 |
| POST | /api/v1/members/check-email | 이메일 중복 확인 | 로그인 불필요 |
| POST | /api/v1/members/check-id | 회원 아이디 중복 확인 | 로그인 불필요 |
| POST | /api/v1/members/check-recommend | 추천인 코드 유효 확인 | 로그인 불필요 |
| GET | /api/v1/members/me | 내 정보 조회 | 회원 토큰 |
| POST | /api/v1/members/me/register-fcm | FCM 토큰 회원 레코드에 저장 | 회원 토큰 |
| POST | /api/v1/members/me/update | 내 정보 수정 | 회원 토큰 |
| POST | /api/v1/members/me/update-password | 비밀번호 변경 | 회원 토큰 |
| POST | /api/v1/members/me/update-push | 광고성 푸시 수신동의 설정 | 회원 토큰 |
| POST | /api/v1/members/me/withdraw | 회원 탈퇴 | 회원 토큰 |
| POST | /api/v1/members/password | 비밀번호 재설정 (임시 비밀번호 메일) | 로그인 불필요 |
| POST | /api/v1/members/signup | 회원가입 | 로그인 불필요 |
NICE 본인인증을 마친 뒤 그 DI(memDi)로 이미 가입된 회원이 있는지 확인한다. 가입 가능하면 {available:true}. 로그인 불필요.
application/json — CheckDiRequest본인인증 DI 중복 확인 요청 — POST /api/v1/members/check-di (이미 가입된 DI 인지 확인)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memDi | string | 필수 | 본인인증(NICE) DI 값 예: MC0GCCqGSIb3DQIJAyEA3f9a… |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 회원가입 화면과 내 정보 수정 화면(EditProfile)에서 호출한다. 사용 가능하면 {available:true}. 로그인 불필요.
application/json — CheckEmailRequest이메일 중복 확인 요청 — POST /api/v1/members/check-email
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memEmail | string | 필수 | 확인할 이메일 예: hong@example.com |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 회원가입 정보 입력 화면(SignUpInfo)의 중복확인 버튼. 사용 가능하면 {available:true}, 빈 값이면 false. 로그인 불필요.
application/json — CheckIdRequest아이디 중복 확인 요청 — POST /api/v1/members/check-id
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 확인할 로그인 아이디 예: hong1234 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 회원가입 정보 입력 화면(SignUpInfo)에서 추천인 코드를 입력했을 때 호출한다. 코드를 회원번호로 환산해 해당 회원이 존재하면 {valid:true}. 숫자가 아닌 코드는 서버 오류(COMMON_002)가 나므로 앱에서 숫자만 보낸다. 로그인 불필요.
application/json — CheckRecommendRequest추천인 코드 확인 요청 — POST /api/v1/members/check-recommend
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| code | string | 필수 | 추천인 코드 (숫자) — 97593712 − 추천인 회원 PK 로 생성, 해당 회원 존재 시 valid=true 예: 97593709 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 더보기(More)·내 정보 수정(EditProfile) 화면에서 호출한다. 로그인 응답의 myInfo 와 같은 형태. 회원 토큰 필요.
object (조회 성공)
{
"success": true,
"data": {
"id": 12,
"memId": "hong123",
"memEmail": "hong@example.com",
"memName": "홍길동",
"memBirth": "1990-01-15",
"memGender": "1",
"memTel": "010-1234-5678",
"memPush": "Y",
"memState": "ACTIVE",
"roles": [
"USER"
]
}
}{"success":true,"data":…} — data: MemberInfo (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
회원 레코드에 최신 FCM 토큰을 보관한다. 실제 푸시 발송 대상은 /api/v1/push/subscribe 로 등록한 구독 정보를 기준으로 고르므로, 앱은 subscribe 를 반드시 함께 호출해야 한다. 회원 토큰 필요.
application/json — FcmTokenRequestFCM 토큰 등록 요청 — POST /api/v1/members/me/register-fcm
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fcmToken | string | 필수 | Firebase Cloud Messaging 디바이스 토큰 예: dXk9f3…:APA91bH… |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 내 정보 수정 화면(EditProfile)에서 호출한다. 이메일·전화·우편번호·주소만 바꿀 수 있고 null 로 보낸 항목은 유지된다. 이메일을 바꾸면 다른 회원과 중복인지 검사해 MEMBER_002 로 거절한다. 회원 토큰 필요.
application/json — UpdateProfileRequest회원 프로필 수정 요청 — POST /api/v1/members/me/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memEmail | string | - | 이메일 — null = 미변경 예: hong@example.com |
| memTel | string | - | 휴대폰 번호 — null = 미변경 예: 010-1234-5678 |
| memZipcode | string | - | 우편번호 (5자리) — null = 미변경 예: 48058 |
| memAddr1 | string | - | 기본 주소 — null = 미변경 예: 부산광역시 해운대구 센텀중앙로 79 |
| memAddr2 | string | - | 상세 주소 — null = 미변경 예: 101동 1203호 |
{"success":true,"data":…} — data: MemberInfo (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 비밀번호 변경 화면(ChangePassword)에서 호출한다. 현재 비밀번호(oldPass)가 맞아야 하며 틀리면 AUTH_002. 새 비밀번호는 8~64자. 회원 토큰 필요.
application/json — ChangePasswordRequest회원 비밀번호 변경 요청 — POST /api/v1/members/me/update-password
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| oldPass | string | 필수 | 현재 비밀번호 예: ******** |
| newPass | string | 필수 | 새 비밀번호 (8~64자) 예: ******** |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 더보기(More)의 수신동의 토글과 회원가입 직후(SignUpInfo)에 호출한다. memPush 는 Y 또는 N. 이 값은 마케팅 수신 여부만 기록하며 주문·심사 결과 같은 서비스 푸시 발송을 막지는 않는다. 회원 토큰 필요.
application/json — SetPushAgreeRequest푸시 수신 동의 변경 요청 — POST /api/v1/members/me/update-push
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memPush | string | 필수 | 푸시 수신 동의 — Y 동의 / N 거부 예: Y |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 탈퇴 확인 화면(WithdrawConfirm)에서 호출한다. 회원 상태를 WITHDRAWN 으로 바꾸고 soft delete 처리하며, 이후 로그인은 MEMBER_004 로 거절된다. 되돌릴 수 없다. 회원 토큰 필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 비밀번호 찾기 화면(ResetPassword)에서 호출한다. 아이디(memId)와 등록 이메일(memEmail)이 일치하면 12자 임시 비밀번호로 바꾸고 그 이메일로 발송한다. 없는 아이디는 MEMBER_001, 이메일 불일치는 AUTH_002, 메일 발송 실패 시 비밀번호 변경도 롤백되고 COMMON_004. 로그인 불필요.
application/json — ResetPasswordRequest회원 비밀번호 찾기 요청 — POST /api/v1/members/password (아이디+이메일 일치 시 임시 비밀번호 메일 발송)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 로그인 아이디 예: hong1234 |
| memEmail | string | 필수 | 계정에 등록된 이메일 — 아이디와 일치해야 발송 예: hong@example.com |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 회원가입 정보 입력 화면(SignUpInfo)에서 호출한다. 이메일 중복은 MEMBER_002, 본인인증 DI 중복은 MEMBER_003 으로 거절되며, 아이디 중복은 사전에 check-id 로 확인해야 한다. 현재는 memId/memPass/memEmail/memName 만 저장되고 생년월일·성별·전화·추천인은 저장되지 않으므로 필요하면 가입 후 내 정보 수정으로 보완한다. 가입 즉시 로그인과 같은 토큰 쌍을 돌려준다. 로그인 불필요.
application/json — SignUpRequest회원가입 요청 — POST /api/v1/members/signup
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 로그인 아이디 (4~64자, 중복 불가 — POST /api/v1/members/check-id 로 사전 확인) 예: hong1234 |
| memPass | string | 필수 | 비밀번호 (8~64자) 예: ******** |
| memEmail | string | 필수 | 이메일 (중복 불가 — POST /api/v1/members/check-email 로 사전 확인) 예: hong@example.com |
| memName | string | 필수 | 회원 이름 예: 홍길동 |
| memBirth | string | - | 생년월일 (YYYY-MM-DD) 예: 1960-05-20 |
| memGender | string | - | 성별 코드 — 0 남성 / 1 여성 예: 0 |
| memTel | string | - | 휴대폰 번호 예: 010-1234-5678 |
| memDi | string | - | 본인인증(NICE) DI 값 — 중복 가입 차단 키, POST /api/v1/members/check-di 로 사전 확인 예: MC0GCCqGSIb3DQIJAyEA3f9a… |
| memRecommend | integer | - | 추천인 회원 PK (97593712 − 추천인 코드) — 현재 서버에서 저장하지 않는 예약 필드 예: 3 |
{"success":true,"data":…} — data: TokenResponse (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 부팅 시 읽는 플랫폼별 운영 플래그. 강제 업데이트(up_*), 약관 재동의(agree_*), 팝업(popup_*), 서버 점검(server_*) 4종 차단 모달의 트리거. 조회는 공개, 갱신은 SYSTEM_ADMIN 토큰 전용.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/app/setting | 앱 부팅 설정 조회 | 로그인 불필요 |
앱 로딩 화면(Loading)이 시작할 때마다 호출한다. platform 은 android 또는 ios(그 외는 COMMON_001). 응답 키는 RN 호환을 위해 snake_case 이며 up_bool/agree_bool/popup_bool/server_bool 값에 따라 앱이 차단 모달을 띄운다. 해당 플랫폼 행이 없으면 모든 플래그가 꺼진 기본 행을 자동 생성해 돌려준다. 로그인 불필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| platform | query | string (기본 android) | - | 플랫폼: android | ios 예: android |
object (조회 성공)
{
"success": true,
"data": {
"platform": "android",
"up_bool": "yes",
"up_build": 120,
"up_img": "/uploads/setting/update.png",
"up_img_width": 300,
"up_img_height": 400,
"agree_bool": "no",
"agree_no": 3,
"popup_bool": "no",
"server_bool": "no"
}
}{"success":true,"data":…} — data: AppSettingView (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 약국 찾기 화면용 공개 API. 약국 검색·상세와 비배송(산간) 지역 확인. 로그인 없이 호출 가능.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/pharmacies | 약국 검색 | 로그인 불필요 |
| POST | /api/v1/pharmacies/check-delivery | 비배송 지역 확인 | 로그인 불필요 |
| GET | /api/v1/pharmacies/detail | 약국 상세 | 로그인 불필요 |
앱 약국 찾기 화면에서 호출한다. gpsX(경도)와 gpsY(위도)를 함께 주면 거리순으로 정렬되고 각 항목의 distance(미터)가 채워지며, 없으면 이름순. keyword 는 약국명 검색, deliveryYn=Y 면 배송 가능 약국만. effectiveStatus 는 요일별 영업시간과 현재 시각(KST)으로 계산한 실효 상태(영업중/준비중)이며 화면 표시는 이 값을 쓴다. 로그인 불필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| gpsX | query | number | - | 현재 위치 경도(longitude). gpsY 와 함께 줘야 거리순 정렬 예: 127.0276 |
| gpsY | query | number | - | 현재 위치 위도(latitude) 예: 37.4979 |
| keyword | query | string | - | 약국명 검색어(부분 일치) 예: 약나루 |
| deliveryYn | query | string | - | 배송 가능 약국만 조회하려면 Y 예: Y |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 예: 20 |
object (검색 성공 (Spring Data Page 형태))
{"success":true,"data":…} — data: Page<PharmacyView> (검색 성공 (Spring Data Page 형태))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 배송지 관리 화면(AddressManagement)에서 배송지 저장 전에 호출한다. 우편번호(zonecode, 필수) 또는 도로명(roadname) 중 하나라도 비배송 지역 목록과 일치하면 deliveryYn=N 과 사유(reason)를 돌려주고, 둘 다 아니면 deliveryYn=Y. 로그인 불필요.
application/json — CheckDeliveryRequest비배송(산간/도서) 지역 확인 요청 — POST /api/v1/pharmacies/check-delivery
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| zonecode | string | 필수 | 우편번호 (5자리) — 비배송 우편번호 목록과 대조 예: 48058 |
| roadname | string | - | 도로명 — 비배송 도로명 목록과 부분 일치 대조 예: 센텀중앙로 |
{"success":true,"data":…} — data: CheckDeliveryResponse (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 약국 상세/선택 화면에서 호출한다. 식별자는 쿼리 code(약국 코드, 예 PH-001). 없는 코드는 COMMON_003. distance 는 채워지지 않는다. 로그인 불필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| code | query | string | 필수 | 약국 코드 예: PH-001 |
{"success":true,"data":…} — data: PharmacyView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 회원의 택배 수령 배송지 관리. 목록·추가·수정·삭제 모두 회원 토큰이 필요하며, 기본 배송지는 서버가 자동으로 관리한다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/addresses | 내 배송지 목록 | 회원 토큰 |
| POST | /api/v1/addresses/create | 배송지 추가 | 회원 토큰 |
| POST | /api/v1/addresses/delete | 배송지 삭제 | 회원 토큰 |
| POST | /api/v1/addresses/update | 배송지 수정 | 회원 토큰 |
앱 배송지 관리 화면(AddressManagement)과 약 주문 시작 화면(OrderMedicineMain)의 배송지 선택에서 호출한다. 삭제되지 않은 본인 배송지만 반환하며 기본 배송지(isDefault=true)가 먼저, 그다음 최근 등록순이다. 회원 토큰 필요.
object (조회 성공)
{
"success": true,
"data": [
{
"deliveryAddressSeq": 5,
"deliveryAddressName": "홍길동",
"deliveryAddressPhone": "010-1234-5678",
"deliveryAddressZipcode": "06578",
"deliveryAddress": "서울특별시 서초구 반포대로 45",
"deliveryDetailAddress": "101동 202호",
"roadName": "반포대로",
"isDefault": true
},
{
"deliveryAddressSeq": 3,
"deliveryAddressName": "홍길동(회사)",
"deliveryAddressPhone": "010-1234-5678",
"deliveryAddressZipcode": "06236",
"deliveryAddress": "서울특별시 강남구 테헤란로 123",
"deliveryDetailAddress": "7층",
"roadName": "테헤란로",
"isDefault": false
}
]
}{"success":true,"data":…} — data: array<AddressView> (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 배송지 등록 화면(AddressEdit)에서 호출한다. 받는 분 이름과 연락처는 필수. 회원의 첫 배송지이거나 isDefault=true 로 보내면 기본 배송지가 되고, 기존 기본 배송지는 자동 해제된다. 회원 토큰 필요.
application/json — CreateRequest관리자 계정 생성 요청 — POST /api/v1/admin/admin-users/create (SYSTEM_ADMIN 전용)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | string | 필수 | 관리자 로그인 아이디 (3~64자, 중복 불가) 예: pharmacist06 |
| password | string | 필수 | 초기 비밀번호 (6~64자) 예: ******** |
| adminName | string | 필수 | 관리자 이름 (40자 이하) 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 (120자 이하) 예: pharm06@yaknaru.local |
| adminTel | string | - | 전화번호 (20자 이하) 예: 010-1234-5678 |
| roles | array<string> | 필수 | 권한 집합 (1개 이상) — PHARMACY_ADMIN 약사 / SYSTEM_ADMIN 시스템 운영자 예: ['PHARMACY_ADMIN'] |
| pharmacyCodes | array<string> | - | 등록 시 초기 매핑할 약국 코드 목록 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식), PHARMACY_ADMIN 일 때만 의미 예: ['PH-001'] |
{"success":true,"data":…} — data: AddressView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 배송지 관리 화면(AddressManagement)에서 호출한다. 대상은 본문 addressId. 실제 삭제가 아닌 soft delete 이며, 삭제한 배송지가 기본 배송지였다면 남은 배송지 중 첫 번째가 자동으로 기본 배송지가 된다. 회원 토큰 필요.
application/json — DeleteRequest배송지 삭제 요청 — POST /api/v1/addresses/delete
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| addressId | integer | 필수 | 삭제 대상 배송지 PK — GET /api/v1/addresses 의 deliveryAddressSeq 예: 12 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 배송지 수정 화면(AddressEdit)에서 호출한다. 대상은 본문 addressId 로 식별하며 본인 배송지가 아니면 COMMON_003. null 로 보낸 필드는 변경하지 않는다. isDefault=true 면 기본 배송지로 승격하고 다른 배송지의 기본 표시를 해제한다(기본 해제는 불가). 회원 토큰 필요.
application/json — UpdateRequest앱 구동 설정 갱신 요청 — POST /api/v1/app/setting/update (관리자, null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| platform | string | 필수 | 대상 플랫폼 — android / ios 예: android |
| up_bool | string | - | 강제 업데이트 사용 여부 — yes / no, null = 미변경 예: no |
| up_build | integer | - | 강제 업데이트 기준 빌드 번호 — null = 미변경 예: 12 |
| up_img | string | - | 업데이트 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/update.png |
| up_img_width | integer | - | 업데이트 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| up_img_height | integer | - | 업데이트 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
| agree_bool | string | - | 약관 재동의 강제 여부 — yes / no, null = 미변경 예: no |
| agree_no | integer | - | 재동의가 필요한 약관 버전 번호 — null = 미변경 예: 2 |
| popup_bool | string | - | 팝업 노출 여부 — yes / no, null = 미변경 예: no |
| popup_img | string | - | 팝업 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/popup.png |
| server_bool | string | - | 서버 점검 중 여부 — yes / no, null = 미변경 예: no |
| server_img | string | - | 점검 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/maint.png |
| server_img_width | integer | - | 점검 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| server_img_height | integer | - | 점검 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
{"success":true,"data":…} — data: AddressView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱의 처방전 접수(촬영 → 인식 → 약국 선택 → 등록)와, 등록된 처방전을 주문 관점으로 보는 주문 내역·상세. 상태코드: 01 발송(접수) → 02 조제가능(결제 대기) → 04 결제완료 → 05 조제완료(방문수령) 또는 06 배송중 → 07 배송완료 → 010 수령완료, 03 조제불가, 08 미방문, 09 오류. 모두 회원 토큰 필요.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/orders | 내 주문 내역 | 회원 토큰 |
| GET | /api/v1/orders/detail | 주문 상세 | 회원 토큰 |
| POST | /api/v1/prescriptions | 처방전 등록 (약국 접수) | 회원 토큰 |
| GET | /api/v1/prescriptions/detail | 내 처방전 상세 | 회원 토큰 |
| POST | /api/v1/prescriptions/qr-callback | 처방전 인식 결과 저장 (OCR 콜백) | 회원 토큰 |
| POST | /api/v1/prescriptions/update-status | 처방전 상태 변경 (회원) | 회원 토큰 |
| POST | /api/v1/prescriptions/upload-image | 처방전 이미지 업로드 | 회원 토큰 |
앱 홈(Home)의 최근 주문과 주문 내역 화면(OrderHistory)에서 호출한다. 본인 처방전을 최신순으로 페이징한 뒤 접수일(targetDate, yyyy-MM-dd) 별로 묶어 RN SectionList 형태로 돌려준다. 목록의 medicineList 는 항상 빈 배열이며 약품 목록은 상세에서만 제공된다. 회원 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기(처방전 건수 기준, 날짜 그룹 수 아님) 예: 20 |
object (조회 성공)
{
"success": true,
"data": [
{
"targetDate": "2026-09-10",
"deliveryList": [
{
"prescriptionSeq": 41,
"prescriptionStatus": "06",
"prescriptionStatusName": "배송중",
"prescriptionRegdate": "2026-09-10",
"prescriptionPrice": 12500,
"totalPrice": 15500,
"receiveType": "onLine",
"pharmacyCode": "PH-001",
"pharmacyName": "약나루약국",
"medicineList": []
}
]
},
{
"targetDate": "2026-09-03",
"deliveryList": [
{
"prescriptionSeq": 37,
"prescriptionStatus": "03",
"prescriptionStatusName": "조제불가",
"prescriptionRegdate": "2026-09-03",
"unavailableReason": "재고 없음",
"receiveType": "offLine",
"pharmacyCode": "PH-002",
"pharmacyName": "건강약국",
"medicineList": []
}
]
}
]
}{"success":true,"data":…} — data: array<OrderHistoryGroup> (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 주문 진행 화면(MedicineOrder)과 주문 상세 화면(MedicineOrderDetail)에서 호출한다. 식별자는 쿼리 id(처방전 id). 본인 처방전이 아니면 AUTH_005, 없으면 COMMON_003. 처방전 인식 정보(partnerInfo)가 연결된 경우 약품 목록(medicineList)과 병원·의사 정보가 함께 오고, 03 조제불가 건은 pharmacyCode 로 거절 약국을 식별해 다른 약국 선택 흐름에 쓴다. 회원 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 처방전(주문) id 예: 41 |
object (조회 성공)
{
"success": true,
"data": {
"prescriptionSeq": 41,
"prescriptionStatus": "06",
"prescriptionStatusName": "배송중",
"reqDate": "2026-09-10T09:12:33.481",
"receiveType": "onLine",
"prescriptionPrice": 12500,
"deliveryPrice": 3000,
"totalPrice": 15500,
"medicineDirection": "1일 3회 식후 30분 복용",
"medicineList": [
{
"drgCd": "641102470",
"drgNm": "타이레놀정500밀리그램",
"dosage": "1",
"daysTotal": "3"
}
],
"pharmacyCode": "PH-001",
"pharmacyName": "약나루약국",
"pharmacyPhone": "02-1234-5678",
"pharmacyAddress": "서울특별시 강남구 테헤란로 123 1층",
"deliveryName": "홍길동",
"deliveryPhone": "010-1234-5678",
"deliveryAddress": "서울특별시 서초구 반포대로 45",
"deliveryDetailAddress": "101동 202호",
"deliveryNumber": "123456789012",
"deliveryCompany": "CJ대한통운",
"partnerInfo": {
"seq": 15,
"hospitalName": "서울내과의원",
"doctorName": "이의사",
"patientName": "홍길동",
"prescriptionDate": "2026-09-10",
"useDays": "3"
}
}
}{"success":true,"data":…} — data: OrderDetail (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 처방전 미리보기 화면(PrescPreview)에서 약국 선택까지 마친 뒤 호출한다. pharmacyCode(필수), receiveType(onLine 택배 / offLine 방문), 배송지 스냅샷, 업로드 이미지 경로, qrValue(필수), medicineSeq 를 한 번에 저장하며, 상태 01 발송으로 생성되고 약국명·전화·주소가 스냅샷으로 복사된다. 없는 약국 코드는 COMMON_003. 이 시점에는 푸시가 나가지 않는다. 회원 토큰 필요.
application/json — CreatePrescriptionRequest처방전 등록(주문 생성) 요청 — POST /api/v1/prescriptions (이미지 업로드·QR/OCR 콜백 결과를 묶어 저장)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 조제 요청 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| receiveType | string | - | 수령 방식 — onLine 택배배송 / offLine 방문수령 예: onLine |
| deliveryAddressId | integer | - | 배송지 PK — GET /api/v1/addresses 의 deliveryAddressSeq, onLine 일 때 예: 12 |
| deliveryName | string | - | 수령인 이름 (onLine 스냅샷) 예: 홍길동 |
| deliveryPhone | string | - | 수령인 연락처 (onLine 스냅샷) 예: 010-1234-5678 |
| deliveryAddress | string | - | 배송 기본 주소 (onLine 스냅샷) 예: 부산광역시 해운대구 센텀중앙로 79 |
| deliveryDetailAddress | string | - | 배송 상세 주소 (동/호수) 예: 101동 1203호 |
| prescriptionImagePath | string | - | 처방전 이미지 저장 경로 — POST /api/v1/prescriptions/upload-image 응답의 storagePath 예: C:/DEV/.../uploads/prescription/7/2026-09-11/3f9c1a2b__rx.jpg |
| qrImagePath | string | - | QR 영역 이미지 저장 경로 — upload-image 응답의 storagePath 예: C:/DEV/.../uploads/prescription/7/2026-09-11/3f9c1a2b__qr.jpg |
| qrValue | string | 필수 | 처방전 QR 원문 (또는 OCR 식별값) 예: PRS_ENC:9f3a2b1c… |
| medicineSeq | integer | - | 발급정보 PK — POST /api/v1/prescriptions/qr-callback 응답의 medicineSeq, null = 미인식 예: 55 |
object (등록 성공 (상태 01 발송))
{
"success": true,
"data": {
"id": 42,
"status": "01",
"statusName": "발송",
"receiveType": "onLine",
"qrValue": "OCR",
"prescriptionImageUrl": "/uploads/prescription/12/2026-09-11/3f2a9c__rx.jpg",
"pharmacyName": "약나루약국",
"pharmacyPhone": "02-1234-5678",
"pharmacyAddress": "서울특별시 강남구 테헤란로 123 1층",
"memId": "hong123",
"memName": "홍길동",
"deliveryName": "홍길동",
"deliveryPhone": "010-1234-5678",
"deliveryAddress": "서울특별시 서초구 반포대로 45",
"deliveryDetailAddress": "101동 202호",
"reqDate": "2026-09-11T10:15:30.123",
"medicineList": [
{
"drgCd": "641102470",
"drgNm": "타이레놀정500밀리그램"
}
],
"partnerInfo": {
"seq": 16,
"hospitalName": "서울내과의원",
"doctorName": "이의사",
"patientName": "홍길동",
"prescriptionDate": "2026-09-11"
}
}
}{"success":true,"data":…} — data: PrescriptionView (등록 성공 (상태 01 발송))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
식별자는 쿼리 id(처방전 id). 본인 처방전이 아니면 AUTH_005, 없으면 COMMON_003. 단계별 진입 시각(readyAt/paidAt 등)과 약품 목록, 인식 정보(partnerInfo)를 포함한다. 앱 주문 화면은 주로 /api/v1/orders/detail 을 쓰고, 이 API 는 처방전 원본 관점(이미지 URL, 약사 메모 등)이 필요할 때 쓴다. 회원 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 처방전 id 예: 41 |
{"success":true,"data":…} — data: PrescriptionView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 처방전 미리보기 화면(PrescPreview)에서 CLOVA OCR 로 파싱한 결과(ocr: 교부번호·환자·병원·의사·교부일·약품코드)를 보내면 처방전 발급 정보를 저장하고 medicineSeq 를 돌려준다. 이 값을 처방전 등록 요청의 medicineSeq 로 전달해야 상세에 약품 목록과 병원 정보가 붙는다. 약품명은 OCR 인식값을 쓰지 않고 약품코드로 약품 마스터(없으면 대체약품 자료)를 조회해 채운다. prsEnc(QR) 경로는 EDB 연동 중단으로 현재 사용하지 않으며, ocr 이 없으면 success=false 로 응답한다. 회원 토큰 필요.
application/json — QrCallbackRequest처방전 QR/OCR 콜백 요청 — POST /api/v1/prescriptions/qr-callback (현재는 ocr 파싱 결과 전송, prsEnc 는 구 QR 경로)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prsEnc | string | - | 처방전 QR 암호문 (구 EDB QR 방식) — 현재 미사용 예: PRS_ENC:9f3a2b1c… |
| ocr | OcrPrescriptionData | - | 앱 CLOVA OCR 파싱 결과 — 현행 경로 |
{"success":true,"data":…} — data: QrCallbackResponse (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 주문 진행 화면(MedicineOrder)과 결제 화면(MedicineOrderNicePay)에서 회원 측 상태 전이(예: 결제 완료 후 04, 수령 완료 010)에 호출한다. 대상은 본문 prescriptionId 이며 본인 처방전만 가능(아니면 AUTH_005). status 는 상태코드 문자열이고 알 수 없는 코드는 COMMON_001. 03 조제불가로 바꿀 때만 unavailableReason 이 저장된다. 회원이 바꾼 상태는 푸시를 발송하지 않는다(푸시는 관리자 처방전 갱신에서만). 회원 토큰 필요.
application/json — ChangeStatusRequest처방전 상태 변경 요청 — POST /api/v1/prescriptions/update-status (회원 취소/수령완료 등)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionId | integer | 필수 | 대상 처방전(주문) PK — GET /api/v1/orders 의 prescriptionSeq 예: 101 |
| status | string | 필수 | 변경할 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료 예: 010 |
| unavailableReason | string | - | 조제불가 사유 — status=03 일 때 예: 재고 부족 |
{"success":true,"data":…} — data: PrescriptionView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 처방전 미리보기 화면(PrescPreview)에서 촬영본을 먼저 올릴 때 호출한다. multipart 파트명은 file, 허용 형식 jpeg/png/pdf, 최대 20MB. 응답의 storagePath 를 처방전 등록 요청의 prescriptionImagePath 로 그대로 전달한다. 파일만 저장하고 DB 레코드는 만들지 않는다. 회원 토큰 필요.
multipart/form-data| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| file | file(binary) | 필수 | 처방전 이미지 파일 (jpeg/png/pdf, 20MB 이하) |
{"success":true,"data":…} — data: UploadImageResponse (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
약 배송(택배 수령) 자격 신청. 회원이 4종 카테고리 중 하나를 골라 증빙 서류를 올리면 심사중(I)으로 접수되고 관리자가 승인(S)/반려(R)한다. 승인/반려 오퍼레이션은 관리자 토큰 전용이며 관리자 API 의 /admin/eligibility/approve, /reject 와 같은 동작이다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/eligibility/documents | 자격 신청 (서류 업로드) | 회원 토큰 |
| GET | /api/v1/eligibility/latest | 내 자격 최신 1건 조회 | 회원 토큰 |
앱 약 배송 자격 화면(DeliveryEligibility)에서 호출한다. multipart 로 documentTypes(카테고리 코드 1개: ltc65plus 65세 이상 장기요양등급자 / disabled 장애인 / infectiousDisease 감염병 환자 / rareDisease 희귀질환자)와 files(1개 이상, jpg/jpeg/gif/png/pdf, 각 20MB 이하)를 보낸다. 심사중(I) 상태의 신청 1건이 새로 만들어지며 이전 신청을 덮어쓰지 않는다. 회원 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| documentTypes | query | string | 필수 | 카테고리 코드: ltc65plus | disabled | infectiousDisease | rareDisease 예: ltc65plus |
multipart/form-data| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| files | array<file(binary)> | 필수 | 증빙 서류 파일 목록 (jpg/jpeg/gif/png/pdf, 각 20MB 이하) |
{"success":true,"data":…} — data: EligibilityDetail (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 약 배송 자격 화면(DeliveryEligibility)과 배송지 관리 화면(AddressManagement)의 택배 가능 여부 판단에서 호출한다. 본인 신청 중 가장 최근 1건을 첨부 문서 목록과 함께 돌려주며, 신청 이력이 없으면 data 가 없다(null). state: I 심사중 / S 승인 / R 반려(rejectDesc 에 사유). 회원 토큰 필요.
object (조회 성공 (이력 없으면 data 생략))
{
"success": true,
"data": {
"summary": {
"id": 9,
"memberId": 12,
"state": "I",
"documentTypes": "ltc65plus",
"documentCount": 1,
"createdAt": "2026-09-11T10:15:30.123",
"updatedAt": "2026-09-11T10:15:30.123"
},
"documents": [
{
"id": 21,
"fileName": "인정서.jpg",
"fileSize": 184233,
"mimeType": "image/jpeg",
"fileUrl": "/uploads/eligibility/9/2026-09-11/8c1d2e__인정서.jpg"
}
]
}
}{"success":true,"data":…} — data: EligibilityDetail (조회 성공 (이력 없으면 data 생략))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 건강샵 탭의 건강기능식품 판매. 상품·배송비 정책 조회와 주문 생성·내 주문 목록. 모두 회원 토큰 필요.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/shop/orders | 내 건강샵 주문 목록 | 회원 토큰 |
| POST | /api/v1/shop/orders/create | 주문 생성 | 회원 토큰 |
| GET | /api/v1/shop/products | 상품 목록 | 회원 토큰 |
| GET | /api/v1/shop/settings | 배송비 정책 조회 | 회원 토큰 |
앱 건강샵 주문 내역에서 호출한다. 본인 주문을 최신순으로 돌려주며 status 는 PAID/SHIPPING/DELIVERED, statusLabel 은 한글 라벨. 회원 토큰 필요.
{"success":true,"data":…} — data: array<OrderView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 건강샵 결제가 끝난 뒤 호출한다. 서버는 결제를 검증하지 않으며 items 의 productId 로 상품을 다시 조회해 단가와 배송비(정책 기준)를 재계산한 뒤 결제 완료(PAID) 상태로 저장한다. 수량은 1~99 로 보정되고 없는 상품은 COMMON_003. 주문번호는 SO-YYYYMMDD-### 형식. 회원 토큰 필요.
application/json — OrderCreateRequest건강샵 주문 생성 요청 — POST /api/v1/shop/orders/create (결제 승인 후 호출, 주문번호 SO-YYYYMMDD-### 자동 채번)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| items | array<OrderItemRequest> | 필수 | 주문 상품 목록 (1개 이상) |
| delivery | DeliveryRequest | - | 배송지 정보 |
{"success":true,"data":…} — data: OrderView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 건강샵 탭 진입 시 호출한다. 관리자가 노출(visible=true)로 둔 삭제되지 않은 상품만 등록순으로 돌려준다. id 는 상품 코드(HP-001 형식)이며 주문 시 productId 로 쓴다. 회원 토큰 필요.
object (조회 성공)
{
"success": true,
"data": [
{
"id": "HP-001",
"category": "비타민",
"emoji": "🍊",
"name": "비타민C 1000",
"brand": "약나루헬스",
"brief": "하루 한 알 고함량 비타민C",
"price": 15900,
"originalPrice": 19900,
"badge": "BEST",
"visible": true,
"functionality": "항산화 및 면역 기능 유지에 도움",
"intake": "1일 1회, 1회 1정을 물과 함께 섭취",
"caution": "특정 질환이 있는 경우 전문가와 상담",
"image": "/uploads/shop/hp-001.jpg",
"detailImages": [
"/uploads/shop/hp-001-d1.jpg"
]
}
]
}{"success":true,"data":…} — data: array<ProductView> (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 장바구니·결제 화면에서 배송비 계산에 쓴다. deliveryFee(기본 배송비)와 freeThreshold(무료배송 기준 금액)를 돌려준다. 회원 토큰 필요.
{"success":true,"data":…} — data: SettingView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
FCM 토큰 구독/해제와 앱 알림함(인박스). 서버가 발송한 모든 푸시는 메시지 이력으로 남아 알림함에서 다시 볼 수 있다. 발송(send)은 SYSTEM_ADMIN 전용이며, 처방전 상태 변경·자격 심사·공지·문의 답변 푸시는 각 서비스가 자동으로 발송한다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/push/messages | 내 알림함 | 회원 토큰 |
| POST | /api/v1/push/messages/delete | 알림 1건 삭제 | 회원 토큰 |
| POST | /api/v1/push/messages/read | 알림 1건 읽음 처리 | 회원 토큰 |
| POST | /api/v1/push/messages/read-all | 알림 전체 읽음 처리 | 회원 토큰 |
| GET | /api/v1/push/messages/unread-count | 미읽음 알림 개수 | 회원 토큰 |
| POST | /api/v1/push/subscribe | FCM 토큰 구독 등록/갱신 | 회원 토큰 |
| POST | /api/v1/push/unsubscribe | FCM 토큰 구독 해제 | 회원 토큰 |
앱 알림 목록 화면(PushList)에서 호출한다. 본인에게 보낸 메시지와 전체 공지(broadcast, memberId 없음)를 최신순으로 페이징한다. readAt 이 없으면 미읽음. relatedType(prescription_approved / prescription_rejected / order / delivery / eligibility / notice / qna)과 relatedId, payload(JSON 문자열)로 화면 이동에 쓴다. 회원 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 예: 20 |
object (조회 성공 (Spring Data Page 형태))
{
"success": true,
"data": {
"content": [
{
"id": 88,
"memberId": 12,
"title": "배송이 시작되었습니다",
"body": "약이 배송 출발했습니다. 배송 조회로 위치를 확인하세요.",
"payload": "{\"pharmacyName\":\"약나루약국\",\"pharmacyCode\":\"PH-001\",\"deliveryNumber\":\"123456789012\",\"deliveryCompany\":\"CJ대한통운\"}",
"relatedType": "delivery",
"relatedId": 41,
"createdAt": "2026-09-11T08:30:01.204"
},
{
"id": 80,
"title": "새 공지가 등록되었습니다",
"body": "추석 연휴 배송 안내",
"relatedType": "notice",
"relatedId": 7,
"readAt": "2026-09-09T12:00:10.5",
"createdAt": "2026-09-09T11:00:00.1"
}
],
"pageable": {
"pageNumber": 0,
"pageSize": 20,
"sort": {
"empty": false,
"sorted": true,
"unsorted": false
},
"offset": 0,
"paged": true,
"unpaged": false
},
"last": true,
"totalElements": 2,
"totalPages": 1,
"size": 20,
"number": 0,
"sort": {
"empty": false,
"sorted": true,
"unsorted": false
},
"first": true,
"numberOfElements": 2,
"empty": false
}
}{"success":true,"data":…} — data: Page<MessageInfo> (조회 성공 (Spring Data Page 형태))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 알림 목록 화면(PushList)의 삭제. 대상은 본문 pushId. 본인에게 온 메시지만 지울 수 있고 전체 공지(broadcast)나 타인 메시지는 AUTH_005. 회원 토큰 필요.
application/json — MessageDeleteRequest알림 1건 삭제 요청 — POST /api/v1/push/messages/delete
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pushId | integer | 필수 | 알림 PK — GET /api/v1/push/messages 목록의 id 예: 88 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 알림 목록 화면(PushList)에서 항목을 열 때 호출한다. 대상은 본문 pushId. 타인의 메시지는 AUTH_005, 없으면 COMMON_003. 전체 공지도 읽음 처리할 수 있다. 회원 토큰 필요.
application/json — MessageReadRequest알림 1건 읽음 처리 요청 — POST /api/v1/push/messages/read
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pushId | integer | 필수 | 알림 PK — GET /api/v1/push/messages 목록의 id 예: 88 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 알림 목록 화면(PushList)의 모두 읽음 버튼. 본인 미읽음 메시지를 한 번에 읽음 처리하고 처리 건수를 {updated} 로 돌려준다. 회원 토큰 필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 홈(Home) 화면의 알림 뱃지용. 본인 메시지와 전체 공지 중 readAt 이 없는 건수를 {count} 로 돌려준다. 회원 토큰 필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱이 로그인 후(FcmEffect) FCM 토큰을 얻을 때마다 호출한다. 같은 토큰이 이미 있으면 회원·기기(deviceId)·플랫폼(platform) 정보만 갱신한다. 푸시 발송 시 회원별로 가장 최근에 갱신된 토큰 1개(마지막 로그인 폰)에만 보내므로, 토큰이 바뀌면 반드시 다시 호출해야 한다. 회원 토큰 필요.
application/json — SubscribeRequest푸시 토큰 구독 요청 — POST /api/v1/push/subscribe (동일 토큰 재전송 시 메타 갱신)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fcmToken | string | 필수 | Firebase Cloud Messaging 디바이스 토큰 예: dXk9f3…:APA91bH… |
| deviceId | string | - | 단말 식별자 (앱이 생성한 고유값) 예: a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| platform | string | - | 단말 플랫폼 — android / ios 예: android |
{"success":true,"data":…} — data: SubscriptionInfo (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 로그아웃 직전에 호출해 이 기기의 토큰(본문 fcmToken)을 구독 목록에서 지운다. 이후 이 기기로는 푸시가 오지 않는다. 회원 토큰 필요.
application/json — UnsubscribeRequest푸시 토큰 구독 해제 요청 — POST /api/v1/push/unsubscribe
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fcmToken | string | 필수 | 해제할 FCM 디바이스 토큰 — 구독 시 전송한 값 예: dXk9f3…:APA91bH… |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 공지사항·FAQ(공개)와 1:1 문의 Q&A(회원 토큰 필요). 공지·FAQ 는 관리자웹 게시판 관리에서 작성한 글을 읽기만 한다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/bbs/faq-categories | FAQ 카테고리 목록 | 로그인 불필요 |
| GET | /api/v1/bbs/faqs | FAQ 목록 | 로그인 불필요 |
| GET | /api/v1/bbs/notices | 공지사항 목록 | 로그인 불필요 |
| GET | /api/v1/bbs/notices/detail | 공지사항 상세 | 로그인 불필요 |
| GET | /api/v1/bbs/qna-form | Q&A 작성 폼 (카테고리 목록) | 회원 토큰 |
| GET | /api/v1/bbs/qnas | 내 Q&A 목록 | 회원 토큰 |
| POST | /api/v1/bbs/qnas | Q&A 작성 | 회원 토큰 |
앱 FAQ 화면(Faq)의 카테고리 탭 구성용. 활성 카테고리만 정렬순(sort)으로 돌려준다. 로그인 불필요.
{"success":true,"data":…} — data: array<CategoryView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 FAQ 화면(Faq)과 관리자웹 FAQ 관리에서 호출한다. 각 항목에 categoryId 와 categoryName 이 포함되어 앱이 카테고리 탭으로 묶어 보여준다. categoryId 를 주면 그 카테고리만, 안 주면 전체를 돌려준다(관리자웹 카테고리 필터). 기본 페이지 크기 50. 로그인 불필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 50) | - | 페이지 크기 예: 50 |
| categoryId | query | integer | - | 선택 — 카테고리 id (GET /api/v1/bbs/faq-categories 의 id). 없으면 전체 예: 3 |
{"success":true,"data":…} — data: Page<PostView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 공지사항 목록 화면(NoticeList)에서 호출한다. 삭제되지 않은 공지를 페이징해 돌려주며 contents(본문)도 포함된다. 로그인 불필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 예: 20 |
object (조회 성공 (Spring Data Page 형태))
{
"success": true,
"data": {
"content": [
{
"id": 7,
"boardType": "notice",
"subject": "추석 연휴 배송 안내",
"contents": "9/24~9/27 은 택배 배송이 중단됩니다.",
"viewCount": 132,
"regDate": "2026-09-09T11:00:00.1"
}
],
"pageable": {
"pageNumber": 0,
"pageSize": 20,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"offset": 0,
"paged": true,
"unpaged": false
},
"last": true,
"totalElements": 1,
"totalPages": 1,
"size": 20,
"number": 0,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"first": true,
"numberOfElements": 1,
"empty": false
}
}{"success":true,"data":…} — data: Page<PostView> (조회 성공 (Spring Data Page 형태))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 공지 상세 화면(NoticeDetail)에서 호출한다. 식별자는 쿼리 id. 호출할 때마다 조회수(viewCount)가 1 증가한다. 삭제된 글이나 공지가 아닌 글은 COMMON_003. 로그인 불필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 공지 게시글 id 예: 7 |
{"success":true,"data":…} — data: PostView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
앱 문의 작성 화면(QnaWrite)에 들어갈 때 호출한다. 활성 Q&A 카테고리를 정렬순으로 돌려준다. 회원 토큰 필요.
{"success":true,"data":…} — data: array<CategoryView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 문의 내역 화면(QnaList)에서 호출한다. 본인이 작성한 문의만 페이징하며 status 는 한글 라벨(답변대기/답변완료)이다. 회원 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 예: 20 |
{"success":true,"data":…} — data: Page<QnaView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 문의 작성 화면(QnaWrite)에서 호출한다. question(2~4000자) 필수, categoryId 는 선택이며 없는 카테고리면 COMMON_001. 답변대기 상태로 저장되고, 관리자가 답변을 달면 회원에게 FCM 푸시(문의 답변 도착)가 온다. 회원 토큰 필요.
application/json — QnaWriteRequest1:1 문의 작성 요청 — POST /api/v1/bbs/qnas (회원)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| categoryId | integer | - | 문의 카테고리 PK — GET /api/v1/bbs/qna-form 의 카테고리 id 예: 3 |
| question | string | 필수 | 문의 내용 (2~4000자) 예: 배송이 며칠 걸리나요? |
{"success":true,"data":…} — data: QnaView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
dev/local 프로파일에서만 뜨는 테스트 데이터 초기화 API. 인증 없이 호출되며 운영(prod)에는 존재하지 않는다. 회원·약국·관리자 같은 마스터 데이터는 건드리지 않는다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/dev/reset-eligibility | 약 배송 자격 이력 전체 삭제 | dev 전용 |
| POST | /api/v1/dev/reset-prescriptions | 처방전 이력 전체 삭제 | dev 전용 |
개발자가 테스트 데이터를 비울 때 직접 호출한다. eligibility_file(첨부 서류)과 eligibility_info(자격 신청)를 모두 DELETE 하고 테이블별 삭제 건수를 돌려준다. 업로드된 실제 파일은 지우지 않는다. 되돌릴 수 없다. 로그인 불필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
개발자가 테스트 데이터를 비울 때 직접 호출한다. order_info(처방전/주문), issue_drug(인식 약품), issue_info(처방전 인식 정보) 테이블을 FK 순서대로 모두 DELETE 하고 테이블별 삭제 건수를 돌려준다. 되돌릴 수 없다. 로그인 불필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
관리자웹(약사·운영자)용 + 약사 회원가입(공개) + 관리자 전용 오퍼레이션. 쓰기 작업은 대부분 감사기록(audit)을 남김.
관리자웹(약사 PHARMACY_ADMIN, 운영자 SYSTEM_ADMIN) 로그인·토큰 갱신·비밀번호 찾기. 여기서 발급한 토큰은 관리자용(userType=ADMIN)이며 앱 회원 API 와 섞어 쓸 수 없다. 모두 로그인 없이 호출한다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/admin/auth/login | 관리자 로그인 | 로그인 불필요 |
| POST | /api/v1/admin/auth/refresh | 관리자 토큰 갱신 | 로그인 불필요 |
| POST | /api/v1/admin/auth/reset-password | 관리자 비밀번호 찾기 (임시 비밀번호 메일) | 로그인 불필요 |
관리자웹 로그인 화면에서 호출한다. adminId + adminPass 검증 후 access 토큰(30분)/refresh 토큰(14일)과 adminInfo(역할 포함)를 돌려주고 마지막 로그인 시각을 갱신한다. 계정 상태에 따라 거절된다: 가입 검토 대기(PENDING)와 정지(SUSPENDED)는 AUTH_005, 탈퇴(WITHDRAWN)는 MEMBER_004, 아이디·비밀번호 불일치는 AUTH_002. 로그인 불필요.
application/json — AdminLoginRequest관리자(약사/시스템 운영자) 로그인 요청 — POST /api/v1/admin/auth/login
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | string | 필수 | 관리자 로그인 아이디 — 약사 회원가입(POST /api/v1/pharmacist/signup) 또는 SYSTEM_ADMIN 등록 시 지정 예: pharmacist01 |
| adminPass | string | 필수 | 비밀번호 (평문, TLS 구간 전송) 예: ******** |
object (로그인 성공)
{
"success": true,
"data": {
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIzMSIsInVzZXJUeXBlIjoiQURNSU4ifQ.xxxxx",
"refreshToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIzMSIsInR5cCI6InJlZnJlc2gifQ.yyyyy",
"expiresIn": 1800,
"adminInfo": {
"id": 31,
"adminId": "pharm_kim",
"adminName": "김약사",
"adminEmail": "kim@pharmacy.kr",
"adminTel": "010-1111-2222",
"adminState": "ACTIVE",
"roles": [
"PHARMACY_ADMIN"
]
}
}
}오류 응답: 401 아이디 또는 비밀번호 불일치 · 403 가입 검토 대기 또는 정지된 계정 · 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
관리자웹 요청 계층이 access 토큰 만료(401)를 받으면 자동으로 호출한다. 관리자용(userType=ADMIN) refresh 토큰만 받으며 회원 토큰이나 위조·만료 토큰은 AUTH_004. 새 access/refresh 토큰 쌍과 adminInfo 를 다시 돌려준다. 로그인 불필요(본문 refreshToken 만 사용).
application/json — AdminRefreshRequest관리자 토큰 갱신 요청 — POST /api/v1/admin/auth/refresh
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| refreshToken | string | 필수 | 갱신 토큰 — POST /api/v1/admin/auth/login 응답의 refreshToken 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJwaGFybWFjaXN0MDEiLCJ0eXAiOiJyZWZyZXNoIn0.9qZk… |
{"success":true,"data":…} — data: AdminTokenResponse (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
관리자웹 로그인 화면의 비밀번호 찾기 모달에서 호출한다. adminId 와 등록 이메일(adminEmail)이 일치하면 12자 임시 비밀번호로 바꾸고 그 이메일로 발송한다. 불일치는 AUTH_002, 탈퇴 계정은 MEMBER_004, 메일 발송 실패 시 비밀번호 변경도 롤백되고 COMMON_004. 로그인 불필요.
application/json — AdminResetPasswordRequest관리자 비밀번호 찾기 요청 — POST /api/v1/admin/auth/reset-password (아이디+이메일 일치 시 임시 비밀번호 메일 발송)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | string | 필수 | 관리자 로그인 아이디 예: pharmacist01 |
| adminEmail | string | 필수 | 계정에 등록된 이메일 — 아이디와 일치해야 임시 비밀번호 발송 예: pharm01@yaknaru.local |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
관리자웹 회원가입 화면에서 약사가 직접 가입 신청하는 공개 API. 신청 즉시 약사 계정(PENDING)과 약국이 만들어지고, 운영자가 약국 관리에서 승인해야 로그인할 수 있다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/pharmacist/check-id | 약사 아이디 중복 확인 | 로그인 불필요 |
| POST | /api/v1/pharmacist/signup | 약사 회원가입 신청 | 로그인 불필요 |
관리자웹 회원가입 화면(signup)의 중복확인 버튼. 관리자 계정 전체(약사·운영자)를 대상으로 검사해 {adminId, available} 를 돌려준다. 빈 값이면 available=false. 로그인 불필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| adminId | query | string | 필수 | 확인할 관리자 로그인 아이디 예: pharm_kim |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
관리자웹 회원가입 화면(signup)에서 호출한다. multipart 로 payload(약사·약국·계좌 정보 JSON 문자열)와 businessLicense(사업자등록증 파일, 필수)를 보낸다. 한 트랜잭션으로 약사 계정(PHARMACY_ADMIN, 상태 PENDING) + 약국(코드 PH-### 자동 채번, 배송 가능 Y 로 즉시 앱 약국 목록에 노출) + 약사-약국 매핑 + 사업자등록증 첨부를 만든다. 아이디 중복이나 payload 형식 오류, 파일 누락은 COMMON_001. PENDING 동안 로그인은 AUTH_005 로 거절되며 운영자가 /api/v1/admin/pharmacies/approve 로 승인하면 ACTIVE 가 된다. 로그인 불필요.
multipart/form-data| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| payload | string | 필수 | PharmacistSignUpRequest 를 JSON 문자열로 직렬화한 값 (adminId, adminPass, adminName, adminEmail, adminTel, pharmacyName, alarmPhone, pharmacyAddress, pharmacistName, pharmacistPhone, licenseNum, businessNum, accountBankName, accountBankNumber, accountOwner 필수) |
| businessLicense | file(binary) | - | 사업자등록증 파일 (필수) |
object (신청 접수 (검토 대기))
{
"success": true,
"data": {
"adminUserId": 31,
"pharmacyCode": "PH-012",
"adminId": "pharm_kim",
"pharmacyName": "약나루약국",
"state": "PENDING"
}
}{"success":true,"data":…} — data: PharmacistSignUpResponse (신청 접수 (검토 대기))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩)
로그인한 관리자 본인의 프로필·비밀번호와, 약사(PHARMACY_ADMIN)가 자기 약국 정보를 직접 관리하는 약국정보 메뉴용 API. 관리자 토큰(SYSTEM_ADMIN 또는 PHARMACY_ADMIN) 필요. 아이디·역할·상태·약국 매핑은 여기서 바꿀 수 없고 운영자가 관리자 계정 메뉴에서 처리한다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/me | 내 정보 조회 | 관리자 토큰 |
| GET | /api/v1/admin/me/pharmacies | 내 약국 목록 | 관리자 토큰 |
| POST | /api/v1/admin/me/pharmacies/update | 내 약국 정보 수정 | 관리자 토큰 |
| POST | /api/v1/admin/me/update | 내 정보 수정 | 관리자 토큰 |
| POST | /api/v1/admin/me/update-password | 내 비밀번호 변경 | 관리자 토큰 |
관리자웹 헤더와 내 정보 메뉴(myProfile)에서 호출한다. 역할(roles), 상태, 마지막 로그인 시각, 약사 생년월일(adminBirth, PHARMACY_ADMIN 만 의미)을 포함한다. 관리자 토큰 필요.
object (조회 성공)
{
"success": true,
"data": {
"id": 31,
"adminId": "pharm_kim",
"adminName": "김약사",
"adminEmail": "kim@pharmacy.kr",
"adminTel": "010-1111-2222",
"adminBirth": "1985-03-02",
"adminState": "ACTIVE",
"roles": [
"PHARMACY_ADMIN"
],
"lastLoginAt": "2026-09-11T09:02:11.53",
"createdAt": "2026-08-20T14:10:00.2"
}
}{"success":true,"data":…} — data: MeInfo (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국정보 메뉴(pharmacyInfo, 약사 전용)에서 호출한다. 본인에게 매핑된 약국을 영업시간·약사·계좌 정보까지 포함해 돌려준다. 매핑이 없으면 빈 배열(SYSTEM_ADMIN 도 매핑이 있으면 표시). 관리자 토큰 필요.
{"success":true,"data":…} — data: array<PharmacyView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국정보 메뉴(pharmacyInfo)의 저장 버튼. 대상은 본문 pharmacyCode 이며 본인에게 매핑된 약국이 아니면 AUTH_005. null 로 보낸 항목은 유지된다. 주소(address)가 바뀌었는데 gpsLat/gpsLon 을 주지 않으면 카카오 지오코딩으로 위경도를 자동 산출한다. 영업시간은 요일별 'HH:mm~HH:mm' 또는 '휴무'. 감사기록 ADMIN_ME_PHARMACY_UPDATE 를 남긴다. 관리자 토큰 필요.
application/json — AdminPharmacyUpdateRequest약국 부분 수정 요청 — POST /api/v1/admin/pharmacies/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| pharmacyName | string | - | 약국명 — null = 미변경 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 대표 전화 — null = 미변경 예: 051-123-4567 |
| zipcode | string | - | 우편번호 (5자리) — null = 미변경 예: 48434 |
| address | string | - | 약국 기본 주소 — null = 미변경 예: 부산광역시 남구 수영로 200 |
| detailAddress | string | - | 약국 상세 주소 — null = 미변경 예: 1층 101호 |
| gpsLat | number | - | 위도 (WGS84) — null = 미변경 예: 35.1367 |
| gpsLon | number | - | 경도 (WGS84) — null = 미변경 예: 129.0862 |
| deliveryYn | string | - | 택배 배송 지원 여부 — Y / N, null = 미변경 예: Y |
| alarmPhone | string | - | 처방전 접수 알림 수신 전화번호 — null = 미변경 예: 010-9876-5432 |
| pharmacistName | string | - | 약사 이름 — null = 미변경 예: 홍길동 |
| pharmacistPhone | string | - | 약사 전화번호 — null = 미변경 예: 010-1234-5678 |
| licenseNum | string | - | 약사 면허번호 — null = 미변경 예: 12345 |
| businessNum | string | - | 사업자등록번호 — null = 미변경 예: 123-45-67890 |
| accountBankName | string | - | 정산 계좌 은행명 — null = 미변경 예: 부산은행 |
| accountBankNumber | string | - | 정산 계좌번호 — null = 미변경 예: 101-2345-6789-01 |
| accountOwner | string | - | 정산 계좌 예금주 — null = 미변경 예: 홍길동 |
| openTimeMon | string | - | 월요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeTue | string | - | 화요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeWed | string | - | 수요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeThu | string | - | 목요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeFri | string | - | 금요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeSat | string | - | 토요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~13:00 |
| openTimeSun | string | - | 일요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 휴무 |
| pharmacyCharge | number | - | 플랫폼 중개 수수료율 (%) — null = 미변경 예: 3.5 |
| reviewMemo | string | - | SYSTEM_ADMIN 검토 메모 — null = 미변경 예: 사업자등록증 확인 완료 |
{"success":true,"data":…} — data: PharmacyView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 내 정보 메뉴의 수정 모달에서 호출한다. 이름·이메일·전화·생년월일만 바꿀 수 있고 null 로 보낸 항목은 유지된다. 변경 전/후 값으로 감사기록 ADMIN_ME_UPDATE 를 남긴다. 관리자 토큰 필요.
application/json — UpdateMeRequest관리자 내 프로필 부분 수정 요청 — POST /api/v1/admin/me/update (null 필드는 미변경, adminId/roles/state 는 본인 변경 불가)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminName | string | - | 관리자 이름 (40자 이하) — null = 미변경 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 (120자 이하) — null = 미변경 예: pharm01@yaknaru.local |
| adminTel | string | - | 전화번호 (20자 이하) — null = 미변경 예: 010-1234-5678 |
| adminBirth | date | - | 약사 생년월일 (YYYY-MM-DD) — null = 미변경 예: 1985-03-15 |
{"success":true,"data":…} — data: MeInfo (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 내 정보 메뉴의 비밀번호 변경에서 호출한다. currentPassword 가 맞아야 하며 틀리면 AUTH_002. 새 비밀번호는 6~64자. 감사기록 ADMIN_ME_PASSWORD_UPDATE 를 남기되 비밀번호 값은 기록하지 않는다. 관리자 토큰 필요.
application/json — ChangePasswordRequest회원 비밀번호 변경 요청 — POST /api/v1/members/me/update-password
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| oldPass | string | 필수 | 현재 비밀번호 예: ******** |
| newPass | string | 필수 | 새 비밀번호 (8~64자) 예: ******** |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 홈(대시보드) 화면의 집계 1회 호출. 관리자 토큰 필요: SYSTEM_ADMIN 은 전체, PHARMACY_ADMIN 은 매핑된 소속 약국 기준으로 집계된다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/dashboard/summary | 대시보드 요약 | 관리자 토큰 |
관리자웹 홈(대시보드) 진입 시 호출한다. counts: todayNew(오늘 접수된 01 발송 건, 최근 100건 내에서 집계) / paymentWaiting(02 조제가능) / shipping(06 배송중), monthRevenue·monthOrderCount(이번 달 1일~오늘, 010 수령완료 기준 매출·건수), recent(최근 처방전 5건, 상태 무관), asOf(집계 시각), period(집계 기간). 약국 범위는 토큰 역할로 자동 적용되며 매핑 약국이 없는 약사는 모두 0/빈 배열. 관리자 토큰 필요.
object (집계 성공)
{
"success": true,
"data": {
"counts": {
"todayNew": 3,
"paymentWaiting": 5,
"shipping": 2
},
"monthRevenue": 1250000,
"monthOrderCount": 48,
"recent": [
{
"id": 42,
"status": "01",
"statusName": "발송",
"receiveType": "onLine",
"pharmacyName": "약나루약국",
"pharmacyPhone": "02-1234-5678",
"pharmacyAddress": "서울특별시 강남구 테헤란로 123 1층",
"memId": "hong123",
"memName": "홍길동",
"deliveryName": "홍길동",
"deliveryPhone": "010-1234-5678",
"deliveryAddress": "서울특별시 서초구 반포대로 45",
"reqDate": "2026-09-11T10:15:30.123",
"medicineList": []
}
],
"asOf": "2026-09-11T10:20:01.554",
"period": {
"from": "2026-09-01",
"to": "2026-09-11"
}
}
}{"success":true,"data":…} — data: DashboardSummary (집계 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 처방전 관리 메뉴. 약사가 접수된 처방전을 확인하고 상태(조제가능/불가, 조제완료, 배송중 등)·가격·복약안내·송장을 갱신한다. 관리자 토큰 필요: SYSTEM_ADMIN 은 전체, PHARMACY_ADMIN 은 매핑된 소속 약국 처방전만 보이고 수정할 수 있다(약국 밖 건은 AUTH_005).
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/prescriptions | 처방전 검색 | 관리자 토큰 |
| GET | /api/v1/admin/prescriptions/detail | 처방전 상세 | 관리자 토큰 |
| POST | /api/v1/admin/prescriptions/update | 처방전 갱신 (상태·가격·메모·송장) | 관리자 토큰 |
| POST | /api/v1/admin/prescriptions/update-partner-info | 처방전 인식 정보 수정 (OCR 보정) | 관리자 토큰 |
관리자웹 처방전 관리 메뉴의 목록. status(상태코드 01~010)와 keyword 로 거르고 약국 범위(scope)는 토큰의 역할로 자동 적용된다. PHARMACY_ADMIN 인데 매핑 약국이 없으면 빈 목록. 각 행에 회원 아이디·이름(memId/memName)과 약품 목록, 인식 정보가 포함된다. perPage 는 1~100. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| status | query | string | - | 상태코드 필터: 01 발송 | 02 조제가능 | 03 조제불가 | 04 결제완료 | 05 조제완료 | 06 배송중 | 07 배송완료 | 08 미방문 | 09 오류 | 010 수령완료 예: 02 |
| keyword | query | string | - | 검색어 (회원 이름·연락처·약국명 등 부분 일치) 예: 홍길동 |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 (최대 100) 예: 20 |
{"success":true,"data":…} — data: Page<PrescriptionView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 처방전 관리 메뉴의 상세/크게보기 모달에서 호출한다. 식별자는 쿼리 id(처방전 id). 없으면 COMMON_003, 소속 약국 밖이면 AUTH_005. 이미지 URL, 약사 메모, 단계별 진입 시각(readyAt/paidAt/preparedAt/inTransitAt/deliveredAt/pickedUpAt), 약품 목록, 병원·의사 인식 정보(partnerInfo)를 모두 포함한다. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 처방전 id 예: 41 |
object (조회 성공)
{"success":true,"data":…} — data: PrescriptionView (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 처방전 관리 상세 모달의 저장/상태 변경 버튼. 대상은 본문 prescriptionId. status(상태코드), 조제비·배송비, 복약안내(medicineDirection), 송장번호·택배사, 조제불가 사유, 약사 내부 메모(pharmacistMemo, 회원 미노출)를 부분 수정하며 null 은 유지. status 가 실제로 바뀌면 회원에게 FCM 푸시가 자동 발송된다(02 조제가능·03 조제불가·04 결제완료·05 조제완료·06 배송중·07 배송완료·010 수령완료). 알 수 없는 코드는 COMMON_001. 변경 전/후 값으로 감사기록 PRESCRIPTION_UPDATE. 관리자 토큰 필요(소속 약국 밖은 AUTH_005).
application/json — AdminUpdatePrescriptionRequest관리자 처방전 부분 수정 요청 — POST /api/v1/admin/prescriptions/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionId | integer | 필수 | 대상 처방전(주문) PK — GET /api/v1/admin/prescriptions 목록의 id 예: 101 |
| status | string | - | 변경할 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료, null = 미변경 예: 06 |
| prescriptionPrice | number | - | 약제비 (원) — null = 미변경 예: 12500 |
| deliveryPrice | number | - | 배송비 (원) — null = 미변경 예: 3000 |
| medicineDirection | string | - | 약사 복약 안내 (회원 노출) — null = 미변경 예: 식후 30분에 1정씩 복용하세요. |
| deliveryNumber | string | - | 택배 송장번호 — 배송중(06) 전환 시 입력, null = 미변경 예: 6889012345678 |
| deliveryCompany | string | - | 택배사명 (CJ대한통운/우체국 등) — 배송중(06) 전환 시 입력, null = 미변경 예: CJ대한통운 |
| unavailableReason | string | - | 조제불가 사유 — status=03 일 때, null = 미변경 예: 재고 부족 |
| pharmacistMemo | string | - | 약사 내부 메모 (회원 미노출) — null = 미변경 예: 재고 확인 필요 |
{"success":true,"data":…} — data: PrescriptionView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 처방전 관리 상세 모달에서 OCR 오인식된 병원·의사·환자·진단코드·교부일·약품을 약사가 바로잡을 때 호출한다. 대상은 본문 prescriptionId. 모든 필드는 보낸 값 그대로 저장되고(빈 문자열은 null), 인식 정보가 없던 처방전이면 ADMIN 유형으로 새로 만들어 연결한다. medicines 를 리스트로 보내면 기존 약품을 전부 교체하며(null 이면 유지) 약품명은 보낸 값을 무시하고 코드로 약품 마스터를 조회해 채운다. 푸시는 없다. 감사기록 PRESCRIPTION_PARTNER_INFO_UPDATE. 관리자 토큰 필요.
application/json — AdminUpdatePartnerInfoRequest관리자 처방전 발급정보 수정 요청 — POST /api/v1/admin/prescriptions/update-partner-info (OCR 오인식 보정, 전송값 그대로 저장·빈 문자열은 null)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionId | integer | 필수 | 대상 처방전(주문) PK — GET /api/v1/admin/prescriptions 목록의 id 예: 101 |
| hospitalName | string | - | 의료기관 명칭 예: 부산대학교병원 |
| hospitalPhone | string | - | 의료기관 전화번호 예: 051-240-7000 |
| doctorName | string | - | 처방 의사 성명 예: 김의사 |
| doctorLicenseNo | string | - | 의사 면허번호 예: 98765 |
| patientName | string | - | 환자 성명 예: 홍길동 |
| departmentCode | string | - | 진료과목 코드 예: 01 |
| diagnosisCode1 | string | - | 주상병 코드 (KCD) 예: J06.9 |
| diagnosisCode2 | string | - | 부상병 코드 (KCD) 예: R50.9 |
| prescriptionDate | string | - | 처방전 교부일 (YYYY-MM-DD) 예: 2026-09-11 |
| useDays | string | - | 처방전 사용기간 (일) 예: 3 |
| medicines | array<AdminMedicineItem> | - | 약품 목록 — null = 미변경, 리스트 전송 시 기존 약품 전체 교체 |
{"success":true,"data":…} — data: PrescriptionView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 주문 관리·매출 정산 메뉴. 처방전을 주문/회계 관점으로 조회하고 약국별 매출을 집계하며 Excel 로 내려받는다. 관리자 토큰 필요: SYSTEM_ADMIN 은 전체, PHARMACY_ADMIN 은 매핑된 소속 약국만.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/orders | 주문 검색 | 관리자 토큰 |
| GET | /api/v1/admin/orders/detail | 주문 상세 | 관리자 토큰 |
| GET | /api/v1/admin/orders/export.xlsx | 주문 목록 Excel 다운로드 | 관리자 토큰 |
| GET | /api/v1/admin/orders/revenue | 약국별 매출 정산 | 관리자 토큰 |
| GET | /api/v1/admin/orders/revenue/export.xlsx | 매출 정산 Excel 다운로드 | 관리자 토큰 |
관리자웹 주문 관리 메뉴의 목록. status(상태코드), pharmacyId(약국 PK), 접수일 범위 dateFrom~dateTo(yyyy-MM-dd, dateTo 당일 포함)로 거르고 약국 범위는 토큰 역할로 자동 적용된다. 행은 Excel 변환이 쉬운 평탄한 형태(회원명·연락처는 배송지 스냅샷). perPage 는 1~100. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| status | query | string | - | 상태코드 필터 (01~010) 예: 010 |
| pharmacyId | query | integer | - | 약국 PK (코드 아님) 예: 3 |
| dateFrom | query | date | - | 접수일 시작 (yyyy-MM-dd) 예: 2026-09-01 |
| dateTo | query | date | - | 접수일 끝 (yyyy-MM-dd, 당일 포함) 예: 2026-09-30 |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 (최대 100) 예: 20 |
{"success":true,"data":…} — data: Page<AdminOrderRow> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 주문 관리 메뉴의 상세 모달에서 호출한다. 식별자는 쿼리 id(처방전 id). 앱 주문 상세와 같은 형태이며 없으면 COMMON_003, 소속 약국 밖이면 AUTH_005. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 처방전(주문) id 예: 41 |
{"success":true,"data":…} — data: OrderDetail (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 주문 관리 메뉴의 Excel 버튼. 검색과 같은 필터를 받되 페이징 없이 최대 100,000 행을 xlsx 파일(orders-yyyy-MM-dd.xlsx, Content-Disposition attachment)로 내려준다. 응답은 공통 JSON 래퍼가 아닌 바이너리다. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| status | query | string | - | 상태코드 필터 (01~010) 예: 010 |
| pharmacyId | query | integer | - | 약국 PK 예: 3 |
| dateFrom | query | date | - | 접수일 시작 (yyyy-MM-dd) 예: 2026-09-01 |
| dateTo | query | date | - | 접수일 끝 (yyyy-MM-dd, 당일 포함) 예: 2026-09-30 |
바이너리 파일 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet — xlsx 파일
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 매출 정산 메뉴에서 호출한다. status 기본값은 010(수령완료)이며 날짜 범위(접수일 기준)를 비우면 전체 기간. 약국별 주문 수·총액·조제비 합·배송비 합(rows)과 전체 합계(totalOrderCount, totalRevenueSum)를 돌려준다. 약국 범위는 토큰 역할로 자동 적용. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| status | query | string (기본 010) | - | 집계 대상 상태코드 (기본 010 수령완료) 예: 010 |
| dateFrom | query | date | - | 접수일 시작 (yyyy-MM-dd) 예: 2026-09-01 |
| dateTo | query | date | - | 접수일 끝 (yyyy-MM-dd, 당일 포함) 예: 2026-09-30 |
object (집계 성공)
{
"success": true,
"data": {
"rows": [
{
"pharmacyId": 3,
"pharmacyName": "약나루약국",
"orderCount": 31,
"totalSum": 842000,
"prescriptionSum": 749000,
"deliverySum": 93000
},
{
"pharmacyId": 5,
"pharmacyName": "건강약국",
"orderCount": 17,
"totalSum": 408000,
"prescriptionSum": 372000,
"deliverySum": 36000
}
],
"totalOrderCount": 48,
"totalRevenueSum": 1250000,
"dateFrom": "2026-09-01",
"dateTo": "2026-09-30",
"status": "010"
}
}{"success":true,"data":…} — data: AdminRevenueSummary (집계 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 매출 정산 메뉴의 Excel 버튼. 매출 정산 조회와 같은 집계를 xlsx 파일(revenue-yyyy-MM-dd.xlsx)로 내려준다. 응답은 공통 JSON 래퍼가 아닌 바이너리다. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| status | query | string (기본 010) | - | 집계 대상 상태코드 (기본 010 수령완료) 예: 010 |
| dateFrom | query | date | - | 접수일 시작 (yyyy-MM-dd) 예: 2026-09-01 |
| dateTo | query | date | - | 접수일 끝 (yyyy-MM-dd, 당일 포함) 예: 2026-09-30 |
바이너리 파일 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet — xlsx 파일
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약 배송 자격 메뉴. 회원이 올린 자격 신청(서류)을 검색·열람하고 승인/반려한다. 관리자 토큰(SYSTEM_ADMIN 또는 PHARMACY_ADMIN) 필요. 자격 신청은 약국에 속하지 않으므로 약사도 전체 신청을 본다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/eligibility | 자격 신청 검색 | 관리자 토큰 |
| POST | /api/v1/admin/eligibility/approve | 자격 승인 | 관리자 토큰 |
| GET | /api/v1/admin/eligibility/detail | 자격 신청 상세 | 관리자 토큰 |
| POST | /api/v1/admin/eligibility/reject | 자격 반려 | 관리자 토큰 |
관리자웹 약 배송 자격 메뉴의 목록. state 로 I(심사중)/S(승인)/R(반려)만 거르거나 비우면 전체. 각 행에 회원 아이디·이름(memberLoginId/memberName)과 첨부 수(documentCount)가 포함된다. 잘못된 state 값은 COMMON_001. perPage 는 1~100. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| state | query | string | - | 상태 필터: I 심사중 | S 승인 | R 반려 (미지정 = 전체) 예: I |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 (최대 100) 예: 20 |
{"success":true,"data":…} — data: Page<EligibilitySummary> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약 배송 자격 상세 모달의 승인 버튼. 대상은 본문 eligibilityId(없으면 COMMON_003). 상태를 S 로 바꾸고 신청 회원에게 FCM 푸시(약 배송 자격 승인)를 보내며 변경 전/후 값으로 감사기록 ELIGIBILITY_APPROVE 를 남긴다. /api/v1/eligibility/approve 와 같은 동작. 관리자 토큰 필요.
application/json — ApproveRequest자격 승인 요청 — POST /api/v1/admin/eligibility/approve (상태 I → S)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| eligibilityId | integer | 필수 | 승인 대상 자격 신청 PK — GET /api/v1/admin/eligibility 목록의 id 예: 21 |
{"success":true,"data":…} — data: EligibilitySummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약 배송 자격 메뉴의 상세 모달에서 호출한다. 식별자는 쿼리 id(신청 id). 첨부 서류 목록(fileUrl 은 /uploads/... 경로)을 포함하며 없으면 COMMON_003. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 자격 신청 id 예: 9 |
{"success":true,"data":…} — data: EligibilityDetail (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약 배송 자격 상세 모달의 반려 버튼. 대상은 본문 eligibilityId, reason 을 비우면 '사유 미입력' 으로 저장된다. 상태를 R 로 바꾸고 rejectDesc 에 사유를 남기며 신청 회원에게 FCM 푸시(약 배송 자격 반려, payload 에 reason)를 보낸다. 회원은 앱에서 재신청할 수 있다. 감사기록 ELIGIBILITY_REJECT. /api/v1/eligibility/reject 와 같은 동작. 관리자 토큰 필요.
application/json — RejectRequest자격 반려 요청 — POST /api/v1/admin/eligibility/reject (상태 I → R, 사유 회원 노출)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| eligibilityId | integer | 필수 | 반려 대상 자격 신청 PK — GET /api/v1/admin/eligibility 목록의 id 예: 21 |
| reason | string | - | 반려 사유 — 회원 앱에 rejectDesc 로 노출 예: 서류 식별이 불가하여 재제출이 필요합니다. |
{"success":true,"data":…} — data: EligibilitySummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 회원 관리(앱) 메뉴. 앱 회원 검색·상세·상태 변경. SYSTEM_ADMIN 토큰 전용.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/members | 회원 검색 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/members/detail | 회원 상세 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/members/update-state | 회원 상태 변경 | SYSTEM_ADMIN 토큰 |
관리자웹 회원 관리(앱) 메뉴의 목록. keyword 와 state(ACTIVE/DORMANT/SUSPENDED/WITHDRAWN)로 거르고 withDeleted=true 면 탈퇴 회원도 포함한다. perPage 는 1~100 으로 보정. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| keyword | query | string | - | 검색어 (아이디·이름·이메일·전화 부분 일치) 예: hong |
| state | query | string | - | 상태 필터: ACTIVE | DORMANT | SUSPENDED | WITHDRAWN 예: ACTIVE |
| withDeleted | query | boolean (기본 False) | - | 탈퇴(삭제) 회원 포함 여부 예: False |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 (최대 100) 예: 20 |
object (검색 성공 (Spring Data Page 형태))
{
"success": true,
"data": {
"content": [
{
"id": 12,
"memId": "hong123",
"memName": "홍길동",
"memEmail": "hong@example.com",
"memTel": "010-1234-5678",
"memState": "ACTIVE",
"roles": [
"USER"
],
"createdAt": "2026-08-01T10:00:00.123"
}
],
"pageable": {
"pageNumber": 0,
"pageSize": 20,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"offset": 0,
"paged": true,
"unpaged": false
},
"last": true,
"totalElements": 1,
"totalPages": 1,
"size": 20,
"number": 0,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"first": true,
"numberOfElements": 1,
"empty": false
}
}{"success":true,"data":…} — data: Page<AdminMemberSummary> (검색 성공 (Spring Data Page 형태))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 회원 관리(앱) 메뉴의 상세 모달에서 호출한다. 식별자는 쿼리 id(회원 PK). 앱의 내 정보와 같은 형태이며 없으면 MEMBER_001. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 회원 PK 예: 12 |
{"success":true,"data":…} — data: MemberInfo (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 회원 관리(앱) 메뉴의 상세 모달에서 호출한다. 대상은 본문 memberId, state 는 ACTIVE / DORMANT / SUSPENDED / WITHDRAWN (대소문자 무관, 그 외는 COMMON_001). WITHDRAWN 으로 바꾸면 soft delete 도 함께 처리되어 회원은 더 이상 로그인할 수 없다. 변경 전/후 값으로 감사기록 MEMBER_STATE_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminMemberStateRequest회원 상태 변경 요청 — POST /api/v1/admin/members/update-state (SYSTEM_ADMIN)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memberId | integer | 필수 | 대상 회원 PK — GET /api/v1/admin/members 목록의 id 예: 7 |
| state | string | 필수 | 변경할 회원 상태 — ACTIVE 정상 / DORMANT 휴면 / SUSPENDED 정지 / WITHDRAWN 탈퇴 예: SUSPENDED |
{"success":true,"data":…} — data: AdminMemberSummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 메뉴. 약국 등록·정보 수정·수수료·검토 메모와 약사 회원가입 검토(승인/반려), 매핑 약사·첨부 서류 조회. 약국 목록 자체는 앱과 같은 공개 API(GET /api/v1/pharmacies)를 쓴다. SYSTEM_ADMIN 토큰 전용이며 쓰기 작업은 모두 감사기록을 남긴다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/pharmacies/admins | 약국에 매핑된 약사 계정 목록 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/pharmacies/approve | 약사 회원가입 승인 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/pharmacies/create | 약국 등록 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/pharmacies/documents | 약국 첨부 서류 목록 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/pharmacies/reject | 약사 회원가입 반려 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/pharmacies/update | 약국 정보 수정 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/pharmacies/update-charge | 중개 수수료 저장 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/pharmacies/update-review-memo | 검토 메모 저장 | SYSTEM_ADMIN 토큰 |
관리자웹 약국 관리 상세 모달의 약사 회원정보 카드에서 호출한다. 식별자는 쿼리 code(약국 코드). 매핑된 관리자 계정을 상태(PENDING/ACTIVE 등)와 함께 돌려주며 각 항목의 pharmacies 는 비어 있다. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| code | query | string | 필수 | 약국 코드 예: PH-001 |
{"success":true,"data":…} — data: array<AdminUserSummary> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 상세 모달의 승인 버튼. 대상은 본문 pharmacyCode. 이 약국에 매핑된 PENDING 약사 계정을 모두 ACTIVE 로 바꾸고(affectedAdminCount), 각 약사에게 승인 안내 메일을 보낸다(메일 실패는 무시). reviewMemo 를 주면 검토 메모도 저장한다. 감사기록 PHARMACY_APPROVE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPharmacyApproveRequest약사 회원가입 승인 요청 — POST /api/v1/admin/pharmacies/approve (매핑 약사 PENDING → ACTIVE)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — 약사 회원가입 응답의 pharmacyCode (PH-001 형식) 예: PH-006 |
| reviewMemo | string | - | 승인 시 남길 검토 메모 예: 서류 확인 완료, 승인 |
object (승인 처리 결과)
{
"success": true,
"data": {
"pharmacyCode": "PH-012",
"affectedAdminCount": 1,
"result": "APPROVED"
}
}{"success":true,"data":…} — data: AdminPharmacyReviewResponse (승인 처리 결과)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 메뉴의 신규 등록 모달에서 운영자가 직접 약국을 만들 때 호출한다(약사 회원가입 경로는 자동 채번). pharmacyCode 를 직접 지정하며 이미 있으면 COMMON_001. deliveryYn 은 Y/N(미지정 시 N), 영업시간 7종은 'HH:mm~HH:mm' 또는 '휴무'. 감사기록 PHARMACY_CREATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPharmacyCreateRequest약국 등록 요청 — POST /api/v1/admin/pharmacies/create (SYSTEM_ADMIN)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 약국 코드 (PH-### 형식, 중복 불가) 예: PH-006 |
| pharmacyName | string | 필수 | 약국명 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 대표 전화 예: 051-123-4567 |
| zipcode | string | - | 우편번호 (5자리) 예: 48434 |
| address | string | - | 약국 기본 주소 예: 부산광역시 남구 수영로 200 |
| detailAddress | string | - | 약국 상세 주소 예: 1층 101호 |
| gpsLat | number | - | 위도 (WGS84) 예: 35.1367 |
| gpsLon | number | - | 경도 (WGS84) 예: 129.0862 |
| deliveryYn | string | - | 택배 배송 지원 여부 — Y / N, null = N 예: Y |
| openTimeMon | string | - | 월요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeTue | string | - | 화요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeWed | string | - | 수요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeThu | string | - | 목요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeFri | string | - | 금요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeSat | string | - | 토요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~13:00 |
| openTimeSun | string | - | 일요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 휴무 |
{"success":true,"data":…} — data: PharmacyView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 상세 모달의 사업자등록증/기타 서류 카드에서 호출한다. 식별자는 쿼리 code(약국 코드). 약사 회원가입 때 올린 사업자등록증 등을 fileUrl(/uploads/...)과 함께 등록순으로 돌려준다. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| code | query | string | 필수 | 약국 코드 예: PH-012 |
{"success":true,"data":…} — data: array<PharmacyDocumentView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 상세 모달의 반려 버튼. 대상은 본문 pharmacyCode, reviewMemo(반려 사유)는 필수. 매핑된 PENDING 약사 계정을 모두 SUSPENDED 로 바꾸고(affectedAdminCount) 사유를 담은 반려 메일을 보낸다(메일 실패는 무시). 약국 레코드 자체는 삭제하지 않는다. 감사기록 PHARMACY_REJECT. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPharmacyRejectRequest약사 회원가입 반려 요청 — POST /api/v1/admin/pharmacies/reject (매핑 약사 PENDING → SUSPENDED, 사유 메일 통보)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — 약사 회원가입 응답의 pharmacyCode (PH-001 형식) 예: PH-006 |
| reviewMemo | string | 필수 | 반려 사유 (필수) — 약사에게 통보 예: 사업자등록증 이미지가 식별되지 않습니다. |
{"success":true,"data":…} — data: AdminPharmacyReviewResponse (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 상세 모달의 저장 버튼. 대상은 본문 pharmacyCode(없으면 COMMON_003). 기본 정보·배송 가능 여부·약사/계좌 정보·영업시간·수수료·검토 메모를 부분 수정하며 null 은 유지. 여기서는 지오코딩을 하지 않으므로 주소를 바꾸면 gpsLat/gpsLon 도 함께 보내야 한다. 변경 전/후 값으로 감사기록 PHARMACY_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPharmacyUpdateRequest약국 부분 수정 요청 — POST /api/v1/admin/pharmacies/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| pharmacyName | string | - | 약국명 — null = 미변경 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 대표 전화 — null = 미변경 예: 051-123-4567 |
| zipcode | string | - | 우편번호 (5자리) — null = 미변경 예: 48434 |
| address | string | - | 약국 기본 주소 — null = 미변경 예: 부산광역시 남구 수영로 200 |
| detailAddress | string | - | 약국 상세 주소 — null = 미변경 예: 1층 101호 |
| gpsLat | number | - | 위도 (WGS84) — null = 미변경 예: 35.1367 |
| gpsLon | number | - | 경도 (WGS84) — null = 미변경 예: 129.0862 |
| deliveryYn | string | - | 택배 배송 지원 여부 — Y / N, null = 미변경 예: Y |
| alarmPhone | string | - | 처방전 접수 알림 수신 전화번호 — null = 미변경 예: 010-9876-5432 |
| pharmacistName | string | - | 약사 이름 — null = 미변경 예: 홍길동 |
| pharmacistPhone | string | - | 약사 전화번호 — null = 미변경 예: 010-1234-5678 |
| licenseNum | string | - | 약사 면허번호 — null = 미변경 예: 12345 |
| businessNum | string | - | 사업자등록번호 — null = 미변경 예: 123-45-67890 |
| accountBankName | string | - | 정산 계좌 은행명 — null = 미변경 예: 부산은행 |
| accountBankNumber | string | - | 정산 계좌번호 — null = 미변경 예: 101-2345-6789-01 |
| accountOwner | string | - | 정산 계좌 예금주 — null = 미변경 예: 홍길동 |
| openTimeMon | string | - | 월요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeTue | string | - | 화요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeWed | string | - | 수요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeThu | string | - | 목요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeFri | string | - | 금요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeSat | string | - | 토요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~13:00 |
| openTimeSun | string | - | 일요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 휴무 |
| pharmacyCharge | number | - | 플랫폼 중개 수수료율 (%) — null = 미변경 예: 3.5 |
| reviewMemo | string | - | SYSTEM_ADMIN 검토 메모 — null = 미변경 예: 사업자등록증 확인 완료 |
{"success":true,"data":…} — data: PharmacyView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 상세 모달의 수수료 저장 버튼. 대상은 본문 pharmacyCode, pharmacyCharge 는 % 값이며 다른 항목은 건드리지 않는다. 변경 전/후 값으로 감사기록 PHARMACY_CHARGE_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPharmacyChargeRequest약국 중개 수수료율 저장 요청 — POST /api/v1/admin/pharmacies/update-charge (SYSTEM_ADMIN)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| pharmacyCharge | number | - | 플랫폼 중개 수수료율 (%) — null = 미설정으로 저장 예: 3.5 |
{"success":true,"data":…} — data: PharmacyView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약국 관리 상세 모달의 검토 메모 저장 버튼. 대상은 본문 pharmacyCode. 운영자 내부 메모(reviewMemo)만 바꾸고 lastReviewedAt 이 갱신된다. 변경 전/후 값으로 감사기록 PHARMACY_REVIEW_MEMO_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPharmacyReviewMemoRequest약국 검토 메모 저장 요청 — POST /api/v1/admin/pharmacies/update-review-memo (SYSTEM_ADMIN, lastReviewedAt 갱신)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| reviewMemo | string | - | 검토 메모 — null/공백 = 메모 삭제 예: 사업자등록증 확인 완료 |
{"success":true,"data":…} — data: PharmacyView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 시스템 관리 > 관리자 계정 메뉴. 약사·운영자 계정의 검색·생성·수정·비밀번호 초기화와 약사-약국 매핑. SYSTEM_ADMIN 토큰 전용이며 쓰기 작업은 모두 감사기록을 남긴다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/admin-users | 관리자 계정 검색 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/admin-users/create | 관리자 계정 생성 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/admin-users/detail | 관리자 계정 상세 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/admin-users/pending-count | 가입 대기 약사 수 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/admin-users/pharmacies/add | 약사-약국 매핑 추가 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/admin-users/pharmacies/remove | 약사-약국 매핑 해제 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/admin-users/reset-password | 관리자 비밀번호 강제 변경 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/admin-users/update | 관리자 계정 수정 | SYSTEM_ADMIN 토큰 |
관리자웹 관리자 계정 메뉴의 목록. keyword(아이디·이름 등), role, state 로 거르고 withDeleted=true 면 탈퇴 계정도 포함한다. 각 행에 매핑 약국 목록(pharmacies, 첨부 서류 수 포함)이 채워진다. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| keyword | query | string | - | 검색어 (아이디·이름·이메일 부분 일치) 예: kim |
| role | query | string | - | 역할 필터: SYSTEM_ADMIN | PHARMACY_ADMIN 예: PHARMACY_ADMIN |
| state | query | string | - | 상태 필터: PENDING | ACTIVE | SUSPENDED | WITHDRAWN 예: PENDING |
| withDeleted | query | boolean (기본 False) | - | 탈퇴(삭제) 계정 포함 여부 예: False |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 예: 20 |
{"success":true,"data":…} — data: Page<AdminUserSummary> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 관리자 계정 메뉴의 신규 등록 모달에서 호출한다. roles 에 SYSTEM_ADMIN 이 있으면 운영자, 아니면 약사 계정으로 만들며 상태는 즉시 ACTIVE. PHARMACY_ADMIN 은 pharmacyCodes 로 초기 약국 매핑을 함께 걸 수 있다(없는 코드는 COMMON_003). 아이디 중복은 COMMON_001. 감사기록 ADMIN_USER_CREATE. SYSTEM_ADMIN 토큰 필요.
application/json — CreateRequest관리자 계정 생성 요청 — POST /api/v1/admin/admin-users/create (SYSTEM_ADMIN 전용)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | string | 필수 | 관리자 로그인 아이디 (3~64자, 중복 불가) 예: pharmacist06 |
| password | string | 필수 | 초기 비밀번호 (6~64자) 예: ******** |
| adminName | string | 필수 | 관리자 이름 (40자 이하) 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 (120자 이하) 예: pharm06@yaknaru.local |
| adminTel | string | - | 전화번호 (20자 이하) 예: 010-1234-5678 |
| roles | array<string> | 필수 | 권한 집합 (1개 이상) — PHARMACY_ADMIN 약사 / SYSTEM_ADMIN 시스템 운영자 예: ['PHARMACY_ADMIN'] |
| pharmacyCodes | array<string> | - | 등록 시 초기 매핑할 약국 코드 목록 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식), PHARMACY_ADMIN 일 때만 의미 예: ['PH-001'] |
{"success":true,"data":…} — data: AdminUserSummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 관리자 계정 메뉴의 상세/수정 모달에서 호출한다. 식별자는 쿼리 id(관리자 PK). 매핑 약국 목록을 포함하며 없으면 COMMON_003. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 관리자 PK (admin_user.admin_id) 예: 31 |
{"success":true,"data":…} — data: AdminUserSummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 헤더 뱃지가 주기적으로 호출한다. 상태 PENDING 인 관리자 계정 수를 {count} 로 돌려주며 60초 인메모리 캐시라 승인/반려 직후 최대 60초 늦게 반영될 수 있다. SYSTEM_ADMIN 토큰 필요.
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 관리자 계정 상세에서 약국을 연결할 때 호출한다. 본문 adminId(관리자 PK) + pharmacyCode. 이미 매핑돼 있으면 그대로 두고, 없는 약국 코드는 COMMON_003. 응답은 갱신된 매핑 목록 전체. 감사기록 ADMIN_USER_PHARMACY_ADD. SYSTEM_ADMIN 토큰 필요.
application/json — PharmacyMappingRequest관리자-약국 매핑 추가 요청 — POST /api/v1/admin/admin-users/pharmacies/add
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | integer | 필수 | 대상 관리자 PK — GET /api/v1/admin/admin-users 목록의 id 예: 3 |
| pharmacyCode | string | 필수 | 매핑할 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
{"success":true,"data":…} — data: array<PharmacyMappingItem> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 관리자 계정 상세에서 약국 연결을 끊을 때 호출한다. 본문 adminId(관리자 PK) + pharmacyId(약국 PK, 코드 아님). 응답은 갱신된 매핑 목록 전체. 매핑이 모두 없어진 약사는 처방전·주문 메뉴에서 아무 것도 보지 못한다. 감사기록 ADMIN_USER_PHARMACY_REMOVE. SYSTEM_ADMIN 토큰 필요.
application/json — PharmacyMappingRemoveRequest관리자-약국 매핑 해제 요청 — POST /api/v1/admin/admin-users/pharmacies/remove
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | integer | 필수 | 대상 관리자 PK — GET /api/v1/admin/admin-users 목록의 id 예: 3 |
| pharmacyId | integer | 필수 | 해제할 약국 PK — 관리자 상세(/detail) pharmacies 항목의 pharmacyId 예: 1 |
{"success":true,"data":…} — data: array<PharmacyMappingItem> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 관리자 계정 메뉴에서 운영자가 다른 계정의 비밀번호를 바로 바꿀 때 호출한다. 대상은 본문 adminId, 현재 비밀번호 검증 없이 newPassword(6~64자)로 교체한다. 감사기록 ADMIN_USER_PASSWORD_RESET 을 남기되 비밀번호 값은 기록하지 않는다. SYSTEM_ADMIN 토큰 필요.
application/json — ResetPasswordByAdminRequest관리자 비밀번호 초기화 요청 — POST /api/v1/admin/admin-users/reset-password (SYSTEM_ADMIN 이 타 계정 비밀번호 재설정)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | integer | 필수 | 대상 관리자 PK — GET /api/v1/admin/admin-users 목록의 id 예: 3 |
| newPassword | string | 필수 | 새 비밀번호 (6~64자) 예: ******** |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 관리자 계정 메뉴의 수정 모달에서 호출한다. 대상은 본문 adminId(PK). 이름·이메일·전화·역할(roles)·상태(adminState: ACTIVE/SUSPENDED/WITHDRAWN)를 부분 수정하며 null 은 유지. 본인 계정의 역할·상태 변경은 락아웃 방지를 위해 COMMON_001 로 거절된다. 변경 전/후 값으로 감사기록 ADMIN_USER_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — UpdateRequest앱 구동 설정 갱신 요청 — POST /api/v1/app/setting/update (관리자, null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| platform | string | 필수 | 대상 플랫폼 — android / ios 예: android |
| up_bool | string | - | 강제 업데이트 사용 여부 — yes / no, null = 미변경 예: no |
| up_build | integer | - | 강제 업데이트 기준 빌드 번호 — null = 미변경 예: 12 |
| up_img | string | - | 업데이트 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/update.png |
| up_img_width | integer | - | 업데이트 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| up_img_height | integer | - | 업데이트 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
| agree_bool | string | - | 약관 재동의 강제 여부 — yes / no, null = 미변경 예: no |
| agree_no | integer | - | 재동의가 필요한 약관 버전 번호 — null = 미변경 예: 2 |
| popup_bool | string | - | 팝업 노출 여부 — yes / no, null = 미변경 예: no |
| popup_img | string | - | 팝업 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/popup.png |
| server_bool | string | - | 서버 점검 중 여부 — yes / no, null = 미변경 예: no |
| server_img | string | - | 점검 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/maint.png |
| server_img_width | integer | - | 점검 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| server_img_height | integer | - | 점검 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
{"success":true,"data":…} — data: AdminUserSummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 시스템 관리 > 약품 마스터 메뉴. 심평원 약제급여목록표(약가파일) 엑셀을 적재하고 EDI 약품코드로 약품명·업체·상한가를 조회한다. 적재는 SYSTEM_ADMIN 전용, 조회는 약사(PHARMACY_ADMIN)도 처방전 상세에서 쓴다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/drug-master/lookup | 약품 코드 조회 | 관리자 토큰 |
| GET | /api/v1/admin/drug-master/status | 약품 마스터 적재 현황 | 관리자 토큰 |
| POST | /api/v1/admin/drug-master/upload | 약제급여목록표 엑셀 업로드 (전체 교체) | SYSTEM_ADMIN 토큰 |
관리자웹 처방전 상세(크게보기)에서 약품코드 입력 시 약품명 자동 조회와 약품 마스터 메뉴의 검색에서 호출한다. 식별자는 쿼리 code(EDI 9자리 보험코드, 공백은 COMMON_001). 약품 마스터를 먼저 찾고(source=MASTER) 없으면 대체약품 자료의 원처방 약품명으로 대신하며(SUBSTITUTE), 둘 다 없으면 NONE. 같은 코드의 대체약품 목록(substitutes)을 항상 함께 돌려준다. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| code | query | string | 필수 | EDI 약품코드 (9자리 숫자) 예: 641102470 |
object (조회 성공 (미등록 코드도 200 + source=NONE))
{
"success": true,
"data": {
"ediCode": "641102470",
"name": "타이레놀정500밀리그램",
"company": "한국얀센",
"price": 51,
"source": "MASTER",
"substitutes": []
}
}{"success":true,"data":…} — data: DrugLookupView (조회 성공 (미등록 코드도 200 + source=NONE))
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약품 마스터 메뉴 상단 현황 카드에서 호출한다. 적재된 약품 수(count)와 가장 최근 적재 시각(lastLoadedAt, 없으면 생략)을 돌려준다. 관리자 토큰(SYSTEM_ADMIN 또는 PHARMACY_ADMIN) 필요.
{"success":true,"data":…} — data: StatusView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 약품 마스터 메뉴의 업로드 버튼. multipart 파트명 file 로 심평원 약제급여목록 및 급여상한금액표 엑셀을 올린다. 상단 30행에서 '제품코드'와 '제품명' 헤더 행을 자동으로 찾고(못 찾으면 COMMON_001), 제품코드가 9자리 숫자인 행만 적재하며 중복 코드는 뒤 행이 이긴다. 기존 마스터를 모두 지운 뒤 다시 넣는 전체 교체라 실패하면 롤백된다. 응답 loaded/skipped/total. 감사기록 DRUG_MASTER_UPLOAD. SYSTEM_ADMIN 토큰 필요.
multipart/form-data| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| file | file(binary) | 필수 | 심평원 약제급여목록표 엑셀 파일 (xls/xlsx) |
{"success":true,"data":…} — data: UploadResult (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
원외처방 대체약품 자료(원처방 약품 ↔ 같은 주성분 대체 약품 매핑) 조회 전용. 관리자웹 처방전 상세의 대체약 조회 팝업이 사용한다. 관리자 토큰(SYSTEM_ADMIN 또는 PHARMACY_ADMIN) 필요. 자료 적재 API 는 없고 DB 에 직접 넣는다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/substitute-medicines | 대체약품 검색 | 관리자 토큰 |
| GET | /api/v1/admin/substitute-medicines/detail | 대체약품 상세 | 관리자 토큰 |
| GET | /api/v1/admin/substitute-medicines/lookup | 약품코드로 대체약 조회 | 관리자 토큰 |
keyword(약품명·코드·업체 부분 일치)와 hasSubstitute(true 면 대체약이 있는 행만)로 거른 페이징 목록. 관리자웹에 전용 화면은 아직 없다. perPage 는 1~100. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| keyword | query | string | - | 검색어 (약품명·약품코드·업체명 부분 일치) 예: 타이레놀 |
| hasSubstitute | query | boolean | - | 대체약 존재 여부 필터 (true / false, 미지정 = 전체) 예: True |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 (최대 100) 예: 20 |
{"success":true,"data":…} — data: Page<SubstituteMedicineView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
식별자는 쿼리 id(대체약품 행 id). 원처방 약품·3개월/월 사용량·대체 약품·수수료율을 한 행으로 돌려주며 없으면 COMMON_003. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 대체약품 행 id 예: 120 |
{"success":true,"data":…} — data: SubstituteMedicineView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 처방전 상세의 대체약 조회 팝업에서 호출한다. 쿼리 medicineCode(처방전 약품코드 = 품목코드)와 정확히 일치하는 원처방 행을 모두 돌려주며, 각 행의 substitute* 필드가 대체 약품이다(hasSubstitute=false 면 대체약 없음). 빈 값이면 빈 배열. 관리자 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| medicineCode | query | string | 필수 | 처방전 약품코드 (품목코드, 정확 일치) 예: 641102470 |
{"success":true,"data":…} — data: array<SubstituteMedicineView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 건강샵 관리 메뉴(상품 관리 / 주문 관리 / 운영 설정). 앱 건강샵에 노출할 상품과 배송비 정책, 건강샵 주문 상태를 관리한다. SYSTEM_ADMIN 토큰 전용이며 쓰기 작업은 모두 감사기록을 남긴다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| GET | /api/v1/admin/shop/orders | 건강샵 주문 전체 목록 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/shop/orders/update-status | 건강샵 주문 상태 변경 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/shop/products | 상품 전체 목록 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/shop/products/create | 상품 등록 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/shop/products/delete | 상품 삭제 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/shop/products/update | 상품 수정 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/shop/settings | 운영 설정 조회 (배송비 정책) | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/shop/settings/update | 운영 설정 수정 (배송비 정책) | SYSTEM_ADMIN 토큰 |
관리자웹 건강샵 주문 관리 메뉴의 목록. 모든 회원의 주문을 최신순으로 돌려준다(페이징 없음). id 는 주문번호(SO-YYYYMMDD-###), memberId 는 회원 로그인 아이디. SYSTEM_ADMIN 토큰 필요.
object (조회 성공)
{
"success": true,
"data": [
{
"id": "SO-20260911-001",
"date": "2026-09-11",
"memberId": "hong123",
"status": "PAID",
"statusLabel": "결제 완료",
"deliveryFee": 3000,
"total": 18900,
"items": [
{
"productId": "HP-001",
"productName": "비타민C 1000",
"quantity": 1,
"price": 15900
}
],
"delivery": {
"name": "홍길동",
"phone": "010-1234-5678",
"zipcode": "06578",
"address": "서울특별시 서초구 반포대로 45",
"detailAddress": "101동 202호",
"memo": "문 앞에 놓아주세요"
}
}
]
}{"success":true,"data":…} — data: array<OrderView> (조회 성공)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 건강샵 주문 관리 메뉴의 상태 변경. 대상은 본문 orderNo, status 는 PAID(결제 완료) / SHIPPING(배송 중) / DELIVERED(배송 완료) 중 하나(그 외는 COMMON_001). 상태 순서 검증이나 회원 푸시는 없다. 감사기록 SHOP_ORDER_STATUS_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — StatusUpdateRequest건강샵 주문 상태 변경 요청 — POST /api/v1/admin/shop/orders/update-status
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| orderNo | string | 필수 | 대상 주문번호 — GET /api/v1/admin/shop/orders 의 id (SO-YYYYMMDD-### 형식) 예: SO-20260911-001 |
| status | string | 필수 | 변경할 상태 코드 — PAID 결제 완료 / SHIPPING 배송 중 / DELIVERED 배송 완료 예: SHIPPING |
{"success":true,"data":…} — data: OrderView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 상품 관리 메뉴의 목록. 숨김(visible=false) 상품까지 포함해 최신 등록순으로 돌려주되 삭제된 상품은 제외한다. SYSTEM_ADMIN 토큰 필요.
{"success":true,"data":…} — data: array<ProductView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 상품 관리 메뉴의 등록 모달. category, name, price 필수. 상품 코드는 HP-### 로 자동 채번되고 visible 을 비우면 노출된다. 정가(originalPrice)는 할인 표시용이라 판매가(price)보다 커야 하며 아니면 COMMON_001. 감사기록 SHOP_PRODUCT_CREATE. SYSTEM_ADMIN 토큰 필요.
application/json — ProductCreateRequest상품 등록 요청 — POST /api/v1/admin/shop/products/create (상품 코드 HP-### 자동 채번)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| category | string | 필수 | 상품 카테고리명 예: 비타민 |
| emoji | string | - | 카테고리 대표 이모지 예: 🍊 |
| name | string | 필수 | 상품명 예: 멀티비타민 미네랄 90정 |
| brand | string | - | 브랜드명 예: 약나루 헬스 |
| brief | string | - | 한 줄 소개 예: 하루 1정으로 챙기는 12종 비타민 + 8종 미네랄 |
| price | integer | 필수 | 판매가 (원) 예: 24900 |
| originalPrice | integer | - | 할인 전 정가 (원) — null = 할인 없음 예: 32000 |
| badge | string | - | 뱃지 — BEST / NEW 예: BEST |
| visible | boolean | - | 앱 노출 여부 — null = true 예: True |
| functionality | string | - | 기능성 내용 (줄바꿈 구분) 예: 비타민 A·C·D·E 등 12종 비타민 보충 |
| intake | string | - | 섭취 방법 예: 1일 1회, 1회 1정을 물과 함께 섭취 |
| caution | string | - | 섭취 시 주의사항 예: 특정 질환이 있거나 의약품 복용 시 전문가와 상담 후 섭취하세요. |
| image | string | - | 대표 이미지 (URL 또는 data URI) 예: https://cdn.yaknaru.co.kr/shop/HP-001.png |
| detailImages | array<string> | - | 상세 이미지 목록 (URL 또는 data URI) 예: ['https://cdn.yaknaru.co.kr/shop/HP-001_1.png'] |
{"success":true,"data":…} — data: ProductView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 상품 관리 메뉴의 삭제 버튼. 대상은 본문 productCode. soft delete 라 앱·관리자 목록에서 사라지지만 기존 주문의 상품 스냅샷에는 영향이 없다. 감사기록 SHOP_PRODUCT_DELETE. SYSTEM_ADMIN 토큰 필요.
application/json — ProductDeleteRequest상품 삭제 요청 — POST /api/v1/admin/shop/products/delete
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| productCode | string | 필수 | 삭제 대상 상품 코드 — GET /api/v1/shop/products 의 id (HP-001 형식) 예: HP-001 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 상품 관리 메뉴의 수정 모달. 대상은 본문 productCode(HP-###, 없거나 삭제된 상품은 COMMON_003). 보낸 항목만 바꾸고 null 은 유지하며 정가 > 판매가 검증은 수정 후 값 기준으로 다시 한다. visible=false 로 두면 앱 목록에서 즉시 사라진다. 감사기록 SHOP_PRODUCT_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — ProductUpdateRequest상품 부분 수정 요청 — POST /api/v1/admin/shop/products/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| productCode | string | 필수 | 대상 상품 코드 — GET /api/v1/shop/products 의 id (HP-001 형식) 예: HP-001 |
| category | string | - | 상품 카테고리명 — null = 미변경 예: 비타민 |
| emoji | string | - | 카테고리 대표 이모지 — null = 미변경 예: 🍊 |
| name | string | - | 상품명 — null = 미변경 예: 멀티비타민 미네랄 90정 |
| brand | string | - | 브랜드명 — null = 미변경 예: 약나루 헬스 |
| brief | string | - | 한 줄 소개 — null = 미변경 예: 하루 1정으로 챙기는 12종 비타민 + 8종 미네랄 |
| price | integer | - | 판매가 (원) — null = 미변경 예: 24900 |
| originalPrice | integer | - | 할인 전 정가 (원) — null = 미변경 예: 32000 |
| badge | string | - | 뱃지 — BEST / NEW, null = 미변경 예: BEST |
| visible | boolean | - | 앱 노출 여부 — null = 미변경 예: True |
| functionality | string | - | 기능성 내용 — null = 미변경 예: 비타민 A·C·D·E 등 12종 비타민 보충 |
| intake | string | - | 섭취 방법 — null = 미변경 예: 1일 1회, 1회 1정을 물과 함께 섭취 |
| caution | string | - | 섭취 시 주의사항 — null = 미변경 예: 특정 질환이 있거나 의약품 복용 시 전문가와 상담 후 섭취하세요. |
| image | string | - | 대표 이미지 (URL 또는 data URI) — null = 미변경 예: https://cdn.yaknaru.co.kr/shop/HP-001.png |
| detailImages | array<string> | - | 상세 이미지 목록 — null = 미변경 예: ['https://cdn.yaknaru.co.kr/shop/HP-001_1.png'] |
{"success":true,"data":…} — data: ProductView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 운영 설정 메뉴에서 호출한다. 앱과 같은 값(deliveryFee, freeThreshold)을 돌려준다. SYSTEM_ADMIN 토큰 필요.
{"success":true,"data":…} — data: SettingView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 운영 설정 메뉴의 저장 버튼. deliveryFee(기본 배송비), freeThreshold(무료배송 기준 금액) 중 보낸 항목만 바꾸며 음수는 COMMON_001. 이후 생성되는 주문부터 새 배송비가 적용된다. 변경 전/후 값으로 감사기록 SHOP_SETTING_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — SettingUpdateRequest건강샵 운영 설정 변경 요청 — POST /api/v1/admin/shop/settings/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| deliveryFee | integer | - | 기본 배송비 (원) — null = 미변경 예: 3000 |
| freeThreshold | integer | - | 무료 배송 기준 주문 금액 (원) — null = 미변경 예: 30000 |
{"success":true,"data":…} — data: SettingView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 게시판 관리 메뉴(공지 관리 / FAQ 관리 / QnA 답변 / 카테고리). 앱에 보이는 공지·FAQ 작성과 회원 문의 답변, FAQ·QnA 카테고리 운영. SYSTEM_ADMIN 토큰 전용이며 쓰기 작업은 모두 감사기록을 남긴다. 목록 조회(공지·FAQ)는 앱과 같은 공개 API(/api/v1/bbs/notices, /faqs)를 쓴다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/admin/bbs/categories/delete | 카테고리 비활성화 (삭제) | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/categories/update | 카테고리 수정 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/faqs | FAQ 작성 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/faqs/delete | FAQ 삭제 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/faqs/update | FAQ 수정 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/notices | 공지 작성 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/notices/delete | 공지 삭제 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/notices/update | 공지 수정 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/bbs/qnas | QnA 목록 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/qnas/answer | QnA 답변 작성/수정 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/bbs/qnas/detail | QnA 상세 | SYSTEM_ADMIN 토큰 |
| GET | /api/v1/admin/bbs/{board}-categories | 카테고리 목록 | SYSTEM_ADMIN 토큰 |
| POST | /api/v1/admin/bbs/{board}-categories/create | 카테고리 작성 | SYSTEM_ADMIN 토큰 |
관리자웹 카테고리 메뉴의 삭제 버튼. 대상은 본문 categoryId. 행을 지우지 않고 active=false 로 바꿔 앱 목록에서만 숨기며, 그 카테고리를 쓰던 글은 그대로 남는다. 감사기록 BBS_CATEGORY_DELETE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminCategoryDeleteRequest게시판 카테고리 삭제(비활성) 요청 — POST /api/v1/admin/bbs/categories/delete
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| categoryId | integer | 필수 | 삭제 대상 카테고리 PK — GET /api/v1/admin/bbs/{board}-categories 의 id 예: 2 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 카테고리 메뉴의 수정 모달. 대상은 본문 categoryId(없으면 COMMON_003). name / sort / active 중 보낸 항목만 바꾸고 null 은 유지. 게시판 종류는 바꿀 수 없다. 감사기록 BBS_CATEGORY_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminCategoryUpdateRequest게시판 카테고리 부분 수정 요청 — POST /api/v1/admin/bbs/categories/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| categoryId | integer | 필수 | 수정 대상 카테고리 PK — GET /api/v1/admin/bbs/{board}-categories 의 id 예: 2 |
| name | string | - | 카테고리명 — null = 미변경 예: 배송/결제 |
| sort | integer | - | 정렬 순서 — null = 미변경 예: 1 |
| active | boolean | - | 활성 여부 (false 면 목록에서 숨김) — null = 미변경 예: True |
{"success":true,"data":…} — data: CategoryView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 FAQ 관리 메뉴의 등록 모달. subject(질문), contents(답변) 필수, categoryId 는 앱 탭 분류용이며 없는 카테고리면 COMMON_001. 공지와 달리 푸시는 나가지 않는다. 감사기록 BBS_FAQ_CREATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPostCreateRequest공지/FAQ 작성 요청 — POST /api/v1/admin/bbs/notices, /faqs
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| subject | string | 필수 | 제목 예: 추석 연휴 배송 안내 |
| contents | string | 필수 | 본문 (HTML/텍스트) 예: 추석 연휴 기간(10/3~10/6) 동안 택배 배송이 지연될 수 있습니다. |
| categoryId | integer | - | 카테고리 PK — GET /api/v1/admin/bbs/faq-categories 의 id, FAQ 는 필수 / 공지는 null 예: 2 |
{"success":true,"data":…} — data: PostView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 FAQ 관리 메뉴의 삭제 버튼. 대상은 본문 postId. soft delete. 감사기록 BBS_FAQ_DELETE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPostDeleteRequest공지/FAQ 삭제 요청 — POST /api/v1/admin/bbs/notices/delete, /faqs/delete
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 삭제 대상 게시글 PK — GET /api/v1/bbs/notices, /faqs 목록의 id 예: 15 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 FAQ 관리 메뉴의 수정 모달. 대상은 본문 postId(FAQ 가 아니거나 삭제된 글은 COMMON_003). 보낸 항목만 바꾸고 null 은 유지. 감사기록 BBS_FAQ_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPostUpdateRequest공지/FAQ 부분 수정 요청 — POST /api/v1/admin/bbs/notices/update, /faqs/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 수정 대상 게시글 PK — GET /api/v1/bbs/notices, /faqs 목록의 id 예: 15 |
| subject | string | - | 제목 — null = 미변경 예: 추석 연휴 배송 안내 |
| contents | string | - | 본문 — null = 미변경 예: 추석 연휴 기간(10/3~10/6) 동안 택배 배송이 지연될 수 있습니다. |
| categoryId | integer | - | 카테고리 PK (FAQ) — null = 미변경 예: 2 |
{"success":true,"data":…} — data: PostView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 공지 관리 메뉴의 등록 모달. subject, contents 필수, categoryId 는 선택(없는 카테고리면 COMMON_001). 저장 즉시 전체 회원에게 FCM 푸시(새 공지가 등록되었습니다, relatedType=notice)가 broadcast 되므로 임시 저장 용도로 쓰면 안 된다. 감사기록 BBS_NOTICE_CREATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPostCreateRequest공지/FAQ 작성 요청 — POST /api/v1/admin/bbs/notices, /faqs
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| subject | string | 필수 | 제목 예: 추석 연휴 배송 안내 |
| contents | string | 필수 | 본문 (HTML/텍스트) 예: 추석 연휴 기간(10/3~10/6) 동안 택배 배송이 지연될 수 있습니다. |
| categoryId | integer | - | 카테고리 PK — GET /api/v1/admin/bbs/faq-categories 의 id, FAQ 는 필수 / 공지는 null 예: 2 |
{"success":true,"data":…} — data: PostView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 공지 관리 메뉴의 삭제 버튼. 대상은 본문 postId. soft delete 라 앱 목록·상세에서 즉시 사라지지만 DB 행은 남는다. 감사기록 BBS_NOTICE_DELETE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPostDeleteRequest공지/FAQ 삭제 요청 — POST /api/v1/admin/bbs/notices/delete, /faqs/delete
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 삭제 대상 게시글 PK — GET /api/v1/bbs/notices, /faqs 목록의 id 예: 15 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 공지 관리 메뉴의 수정 모달. 대상은 본문 postId(공지가 아니거나 삭제된 글은 COMMON_003). subject/contents/categoryId 중 보낸 항목만 바꾸고 null 은 유지. 푸시는 다시 나가지 않는다. 감사기록 BBS_NOTICE_UPDATE. SYSTEM_ADMIN 토큰 필요.
application/json — AdminPostUpdateRequest공지/FAQ 부분 수정 요청 — POST /api/v1/admin/bbs/notices/update, /faqs/update (null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 수정 대상 게시글 PK — GET /api/v1/bbs/notices, /faqs 목록의 id 예: 15 |
| subject | string | - | 제목 — null = 미변경 예: 추석 연휴 배송 안내 |
| contents | string | - | 본문 — null = 미변경 예: 추석 연휴 기간(10/3~10/6) 동안 택배 배송이 지연될 수 있습니다. |
| categoryId | integer | - | 카테고리 PK (FAQ) — null = 미변경 예: 2 |
{"success":true,"data":…} — data: PostView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 QnA 답변 메뉴의 목록. status 로 WAITING(답변대기)/ANSWERED(답변완료)만 거르거나 비우면 전체(그 외 값은 COMMON_001). 응답의 status 는 한글 라벨. perPage 는 1~100. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| status | query | string | - | 상태 필터: WAITING | ANSWERED (미지정 = 전체) 예: WAITING |
| page | query | integer (기본 0) | - | 페이지 번호(0부터) 예: 0 |
| perPage | query | integer (기본 20) | - | 페이지 크기 (최대 100) 예: 20 |
{"success":true,"data":…} — data: Page<QnaView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 QnA 답변 메뉴의 답변 저장 버튼. 대상은 본문 postId, answer 필수. 답변을 저장하고 상태를 답변완료(ANSWERED)로 바꾸며 답변 시각을 기록한다. 질문한 회원에게 FCM 푸시(문의 답변 도착, relatedType=qna)를 보낸다(이미 답변된 글을 수정해도 다시 발송). 변경 전/후 값으로 감사기록 BBS_QNA_ANSWER. SYSTEM_ADMIN 토큰 필요.
application/json — AdminQnaAnswerRequest1:1 문의 관리자 답변 요청 — POST /api/v1/admin/bbs/qnas/answer (답변 저장 시 상태 답변완료)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 답변 대상 문의글 PK — GET /api/v1/admin/bbs/qnas 목록의 id 예: 42 |
| answer | string | 필수 | 답변 내용 예: 결제 완료 후 보통 1~2일 내 도착합니다. |
{"success":true,"data":…} — data: QnaView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 QnA 답변 메뉴의 답변 모달에서 호출한다. 식별자는 쿼리 id(문의 글 id). 질문·기존 답변·작성 회원 id 를 돌려주며 삭제되었거나 QnA 가 아니면 COMMON_003. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| id | query | integer | 필수 | 문의 글 id 예: 15 |
{"success":true,"data":…} — data: QnaView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 카테고리 메뉴와 FAQ/QnA 등록 모달의 선택 목록. 경로의 board 는 faq 또는 qna. includeInactive=true 면 비활성 카테고리도 포함한다. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| board | path | string | 필수 | 게시판 종류: faq | qna 예: faq |
| includeInactive | query | boolean (기본 False) | - | 비활성 카테고리 포함 여부 예: False |
{"success":true,"data":…} — data: array<CategoryView> (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자웹 카테고리 메뉴의 등록 모달. 경로의 board 는 faq 또는 qna, 본문 name 필수, sort 는 정렬 순서(기본 0). 활성 상태로 만들어진다. 감사기록 BBS_CATEGORY_CREATE. SYSTEM_ADMIN 토큰 필요.
| 이름 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
| board | path | string | 필수 | 게시판 종류: faq | qna 예: faq |
application/json — AdminCategoryCreateRequest게시판 카테고리 생성 요청 — POST /api/v1/admin/bbs/{board}-categories/create (board = faq / qna 는 path)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| name | string | 필수 | 카테고리명 예: 배송/결제 |
| sort | integer | - | 정렬 순서 (오름차순) — null = 기본값 예: 1 |
{"success":true,"data":…} — data: CategoryView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
앱 부팅 시 읽는 플랫폼별 운영 플래그. 강제 업데이트(up_*), 약관 재동의(agree_*), 팝업(popup_*), 서버 점검(server_*) 4종 차단 모달의 트리거. 조회는 공개, 갱신은 SYSTEM_ADMIN 토큰 전용.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/app/setting/update | 앱 부팅 설정 갱신 (관리자) | SYSTEM_ADMIN 토큰 |
SYSTEM_ADMIN 토큰 전용. 관리자웹에 전용 메뉴는 없고 운영자가 직접 호출한다. 대상 플랫폼은 본문 platform(android | ios)이며 null 로 보낸 항목은 유지된다. 변경 전/후 값으로 감사기록 APP_SETTING_UPDATE 를 남긴다. 앱은 다음 부팅부터 새 값을 읽는다.
application/json — UpdateRequest앱 구동 설정 갱신 요청 — POST /api/v1/app/setting/update (관리자, null 필드는 미변경)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| platform | string | 필수 | 대상 플랫폼 — android / ios 예: android |
| up_bool | string | - | 강제 업데이트 사용 여부 — yes / no, null = 미변경 예: no |
| up_build | integer | - | 강제 업데이트 기준 빌드 번호 — null = 미변경 예: 12 |
| up_img | string | - | 업데이트 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/update.png |
| up_img_width | integer | - | 업데이트 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| up_img_height | integer | - | 업데이트 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
| agree_bool | string | - | 약관 재동의 강제 여부 — yes / no, null = 미변경 예: no |
| agree_no | integer | - | 재동의가 필요한 약관 버전 번호 — null = 미변경 예: 2 |
| popup_bool | string | - | 팝업 노출 여부 — yes / no, null = 미변경 예: no |
| popup_img | string | - | 팝업 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/popup.png |
| server_bool | string | - | 서버 점검 중 여부 — yes / no, null = 미변경 예: no |
| server_img | string | - | 점검 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/maint.png |
| server_img_width | integer | - | 점검 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| server_img_height | integer | - | 점검 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
{"success":true,"data":…} — data: AppSettingView (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
약 배송(택배 수령) 자격 신청. 회원이 4종 카테고리 중 하나를 골라 증빙 서류를 올리면 심사중(I)으로 접수되고 관리자가 승인(S)/반려(R)한다. 승인/반려 오퍼레이션은 관리자 토큰 전용이며 관리자 API 의 /admin/eligibility/approve, /reject 와 같은 동작이다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/eligibility/approve | 자격 승인 (관리자) | 관리자 토큰 |
| POST | /api/v1/eligibility/reject | 자격 반려 (관리자) | 관리자 토큰 |
관리자 토큰(SYSTEM_ADMIN 또는 PHARMACY_ADMIN) 전용. 대상은 본문 eligibilityId. 상태를 S(승인)로 바꾸고 신청 회원에게 FCM 푸시(약 배송 자격 승인)를 보내며 감사기록 ELIGIBILITY_APPROVE 를 남긴다. 관리자웹 약 배송 자격 메뉴는 같은 동작의 /api/v1/admin/eligibility/approve 를 호출한다.
application/json — ApproveRequest자격 승인 요청 — POST /api/v1/admin/eligibility/approve (상태 I → S)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| eligibilityId | integer | 필수 | 승인 대상 자격 신청 PK — GET /api/v1/admin/eligibility 목록의 id 예: 21 |
{"success":true,"data":…} — data: EligibilitySummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
관리자 토큰(SYSTEM_ADMIN 또는 PHARMACY_ADMIN) 전용. 대상은 본문 eligibilityId, reason 을 비우면 '사유 미입력' 으로 저장된다. 상태를 R(반려)로 바꾸고 신청 회원에게 FCM 푸시(약 배송 자격 반려, payload 에 reason)를 보내며 감사기록 ELIGIBILITY_REJECT 를 남긴다. 관리자웹 약 배송 자격 메뉴는 같은 동작의 /api/v1/admin/eligibility/reject 를 호출한다.
application/json — RejectRequest자격 반려 요청 — POST /api/v1/admin/eligibility/reject (상태 I → R, 사유 회원 노출)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| eligibilityId | integer | 필수 | 반려 대상 자격 신청 PK — GET /api/v1/admin/eligibility 목록의 id 예: 21 |
| reason | string | - | 반려 사유 — 회원 앱에 rejectDesc 로 노출 예: 서류 식별이 불가하여 재제출이 필요합니다. |
{"success":true,"data":…} — data: EligibilitySummary (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
FCM 토큰 구독/해제와 앱 알림함(인박스). 서버가 발송한 모든 푸시는 메시지 이력으로 남아 알림함에서 다시 볼 수 있다. 발송(send)은 SYSTEM_ADMIN 전용이며, 처방전 상태 변경·자격 심사·공지·문의 답변 푸시는 각 서비스가 자동으로 발송한다.
| 메서드 | 경로 | 요약 | 권한 |
|---|---|---|---|
| POST | /api/v1/push/send | 푸시 수동 발송 (관리자) | SYSTEM_ADMIN 토큰 |
SYSTEM_ADMIN 토큰 전용. 관리자웹에 전용 메뉴는 없고 운영자가 직접 호출한다. memberId 를 주면 그 회원의 마지막 로그인 폰 1대에, 비우면 전체 회원(회원별 최신 토큰 1개씩)에 broadcast 한다. 메시지 이력을 먼저 저장한 뒤 FCM 으로 보내며 응답 {messageId} 는 그 이력 id. 감사기록 PUSH_SEND 를 남긴다.
application/json — SendRequest관리자 푸시 발송 요청 — POST /api/v1/push/send (memberId 없으면 전체 발송)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memberId | integer | - | 수신 회원 PK — GET /api/v1/admin/members 목록의 id, null = 전체 발송(broadcast) 예: 7 |
| title | string | 필수 | 알림 제목 예: 추석 연휴 배송 안내 |
| body | string | 필수 | 알림 본문 예: 연휴 기간 택배 배송이 지연될 수 있습니다. |
| payload | string | - | 앱 딥링크용 부가 데이터 (JSON 문자열) 예: {'screen': 'NoticeDetail', 'id': 15} |
| relatedType | string | - | 연관 대상 유형 — order / delivery / eligibility / notice 등 예: notice |
| relatedId | integer | - | 연관 대상 PK 예: 15 |
{"success":true,"data":…} — data: object (OK)
오류 응답: 400 잘못된 요청 (필수값 누락, 형식·검증 실패, 알 수 없는 코드값, 깨진 JSON·UTF-8 아닌 인코딩) · 401 인증 실패 (토큰 없음 AUTH_001 / 만료 AUTH_003 / 위조 AUTH_004) · 403 권한 없음 (역할 부족, 다른 종류의 토큰, 타인 자원 접근)
공통 래퍼 ApiResponse<T> = {success, data:T, error:{code,message}} 와 Spring Data 페이지 래퍼 Page<T> = {content:T[], totalElements, totalPages, number, size, last, first, empty} 는 아래 목록에서 생략함. 필드명 옆 필수는 OpenAPI required 선언 기준임.
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| deliveryAddressSeq | integer | - | 배송지 PK — 수정/삭제 요청의 addressId 로 사용 예: 12 |
| deliveryAddressName | string | - | 받는 분 이름 예: 홍길동 |
| deliveryAddressPhone | string | - | 받는 분 연락처 — 숫자/하이픈 예: 010-1234-5678 |
| deliveryAddressZipcode | string | - | 우편번호 (5자리) 예: 48058 |
| deliveryAddress | string | - | 기본 주소 (도로명/지번) 예: 부산광역시 해운대구 센텀중앙로 79 |
| deliveryDetailAddress | string | - | 상세 주소 (동/호수) 예: 101동 1203호 |
| roadName | string | - | 도로명 — 비배송 지역 판정(POST /api/v1/pharmacies/check-delivery)에 사용 예: 센텀중앙로 |
| isDefault | boolean | - | 기본 배송지 여부 — 회원당 1건만 true 예: True |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| name | string | 필수 | 카테고리명 예: 배송/결제 |
| sort | integer | - | 정렬 순서 (오름차순) — null = 기본값 예: 1 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| categoryId | integer | 필수 | 삭제 대상 카테고리 PK — GET /api/v1/admin/bbs/{board}-categories 의 id 예: 2 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| categoryId | integer | 필수 | 수정 대상 카테고리 PK — GET /api/v1/admin/bbs/{board}-categories 의 id 예: 2 |
| name | string | - | 카테고리명 — null = 미변경 예: 배송/결제 |
| sort | integer | - | 정렬 순서 — null = 미변경 예: 1 |
| active | boolean | - | 활성 여부 (false 면 목록에서 숨김) — null = 미변경 예: True |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 관리자 PK (admin_user.admin_id) — 관리자 계정 관리 API 의 adminId 로 사용 예: 3 |
| adminId | string | - | 관리자 로그인 아이디 예: pharmacist01 |
| adminName | string | - | 관리자 이름 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 예: pharm01@yaknaru.local |
| adminTel | string | - | 관리자 전화번호 예: 010-1234-5678 |
| adminState | string | - | 계정 상태 — PENDING 검토대기(로그인 차단) / ACTIVE 정상 / SUSPENDED 정지 / WITHDRAWN 탈퇴 예: ACTIVE |
| roles | array<string> | - | 권한 집합 — PHARMACY_ADMIN 약사 / SYSTEM_ADMIN 시스템 운영자 예: ['PHARMACY_ADMIN'] |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | string | 필수 | 관리자 로그인 아이디 — 약사 회원가입(POST /api/v1/pharmacist/signup) 또는 SYSTEM_ADMIN 등록 시 지정 예: pharmacist01 |
| adminPass | string | 필수 | 비밀번호 (평문, TLS 구간 전송) 예: ******** |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| code | string | - | 약품 코드 (EDI 보험코드 9자리) 예: 640007270 |
| name | string | - | 약품명 예: 타이레놀정500mg |
| dosage | string | - | 1회 투약량 예: 1 |
| daysTotal | string | - | 총 투약 일수 예: 3 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memberId | integer | 필수 | 대상 회원 PK — GET /api/v1/admin/members 목록의 id 예: 7 |
| state | string | 필수 | 변경할 회원 상태 — ACTIVE 정상 / DORMANT 휴면 / SUSPENDED 정지 / WITHDRAWN 탈퇴 예: SUSPENDED |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 회원 PK — 상태 변경 요청(POST /api/v1/admin/members/update-state)의 memberId 예: 7 |
| memSeq | integer | - | 구 시스템 회원 순번 — V28 이후 컬럼 제거, 항상 null |
| memId | string | - | 로그인 아이디 예: hong1234 |
| memName | string | - | 회원 이름 예: 홍길동 |
| memEmail | string | - | 이메일 예: hong@example.com |
| memTel | string | - | 휴대폰 번호 예: 010-1234-5678 |
| memState | string | - | 회원 상태 — ACTIVE 정상 / DORMANT 휴면 / SUSPENDED 정지 / WITHDRAWN 탈퇴 예: ACTIVE |
| roles | array<string> | - | 권한 집합 — RN 회원은 USER 단일 예: ['USER'] |
| createdAt | string | - | 가입 일시 (ISO-8601 문자열) 예: 2026-05-01T10:00:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 처방전(주문) PK — GET /api/v1/admin/orders/detail?id= 의 id 예: 101 |
| status | string | - | 주문 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료 예: 010 |
| statusName | string | - | 주문 상태 한글 라벨 예: 수령완료 |
| receiveType | string | - | 수령 방식 — onLine 택배배송 / offLine 방문수령 예: onLine |
| memberId | integer | - | 주문 회원 PK (member_info.member_id) 예: 7 |
| memberName | string | - | 수령인 이름 (주문 시점 배송지 스냅샷) 예: 홍길동 |
| memberPhone | string | - | 수령인 연락처 (주문 시점 배송지 스냅샷) 예: 010-1234-5678 |
| pharmacyId | integer | - | 약국 PK (pharmacy.pharmacy_id) — 검색 파라미터 pharmacyId 와 동일 예: 1 |
| pharmacyName | string | - | 약국명 (스냅샷) 예: 약나루약국 남구점 |
| prescriptionPrice | number | - | 약제비 (원) 예: 12500 |
| deliveryPrice | number | - | 배송비 (원) 예: 3000 |
| totalPrice | number | - | 총 결제 금액 (원) 예: 15500 |
| deliveryNumber | string | - | 택배 송장번호 예: 6889012345678 |
| deliveryCompany | string | - | 택배사명 (CJ대한통운/우체국 등) — 배송중(06) 전환 시 약사 입력 예: CJ대한통운 |
| reqDate | string | - | 주문(처방전 접수) 일시 (ISO-8601) 예: 2026-09-11T09:30:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — 약사 회원가입 응답의 pharmacyCode (PH-001 형식) 예: PH-006 |
| reviewMemo | string | - | 승인 시 남길 검토 메모 예: 서류 확인 완료, 승인 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| pharmacyCharge | number | - | 플랫폼 중개 수수료율 (%) — null = 미설정으로 저장 예: 3.5 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 약국 코드 (PH-### 형식, 중복 불가) 예: PH-006 |
| pharmacyName | string | 필수 | 약국명 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 대표 전화 예: 051-123-4567 |
| zipcode | string | - | 우편번호 (5자리) 예: 48434 |
| address | string | - | 약국 기본 주소 예: 부산광역시 남구 수영로 200 |
| detailAddress | string | - | 약국 상세 주소 예: 1층 101호 |
| gpsLat | number | - | 위도 (WGS84) 예: 35.1367 |
| gpsLon | number | - | 경도 (WGS84) 예: 129.0862 |
| deliveryYn | string | - | 택배 배송 지원 여부 — Y / N, null = N 예: Y |
| openTimeMon | string | - | 월요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeTue | string | - | 화요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeWed | string | - | 수요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeThu | string | - | 목요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeFri | string | - | 금요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~18:00 |
| openTimeSat | string | - | 토요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 09:00~13:00 |
| openTimeSun | string | - | 일요일 영업시간 — HH:mm~HH:mm 또는 휴무 예: 휴무 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — 약사 회원가입 응답의 pharmacyCode (PH-001 형식) 예: PH-006 |
| reviewMemo | string | 필수 | 반려 사유 (필수) — 약사에게 통보 예: 사업자등록증 이미지가 식별되지 않습니다. |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| reviewMemo | string | - | 검토 메모 — null/공백 = 메모 삭제 예: 사업자등록증 확인 완료 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | - | 처리된 약국 코드 (PH-001 형식) 예: PH-006 |
| affectedAdminCount | integer | - | 상태가 변경된 약사 계정 수 예: 1 |
| result | string | - | 처리 결과 — APPROVED 승인 / REJECTED 반려 예: APPROVED |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 대상 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| pharmacyName | string | - | 약국명 — null = 미변경 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 대표 전화 — null = 미변경 예: 051-123-4567 |
| zipcode | string | - | 우편번호 (5자리) — null = 미변경 예: 48434 |
| address | string | - | 약국 기본 주소 — null = 미변경 예: 부산광역시 남구 수영로 200 |
| detailAddress | string | - | 약국 상세 주소 — null = 미변경 예: 1층 101호 |
| gpsLat | number | - | 위도 (WGS84) — null = 미변경 예: 35.1367 |
| gpsLon | number | - | 경도 (WGS84) — null = 미변경 예: 129.0862 |
| deliveryYn | string | - | 택배 배송 지원 여부 — Y / N, null = 미변경 예: Y |
| alarmPhone | string | - | 처방전 접수 알림 수신 전화번호 — null = 미변경 예: 010-9876-5432 |
| pharmacistName | string | - | 약사 이름 — null = 미변경 예: 홍길동 |
| pharmacistPhone | string | - | 약사 전화번호 — null = 미변경 예: 010-1234-5678 |
| licenseNum | string | - | 약사 면허번호 — null = 미변경 예: 12345 |
| businessNum | string | - | 사업자등록번호 — null = 미변경 예: 123-45-67890 |
| accountBankName | string | - | 정산 계좌 은행명 — null = 미변경 예: 부산은행 |
| accountBankNumber | string | - | 정산 계좌번호 — null = 미변경 예: 101-2345-6789-01 |
| accountOwner | string | - | 정산 계좌 예금주 — null = 미변경 예: 홍길동 |
| openTimeMon | string | - | 월요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeTue | string | - | 화요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeWed | string | - | 수요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeThu | string | - | 목요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeFri | string | - | 금요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~18:00 |
| openTimeSat | string | - | 토요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 09:00~13:00 |
| openTimeSun | string | - | 일요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미변경 예: 휴무 |
| pharmacyCharge | number | - | 플랫폼 중개 수수료율 (%) — null = 미변경 예: 3.5 |
| reviewMemo | string | - | SYSTEM_ADMIN 검토 메모 — null = 미변경 예: 사업자등록증 확인 완료 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| subject | string | 필수 | 제목 예: 추석 연휴 배송 안내 |
| contents | string | 필수 | 본문 (HTML/텍스트) 예: 추석 연휴 기간(10/3~10/6) 동안 택배 배송이 지연될 수 있습니다. |
| categoryId | integer | - | 카테고리 PK — GET /api/v1/admin/bbs/faq-categories 의 id, FAQ 는 필수 / 공지는 null 예: 2 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 삭제 대상 게시글 PK — GET /api/v1/bbs/notices, /faqs 목록의 id 예: 15 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 수정 대상 게시글 PK — GET /api/v1/bbs/notices, /faqs 목록의 id 예: 15 |
| subject | string | - | 제목 — null = 미변경 예: 추석 연휴 배송 안내 |
| contents | string | - | 본문 — null = 미변경 예: 추석 연휴 기간(10/3~10/6) 동안 택배 배송이 지연될 수 있습니다. |
| categoryId | integer | - | 카테고리 PK (FAQ) — null = 미변경 예: 2 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| postId | integer | 필수 | 답변 대상 문의글 PK — GET /api/v1/admin/bbs/qnas 목록의 id 예: 42 |
| answer | string | 필수 | 답변 내용 예: 결제 완료 후 보통 1~2일 내 도착합니다. |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| refreshToken | string | 필수 | 갱신 토큰 — POST /api/v1/admin/auth/login 응답의 refreshToken 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJwaGFybWFjaXN0MDEiLCJ0eXAiOiJyZWZyZXNoIn0.9qZk… |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | string | 필수 | 관리자 로그인 아이디 예: pharmacist01 |
| adminEmail | string | 필수 | 계정에 등록된 이메일 — 아이디와 일치해야 임시 비밀번호 발송 예: pharm01@yaknaru.local |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyId | integer | - | 약국 PK (pharmacy.pharmacy_id) 예: 1 |
| pharmacyName | string | - | 약국명 예: 약나루약국 남구점 |
| orderCount | integer | - | 집계 대상 주문 건수 예: 42 |
| totalSum | number | - | 총 결제 금액 합계 (원) 예: 651000 |
| prescriptionSum | number | - | 약제비 합계 (원) 예: 525000 |
| deliverySum | number | - | 배송비 합계 (원) 예: 126000 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| rows | array<AdminRevenueRow> | - | 약국별 매출 집계 행 목록 |
| totalOrderCount | integer | - | 전체 주문 건수 (rows 합) 예: 120 |
| totalRevenueSum | number | - | 전체 결제 금액 합계 (원) 예: 1860000 |
| dateFrom | string | - | 조회 시작일 (YYYY-MM-DD, 요청 파라미터 에코) — null = 제한 없음 예: 2026-09-01 |
| dateTo | string | - | 조회 종료일 (YYYY-MM-DD, 요청 파라미터 에코) — null = 제한 없음 예: 2026-09-30 |
| status | string | - | 집계 대상 주문 상태 코드 (기본 010 수령완료) — null = 상태 무시 예: 010 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| tokenType | string | - | 토큰 유형 — 항상 Bearer (Authorization: Bearer {accessToken}) 예: Bearer |
| accessToken | string | - | JWT 액세스 토큰 — 관리자 API 호출 시 Authorization 헤더에 사용 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJwaGFybWFjaXN0MDEiLCJyb2xlcyI6WyJQSEFSTUFDWV9BRE1JTiJdfQ.Kt |
| refreshToken | string | - | 갱신 토큰 — POST /api/v1/admin/auth/refresh 에 사용 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJwaGFybWFjaXN0MDEiLCJ0eXAiOiJyZWZyZXNoIn0.9qZk… |
| expiresIn | integer | - | 액세스 토큰 만료까지 남은 시간 (초) 예: 3600 |
| adminInfo | AdminInfo | - | 로그인한 관리자 요약 정보 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionId | integer | 필수 | 대상 처방전(주문) PK — GET /api/v1/admin/prescriptions 목록의 id 예: 101 |
| hospitalName | string | - | 의료기관 명칭 예: 부산대학교병원 |
| hospitalPhone | string | - | 의료기관 전화번호 예: 051-240-7000 |
| doctorName | string | - | 처방 의사 성명 예: 김의사 |
| doctorLicenseNo | string | - | 의사 면허번호 예: 98765 |
| patientName | string | - | 환자 성명 예: 홍길동 |
| departmentCode | string | - | 진료과목 코드 예: 01 |
| diagnosisCode1 | string | - | 주상병 코드 (KCD) 예: J06.9 |
| diagnosisCode2 | string | - | 부상병 코드 (KCD) 예: R50.9 |
| prescriptionDate | string | - | 처방전 교부일 (YYYY-MM-DD) 예: 2026-09-11 |
| useDays | string | - | 처방전 사용기간 (일) 예: 3 |
| medicines | array<AdminMedicineItem> | - | 약품 목록 — null = 미변경, 리스트 전송 시 기존 약품 전체 교체 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionId | integer | 필수 | 대상 처방전(주문) PK — GET /api/v1/admin/prescriptions 목록의 id 예: 101 |
| status | string | - | 변경할 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료, null = 미변경 예: 06 |
| prescriptionPrice | number | - | 약제비 (원) — null = 미변경 예: 12500 |
| deliveryPrice | number | - | 배송비 (원) — null = 미변경 예: 3000 |
| medicineDirection | string | - | 약사 복약 안내 (회원 노출) — null = 미변경 예: 식후 30분에 1정씩 복용하세요. |
| deliveryNumber | string | - | 택배 송장번호 — 배송중(06) 전환 시 입력, null = 미변경 예: 6889012345678 |
| deliveryCompany | string | - | 택배사명 (CJ대한통운/우체국 등) — 배송중(06) 전환 시 입력, null = 미변경 예: CJ대한통운 |
| unavailableReason | string | - | 조제불가 사유 — status=03 일 때, null = 미변경 예: 재고 부족 |
| pharmacistMemo | string | - | 약사 내부 메모 (회원 미노출) — null = 미변경 예: 재고 확인 필요 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 관리자 PK (admin_user.admin_id) — 수정/비밀번호 초기화/약국 매핑 요청의 adminId 예: 3 |
| adminId | string | - | 관리자 로그인 아이디 예: pharmacist01 |
| adminName | string | - | 관리자 이름 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 예: pharm01@yaknaru.local |
| adminTel | string | - | 관리자 전화번호 예: 010-1234-5678 |
| adminBirth | date | - | 약사 생년월일 (YYYY-MM-DD) — PHARMACY_ADMIN 만 의미, null 가능 예: 1985-03-15 |
| adminState | string | - | 계정 상태 — PENDING 검토대기(로그인 차단) / ACTIVE 정상 / SUSPENDED 정지 / WITHDRAWN 탈퇴 예: ACTIVE |
| roles | array<string> | - | 권한 집합 — PHARMACY_ADMIN 약사 / SYSTEM_ADMIN 시스템 운영자 예: ['PHARMACY_ADMIN'] |
| pharmacies | array<PharmacyMappingItem> | - | 매핑된 약국 목록 — 단건 상세에서만 채움, 목록 검색에서는 빈 배열 |
| lastLoginAt | datetime | - | 마지막 로그인 일시 (ISO-8601) — null = 로그인 이력 없음 예: 2026-09-11T09:30:00 |
| createdAt | datetime | - | 계정 생성 일시 (ISO-8601) 예: 2026-05-01T10:00:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| platform | string | - | 대상 플랫폼 — android / ios 예: android |
| up_bool | string | - | 강제 업데이트 사용 여부 — yes / no (yes 이고 up_build > 단말 빌드면 업데이트 안내) 예: no |
| up_build | integer | - | 강제 업데이트 기준 빌드 번호 — 단말 빌드가 이보다 작으면 업데이트 예: 12 |
| up_img | string | - | 업데이트 안내 이미지 URL 예: https://cdn.yaknaru.co.kr/app/update.png |
| up_img_width | integer | - | 업데이트 안내 이미지 가로 (px) 예: 720 |
| up_img_height | integer | - | 업데이트 안내 이미지 세로 (px) 예: 1280 |
| agree_bool | string | - | 약관 재동의 강제 여부 — yes / no 예: no |
| agree_no | integer | - | 재동의가 필요한 약관 버전 번호 예: 2 |
| popup_bool | string | - | 광고/공지 팝업 노출 여부 — yes / no 예: no |
| popup_img | string | - | 팝업 이미지 URL 예: https://cdn.yaknaru.co.kr/app/popup.png |
| server_bool | string | - | 서버 점검 중 여부 — yes / no (yes 면 앱 진입 차단) 예: no |
| server_img | string | - | 서버 점검 안내 이미지 URL 예: https://cdn.yaknaru.co.kr/app/maint.png |
| server_img_width | integer | - | 점검 안내 이미지 가로 (px) 예: 720 |
| server_img_height | integer | - | 점검 안내 이미지 세로 (px) 예: 1280 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| eligibilityId | integer | 필수 | 승인 대상 자격 신청 PK — GET /api/v1/admin/eligibility 목록의 id 예: 21 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 카테고리 PK — 게시글 작성/수정의 categoryId, 관리자 카테고리 수정/삭제의 categoryId 예: 2 |
| boardType | string | - | 소속 게시판 슬러그 — faq / qna 예: faq |
| name | string | - | 카테고리명 예: 배송/결제 |
| sort | integer | - | 정렬 순서 (오름차순) 예: 1 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| oldPass | string | 필수 | 현재 비밀번호 예: ******** |
| newPass | string | 필수 | 새 비밀번호 (8~64자) 예: ******** |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionId | integer | 필수 | 대상 처방전(주문) PK — GET /api/v1/orders 의 prescriptionSeq 예: 101 |
| status | string | 필수 | 변경할 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료 예: 010 |
| unavailableReason | string | - | 조제불가 사유 — status=03 일 때 예: 재고 부족 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| zonecode | string | 필수 | 우편번호 (5자리) — 비배송 우편번호 목록과 대조 예: 48058 |
| roadname | string | - | 도로명 — 비배송 도로명 목록과 부분 일치 대조 예: 센텀중앙로 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| deliveryYn | string | - | 배송 가능 여부 — Y 가능 / N 비배송 지역 예: Y |
| reason | string | - | 비배송 판정 사유 — deliveryYn=N 일 때만 (비배송 지역 (zipcode) / 비배송 지역 (도로명)) |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memDi | string | 필수 | 본인인증(NICE) DI 값 예: MC0GCCqGSIb3DQIJAyEA3f9a… |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memEmail | string | 필수 | 확인할 이메일 예: hong@example.com |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 확인할 로그인 아이디 예: hong1234 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| code | string | 필수 | 추천인 코드 (숫자) — 97593712 − 추천인 회원 PK 로 생성, 해당 회원 존재 시 valid=true 예: 97593709 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| todayNew | integer | - | 오늘 새로 접수된 처방전 수 (01 발송 상태) 예: 3 |
| paymentWaiting | integer | - | 결제 대기 건수 (02 조제가능) 예: 2 |
| shipping | integer | - | 배송 중 건수 (06 배송중) 예: 1 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | 필수 | 조제 요청 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| receiveType | string | - | 수령 방식 — onLine 택배배송 / offLine 방문수령 예: onLine |
| deliveryAddressId | integer | - | 배송지 PK — GET /api/v1/addresses 의 deliveryAddressSeq, onLine 일 때 예: 12 |
| deliveryName | string | - | 수령인 이름 (onLine 스냅샷) 예: 홍길동 |
| deliveryPhone | string | - | 수령인 연락처 (onLine 스냅샷) 예: 010-1234-5678 |
| deliveryAddress | string | - | 배송 기본 주소 (onLine 스냅샷) 예: 부산광역시 해운대구 센텀중앙로 79 |
| deliveryDetailAddress | string | - | 배송 상세 주소 (동/호수) 예: 101동 1203호 |
| prescriptionImagePath | string | - | 처방전 이미지 저장 경로 — POST /api/v1/prescriptions/upload-image 응답의 storagePath 예: C:/DEV/.../uploads/prescription/7/2026-09-11/3f9c1a2b__rx.jpg |
| qrImagePath | string | - | QR 영역 이미지 저장 경로 — upload-image 응답의 storagePath 예: C:/DEV/.../uploads/prescription/7/2026-09-11/3f9c1a2b__qr.jpg |
| qrValue | string | 필수 | 처방전 QR 원문 (또는 OCR 식별값) 예: PRS_ENC:9f3a2b1c… |
| medicineSeq | integer | - | 발급정보 PK — POST /api/v1/prescriptions/qr-callback 응답의 medicineSeq, null = 미인식 예: 55 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | string | 필수 | 관리자 로그인 아이디 (3~64자, 중복 불가) 예: pharmacist06 |
| password | string | 필수 | 초기 비밀번호 (6~64자) 예: ******** |
| adminName | string | 필수 | 관리자 이름 (40자 이하) 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 (120자 이하) 예: pharm06@yaknaru.local |
| adminTel | string | - | 전화번호 (20자 이하) 예: 010-1234-5678 |
| roles | array<string> | 필수 | 권한 집합 (1개 이상) — PHARMACY_ADMIN 약사 / SYSTEM_ADMIN 시스템 운영자 예: ['PHARMACY_ADMIN'] |
| pharmacyCodes | array<string> | - | 등록 시 초기 매핑할 약국 코드 목록 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식), PHARMACY_ADMIN 일 때만 의미 예: ['PH-001'] |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| counts | Counts | - | 상태별 처리 대기 건수 |
| monthRevenue | number | - | 이번 달 매출(원) — 수령완료(010) 주문 기준 예: 1250000 |
| monthOrderCount | integer | - | 이번 달 수령완료(010) 주문 수 예: 42 |
| recent | array<PrescriptionView> | - | 최근 처방전 5건 (상태 무관, 최신순) |
| asOf | datetime | - | 집계 시각 (ISO-8601) 예: 2026-09-11T16:55:42 |
| period | Period | - | 매출 집계 기간 — 이번 달 1일 ~ 오늘 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| addressId | integer | 필수 | 삭제 대상 배송지 PK — GET /api/v1/addresses 의 deliveryAddressSeq 예: 12 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| name | string | 필수 | 받는 분 이름 예: 홍길동 |
| phone | string | 필수 | 받는 분 연락처 예: 010-1234-5678 |
| zipcode | string | - | 우편번호 (5자리) 예: 48058 |
| address | string | 필수 | 배송 기본 주소 예: 부산광역시 해운대구 센텀중앙로 79 |
| detailAddress | string | - | 배송 상세 주소 (동/호수) 예: 101동 1203호 |
| memo | string | - | 배송 요청사항 예: 부재 시 문 앞에 놓아주세요. |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| name | string | - | 받는 분 이름 예: 홍길동 |
| phone | string | - | 받는 분 연락처 예: 010-1234-5678 |
| zipcode | string | - | 우편번호 (5자리) 예: 48058 |
| address | string | - | 배송 기본 주소 예: 부산광역시 해운대구 센텀중앙로 79 |
| detailAddress | string | - | 배송 상세 주소 (동/호수) 예: 101동 1203호 |
| memo | string | - | 배송 요청사항 예: 부재 시 문 앞에 놓아주세요. |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| ediCode | string | - | 조회한 EDI(보험) 약품코드 9자리 예: 661700390 |
| name | string | - | 약품명 — source 가 MASTER 면 마스터 제품명, SUBSTITUTE 면 대체약품 자료의 원처방 약품명, NONE 이면 null |
| company | string | - | 선택 — 제조/수입사 |
| price | number | - | 선택 — 급여 상한금액(원). source 가 MASTER 일 때만 |
| source | string | - | 약품명 출처 — MASTER(약품 마스터) / SUBSTITUTE(대체약품 자료) / NONE(미등록) 예: MASTER |
| substitutes | array<SubstituteMedicineView> | - | 같은 원처방 코드의 대체약품 목록 (없으면 빈 배열) |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| summary | EligibilitySummary | - | 자격 신청 요약 |
| documents | array<EligibilityDocumentInfo> | - | 첨부 서류 목록 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 첨부 파일 PK (eligibility_file.file_id) 예: 33 |
| fileName | string | - | 업로드 원본 파일명 예: 장기요양인정서.jpg |
| fileSize | integer | - | 파일 크기 (byte) 예: 512000 |
| mimeType | string | - | 파일 MIME 타입 예: image/jpeg |
| fileUrl | string | - | 조회 URL (/uploads/... 경로, UPLOAD_URL_PREFIX 접두) 예: /uploads/eligibility/7/2026-09-10/9a1b2c3d__doc.jpg |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 자격 신청 PK — 관리자 승인/반려 요청의 eligibilityId 예: 21 |
| memberId | integer | - | 신청 회원 PK (member_info.member_id) 예: 7 |
| memberLoginId | string | - | 신청 회원 로그인 아이디 — 관리자 목록에서만 채움 예: hong1234 |
| memberName | string | - | 신청 회원 이름 — 관리자 목록에서만 채움 예: 홍길동 |
| state | string | - | 자격 상태 — I 심사중 / S 완료(배송 이용 가능) / R 반려(재신청 가능) enum: I, S, R 예: I |
| documentTypes | string | - | 신청 자격 유형 코드 — ltc65plus 65세 이상 장기요양등급자 / disabled 장애인 / infectiousDisease 감염병 환자 / rareDisease 희귀질환자 예: ltc65plus |
| rejectDesc | string | - | 반려 사유 — state=R 일 때만, 그 외 null 예: 서류 식별이 불가하여 재제출이 필요합니다. |
| documentCount | integer | - | 첨부 서류 파일 수 예: 2 |
| createdAt | datetime | - | 신청 일시 (ISO-8601) 예: 2026-09-10T14:20:00 |
| updatedAt | datetime | - | 최종 변경 일시 (ISO-8601) — 승인/반려 시 갱신 예: 2026-09-11T09:30:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| code | string | - | 오류 코드 — COMMON_001 / AUTH_001 / MEMBER_002 … (Swagger 상단 표 참고) 예: COMMON_001 |
| message | string | - | 사용자에게 그대로 보여줄 한국어 문장 예: addressId: 수정할 배송지를 선택해 주세요. |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fcmToken | string | 필수 | Firebase Cloud Messaging 디바이스 토큰 예: dXk9f3…:APA91bH… |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 회원 로그인 아이디 — 회원가입(POST /api/v1/members/signup) 시 지정 예: hong1234 |
| memPass | string | 필수 | 비밀번호 (평문, TLS 구간 전송) 예: ******** |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 관리자 PK (admin_user.admin_id) 예: 3 |
| adminId | string | - | 관리자 로그인 아이디 예: pharmacist01 |
| adminName | string | - | 관리자 이름 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 예: pharm01@yaknaru.local |
| adminTel | string | - | 관리자 전화번호 예: 010-1234-5678 |
| adminBirth | date | - | 약사 생년월일 (YYYY-MM-DD) — PHARMACY_ADMIN 만 의미, null = 미설정 예: 1985-03-15 |
| adminState | string | - | 계정 상태 — PENDING 검토대기 / ACTIVE 정상 / SUSPENDED 정지 / WITHDRAWN 탈퇴 예: ACTIVE |
| roles | array<string> | - | 권한 집합 — PHARMACY_ADMIN 약사 / SYSTEM_ADMIN 시스템 운영자 예: ['PHARMACY_ADMIN'] |
| lastLoginAt | datetime | - | 마지막 로그인 일시 (ISO-8601) — null = 로그인 이력 없음 예: 2026-09-11T09:30:00 |
| createdAt | datetime | - | 계정 생성 일시 (ISO-8601) 예: 2026-05-01T10:00:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| drgCd | string | - | 약품 코드 (EDI 보험코드 9자리) 예: 640007270 |
| drgNm | string | - | 약품명 예: 타이레놀정500mg |
| amount | integer | - | 총 수량 — 현재 발급정보에 없어 항상 null |
| dosage | string | - | 1회 투약량 예: 1 |
| daysTotal | string | - | 총 투약 일수 예: 3 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| drgCd | string | - | 약품 코드 (EDI 보험코드 9자리) 예: 640007270 |
| drgNm | string | - | 약품명 예: 타이레놀정500mg |
| amount | integer | - | 총 수량 — 현재 발급정보에 없어 항상 null |
| dosage | string | - | 1회 투약량 예: 1 |
| daysTotal | string | - | 총 투약 일수 예: 3 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 회원 PK (member_info.member_id) 예: 7 |
| memSeq | integer | - | 구 시스템 회원 순번 — V28 이후 컬럼 제거, 항상 null (RN 호환용 잔존) |
| memId | string | - | 로그인 아이디 예: hong1234 |
| memEmail | string | - | 이메일 예: hong@example.com |
| memName | string | - | 회원 이름 예: 홍길동 |
| memBirth | string | - | 생년월일 (YYYY-MM-DD) — null = 미입력 예: 1960-05-20 |
| memGender | string | - | 성별 코드 — 0 남성 / 1 여성 예: 0 |
| memTel | string | - | 휴대폰 번호 예: 010-1234-5678 |
| memPush | string | - | 푸시 수신 동의 — Y / N 예: Y |
| memState | string | - | 회원 상태 — ACTIVE 정상 / DORMANT 휴면 / SUSPENDED 정지 / WITHDRAWN 탈퇴 예: ACTIVE |
| roles | array<string> | - | 권한 집합 — RN 회원은 USER 단일 예: ['USER'] |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pushId | integer | 필수 | 알림 PK — GET /api/v1/push/messages 목록의 id 예: 88 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 알림 PK — 읽음/삭제 요청의 pushId 예: 88 |
| memberId | integer | - | 수신 회원 PK — null = 전체 발송(broadcast) 예: 7 |
| title | string | - | 알림 제목 예: 처방전 접수 완료 |
| body | string | - | 알림 본문 예: 약나루약국 남구점에서 처방전을 확인했습니다. 결제를 진행해 주세요. |
| payload | string | - | 앱 딥링크용 부가 데이터 (JSON 문자열) 예: {'screen': 'OrderDetail', 'prescriptionSeq': 101} |
| relatedType | string | - | 연관 대상 유형 — order 주문 / delivery 배송 / prescription_approved 조제가능 / prescription_rejected 조제불가 / eligibility 자격심사 / notice 공지 등 예: order |
| relatedId | integer | - | 연관 대상 PK (relatedType 별 — 주문/배송/처방은 처방전 id, eligibility 는 자격 신청 id) 예: 101 |
| readAt | datetime | - | 읽음 처리 일시 (ISO-8601) — null = 미읽음 예: 2026-09-11T10:05:00 |
| createdAt | datetime | - | 발송 일시 (ISO-8601) 예: 2026-09-11T09:45:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pushId | integer | 필수 | 알림 PK — GET /api/v1/push/messages 목록의 id 예: 88 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| code | string | - | 약품 코드 (EDI 보험코드 9자리) 예: 640007270 |
| name | string | - | 약품명 (인접 텍스트 기반 추정) 예: 타이레놀정500mg |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| issueNo | string | - | 처방전 교부번호 예: 2026-0911-00042 |
| patientName | string | - | 환자 성명 예: 홍길동 |
| hospitalName | string | - | 의료기관 명칭 예: 부산대학교병원 |
| doctorName | string | - | 처방 의사 성명 예: 김의사 |
| prescriptionDate | string | - | 교부일 (YYYY-MM-DD) 예: 2026-09-11 |
| medicines | array<OcrMedicine> | - | OCR 추출 약품 목록 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| items | array<OrderItemRequest> | 필수 | 주문 상품 목록 (1개 이상) |
| delivery | DeliveryRequest | - | 배송지 정보 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionSeq | integer | - | 처방전(주문) PK 예: 101 |
| prescriptionStatus | string | - | 주문 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료 예: 06 |
| prescriptionStatusName | string | - | 주문 상태 한글 라벨 예: 배송중 |
| unavailableReason | string | - | 조제불가 사유 — 상태 03 일 때만 예: 재고 부족 |
| reqDate | string | - | 주문(처방전 접수) 일시 (ISO-8601) 예: 2026-09-11T09:30:00 |
| receiveType | string | - | 수령 방식 — onLine 택배배송 / offLine 방문수령 예: onLine |
| prescriptionPrice | number | - | 약제비 (원) 예: 12500 |
| deliveryPrice | number | - | 배송비 (원) — offLine 은 0/null 예: 3000 |
| totalPrice | number | - | 총 결제 금액 (원, 약제비 + 배송비) 예: 15500 |
| medicineDirection | string | - | 약사 복약 안내 (회원 노출) 예: 식후 30분에 1정씩 복용하세요. |
| medicineList | array<MedicineItem> | - | 처방 약품 목록 |
| pharmacyCode | string | - | 약국 코드 (PH-001 형식) — 조제불가(03) 후 다른 약국 재선택 시 거절 약국 식별용 예: PH-001 |
| pharmacyName | string | - | 약국명 (주문 시점 스냅샷) 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 전화번호 (스냅샷) 예: 051-123-4567 |
| pharmacyAddress | string | - | 약국 주소 (스냅샷) 예: 부산광역시 남구 수영로 200 |
| deliveryName | string | - | 수령인 이름 — onLine 배송지 스냅샷 예: 홍길동 |
| deliveryPhone | string | - | 수령인 연락처 — onLine 배송지 스냅샷 예: 010-1234-5678 |
| deliveryAddress | string | - | 배송 기본 주소 — onLine 배송지 스냅샷 예: 부산광역시 해운대구 센텀중앙로 79 |
| deliveryDetailAddress | string | - | 배송 상세 주소 (동/호수) 예: 101동 1203호 |
| deliveryNumber | string | - | 택배 송장번호 — 배송중(06) 전환 시 약사 입력 예: 6889012345678 |
| deliveryCompany | string | - | 택배사명 (CJ대한통운/우체국 등) — 배송중(06) 전환 시 약사 입력 예: CJ대한통운 |
| partnerInfo | PartnerInfo | - | 처방전 발급 정보 (병원/의사/환자/진단) — null = 자가입력 또는 미연동 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| targetDate | string | - | 그룹 기준 주문 일자 (YYYY-MM-DD) 예: 2026-09-11 |
| deliveryList | array<OrderListItem> | - | 해당 일자의 주문 카드 목록 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| productId | string | 필수 | 상품 코드 — GET /api/v1/shop/products 의 id (HP-001 형식) 예: HP-001 |
| quantity | integer | - | 주문 수량 (1 이상) 예: 2 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| productId | string | - | 상품 코드 — GET /api/v1/shop/products 의 id (HP-001 형식) 예: HP-001 |
| productName | string | - | 상품명 (주문 시점 스냅샷) 예: 멀티비타민 미네랄 90정 |
| quantity | integer | - | 주문 수량 예: 2 |
| price | integer | - | 단가 (원, 주문 시점 스냅샷) 예: 24900 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prescriptionSeq | integer | - | 처방전(주문) PK — GET /api/v1/orders/detail?id= 의 id 예: 101 |
| prescriptionStatus | string | - | 주문 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료 예: 04 |
| prescriptionStatusName | string | - | 주문 상태 한글 라벨 — 상태 코드에 대응 예: 결제완료 |
| prescriptionRegdate | string | - | 주문(처방전 접수) 일자 (YYYY-MM-DD) 예: 2026-09-11 |
| prescriptionPrice | number | - | 약제비 (원) — 약국이 조제가능 처리 시 입력, 이전엔 null 예: 12500 |
| totalPrice | number | - | 총 결제 금액 (원, 약제비 + 배송비) 예: 15500 |
| receiveType | string | - | 수령 방식 — onLine 택배배송 / offLine 방문수령 예: onLine |
| unavailableReason | string | - | 조제불가 사유 — 상태 03 일 때만 예: 재고 부족 |
| pharmacyCode | string | - | 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| pharmacyName | string | - | 약국명 (주문 시점 스냅샷) 예: 약나루약국 남구점 |
| medicineList | array<MedicineItem> | - | 약품 목록 — 목록 응답에서는 빈 배열, 상세에서 채움 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | string | - | 주문번호 (SO-YYYYMMDD-### 형식) — 관리자 상태 변경 요청의 orderNo 예: SO-20260911-001 |
| date | string | - | 주문 일자 (YYYY-MM-DD) 예: 2026-09-11 |
| memberId | string | - | 주문 회원 로그인 아이디 예: hong1234 |
| status | string | - | 주문 상태 코드 — PAID 결제 완료 / SHIPPING 배송 중 / DELIVERED 배송 완료 예: PAID |
| statusLabel | string | - | 주문 상태 한글 라벨 — 결제 완료 / 배송 중 / 배송 완료 예: 결제 완료 |
| deliveryFee | integer | - | 적용 배송비 (원) — 무료 배송 기준 이상이면 0 예: 3000 |
| total | integer | - | 총 결제 금액 (원, 상품 합계 + 배송비) 예: 52800 |
| items | array<OrderItemView> | - | 주문 상품 목록 |
| delivery | DeliveryView | - | 배송지 정보 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| seq | integer | - | 발급정보 PK (issue_info.issue_id) — POST /api/v1/prescriptions 의 medicineSeq 와 동일 예: 55 |
| hospitalName | string | - | 의료기관 명칭 예: 부산대학교병원 |
| hospitalPhone | string | - | 의료기관 전화번호 예: 051-240-7000 |
| hospitalFax | string | - | 의료기관 팩스번호 예: 051-240-7001 |
| hospitalEmail | string | - | 의료기관 이메일 예: info@pnuh.or.kr |
| doctorName | string | - | 처방 의사 성명 예: 김의사 |
| doctorLicenseType | string | - | 의사 면허 종별 (발급사 코드값) 예: 의사 |
| doctorLicenseNo | string | - | 의사 면허번호 예: 98765 |
| patientName | string | - | 환자 성명 예: 홍길동 |
| departmentCode | string | - | 진료과목 코드 (발급사 코드값) 예: 01 |
| diagnosisCode1 | string | - | 주상병 코드 (KCD) 예: J06.9 |
| diagnosisCode2 | string | - | 부상병 코드 (KCD) 예: R50.9 |
| prescriptionDate | string | - | 처방전 교부일 (YYYY-MM-DD) 예: 2026-09-11 |
| useDays | string | - | 처방전 사용기간 (일) 예: 3 |
| linkUrl | string | - | 발급사 처방전 원문 링크 — 미연동 시 null 예: https://edb.example.com/rx/9f3a2b1c |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| from | date | - | 시작일 (YYYY-MM-DD) 예: 2026-09-01 |
| to | date | - | 종료일 (YYYY-MM-DD) 예: 2026-09-11 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminUserId | integer | - | 생성된 약사 관리자 PK (admin_user.admin_id) 예: 8 |
| pharmacyCode | string | - | 자동 발급된 약국 코드 (PH-### 형식, 순번 증가) 예: PH-006 |
| adminId | string | - | 약사 로그인 아이디 예: pharmacist06 |
| pharmacyName | string | - | 약국명 예: 약나루약국 남구점 |
| state | string | - | 계정 상태 — 가입 직후 항상 PENDING (SYSTEM_ADMIN 승인 전 로그인 차단) 예: PENDING |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 첨부 파일 PK (pharmacy_file.file_id) 예: 5 |
| documentType | string | - | 서류 종류 — BUSINESS_LICENSE 사업자등록증 / PHARMACIST_LICENSE 약사 면허증 / OTHER 기타 예: BUSINESS_LICENSE |
| fileName | string | - | 업로드 원본 파일명 예: 사업자등록증.pdf |
| fileSize | integer | - | 파일 크기 (byte) 예: 204800 |
| mimeType | string | - | 파일 MIME 타입 예: application/pdf |
| fileUrl | string | - | 다운로드 URL (/uploads/... 경로, UPLOAD_URL_PREFIX 접두) 예: /uploads/pharmacy/6/2026-09-11/3f9c1a2b__license.pdf |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyId | integer | - | 약국 PK (pharmacy.pharmacy_id) — 매핑 해제(POST /api/v1/admin/admin-users/pharmacies/remove) 의 pharmacyId 예: 1 |
| pharmacyCode | string | - | 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| pharmacyName | string | - | 약국명 예: 약나루약국 남구점 |
| documentCount | integer | - | 약국 첨부 서류 수 — 단건 상세에서만 채움, null = 미조회 예: 2 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | integer | 필수 | 대상 관리자 PK — GET /api/v1/admin/admin-users 목록의 id 예: 3 |
| pharmacyId | integer | 필수 | 해제할 약국 PK — 관리자 상세(/detail) pharmacies 항목의 pharmacyId 예: 1 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | integer | 필수 | 대상 관리자 PK — GET /api/v1/admin/admin-users 목록의 id 예: 3 |
| pharmacyCode | string | 필수 | 매핑할 약국 코드 — GET /api/v1/pharmacies 의 pharmacyCode (PH-001 형식) 예: PH-001 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| pharmacyCode | string | - | 약국 코드 (PH-001 형식) — 처방전 등록·관리자 약국 API 의 식별자 예: PH-001 |
| pharmacyName | string | - | 약국명 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 대표 전화 예: 051-123-4567 |
| zipcode | string | - | 우편번호 (5자리) 예: 48434 |
| pharmacyAddress | string | - | 약국 기본 주소 예: 부산광역시 남구 수영로 200 |
| pharmacyDetailAddress | string | - | 약국 상세 주소 예: 1층 101호 |
| gpsLat | number | - | 위도 (WGS84) 예: 35.1367 |
| gpsLon | number | - | 경도 (WGS84) 예: 129.0862 |
| effectiveStatus | string | - | 실효 영업 상태 — 영업중 / 준비중 (현재 시각과 요일별 영업시간으로 자동 계산, 영업시간 미설정 시 영업중) 예: 영업중 |
| deliveryYn | string | - | 택배 배송 지원 여부 — Y / N 예: Y |
| alarmPhone | string | - | 처방전 접수 알림 수신 전화번호 예: 010-9876-5432 |
| pharmacistName | string | - | 약사 이름 예: 홍길동 |
| pharmacistPhone | string | - | 약사 전화번호 예: 010-1234-5678 |
| licenseNum | string | - | 약사 면허번호 예: 12345 |
| businessNum | string | - | 사업자등록번호 예: 123-45-67890 |
| accountBankName | string | - | 정산 계좌 은행명 예: 부산은행 |
| accountBankNumber | string | - | 정산 계좌번호 예: 101-2345-6789-01 |
| accountOwner | string | - | 정산 계좌 예금주 예: 홍길동 |
| openTimeMon | string | - | 월요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미설정 예: 09:00~18:00 |
| openTimeTue | string | - | 화요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미설정 예: 09:00~18:00 |
| openTimeWed | string | - | 수요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미설정 예: 09:00~18:00 |
| openTimeThu | string | - | 목요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미설정 예: 09:00~18:00 |
| openTimeFri | string | - | 금요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미설정 예: 09:00~18:00 |
| openTimeSat | string | - | 토요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미설정 예: 09:00~13:00 |
| openTimeSun | string | - | 일요일 영업시간 — HH:mm~HH:mm 또는 휴무, null = 미설정 예: 휴무 |
| pharmacyCharge | number | - | 플랫폼 중개 수수료율 (%) — SYSTEM_ADMIN 설정, null = 미설정 예: 3.5 |
| reviewMemo | string | - | SYSTEM_ADMIN 검토 메모 — null/공백 = 메모 없음 예: 사업자등록증 확인 완료 |
| lastReviewedAt | datetime | - | 마지막 검토 일시 (ISO-8601) — 검토메모 저장/승인/반려 시 갱신 예: 2026-09-11T09:30:00 |
| pendingAdminCount | integer | - | 매핑된 약사 중 PENDING(검토대기) 수 — 관리자 목록에서만 채움, 0 = 정상 예: 0 |
| distance | integer | - | 검색 위치로부터의 거리 (m) — 위치 기반 검색(lat/lon 전달) 시에만, 그 외 null 예: 850 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 게시글 PK — 관리자 수정/삭제 요청의 postId, GET /api/v1/bbs/notices/detail?id= 의 id 예: 15 |
| bbsSeq | integer | - | 구 시스템 게시글 순번 — V28 이후 컬럼 제거, 항상 null (RN 호환용 잔존) |
| boardType | string | - | 게시판 종류 슬러그 — notice 공지 / faq 자주묻는질문 / qna 문의 예: notice |
| categoryId | integer | - | 카테고리 PK — FAQ 만 사용, 공지는 null 예: 2 |
| categoryName | string | - | 카테고리명 — FAQ 만 사용, 공지는 null 예: 배송/결제 |
| subject | string | - | 제목 예: 추석 연휴 배송 안내 |
| contents | string | - | 본문 (HTML/텍스트) 예: 추석 연휴 기간(10/3~10/6) 동안 택배 배송이 지연될 수 있습니다. |
| viewCount | integer | - | 조회수 예: 128 |
| regDate | datetime | - | 등록 일시 (ISO-8601) 예: 2026-09-11T09:30:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 처방전(주문) PK — 상태 변경/관리자 수정 요청의 prescriptionId 예: 101 |
| prescriptionSeq | integer | - | 주문 번호 (order_no, 순번) — null 가능 예: 1024 |
| status | string | - | 주문 상태 코드 — 01 발송 / 02 조제가능 / 03 조제불가 / 04 결제완료 / 05 조제완료 / 06 배송중 / 07 배송완료 / 08 미방문 / 09 오류 / 010 수령완료 예: 02 |
| statusName | string | - | 주문 상태 한글 라벨 예: 조제가능 |
| receiveType | string | - | 수령 방식 — onLine 택배배송 / offLine 방문수령 예: onLine |
| unavailableReason | string | - | 조제불가 사유 — 상태 03 일 때만 예: 재고 부족 |
| prescriptionPrice | number | - | 약제비 (원) — 조제가능(02) 처리 시 약사 입력 예: 12500 |
| deliveryPrice | number | - | 배송비 (원) — offLine 은 0/null 예: 3000 |
| totalPrice | number | - | 총 결제 금액 (원, 약제비 + 배송비) 예: 15500 |
| medicineDirection | string | - | 약사 복약 안내 (회원 노출) 예: 식후 30분에 1정씩 복용하세요. |
| pharmacistMemo | string | - | 약사 내부 메모 — 관리자 전용, 회원 응답에서는 null 예: 재고 확인 필요 |
| qrValue | string | - | 처방전 QR 원문 (또는 OCR 식별값) 예: PRS_ENC:9f3a2b1c… |
| prescriptionImageUrl | string | - | 처방전 이미지 URL (/uploads/... 경로, UPLOAD_URL_PREFIX 접두) 예: /uploads/prescription/7/2026-09-11/3f9c1a2b__rx.jpg |
| pharmacyName | string | - | 약국명 (주문 시점 스냅샷) 예: 약나루약국 남구점 |
| pharmacyPhone | string | - | 약국 전화번호 (스냅샷) 예: 051-123-4567 |
| pharmacyAddress | string | - | 약국 주소 (스냅샷) 예: 부산광역시 남구 수영로 200 |
| memId | string | - | 주문 회원 로그인 아이디 — 관리자 목록/상세에서만, 회원 응답은 null 예: hong1234 |
| memName | string | - | 주문 회원 이름 — 관리자 목록/상세에서만 예: 홍길동 |
| deliveryName | string | - | 수령인 이름 — onLine 배송지 스냅샷 예: 홍길동 |
| deliveryPhone | string | - | 수령인 연락처 — onLine 배송지 스냅샷 예: 010-1234-5678 |
| deliveryAddress | string | - | 배송 기본 주소 — onLine 배송지 스냅샷 예: 부산광역시 해운대구 센텀중앙로 79 |
| deliveryDetailAddress | string | - | 배송 상세 주소 (동/호수) 예: 101동 1203호 |
| deliveryNumber | string | - | 택배 송장번호 — 배송중(06) 전환 시 약사 입력 예: 6889012345678 |
| deliveryCompany | string | - | 택배사명 (CJ대한통운/우체국 등) — 배송중(06) 전환 시 약사 입력 예: CJ대한통운 |
| reqDate | datetime | - | 처방전 접수(주문) 일시 (ISO-8601) 예: 2026-09-11T09:30:00 |
| readyAt | datetime | - | 조제가능(02) 진입 일시 (ISO-8601) — 미도달 시 null 예: 2026-09-11T09:45:00 |
| paidAt | datetime | - | 결제완료(04) 진입 일시 (ISO-8601) — 미도달 시 null 예: 2026-09-11T10:00:00 |
| preparedAt | datetime | - | 조제완료(05) 진입 일시 (ISO-8601) — 방문수령만, 미도달 시 null 예: 2026-09-11T10:30:00 |
| inTransitAt | datetime | - | 배송중(06) 진입 일시 (ISO-8601) — 택배배송만, 미도달 시 null 예: 2026-09-11T14:00:00 |
| deliveredAt | datetime | - | 배송완료(07) 진입 일시 (ISO-8601) — 미도달 시 null 예: 2026-09-12T11:00:00 |
| pickedUpAt | datetime | - | 수령완료(010) 진입 일시 (ISO-8601) — 미도달 시 null 예: 2026-09-12T11:05:00 |
| medicineList | array<MedicineView> | - | 처방 약품 목록 |
| partnerInfo | PartnerInfo | - | 처방전 발급 정보 (병원/의사/환자/진단/처방일) — null = 자가입력 또는 미연동 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| category | string | 필수 | 상품 카테고리명 예: 비타민 |
| emoji | string | - | 카테고리 대표 이모지 예: 🍊 |
| name | string | 필수 | 상품명 예: 멀티비타민 미네랄 90정 |
| brand | string | - | 브랜드명 예: 약나루 헬스 |
| brief | string | - | 한 줄 소개 예: 하루 1정으로 챙기는 12종 비타민 + 8종 미네랄 |
| price | integer | 필수 | 판매가 (원) 예: 24900 |
| originalPrice | integer | - | 할인 전 정가 (원) — null = 할인 없음 예: 32000 |
| badge | string | - | 뱃지 — BEST / NEW 예: BEST |
| visible | boolean | - | 앱 노출 여부 — null = true 예: True |
| functionality | string | - | 기능성 내용 (줄바꿈 구분) 예: 비타민 A·C·D·E 등 12종 비타민 보충 |
| intake | string | - | 섭취 방법 예: 1일 1회, 1회 1정을 물과 함께 섭취 |
| caution | string | - | 섭취 시 주의사항 예: 특정 질환이 있거나 의약품 복용 시 전문가와 상담 후 섭취하세요. |
| image | string | - | 대표 이미지 (URL 또는 data URI) 예: https://cdn.yaknaru.co.kr/shop/HP-001.png |
| detailImages | array<string> | - | 상세 이미지 목록 (URL 또는 data URI) 예: ['https://cdn.yaknaru.co.kr/shop/HP-001_1.png'] |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| productCode | string | 필수 | 삭제 대상 상품 코드 — GET /api/v1/shop/products 의 id (HP-001 형식) 예: HP-001 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| productCode | string | 필수 | 대상 상품 코드 — GET /api/v1/shop/products 의 id (HP-001 형식) 예: HP-001 |
| category | string | - | 상품 카테고리명 — null = 미변경 예: 비타민 |
| emoji | string | - | 카테고리 대표 이모지 — null = 미변경 예: 🍊 |
| name | string | - | 상품명 — null = 미변경 예: 멀티비타민 미네랄 90정 |
| brand | string | - | 브랜드명 — null = 미변경 예: 약나루 헬스 |
| brief | string | - | 한 줄 소개 — null = 미변경 예: 하루 1정으로 챙기는 12종 비타민 + 8종 미네랄 |
| price | integer | - | 판매가 (원) — null = 미변경 예: 24900 |
| originalPrice | integer | - | 할인 전 정가 (원) — null = 미변경 예: 32000 |
| badge | string | - | 뱃지 — BEST / NEW, null = 미변경 예: BEST |
| visible | boolean | - | 앱 노출 여부 — null = 미변경 예: True |
| functionality | string | - | 기능성 내용 — null = 미변경 예: 비타민 A·C·D·E 등 12종 비타민 보충 |
| intake | string | - | 섭취 방법 — null = 미변경 예: 1일 1회, 1회 1정을 물과 함께 섭취 |
| caution | string | - | 섭취 시 주의사항 — null = 미변경 예: 특정 질환이 있거나 의약품 복용 시 전문가와 상담 후 섭취하세요. |
| image | string | - | 대표 이미지 (URL 또는 data URI) — null = 미변경 예: https://cdn.yaknaru.co.kr/shop/HP-001.png |
| detailImages | array<string> | - | 상세 이미지 목록 — null = 미변경 예: ['https://cdn.yaknaru.co.kr/shop/HP-001_1.png'] |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | string | - | 상품 코드 (HP-001 형식) — 주문 항목의 productId, 관리자 수정/삭제의 productCode 예: HP-001 |
| category | string | - | 상품 카테고리명 (자유 문자열) 예: 비타민 |
| emoji | string | - | 카테고리 대표 이모지 (이미지 없을 때 표시) 예: 🍊 |
| name | string | - | 상품명 예: 멀티비타민 미네랄 90정 |
| brand | string | - | 브랜드명 예: 약나루 헬스 |
| brief | string | - | 한 줄 소개 예: 하루 1정으로 챙기는 12종 비타민 + 8종 미네랄 |
| price | integer | - | 판매가 (원) 예: 24900 |
| originalPrice | integer | - | 할인 전 정가 (원) — null = 할인 없음 예: 32000 |
| badge | string | - | 뱃지 — BEST / NEW, null = 없음 예: BEST |
| visible | boolean | - | 앱 노출 여부 — false 면 관리자에서만 조회 예: True |
| functionality | string | - | 기능성 내용 (줄바꿈 구분) 예: 비타민 A·C·D·E 등 12종 비타민 보충 아연·셀레늄 등 8종 미네랄 보충 |
| intake | string | - | 섭취 방법 예: 1일 1회, 1회 1정을 물과 함께 섭취 |
| caution | string | - | 섭취 시 주의사항 예: 특정 질환이 있거나 의약품 복용 시 전문가와 상담 후 섭취하세요. |
| image | string | - | 대표 이미지 (URL 또는 data URI) 예: https://cdn.yaknaru.co.kr/shop/HP-001.png |
| detailImages | array<string> | - | 상세 이미지 목록 (URL 또는 data URI) 예: ['https://cdn.yaknaru.co.kr/shop/HP-001_1.png'] |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 문의글 PK — 관리자 답변 요청(POST /api/v1/admin/bbs/qnas/answer)의 postId 예: 42 |
| boardType | string | - | 게시판 종류 슬러그 — 항상 qna 예: qna |
| categoryId | integer | - | 문의 카테고리 PK — GET /api/v1/bbs/qna-form 의 카테고리 id 예: 3 |
| categoryName | string | - | 문의 카테고리명 예: 주문/배송 |
| memberId | integer | - | 작성 회원 PK (member_info.member_id) 예: 7 |
| question | string | - | 문의 내용 예: 배송이 며칠 걸리나요? |
| answer | string | - | 관리자 답변 내용 — 미답변 시 null 예: 결제 완료 후 보통 1~2일 내 도착합니다. |
| status | string | - | 답변 상태 한글 라벨 — 답변대기 / 답변완료 예: 답변완료 |
| qDate | datetime | - | 문의 등록 일시 (ISO-8601) 예: 2026-09-10T14:20:00 |
| answerDate | datetime | - | 답변 일시 (ISO-8601) — 미답변 시 null 예: 2026-09-11T09:30:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| categoryId | integer | - | 문의 카테고리 PK — GET /api/v1/bbs/qna-form 의 카테고리 id 예: 3 |
| question | string | 필수 | 문의 내용 (2~4000자) 예: 배송이 며칠 걸리나요? |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| prsEnc | string | - | 처방전 QR 암호문 (구 EDB QR 방식) — 현재 미사용 예: PRS_ENC:9f3a2b1c… |
| ocr | OcrPrescriptionData | - | 앱 CLOVA OCR 파싱 결과 — 현행 경로 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| success | boolean | - | 인식/저장 성공 여부 예: True |
| medicineSeq | integer | - | 생성된 발급정보 PK — 처방전 등록 요청의 medicineSeq, 실패 시 null 예: 55 |
| linkUrl | string | - | 발급사 처방전 원문 링크 — 현재 null |
| message | string | - | 실패 사유 — 성공 시 null 예: 처방전 인식 정보가 없습니다. |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| refreshToken | string | 필수 | 갱신 토큰 — POST /api/v1/auth/login 응답의 refreshToken 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJob25nMTIzNCIsInR5cCI6InJlZnJlc2gifQ.7LmP… |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| eligibilityId | integer | 필수 | 반려 대상 자격 신청 PK — GET /api/v1/admin/eligibility 목록의 id 예: 21 |
| reason | string | - | 반려 사유 — 회원 앱에 rejectDesc 로 노출 예: 서류 식별이 불가하여 재제출이 필요합니다. |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminId | integer | 필수 | 대상 관리자 PK — GET /api/v1/admin/admin-users 목록의 id 예: 3 |
| newPassword | string | 필수 | 새 비밀번호 (6~64자) 예: ******** |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 로그인 아이디 예: hong1234 |
| memEmail | string | 필수 | 계정에 등록된 이메일 — 아이디와 일치해야 발송 예: hong@example.com |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memberId | integer | - | 수신 회원 PK — GET /api/v1/admin/members 목록의 id, null = 전체 발송(broadcast) 예: 7 |
| title | string | 필수 | 알림 제목 예: 추석 연휴 배송 안내 |
| body | string | 필수 | 알림 본문 예: 연휴 기간 택배 배송이 지연될 수 있습니다. |
| payload | string | - | 앱 딥링크용 부가 데이터 (JSON 문자열) 예: {'screen': 'NoticeDetail', 'id': 15} |
| relatedType | string | - | 연관 대상 유형 — order / delivery / eligibility / notice 등 예: notice |
| relatedId | integer | - | 연관 대상 PK 예: 15 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memPush | string | 필수 | 푸시 수신 동의 — Y 동의 / N 거부 예: Y |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| deliveryFee | integer | - | 기본 배송비 (원) — null = 미변경 예: 3000 |
| freeThreshold | integer | - | 무료 배송 기준 주문 금액 (원) — null = 미변경 예: 30000 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| deliveryFee | integer | - | 기본 배송비 (원) 예: 3000 |
| freeThreshold | integer | - | 무료 배송 기준 주문 금액 (원) — 상품 합계가 이상이면 배송비 0 예: 30000 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memId | string | 필수 | 로그인 아이디 (4~64자, 중복 불가 — POST /api/v1/members/check-id 로 사전 확인) 예: hong1234 |
| memPass | string | 필수 | 비밀번호 (8~64자) 예: ******** |
| memEmail | string | 필수 | 이메일 (중복 불가 — POST /api/v1/members/check-email 로 사전 확인) 예: hong@example.com |
| memName | string | 필수 | 회원 이름 예: 홍길동 |
| memBirth | string | - | 생년월일 (YYYY-MM-DD) 예: 1960-05-20 |
| memGender | string | - | 성별 코드 — 0 남성 / 1 여성 예: 0 |
| memTel | string | - | 휴대폰 번호 예: 010-1234-5678 |
| memDi | string | - | 본인인증(NICE) DI 값 — 중복 가입 차단 키, POST /api/v1/members/check-di 로 사전 확인 예: MC0GCCqGSIb3DQIJAyEA3f9a… |
| memRecommend | integer | - | 추천인 회원 PK (97593712 − 추천인 코드) — 현재 서버에서 저장하지 않는 예약 필드 예: 3 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| orderNo | string | 필수 | 대상 주문번호 — GET /api/v1/admin/shop/orders 의 id (SO-YYYYMMDD-### 형식) 예: SO-20260911-001 |
| status | string | 필수 | 변경할 상태 코드 — PAID 결제 완료 / SHIPPING 배송 중 / DELIVERED 배송 완료 예: SHIPPING |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| count | integer | - | 현재 적재된 약품 수 예: 21998 |
| lastLoadedAt | string | - | 선택 — 마지막 적재 일시 (ISO-8601), 적재 이력이 없으면 null 예: 2026-08-19T17:04:25 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fcmToken | string | 필수 | Firebase Cloud Messaging 디바이스 토큰 예: dXk9f3…:APA91bH… |
| deviceId | string | - | 단말 식별자 (앱이 생성한 고유값) 예: a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| platform | string | - | 단말 플랫폼 — android / ios 예: android |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 구독(토큰) PK (push_token.token_id) 예: 14 |
| deviceId | string | - | 단말 식별자 예: a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| platform | string | - | 단말 플랫폼 — android / ios 예: android |
| createdAt | datetime | - | 최초 구독 일시 (ISO-8601) 예: 2026-09-01T10:00:00 |
| updatedAt | datetime | - | 마지막 갱신 일시 (ISO-8601) 예: 2026-09-11T09:30:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | integer | - | 대체약품 분석 PK (drug_substitute.substitute_id) — GET /api/v1/admin/substitute-medicines/detail?id= 의 id 예: 17 |
| mainIngredientCode | string | - | 주성분코드 — 대체 약품 매칭 키 예: 675801ATB |
| medicineCode | string | - | 원처방 품목코드 (약가코드 9자리, 앞자리 0 보존) 예: 640007270 |
| medicineName | string | - | 원처방 품목명 예: 타이레놀정500mg |
| maker | string | - | 원처방 제약사명 예: 한국얀센 |
| feeRate | number | - | 원처방 수수료율 (%) 예: 0.35 |
| feeAmount | number | - | 원처방 수수료 금액 (원) 예: 12500 |
| totalQty3m | number | - | 최근 3개월 총 처방 수량 예: 1200 |
| totalAmount3m | number | - | 최근 3개월 총 처방 금액 (원) 예: 3600000 |
| monthlyQty | number | - | 월평균 처방 수량 예: 400 |
| monthlyAmount | number | - | 월평균 처방 금액 (원) 예: 1200000 |
| substituteMaker | string | - | 대체 약품 제약사명 — 대체 약품 없으면 null 예: 한미약품 |
| substituteMedicineName | string | - | 대체 약품 품목명 예: 써스펜8시간이알서방정 |
| substituteMedicineCode | string | - | 대체 약품 품목코드 (약가코드 9자리) 예: 645500530 |
| substituteFeeRate | number | - | 대체 약품 수수료율 (%) 예: 0.45 |
| substituteFeeAmount | number | - | 대체 약품 수수료 금액 (원) 예: 16200 |
| hasSubstitute | boolean | - | 대체 약품 존재 여부 — substituteMedicineCode 가 있으면 true 예: True |
| filterMaker | string | - | 필터링용 제약사명 (원자료 필터 컬럼) 예: 한미약품 |
| createdAt | datetime | - | 데이터 적재 일시 (ISO-8601) 예: 2026-08-01T00:00:00 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| tokenType | string | - | 토큰 유형 — 항상 Bearer (Authorization: Bearer {accessToken}) 예: Bearer |
| accessToken | string | - | JWT 액세스 토큰 — 회원 API 호출 시 Authorization 헤더에 사용 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJob25nMTIzNCIsInJvbGVzIjpbIlVTRVIiXX0.Q2fX… |
| refreshToken | string | - | 갱신 토큰 — POST /api/v1/auth/refresh 에 사용 예: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJob25nMTIzNCIsInR5cCI6InJlZnJlc2gifQ.7LmP… |
| expiresIn | integer | - | 액세스 토큰 만료까지 남은 시간 (초) 예: 3600 |
| myInfo | MemberInfo | - | 로그인한 회원 정보 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fcmToken | string | 필수 | 해제할 FCM 디바이스 토큰 — 구독 시 전송한 값 예: dXk9f3…:APA91bH… |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| adminName | string | - | 관리자 이름 (40자 이하) — null = 미변경 예: 홍길동 |
| adminEmail | string | - | 관리자 이메일 (120자 이하) — null = 미변경 예: pharm01@yaknaru.local |
| adminTel | string | - | 전화번호 (20자 이하) — null = 미변경 예: 010-1234-5678 |
| adminBirth | date | - | 약사 생년월일 (YYYY-MM-DD) — null = 미변경 예: 1985-03-15 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| memEmail | string | - | 이메일 — null = 미변경 예: hong@example.com |
| memTel | string | - | 휴대폰 번호 — null = 미변경 예: 010-1234-5678 |
| memZipcode | string | - | 우편번호 (5자리) — null = 미변경 예: 48058 |
| memAddr1 | string | - | 기본 주소 — null = 미변경 예: 부산광역시 해운대구 센텀중앙로 79 |
| memAddr2 | string | - | 상세 주소 — null = 미변경 예: 101동 1203호 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| platform | string | 필수 | 대상 플랫폼 — android / ios 예: android |
| up_bool | string | - | 강제 업데이트 사용 여부 — yes / no, null = 미변경 예: no |
| up_build | integer | - | 강제 업데이트 기준 빌드 번호 — null = 미변경 예: 12 |
| up_img | string | - | 업데이트 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/update.png |
| up_img_width | integer | - | 업데이트 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| up_img_height | integer | - | 업데이트 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
| agree_bool | string | - | 약관 재동의 강제 여부 — yes / no, null = 미변경 예: no |
| agree_no | integer | - | 재동의가 필요한 약관 버전 번호 — null = 미변경 예: 2 |
| popup_bool | string | - | 팝업 노출 여부 — yes / no, null = 미변경 예: no |
| popup_img | string | - | 팝업 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/popup.png |
| server_bool | string | - | 서버 점검 중 여부 — yes / no, null = 미변경 예: no |
| server_img | string | - | 점검 안내 이미지 URL — null = 미변경 예: https://cdn.yaknaru.co.kr/app/maint.png |
| server_img_width | integer | - | 점검 안내 이미지 가로 (px) — null = 미변경 예: 720 |
| server_img_height | integer | - | 점검 안내 이미지 세로 (px) — null = 미변경 예: 1280 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| storagePath | string | - | 서버 저장 경로 — 처방전 등록 요청의 prescriptionImagePath / qrImagePath 로 전달 예: C:/DEV/.../uploads/prescription/7/2026-09-11/3f9c1a2b__rx.jpg |
| fileName | string | - | 업로드 원본 파일명 예: rx.jpg |
| size | integer | - | 파일 크기 (byte) 예: 1048576 |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| loaded | integer | - | 적재한 행 수 — 제품코드가 9자리 숫자인 행 예: 21998 |
| skipped | integer | - | 건너뛴 행 수 — 제품코드 형식이 아니거나 빈 행 예: 0 |
| total | integer | - | 적재 후 마스터 전체 건수 예: 21998 |