API Spec - PIC-2-team/PIC-2-team-project GitHub Wiki
API ๋ช ์ธ์
๊ธฐ์ค: PRD, User-Flow, Wireframe, Glossary, ERD, Architecture, Dev-Schedule ๊ณตํต ์ฑ๊ณตยท์ค๋ฅ ์๋ต๊ณผ ํ์ด์ง ํ์: API-Response-Convention ์ํ: ํ ๊ฒํ ์ฉ v1 API ๊ณ์ฝ
๊ณตํต ๊ณ์ฝ
| ํญ๋ชฉ | v1 ๊ท์น |
|---|---|
| ๊ฒฝ๋กยท๋ณธ๋ฌธ | ๊ธฐ๋ณธ ๊ฒฝ๋ก /api, JSON UTF-8, ์
๋ก๋๋ multipart/form-data |
| ์๋ต | ์ฑ๊ณต success=true + data(๊ฐ์ฒดยท๋ฐฐ์ดยทnull), ์ค๋ฅ { "success": false, "error": { "code": "ERROR_CODE", "message": "์ค๋ฅ ์ค๋ช
" } }, ์์ฑ 201, ๊ทธ ์ธ ์ฑ๊ณต 200 |
| ์ธ์ฆ | ๋ณดํธ API๋ Authorization: Bearer {accessToken}, access token 15๋ถ, refresh token 30์ผยทHttpOnly; Secure; SameSite=None ์ฟ ํค |
| ์๋ณ์ | ๊ฒฝ๋ก ID๋ ์ซ์, ๋น์ฌ์ ๊ณต๊ฐ ๋ฒํธ P- + ๋๋ฌธ์ยท์ซ์ 8์, ์ง์์ฌ ๊ณต๊ฐ ๋ฒํธ S- + ๋๋ฌธ์ยท์ซ์ 8์, ๊ธฐ๊ด ์ฝ๋ AA-999 |
| ๋ ์งยท๋ชฉ๋ก | ์๊ฐ ์
๋ ฅ์ ์๊ฐ๋ ํฌํจ ISO 8601, ์๋ต์ UTC ISO 8601, ๋ ์ง๋ YYYY-MM-DD, ์ค๋ยท์๋ณ ์กฐํ์ ๋ฐฐ์ ๊ธฐ๊ฐ์ Asia/Seoul ๊ธฐ์ค |
| ํ์ด์ง | page ๊ธฐ๋ณธ 1, pageSize ๊ธฐ๋ณธ 20ยท์ต๋ 100, ์ต์ ์ยท๋๋ฅ ์ผ ๋ ID ์ญ์ |
| ์ฌ์๋ | ๋ฐฐ์ ยท๋์ ํ๋ ๊ธฐ๋ก ์์ฒญ ์์ฑ์ Idempotency-Key ํ์, ๊ฐ์ ํคยท๋ณธ๋ฌธ์ 24์๊ฐ ๋์ ์ต์ด ์๋ต, ๊ฐ์ ํคยท๋ค๋ฅธ ๋ณธ๋ฌธ์ 409 |
| ์ค๋ฅ | ํ์ 400, ์ธ์ฆ 401, ๊ถํ 403, ๋ฆฌ์์ค 404, ์ถฉ๋ 409, ํฌ๊ธฐ 413, ํ์ผ ํ์ 415, ํ๋ ๊ฒ์ฆ 422, ์๋ฒ 500 |
์ญํ ยท๊ด๊ณ
| ์ฃผ์ฒด | ์ด๋ยท์์ฑ | ๊ด๋ฆฌยท์ ํ |
|---|---|---|
์ฃผ ๋ณดํธ์ GUARDIAN |
๋ณธ์ธ ๋น์ฌ์์ ๊ธฐ๋กยท๋๋ด์ ๋ณด ์ด๋ยท์์ฑยท์์ ยท์ญ์ | ๋น์ฌ์ ๋ฑ๋กยทํ๋กํ, ๊ธฐ๊ด ์ฐ๊ฒฐยท์ด์ , ๋ฐฐ์ ์ข ๋ฃ, ์ธ์ปจ๋ ๋ณดํธ์ ์ง์ , ์์ ์ ์ ์น์ธ |
| ์ธ์ปจ๋ ๋ณดํธ์ | ๋น์ฌ์๋ณ ACTIVE ์ํ์์ ๊ธฐ๋กยท๋๋ด์ ๋ณด ์ด๋ยท์์ฑยท์์ ยท์ญ์ |
ํ๋กํยท๊ธฐ๊ดยท๋ฐฐ์ ยท์์ ๊ด๊ณ ๋ณ๊ฒฝ ๋ถ๊ฐ |
ํ๋ ์ง์์ฌ SUPPORT_WORKER |
์ ํจ ๋ฐฐ์ ๋ ๋น์ฌ์ ์ด๋ยท๊ธฐ๋ก ์์ฑ, ๋ณธ์ธ ๊ธฐ๋ก ์์ ยท์ญ์ | ํ์ธ ๊ธฐ๋ก์ ์์ ์ ์๋ง ๊ฐ๋ฅ |
๊ธฐ๊ด INSTITUTION |
์ฐ๊ฒฐ๋ ๋น์ฌ์ ์ด๋ยท์์ ์ ์ยท๊ธฐ๋ก ์์ฒญยท์ ๋ณด ์์ฒญ ์ค๊ณ | ์์ ์ง์์ฌยท๋ฐฐ์ ๊ด๋ฆฌ, ์ํ๊ธฐ๋ก ์ง์ ์์ฑ ๋ถ๊ฐ |
- ํ ๋ณดํธ์์ ๋ณต์ ๋น์ฌ์ ๋ฑ๋ก, ๋น์ฌ์๋น ๊ธฐ๊ด ํ ๊ณณ, ๊ฐ์ ๊ธฐ๊ฐ ๋ณต์ ์ง์์ฌ ๋ฐฐ์ ํ์ฉ
- ์ธ์ปจ๋ ๋ณดํธ์๋ ์ฃผ ๋ณดํธ์๊ฐ
ACTIVE๋ก ์ ํํ ๋์์๋ง ์ ๊ทผ ๊ฐ๋ฅ
๊ณตํต ๋ฐ์ดํฐ
| ๋ฐ์ดํฐ | ํ๋ยท๊ฐ |
|---|---|
| ์ฑ๋ณ | FEMALE, MALE, NOT_SPECIFIED |
| ์ฅ์ ์ ํ | INTELLECTUAL, AUTISM, OTHER ๋ณต์ ์ ํ, OTHER ์ ํ ์ otherDisabilityType ํ์ |
| ์ํ๊ธฐ๋ก ๋ถ๋ฅ | COMMUNICATION, LIFESTYLE, MEAL, PREFERENCE, CHALLENGING_BEHAVIOR, HEALTH, EMERGENCY, OTHER |
| ๋๋ด์ ๋ณด ๋ถ๋ฅ | COMMUNICATION, PREFERENCE, LIFESTYLE, HEALTH_MEDICATION, PRECAUTION, EMERGENCY |
| ๊ธฐ๋ก ์๋ต | id, careRecipientId, author(id/name/role/publicCode), content, category, recordedAt, createdAt, updatedAt, pinned, media[](๋ฏธ๋์ด ์๋ต) |
| ๋น์ฌ์ ์๋ต | id, careRecipientNumber, name, birthDate, gender, disabilityTypes, otherDisabilityType, disabilityGrade, latestRecordAt, createdAt |
| ๋ชฉ๋ก ์๋ต | data.items[], data.pagination(page/pageSize/totalItems/totalPages) |
| ํ๋ ํ๊ธฐ | ํ์๋ ๋ฐ๋์ ์ ์ก, ์ ํ์ ์๋ต ๊ฐ๋ฅ, ๋ณ๋ ํ๊ธฐ๊ฐ ์๋ ์์ ์์ฒญ์ ๋ช
์ํ ํ๋ ์ค ํ๋ ์ด์ ์ ์ก |
| ์ ๋ ฅ ์์น | ๊ฒฝ๋ก ๋ณ์๋ Endpoint์ ํ์, GET์ ์
๋ ฅ์ ์ฟผ๋ฆฌ, Idempotency-Key๋ ํค๋, ๋๋จธ์ง๋ JSON ๋ณธ๋ฌธ |
| nullable ์๋ต | ์ฌ์ฉ์ phone/publicCode/organization, ๋น์ฌ์ latestRecordAt/gender/otherDisabilityType/disabilityGrade, ๋ฐฐ์ endDate/endedAt, ์ ๋ณด ์์ฒญ reply, ๊ธฐ๋ก ์์ฒญ completedRecordId, ๋๋ด์ ๋ณด updatedAt์ ๊ฐ์ด ์์ผ๋ฉด null |
์ธ์ฆยท๋ด ์ ๋ณด
| Method | Endpoint | ์ ๋ ฅ | ์ถ๋ ฅ dataยท๊ถํ |
|---|---|---|---|
POST |
/api/auth/consent |
ํ์ basicInfo=true, sensitiveInfo=true, caregiverShare=true, termsVersion=2026-10-09์ ํ marketing ๊ธฐ๋ณธ false |
consentTicket, 30๋ถ ์ ํจยท1ํ ์ฌ์ฉ, ํ์ ๋์ ๊ฑฐ๋ถยท๋ฒ์ ๋ถ์ผ์น 422 |
POST |
/api/auth/register |
ํ์ name, email, password(10~72์), role, consentTicket์ง์์ฌ organizationCode ํ์, ๊ธฐ๊ด organizationName ํ์ |
201 ๋ก๊ทธ์ธ ์๋ต์ด๋ฉ์ผ ์ค๋ณต 409 |
POST |
/api/auth/google |
ํ์ idToken์ ๊ท ๊ฐ์
์ role, consentTicket, ์ญํ ๋ณ ๊ธฐ๊ด ์ ๋ณด ํ์ |
๊ธฐ์กด ๊ณ์ 200 ๋ก๊ทธ์ธ ์๋ต, ์ ๊ท ๊ณ์ 201 ๋ก๊ทธ์ธ ์๋ต |
POST |
/api/auth/login |
ํ์ email, password |
๋ก๊ทธ์ธ ์๋ต, ์ธ์ฆ ์คํจ 401 |
POST |
/api/auth/refresh |
refresh ์ฟ ํค | ๋ก๊ทธ์ธ ์๋ต, ๊ฐฑ์ ๋ refresh ์ฟ ํค |
POST |
/api/auth/logout |
refresh ์ฟ ํค | loggedOut=true, refresh ์ฟ ํค ๋ง๋ฃ |
POST |
/api/auth/invitations/accept |
ํ์ invitationToken, ๋ก๊ทธ์ธํ ๋ณดํธ์ ๊ณ์ |
careRecipientId, status=READY, ์ด๋ ์ด๋ฉ์ผ๊ณผ ๊ณ์ ์ด๋ฉ์ผ์ด ๋ฌ๋ผ์ง๋ฉด 403 |
GET |
/api/users/me |
์์ | ์ฌ์ฉ์ ์๋ต |
PATCH |
/api/users/me |
name(1~50์), phone(E.164) ์ค ํ๋ ์ด์ |
์ฌ์ฉ์ ์๋ต |
PATCH |
/api/users/me/password |
ํ์ currentPassword, newPassword(10~72์) |
changed=true, ์ด๋ฉ์ผ ๊ฐ์
๊ณ์ ๋ง |
DELETE |
/api/users/me |
์์ | deletedAt, ํ์ฑ ์ธ์
์ฆ์ ๋ง๋ฃ. ๋ณดํธ์๊ฐ ์ ์ผ ๋ณดํธ์์ธ ๋น์ฌ์๊ฐ ์์ผ๋ฉด ํํด ์ ์ด๊ดยท์ญ์ ์ ํ ํ์(409๋ก ์ฐจ๋จ) โ ADR-012 ์ฐธ๊ณ |
GET |
/api/users/me/notification-settings |
์์ | ์๋ฆผ ์ค์ ์๋ต |
PUT |
/api/users/me/notification-settings |
์๋ฆผ ์ค์ ์ฌ์ฏ boolean ๋ชจ๋ ํ์, ์ ์ฒด ๊ต์ฒด | ์๋ฆผ ์ค์ ์๋ต |
| ์๋ต | data ํ๋ |
|---|---|
| ๋ก๊ทธ์ธ ์๋ต | accessToken, tokenType=Bearer, expiresInSeconds=900, user(id/name/email/role), refresh token์ Set-Cookie ์๋ต ํค๋ |
| ์ฌ์ฉ์ ์๋ต | id, name, email, role, phone, publicCode, organization(id/name/organizationCode ๋๋ null) |
| ์๋ฆผ ์ค์ ์๋ต | recordCreated, recordUpdated, assignmentChanged, suggestionReceived, informationRequestReceived, recordRequestReceived, ๊ธฐ๋ณธ๊ฐ ๋ชจ๋ true |
๋น์ฌ์ยท๊ธฐ๊ดยท๋๋ด ๊ด๊ณ
| Method | Endpoint | ์ ๋ ฅ | ์ถ๋ ฅ dataยท๊ถํ |
|---|---|---|---|
GET |
/api/care-recipients |
์ ํ query(์ด๋ฆยท๊ณต๊ฐ ๋ฒํธ), page, pageSize |
๋น์ฌ์ ์๋ต ๋ชฉ๋ก, ์ ๊ทผ ๊ฐ๋ฅํ ๋น์ฌ์๋ง |
POST |
/api/care-recipients |
ํ์ name(1birthDate(๊ณผ๊ฑฐ ๋ ์ง), disabilityTypes(1gender, disabilityGrade(์ต๋ 20์), OTHER ์ ํ ์ otherDisabilityType(1~50์) ํ์ |
201 ๋น์ฌ์ ์๋ต, ์ฃผ ๋ณดํธ์๋ง |
GET |
/api/care-recipients/{careRecipientId} |
์์ | ๋น์ฌ์ ์๋ต |
PATCH |
/api/care-recipients/{careRecipientId} |
๋น์ฌ์ ๋ฑ๋ก ํ๋ ์ค ํ๋ ์ด์ | ๋น์ฌ์ ์๋ต, ์ฃผ ๋ณดํธ์๋ง |
GET |
/api/organizations/me |
์์ | id, name, organizationCode, ๊ธฐ๊ด๋ง |
GET |
/api/organizations/me/members |
์ ํ query(์ด๋ฆยท๊ณต๊ฐ ๋ฒํธ), page, pageSize |
ํ์ ์๋ต ๋ชฉ๋ก, ๊ธฐ๊ด๋ง |
PATCH |
/api/organizations/me/members/{memberId} |
ํ์ status=ACTIVE ๋๋ INACTIVE |
ํ์ ์๋ต, ๊ธฐ๊ด๋ง, INACTIVE๋ฉด ์งํ ์ค ๋ฐฐ์ ์ข
๋ฃ |
POST |
/api/organizations/me/recipient-links |
ํ์ careRecipientNumber |
201 ๊ธฐ๊ด ์ฐ๊ฒฐ ์์ฒญ ์๋ต, status=PENDING, ๊ธฐ๊ด๋ง, ์ด๋ฏธ ์ฐ๊ฒฐ๋์ผ๋ฉด 409 |
GET |
/api/organizations/me/link-requests |
์ ํ status, page, pageSize |
๊ธฐ๊ด ์ฐ๊ฒฐ ์์ฒญ ์๋ต ๋ชฉ๋ก, ๊ธฐ๊ด๋ง |
GET |
/api/care-recipients/{careRecipientId}/organization-link-requests |
์ ํ status |
๊ธฐ๊ด ์ฐ๊ฒฐ ์์ฒญ ์๋ต ๋ฐฐ์ด, ์ฃผ ๋ณดํธ์๋ง |
POST |
/api/care-recipients/{careRecipientId}/organization-link-requests/{requestId}/accept |
์์ | ๊ธฐ๊ด ์ฐ๊ฒฐ ์์ฒญ ์๋ต, status=ACCEPTED, ์ฃผ ๋ณดํธ์๋ง |
POST |
/api/care-recipients/{careRecipientId}/organization-link-requests/{requestId}/reject |
์์ | ๊ธฐ๊ด ์ฐ๊ฒฐ ์์ฒญ ์๋ต, status=REJECTED, ์ฃผ ๋ณดํธ์๋ง |
DELETE |
/api/care-recipients/{careRecipientId}/organization-link-requests/{linkId} |
์์ | unlinked=true, ์ฃผ ๋ณดํธ์๋ง, ์ฐ๊ฒฐ ํด์ ์ ํด๋น ๊ธฐ๊ด ์ง์์ฌ ๋ฐฐ์ ์ ์ฒด ์ข
๋ฃยท๋ฏธ์๋ฃ ์ ๋ณด ์์ฒญ CLOSEDยท๊ธฐ๋ก ์์ฒญ CANCELLED |
POST |
/api/care-recipients/{careRecipientId}/institution-transfer |
ํ์ organizationCode |
careRecipientId, organization(id/name/organizationCode), ์ฃผ ๋ณดํธ์๋ง, ๊ธฐ์กด ๋ฐฐ์ ์ข
๋ฃ |
GET |
/api/care-recipients/{careRecipientId}/assignments |
์ ํ activeOnly, page, pageSize |
๋ฐฐ์ ์๋ต ๋ชฉ๋ก |
POST |
/api/organizations/me/assignments |
ํ์ Idempotency-Key, careRecipientId, supportWorkerId, startDate์ ํ endDate, notify ๊ธฐ๋ณธ true |
201 ๋ฐฐ์ ์๋ต, ๊ธฐ๊ด๋ง, ๊ธฐ๊ฐ ์ค๋ณต 409 |
PATCH |
/api/care-assignments/{assignmentId} |
ํ์ endDate(๋ ์ง ๋๋ null) |
๋ฐฐ์ ์๋ต, ๊ธฐ๊ด๋ง |
DELETE |
/api/care-assignments/{assignmentId} |
์์ | ๋ฐฐ์ ์๋ต, ๊ธฐ๊ดยท์ฃผ ๋ณดํธ์๋ง, ์ค๋ณต ์ข
๋ฃ 409 |
GET |
/api/care-recipients/{careRecipientId}/secondary-guardian |
์์ | ์ธ์ปจ๋ ๋ณดํธ์ ์๋ต ๋๋ null, ์ฃผ ๋ณดํธ์๋ง |
PUT |
/api/care-recipients/{careRecipientId}/secondary-guardian |
ํ์ name, email, phone |
์ธ์ปจ๋ ๋ณดํธ์ ์๋ต, status=INVITED, ์ฃผ ๋ณดํธ์๋ง |
PATCH |
/api/care-recipients/{careRecipientId}/secondary-guardian |
ํ์ active boolean |
์ธ์ปจ๋ ๋ณดํธ์ ์๋ต, READY โ ACTIVE, ์ฃผ ๋ณดํธ์๋ง |
DELETE |
/api/care-recipients/{careRecipientId}/secondary-guardian |
์์ | revoked=true, ์ฃผ ๋ณดํธ์๋ง |
| ์๋ต | data ํ๋ |
|---|---|
| ํ์ ์๋ต | id, name, publicCode, status, assignedRecipientCount |
| ๊ธฐ๊ด ์ฐ๊ฒฐ ์์ฒญ ์๋ต | id, careRecipientId, organization(id/name/organizationCode), status |
| ๋ฐฐ์ ์๋ต | id, careRecipientId, supportWorker(id/name/publicCode), organization(id/name/organizationCode), startDate, endDate, endedAt |
| ์ธ์ปจ๋ ๋ณดํธ์ ์๋ต | name, email, phone, status(INVITED/READY/ACTIVE), expiresAt |
| ๊ธฐ๊ด ์ฐ๊ฒฐ ์ํ | PENDING, ACCEPTED, REJECTED |
- ๋ฐฐ์ ยท๊ธฐ๊ด ์ฐ๊ฒฐ ์ข ๋ฃ ์ ํด๋น ์ง์์ฌ์ ๋น์ฌ์ ์ ๊ทผ ํ์
- ๋ฐฐ์ ยท๊ธฐ๊ด ์ฐ๊ฒฐ ์ข
๋ฃ ์ ๋ฏธ์๋ฃ ๊ธฐ๋ก ์์ฒญ
CANCELLED - ๊ธฐ๊ด ์ด์ ์ ๋ฏธ์๋ฃ ์ ๋ณด ์์ฒญ
CLOSED, ๊ธฐ๋ก ์์ฒญCANCELLED
์ํ๊ธฐ๋กยท์์ ์ ์
| Method | Endpoint | ์ ๋ ฅ | ์ถ๋ ฅ dataยท๊ถํ |
|---|---|---|---|
GET |
/api/care-recipients/{careRecipientId}/records |
์ ํ date ๋๋ year+month, page, pageSize |
๊ธฐ๋ก ์๋ต ๋ชฉ๋ก, ์ญ์ ๊ธฐ๋ก ์ ์ธ, ๋ ์ง ํํฐ ๋์ ์ฌ์ฉ ๋ถ๊ฐ |
GET |
/api/care-recipients/{careRecipientId}/records/today |
์์ | ์ค๋ ๊ธฐ๋ก ์๋ต ๋ฐฐ์ด |
POST |
/api/care-recipients/{careRecipientId}/records |
ํ์ content(trim ํ 1~500์), category, recordedAt์ ํ mediaIds(์ต๋ 5๊ฐ), recordRequestId, pinned ๊ธฐ๋ณธ false |
201 ๊ธฐ๋ก ์๋ต, ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์ยท๋ฐฐ์ ์ง์์ฌ๋ง, pinned=true๋ ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์๋ง |
GET |
/api/care-recipients/{careRecipientId}/records/{recordId} |
์์ | ๊ธฐ๋ก ์๋ต |
PATCH |
/api/care-recipients/{careRecipientId}/records/{recordId} |
content, category, recordedAt, mediaIds ์ค ํ๋ ์ด์mediaIds๋ ์ฒจ๋ถ ์ ์ฒด ๊ต์ฒด |
๊ธฐ๋ก ์๋ต, ๋ณดํธ์ ๋๋ ๋ฐฐ์ ์ค์ธ ์์ฑ ์ง์์ฌ๋ง |
DELETE |
/api/care-recipients/{careRecipientId}/records/{recordId} |
์์ | deletedAt, restoreUntil, ์์ฑ์ยท๋ณดํธ์๋ง |
POST |
/api/care-recipients/{careRecipientId}/records/{recordId}/restore |
์์ | ๊ธฐ๋ก ์๋ต, ์ญ์ ํ 30์ผ ์ด๋ดยท์ญ์ ๊ถํ์๋ง |
GET |
/api/care-recipients/{careRecipientId}/records/{recordId}/revisions |
์ ํ page, pageSize |
์์ ์ด๋ ฅ ์๋ต ๋ชฉ๋ก |
PATCH |
/api/care-recipients/{careRecipientId}/records/{recordId}/pin |
ํ์ pinned boolean |
๊ธฐ๋ก ์๋ต, ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์๋ง |
POST |
/api/care-recipients/{careRecipientId}/records/{recordId}/suggestions |
ํ์ content, ์ ํ category, reason |
201 ์์ ์ ์ ์๋ต, status=PENDING, ์ง์์ฌยท๊ธฐ๊ด๋ง |
GET |
/api/care-recipients/{careRecipientId}/record-suggestions |
์ ํ status ๊ธฐ๋ณธ PENDING, page, pageSize |
์์ ์ ์ ์๋ต ๋ชฉ๋ก, ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์๋ง |
GET |
/api/record-suggestions/mine |
์ ํ careRecipientId, status, page, pageSize |
์์ ์ ์ ์๋ต ๋ชฉ๋ก, ์ง์์ฌ๋ง (๋ณธ์ธ์ด ์ ์ถํ ์ ์ ์ด๋ ฅ) |
POST |
/api/care-recipients/{careRecipientId}/record-suggestions/{suggestionId}/decision |
ํ์ decision=APPROVE ๋๋ REJECT |
์์ ์ ์ ์๋ต, status=APPROVED/REJECTED, ์๋ณธ ๋ณ๊ฒฝ ์ 409 |
POST |
/api/care-recipients/{careRecipientId}/records/{recordId}/forward-to-guardian |
์์ | recordId, forwardedAt, notificationId, ๊ธฐ๊ด๋ง, ๋์ ํ๋ ๊ธฐ๋ก๋ง, ์ค๋ณต ์ ๋ฌ 409 |
| ์๋ต | data ํ๋ |
|---|---|
| ์์ ์ด๋ ฅ ์๋ต | revision, changedBy(id/name/role), changedAt, content, category, recordedAt |
| ์์ ์ ์ ์๋ต | id, recordId, original(content/category), proposed(content/category), reason(์์ผ๋ฉด null), suggestedBy(id/name/role), status, createdAt |
| ์์ ์ ์ ์ํ | PENDING, APPROVED, REJECTED |
recordRequestId๋ฅผ ์ฌ์ฉํ ๊ธฐ๋ก์ ํด๋น ๋น์ฌ์ยท์ง์์ฌยทOPEN์์ฒญ๊ณผ ์ผ์นํ๊ณcategory=CHALLENGING_BEHAVIORํ์, ์ ์ฅ ์ ์์ฒญCOMPLETED- ์์ ์ ์ ์น์ธ ์ ๊ธฐ๋ก ๊ฐฑ์ ยท์์ ์ด๋ ฅ ์ถ๊ฐ
- ๋์ ํ๋ ๊ธฐ๋ก์ ์์ฑ ์ฆ์ ๋ณดํธ์์๊ฒ ์กฐํ ๊ฐ๋ฅ, ๊ธฐ๊ด์ ์ ๋ฌ ํธ์ถ์ ๋ณดํธ์์๊ฒ ์๋ฆผ ์์ฑ
๋๋ด์ ๋ณดยท๋ฏธ๋์ดยทAI
| Method | Endpoint | ์ ๋ ฅ | ์ถ๋ ฅ dataยท๊ถํ |
|---|---|---|---|
GET |
/api/care-recipients/{careRecipientId}/care-info |
์์ | categories[](6๊ฐ ๋๋ด์ ๋ณด ์๋ต), pinnedRecords[](๊ธฐ๋ก ์๋ต) |
GET |
/api/care-recipients/{careRecipientId}/care-info/{category} |
๊ฒฝ๋ก category |
๋๋ด์ ๋ณด ์๋ต |
PUT |
/api/care-recipients/{careRecipientId}/care-info/{category} |
ํ์ content(0~3000์, ๋น ๋ฌธ์์ด๋ก ๋น์ฐ๊ธฐ) |
๋๋ด์ ๋ณด ์๋ต, ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์๋ง |
POST |
/api/care-recipients/{careRecipientId}/media |
ํ์ file, JPEG/PNG/WebP/MP4/MP3/M4A/WAV/WebM, ์ต๋ 50MB |
201 ๋ฏธ๋์ด ์๋ต, ๊ธฐ๋ก ์์ฑ ๊ถํ์๋ง |
GET |
/api/care-recipients/{careRecipientId}/media/{mediaId}/download-url |
์์ | url, expiresAt, ๋น์ฌ์ ์ ๊ทผ ๊ถํ ํ์ |
DELETE |
/api/care-recipients/{careRecipientId}/media/{mediaId} |
์์ | deleted=true, ๋ฏธ์ฐ๊ฒฐ ํ์ผ์ ์
๋ก๋ยท์ฐ๊ฒฐ ํ์ผ์ ๊ธฐ๋ก ์์ ๊ถํ์๋ง |
POST |
/api/ai/record-drafts |
ํ์ careRecipientId, inputType=TEXT + text(1~3000์) ๋๋ inputType=AUDIO + mediaId(์ต๋ 10๋ถ) |
transcript, content, category, ๊ธฐ๋ก์ ์์ฑ๋์ง ์์ |
| ์๋ต | data ํ๋ |
|---|---|
| ๋๋ด์ ๋ณด ์๋ต | category, content, updatedAt, ๋ฏธ์์ฑ ๋ด์ฉ์ ๋น ๋ฌธ์์ด |
| ๋ฏธ๋์ด ์๋ต | mediaId, fileName, mediaType, sizeBytes |
- ๋ฏธ๋์ด๋ ๊ฐ์ ๋น์ฌ์์ ๊ธฐ๋ก์๋ง ์ฐ๊ฒฐ ๊ฐ๋ฅ, ๊ธฐ๋ก๋น ์ต๋ 5๊ฐ
- ๋ค์ด๋ก๋ URL ์ ํจ ๊ธฐ๊ฐ 5๋ถ
์์ฒญยท์๋ฆผยท์ ๊ทผ ์ด๋ ฅ
| Method | Endpoint | ์ ๋ ฅ | ์ถ๋ ฅ dataยท๊ถํ |
|---|---|---|---|
POST |
/api/care-recipients/{careRecipientId}/information-requests |
ํ์ message(1~1000์) |
201 ์ ๋ณด ์์ฒญ ์๋ต, status=SUBMITTED, ๋ฐฐ์ ์ง์์ฌ๋ง |
GET |
/api/information-requests |
์ ํ status, page, pageSize |
์ ๋ณด ์์ฒญ ์๋ต ๋ชฉ๋ก, ์์ฒญํ ์ง์์ฌ๋ง |
GET |
/api/organizations/me/information-requests |
์ ํ status, page, pageSize |
์ ๋ณด ์์ฒญ ์๋ต ๋ชฉ๋ก, ๊ธฐ๊ด๋ง |
POST |
/api/organizations/me/information-requests/{requestId}/forward |
์์ | ์ ๋ณด ์์ฒญ ์๋ต, status=FORWARDED, ๊ธฐ๊ด๋ง |
GET |
/api/care-recipients/{careRecipientId}/information-requests |
์ ํ status, page, pageSize |
์ ๋ณด ์์ฒญ ์๋ต ๋ชฉ๋ก, ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์๋ง |
POST |
/api/care-recipients/{careRecipientId}/information-requests/{requestId}/reply |
ํ์ message(1~1000์) |
์ ๋ณด ์์ฒญ ์๋ต, status=ANSWERED, ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์๋ง |
POST |
/api/organizations/me/information-requests/{requestId}/close |
์์ | ์ ๋ณด ์์ฒญ ์๋ต, status=CLOSED, ๊ธฐ๊ด๋ง |
POST |
/api/care-recipients/{careRecipientId}/record-requests |
ํ์ Idempotency-Key, supportWorkerId์ ํ message(์ต๋ 1000์) |
201 ๊ธฐ๋ก ์์ฒญ ์๋ต, status=OPEN, ๊ธฐ๊ด๋ง, ์ ํจ ๋ฐฐ์ ์ด ์์ผ๋ฉด 409 |
GET |
/api/care-recipients/{careRecipientId}/record-requests |
์ ํ status, page, pageSize |
๊ธฐ๋ก ์์ฒญ ์๋ต ๋ชฉ๋ก, ๊ธฐ๊ด๋ง |
GET |
/api/record-requests |
์ ํ status, page, pageSize |
๊ธฐ๋ก ์์ฒญ ์๋ต ๋ชฉ๋ก, ์์ ์ง์์ฌ๋ง |
POST |
/api/record-requests/{requestId}/cancel |
์์ | ๊ธฐ๋ก ์์ฒญ ์๋ต, status=CANCELLED, ์์ฒญ ๊ธฐ๊ด๋งยทOPEN ์ํ๋ง |
GET |
/api/notifications |
์ ํ read, page, pageSize |
์๋ฆผ ์๋ต ๋ชฉ๋ก, ๋ณธ์ธ๋ง |
GET |
/api/notifications/unread-count |
์์ | count (๋ฏธํ์ธ ์๋ฆผ ์ ์ ์), ๋ณธ์ธ๋ง |
PATCH |
/api/notifications/{notificationId} |
ํ์ read boolean |
์๋ฆผ ์๋ต, ๋ณธ์ธ๋ง |
GET |
/api/care-recipients/{careRecipientId}/access-logs |
์ ํ page, pageSize |
์ ๊ทผ ์ด๋ ฅ ์๋ต ๋ชฉ๋ก, ๋ณดํธ์ยทํ์ฑ ์ธ์ปจ๋ ๋ณดํธ์๋ง |
| ์๋ต | data ํ๋ |
|---|---|
| ์ ๋ณด ์์ฒญ ์๋ต | id, careRecipientId, requestedBy(id/name/role), message, status, reply, createdAt, updatedAt |
| ๊ธฐ๋ก ์์ฒญ ์๋ต | id, careRecipientId, supportWorker(id/name/publicCode), requestedBy(id/name/role), message, status, completedRecordId, createdAt |
| ์๋ฆผ ์๋ต | id, type, message, read, createdAt |
| ์ ๊ทผ ์ด๋ ฅ ์๋ต | actor(id/name/role), action, resourceType, resourceId, occurredAt |
| ์ ๋ณด ์์ฒญ ์ํ | SUBMITTED, FORWARDED, ANSWERED, CLOSED |
| ๊ธฐ๋ก ์์ฒญ ์ํ | OPEN, COMPLETED, CANCELLED |
| ์๋ฆผ ์ ํ | RECORD_CREATED, RECORD_UPDATED, ASSIGNMENT_CHANGED, SUGGESTION_RECEIVED, SUGGESTION_DECIDED, INFORMATION_REQUEST_RECEIVED, INFORMATION_REQUEST_REPLIED, RECORD_REQUEST_RECEIVED, RECORD_REQUEST_COMPLETED, RECORD_FORWARDED, ORGANIZATION_LINK_REQUESTED, ORGANIZATION_LINK_ACCEPTED, ORGANIZATION_LINK_REJECTED |
| ์ ๊ทผ ๋์ | READ, CREATE, UPDATE, DELETE |
- ์ ๋ณด ์์ฒญ ์ํ
SUBMITTED โ FORWARDED โ ANSWERED โ CLOSED - ์๋ต ๊ธฐ๋ก ์ ์ฅ ์ ํด๋น ๊ธฐ๋ก ์์ฒญ
COMPLETED
์ด๋๋ฏผ
๋ชจ๋ ์๋ํฌ์ธํธ๋
ADMIN์ญํ ์ ์ฉ. ์ผ๋ฐ ์ฌ์ฉ์ ์ ๊ทผ ์403.
| Method | Endpoint | ์ ๋ ฅ | ์ถ๋ ฅ data |
|---|---|---|---|
GET |
/api/admin/stats |
์์ | totalUsers, guardians, supportWorkers, institutions, totalOrganizations, totalCareRecipients, totalRecords |
GET |
/api/admin/users |
์ ํ role, organizationId, page, size |
์ฌ์ฉ์ ์์ฝ ์๋ต ๋ชฉ๋ก |
POST |
/api/admin/users |
ํ์ name, email, password(6์ ์ด์), role์ ํ phone, organizationId |
201 ์ฌ์ฉ์ ์์ฝ ์๋ต |
PATCH |
/api/admin/users/{id} |
ํ์ name, email, role์ ํ phone, organizationId |
์ฌ์ฉ์ ์์ฝ ์๋ต |
DELETE |
/api/admin/users/{id} |
์์ | null (204), ๋ณธ์ธ ๊ณ์ ์ญ์ ๋ถ๊ฐ |
GET |
/api/admin/users/{id}/records |
์์ | ๊ธฐ๋ก ์์ฝ ์๋ต ๋ชฉ๋ก |
GET |
/api/admin/organizations |
์์ | ๊ธฐ๊ด ์ด๋๋ฏผ ์๋ต ๋ชฉ๋ก |
POST |
/api/admin/organizations |
ํ์ name์ ํ ownerId |
201 ๊ธฐ๊ด ์ด๋๋ฏผ ์๋ต, 6์๋ฆฌ organizationCode ์๋ ๋ฐ๊ธ |
PATCH |
/api/admin/organizations/{id} |
ํ์ name |
๊ธฐ๊ด ์ด๋๋ฏผ ์๋ต |
DELETE |
/api/admin/organizations/{id} |
์์ | null (204) |
GET |
/api/admin/organizations/{id}/records |
์์ | ๊ธฐ๋ก ์์ฝ ์๋ต ๋ชฉ๋ก |
GET |
/api/admin/care-recipients |
์ ํ search(์ด๋ฆยท๊ณต๊ฐ ๋ฒํธ) |
๋น์ฌ์ ์ด๋๋ฏผ ์๋ต ๋ชฉ๋ก |
POST |
/api/admin/care-recipients |
ํ์ name(1birthDate, disabilityTypes(1gender, disabilityGrade, otherDisabilityType, guardianId |
201 ๋น์ฌ์ ์ด๋๋ฏผ ์๋ต, careRecipientNumber ์๋ ๋ฐ๊ธ |
| ์๋ต | data ํ๋ |
|---|---|
| ์ฌ์ฉ์ ์์ฝ ์๋ต | id, name, email, role, phone, publicCode, organizationId |
| ๊ธฐ๊ด ์ด๋๋ฏผ ์๋ต | id, name, organizationCode, ownerId, ownerName, createdAt |
| ๋น์ฌ์ ์ด๋๋ฏผ ์๋ต | id, careRecipientNumber, name, birthDate, gender, disabilityTypes, disabilityGrade, otherDisabilityType, guardianName, guardianEmail, organizationName, createdAt |
| ๊ธฐ๋ก ์์ฝ ์๋ต | (AdminRecordSummaryResponse โ ์์ธ ํ๋๋ Swagger ์ฐธ๊ณ ) |
careRecipientNumber(P-XXXXXXXX)๋ ์ด๋๋ฏผ ๋๋ ๋ณดํธ์ ์ง์ ๋ฑ๋ก ์ ์๋ ๋ฐ๊ธ. ๊ธฐ๊ด์ด ์ฐ๊ฒฐ ์์ฒญ(POST /api/organizations/me/recipient-links) ์ ์ด ๋ฒํธ๋ฅผ ๋ณดํธ์๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ์ ๋ ฅํจ.
๋ณ๊ฒฝ ์ด๋ ฅ
| ๋ ์ง | ๋ด์ฉ | ์์ฑ์ |
|---|---|---|
| 2026-10-08 | ์ต์ด API ๊ฒฝ๋กยท์๋ต ์ด์ | |
| 2026-10-09 | PRDยทUser-FlowยทWireframe ๊ธฐ์ค API v1 ์ ๋ ฅยท์ถ๋ ฅ ๊ณ์ฝ ์ ๋ฆฌ | Codex |
| 2026-10-22 | ๋๋ฝ ์๋ํฌ์ธํธ 5๊ฐ ์ถ๊ฐ, ์ด๋๋ฏผ ์น์
์ถ๊ฐ, ์๋ฆผ ํ์
3๊ฐ ์ถ๊ฐ(INFORMATION_REQUEST_REPLIED, RECORD_REQUEST_COMPLETED, ORGANIZATION_LINK_ACCEPTED/REJECTED), DELETE .../organization-link-requests/{linkId} ์ฌ์ด๋์ดํํธ ๋ณด์, GET /api/record-suggestions/mine careRecipientId ํํฐ ์ถ๊ฐ |
Claude Code |