Admin APIAdmin Dashboard API
PATCH /ai/admin/dashboard/applications/prices/bulk
여러 application 가격 4종 벌크 부분 수정 (item 별 독립 트랜잭션)
여러 application 가격 4종 벌크 부분 수정
여러 신청을 한 번의 요청으로 부분 수정합니다. 단건 API(/prices)를 item 별로 호출하는 구조로, item 별 독립 트랜잭션이라 일부 실패가 다른 item 에 영향을 주지 않습니다.
- item 별 처리 룰은 단건 API 와 100% 동일합니다 — 자동계산 트리거, MANUAL override, ACCEPT 차단 모두 동일하게 적용.
forceOverride는 top-level: 모든 item 에 일괄 적용됩니다. item 별 개별 설정 불가.- 한 item 이 throw 해도 나머지는 그대로 처리됩니다. 응답의
failedItems로 실패 사유 확인. - 응답 코드는 부분 실패 여도 200 OK — 메시지에
N건 중 M건 성공, K건 실패요약.
item 별 동작
각 item 은 단건 API 와 동일한 룰로 처리됩니다. 자세한 내용은 단건 가격 수정 문서 참고.
| 필드 | 처리 |
|---|---|
defaultUnitPrice | 직접 UPDATE |
proposedPrice | TB_PRICE_NEGOTIATION 신규 ACCEPT INSERT + (옵션) quote/current 자동계산 |
quotePrice / currentPrice | 명시 시 MANUAL, 미명시 + 제안가 변경 시 AUTO_CALCULATED |
HTTP 요청
PATCH /ai/admin/dashboard/applications/prices/bulk
Authorization: Bearer {access_token}
Content-Type: application/jsonRequest Body
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
forceOverride | Boolean | 아니오 | top-level. 기본 false. true 시 모든 item 에서 ACCEPT 차단 우회 |
items | List<Item> | 예 | 수정할 item 배열 (빈 배열 허용 — successCount=0 반환) |
Item 필드
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
applicationId | Long | 예 | 신청 ID. null 이면 해당 item 은 실패 처리 |
defaultUnitPrice | Long | 아니오 | 희망가 |
proposedPrice | Long | 아니오 | 제안가 |
quotePrice | Long | 아니오 | 기존가 (MANUAL) |
currentPrice | Long | 아니오 | 노출가 (MANUAL) |
요청 예시 1 — 여러 명 한 번에 정정
{
"forceOverride": false,
"items": [
{
"applicationId": 14853,
"defaultUnitPrice": 400000,
"proposedPrice": 400000
},
{
"applicationId": 14854,
"quotePrice": 500000,
"currentPrice": 350000
},
{
"applicationId": 14855,
"defaultUnitPrice": 300000
}
]
}요청 예시 2 — ACCEPT 인원 일괄 강제 정정
{
"forceOverride": true,
"items": [
{ "applicationId": 14853, "proposedPrice": 400000 },
{ "applicationId": 14854, "proposedPrice": 350000 }
]
}응답
성공 응답 (200 OK) — 전부 성공
{
"status": 200,
"code": null,
"message": "3건 중 3건 성공, 0건 실패",
"data": {
"totalCount": 3,
"successCount": 3,
"results": [
{
"applicationId": 14853,
"updatedFields": ["defaultUnitPrice", "proposedPrice", "quotePrice", "currentPrice"],
"defaultUnitPrice": 400000,
"quotePrice": 690000,
"currentPrice": 460000,
"newPriceNegotiationId": 7501,
"overrideApplied": false,
"quotePriceSource": "AUTO_CALCULATED",
"currentPriceSource": "AUTO_CALCULATED"
},
{
"applicationId": 14854,
"updatedFields": ["quotePrice", "currentPrice"],
"defaultUnitPrice": 300000,
"quotePrice": 500000,
"currentPrice": 350000,
"newPriceNegotiationId": null,
"overrideApplied": false,
"quotePriceSource": "MANUAL",
"currentPriceSource": "MANUAL"
},
{
"applicationId": 14855,
"updatedFields": ["defaultUnitPrice"],
"defaultUnitPrice": 300000,
"quotePrice": null,
"currentPrice": null,
"newPriceNegotiationId": null,
"overrideApplied": false,
"quotePriceSource": "UNCHANGED",
"currentPriceSource": "UNCHANGED"
}
],
"failedItems": []
}
}부분 실패 응답 (200 OK)
존재하지 않는 applicationId 나 ACCEPT 차단으로 일부 item 이 실패한 경우:
{
"status": 200,
"code": null,
"message": "3건 중 1건 성공, 2건 실패",
"data": {
"totalCount": 3,
"successCount": 1,
"results": [
{ "applicationId": 14853, "updatedFields": ["defaultUnitPrice"], ... }
],
"failedItems": [
{
"applicationId": 999999,
"error": "CampaignApplication을 찾을 수 없습니다: 999999"
},
{
"applicationId": 14854,
"error": "이미 수락된 협상이 있습니다. 제안가 변경 시 forceOverride=true 가 필요합니다."
}
]
}
}빈 items
{
"status": 200,
"code": null,
"message": "0건 중 0건 성공, 0건 실패",
"data": {
"totalCount": 0,
"successCount": 0,
"results": [],
"failedItems": []
}
}응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
totalCount | int | 요청 item 총 수 |
successCount | int | 성공한 item 수 |
results | List<UpdateApplicationPricesResponseDto> | 성공 item 별 단건 응답 구조 그대로 (각 필드 의미는 단건 문서 참고) |
failedItems | List<{applicationId, error}> | 실패 item 의 신청 ID + 에러 메시지 |