사용자가 실서버에서 「AI 추천 MF 0명」을 보고 물었다. 화면은 「팀을 먼저 만들어야 후보를 찾습니다」라고만 적고 있었는데, 팀을 만들어도 0명이었을 것이다. 그 뒤에 더 근본적인 것이 막혀 있었다.

무엇이 막혀 있었나

후보의 첫 하드 필터는 「그 포지션을 member_match_position 에 등록했는가」다 (계약 3-13절). 그런데:

  • 화면에서 자리를 고르는 곳은 「사람을 찾는 팀」 판의 「내 자리」 하나뿐인데, 그 값이 localStorage 에만 저장되고 있었다 — 서버로 안 올라갔다.
  • 서버에는 경로가 있었다: PUT /me/match-preferences. 그런데 이게 포지션을 position_ids(UUID) 로 받는데, 그 UUID 를 내주는 경로가 없었다. GET /positions 는 {sport_code, code, label} 만 줬다.
  • 약칭(MF)으로는 못 보낸다. 종목 안에서만 유일해서 C 하나로는 야구 포수인지 농구 센터인지 안 가려진다 — 그래서 position 은 대리키를 쓴다.

즉 클라이언트가 자기 포지션을 등록할 방법이 원천적으로 없었다. 계약 문서에 position_ids 라는 말 자체가 없었던 것도(grep 0건) 같은 구멍의 자국이다.

무엇을 했나

fastapi/ 를 직접 고쳤다(사용자 승인). 남의 구역이고 계약이 바뀌는 변경이라 미결 paik 43번에 근거를 남겼다.

  • GET /positions 응답에 id 를 실었다. 지역이 GET /regions 로 id 를 받는 것과 같은 결로 맞춘 것이다.
  • 화면 쪽은 「내 자리」가 서버로 올라가게 배선했다 — 약칭→id 변환은 matchPrefsServer.ts 한 곳에 두고, 읽고 쓰는 것은 myPrefsStore.ts 다.
  • 🔴 조용히 빈 값으로 저장하지 않는다. 고른 자리가 하나도 안 풀리면 저장을 막고 화면에 적는다 — 「화면에는 성공으로 보이는데 후보에는 안 뜨는」 조합이 가장 나쁘다는 판단이다(팀 조건의 지역에서 이미 같은 결정을 했다).
  • 덤으로 두 가지를 걷었다: 조건 폼의 「아직 이 브라우저에만 남습니다」 안내(이제 거짓이다)와, 경기장 판의 「정해 둔 조건에 맞는 곳만」이 아무도 안 쓰는 저장소를 읽던 것(이미 죽어 있던 기능이라 서버를 읽게 고쳤다).

남은 것

🔴 백엔드 배포 전까지 실서버에서는 여전히 등록되지 않는다. 배포는 정어진 담당이다 — 미결 paik 43번에 확인 명령과 함께 남겼다.

같은 날 「심사위원용 로그인」이 실서버에서 안 되던 것도 고쳤다. 원인은 닉네임 충돌이었다 — 심사위원 을 이미 다른 계정이 쓰고 있어서 가입이 409 로 튕겼고, 그 409 를 삼키는 바람에 「이메일 또는 비밀번호가 올바르지 않습니다」만 떴다. 계정을 실제로 만들어 두는 것으로 풀었다(코드는 사용자 판단으로 그대로 뒀다).