지원 무르기·거절을 열었습니다

DELETE /api/v1/matches/{match_id}/applications/{application_id} → 204. 지원 당사자가 부르면 무르기, 주최 팀 주장이 부르면 거절이고 둘 다 행을 지웁니다. 하는 일이 같아서 한 경로로 뒀습니다.

이걸로 09-03에 생겼던 막다른 곳이 풀립니다 — 지원이 붙은 경기는 409 MATCH_HAS_APPLICATIONS 로 취소가 막혀 있었고, 지원을 무르는 경로가 없어 그 409를 풀 수단 자체가 없었습니다.

선택지를 냈다가 제가 틀린 것을 찾았습니다

09-03에 A/B/C 셋으로 올리면서 A를 “지원 취소·거절 경로를 먼저 낸다” 한 줄로 적고 대가를 “부록 D를 건드립니다”라고 썼습니다. 둘 다 정확하지 않았습니다.

거절을 어떻게 담느냐로 A가 갈리는데, 그걸 안 봤습니다.

거절을 행이 RESTRICT는
지운다 (A-1) 없어진다 풀린다 → 취소된다
컬럼에 적는다 (A-2) 남는다 그대로다 → 안 풀린다

즉 A-2는 부록 D를 고치고도 문제를 못 풉니다. 그런데 표에서는 B·C와 나란히 놓여 있었습니다. 그대로 골랐으면 ERD를 고치고 나서야 안 풀린다는 걸 알게 됐을 것입니다.

그리고 “A는 부록 D를 건드린다”고 쓴 것도 반대였습니다 — A-1은 안 건드립니다. 넷 중 유일하게 ERD를 안 고치면서 409를 푸는 안이라 이것으로 정했습니다.

선택지를 낼 때 각 안이 “그래서 문제를 푸는가”를 따로 봐야 한다는 것을 배웠습니다. 대가(무엇을 고쳐야 하나)만 비교하고 효과를 안 봤습니다.

지원자가 스스로 무르는 것만으로는 안 풀립니다

“무를 수 있게 하면 되지 않나”로 읽히기 쉬운데 행위자가 다릅니다. 팀이 취소하려면 지원자 전원이 자발적으로 물러 주어야 합니다. 팀 쪽에서 정리하는 경로가 있어야 해서 거절을 같이 넣었습니다.

지난 경기에서는 막았습니다

422 PAST_MATCH 입니다. 두 수락 시각이 다 찬 행이 “누가 그 경기에 뛰었나”의 유일한 근거라, 지우면 평가(SFR-008 · 부록 D 도메인 「평가·신뢰」)가 대상을 잃습니다. 반대로 경기 전이면 확정된 건도 지웁니다 — 안 그러면 취소가 다시 막혀서 반만 푼 셈이 됩니다.

잃은 것

거절 이력이 남지 않습니다. 지금 요구사항에 쓰는 곳이 없어 받아들였지만, 나중에 필요해지면 컬럼이 아니라 별도 테이블이어야 합니다 — 행이 남으면 같은 막다른 곳이 돌아옵니다.

알림도 안 갑니다. 거절해도 지원자는 모릅니다. 알림 인프라가 없어서인데, 그래서 한 번에 지우는 경로도 일부러 두지 않았습니다 — 건별로 사람이 정리하는 편이 맞다고 봤습니다.

검사

452 passed (신규 13). 그중 TestUnblocksCancel이 409 → 거절 → 204를 실제로 통과시킵니다. 검사가 정말 판별하는지 보려고 세 군데를 일부러 깨뜨려 봤고 (권한 검사 무력화 · 삭제가 아무것도 안 함 · 지난 경기 검사 제거) 전부 잡혔습니다.

클라이언트 쪽

fastapi/docs/client-contract-changes.md 15번입니다. 같은 문서 14번의 “409는 지금 풀 수 없다”를 정정해 두었습니다 — 그렇게 안내를 붙이셨다면 고쳐 주십시오.


박민호 님 답을 기다리지 않고 진행했습니다. 스키마를 안 바꿨으므로 다르게 보시면 되돌리는 비용은 작습니다 — 라우터·인터랙터 하나씩입니다.