첫 팀 프로젝트에서 프론트엔드 개발자로서 놓쳤던 것들
안녕하세요! SCG 31기 손희창입니다😊
함께 진행했던 팀 프로젝트를 마치며 개발 블로그에 회고글을 작성해보려 합니다. 이 글을 통해 제가 했던 실수와 부족했던 점들을 솔직하게 기록하고, 앞으로 같은 실수를 반복하지 않도록 스스로를 돌아보고자 합니다.
또한 팀 프로젝트 경험을 통해 깨달은 점도 글로 기록해보려고 합니다.
그럼, 본격적으로 이번 프로젝트에 대한 회고를 아주 진지하게 시작해 보겠습니다.
6월 말, 내 아이디어로 시작한 팀 프로젝트에서 프론트엔드를 맡았다. 약 두 달 동안 서비스를 만드는 일정이었다.
잘 만들고 싶었다. 머릿속에 있던 서비스를 직접 디자인하고, 실제로 사용할 수 있는 화면으로 구현하고 싶었다. 피그마를 배우며 화면을 만들었고, AI의 도움을 받아 프론트엔드 코드로 옮겼다.
화면이 갖춰질수록 프로젝트도 완성에 가까워지고 있다고 생각했다. 하지만 API 연동을 시작하자 내가 만든 화면과 팀이 구현하고 있던 서비스 사이의 차이가 드러났다.
그 차이를 뒤늦게 맞추는 동안 일정이 밀렸고, 팀원들에게 변경을 요청하는 일이 반복됐다. 또한 반대로 필요한 논의까지 피했다. 결국 알고도 가볍게 판단한 문제가 배포 이후 실제로 발견됐다.
이 글은 그때 내가 왜 그런 판단을 했는지 돌아보는 기록이다. 처음 백엔드와 협업하거나 AI로 프론트엔드를 구현하는 사람에게도, 자신의 작업을 한 번 점검해 볼 계기가 되었으면 한다.
1. 내 머릿속의 서비스가 팀의 합의라고 생각했다
처음 계획은 대략 디자인 2주, 프론트엔드 구현 2주, 백엔드 연동 2주, 테스트 1주였다.
나는 곧바로 AI에게 구현을 맡기기보다 화면을 직접 설계하고 싶었다. 그래서 피그마를 배우면서 앱 기준으로 디자인을 시작했다.
문제는 그 과정에서 백엔드가 논의하던 ERD와 기능 범위를 제대로 확인하지 않았다는 것이다. 내가 생각한 서비스에 필요한 화면과 기능을 그렸지만, 해당 정보가 실제로 저장되는지, 어떤 데이터 관계를 갖는지, API로 제공될 예정인지는 충분히 살펴보지 않았다.
백엔드 팀원들은 슬랙에서 논의했고, 결정된 내용은 노션에 남겼다. 나는 그 내용을 볼 수 있었다. 그런데도 ‘백엔드에서 알아서 진행할 일’이라고 생각했다.
이전까지 내 경험은 주어진 데이터를 보여주는 UI를 개선하거나, 백엔드 없이 동작하는 간단한 개인 프로젝트를 만드는 정도였다. 그래서 화면에 필요한 데이터가 어떤 논의를 거쳐 정해지는지 체감하지 못했다.
내 아이디어로 시작한 프로젝트라는 점도 영향을 준 것 같다. 내가 생각하는 서비스의 모습이 팀원들과도 충분히 공유돼 있다고 무의식적으로 생각했다. 하지만 아이디어를 설명하는 것과 구현할 기능을 구체적으로 합의하는 것은 달랐다.
예를 들어 화면에 정보 하나를 추가하는 것은 디자인에서는 작은 작업이다. 실제 서비스에서는 그 정보의 저장 위치, 생성 주체, 조회 방법까지 결정해야 할 수 있다. 나는 그런 결정을 확인하지 않은 채 화면부터 확정하고 있었다.
다음에는 화면을 그리기 전에, 화면에 필요한 정보와 동작이 팀에서 합의된 것인지 확인하려 한다.
ERD 그대로 화면을 만들겠다는 뜻은 아니다. 데이터 구조를 이해하고, 화면에 필요한 API와 동작을 함께 정하겠다는 뜻이다. 필요한 정보가 없다면 디자인과 구현이 진행되기 전에 논의할 수 있어야 한다.
2. 디자인에 더 쓴 시간이 어디에서 빠지는지 생각하지 않았다
2주로 예상했던 디자인에는 약 4주가 걸렸다.
피그마를 배우는 시간과 실제 화면을 설계하는 시간을 너무 낙관적으로 잡았다. 작업하면서 부족한 부분이 보이면 고치고, 필요한 화면을 추가하다 보니 시간이 계속 늘어났다... (게으름의 탓도 분명 존재했다. 어떤 일을 하든 성실히 마감 기한 안에 끝내야한다.)
당시에는 디자인을 조금 더 완성한 뒤 다음 단계로 넘어가는 것이 좋겠다고 생각했다. 하지만 전체 일정이 정해져 있었기 때문에 디자인에 더 쓴 시간은 연동과 테스트에 쓸 여유를 줄이고 있었다.
팀원들이 독촉하지 않았지만, 그것이 일정 지연에 대한 합의를 의미하지는 않았다. 내가 먼저 진행 상황과 남은 작업을 공유했어야 했다.
지금이라면 일정이 밀리기 시작할 때 이런 내용을 정리해 이야기할 것이다.
- 현재 확정된 화면과 아직 남은 화면
- 예상보다 오래 걸리는 이유
- 먼저 구현을 시작할 수 있는 범위
- 이번 배포에서 미룰 수 있는 기능
이번 경험 이후 ‘계획한 날짜를 무조건 지키겠다’는 다짐만으로는 부족하다고 생각하게 됐다. 예상은 틀릴 수 있고, 처음 해 보는 작업은 더 그렇다.
내가 지켜야 할 원칙은 지연을 늦게 알리지 않는 것이다. 일정이 달라질 조짐이 보이면 공유하고, 범위와 우선순위를 팀과 다시 맞춰야 한다.
3. 목(Mock) 데이터로 동작하는 화면을 너무 믿었다
디자인을 마친 뒤에는 Claude에 화면과 설명을 전달해 프론트엔드 구현을 요청했다.
목 데이터로 디자인이 잘 옮겨졌는지 확인했다. 간단한 수정은 직접 했고, 변경 범위가 크거나 기능을 추가해야 하면 AI에게 요청했다.
그렇게 화면은 빠르게 갖춰졌다. 버튼을 누르면 값이 바뀌고, 목록에는 데이터가 표시됐다. 눈으로 확인할 수 있는 결과가 있었기 때문에 작업이 잘 진행되고 있다고 느꼈다.
하지만 목 데이터는 내가 원하는 구조로 만들 수 있었다. 화면에서 필요한 값이 있으면 넣으면 됐다. 그 값이 실제 API에 있는지 확인하지 않아도 화면은 정상적으로 보였다.
내가 확인한 것은 주로 ‘이 데이터가 주어졌을 때 화면이 잘 보이는가’였다. 내가 해왔던 이전 프로젝트들은 이 단계까지만 해도 충분했다. ‘실제 서비스에서 이 데이터를 받을 수 있는가’는 확인하지 않았다.
API 연동 단계에서 명세서를 분석하고 나서야 일부 기능은 현재 API만으로 구현할 수 없다는 사실을 알게 됐다. 화면에서는 이미 완성된 것처럼 보였던 기능들이었다.
그때 나는 백엔드에 추가 기능을 요청했다. 하지만 팀은 이미 연동과 마무리를 진행해야 하는 시점이었다. 내가 초반에 확인하지 않았던 차이를 뒤늦게 다른 팀원의 작업으로 메우려 한 셈이었다.
목 데이터를 사용하는 것이 문제였던 것은 아니다. 목 데이터로 검증한 범위와 아직 검증하지 못한 범위를 구분하지 않은 것이 문제였다. 1번에서 비롯된 문제라고 보아도 될 것이다.
다음에는 목 데이터도 가능한 한 합의된 API 응답 구조에 맞춰 만들어야겠다고 생각했다. 아직 정해지지 않은 값이나 기능이 있다면 임의로 채운 채 잊어버리지 않고, 확인이 필요한 항목으로 남겨 두려고 한다.
4. AI가 만든 코드 앞에서 내가 할 수 있는 일이 적었다
연동을 시작할 무렵에는 기존에 사용하던 Claude를 사용할 수 없게 됐다. 그러자 무엇부터 해야 할지 막막했다.
GitHub Copilot의 도움을 받았지만, 도구를 바꾼다고 문제가 바로 해결되지는 않았다. 내가 API 연동을 충분히 이해하지 못했고, 이미 만들어진 코드의 데이터 흐름도 제대로 파악하지 못하고 있었기 때문이다.
연동 과정에서는 목 데이터를 사용하는 코드와 실제 API 응답을 사용하는 코드가 섞였다. 응답 JSON의 구조가 화면에서 기대하던 형태와 다른 경우도 많았다.
이 상태에서는 AI에게 “연동해 줘”, “오류를 고쳐 줘”라고 요청하는 것만으로 변경이 올바른지 판단하기 어려웠다. 무엇이 문제인지, 어디까지 수정해야 하는지를 내가 설명할 수 없었다.
결국 코드를 읽고 하나씩 확인하기 시작했다.
어떤 엔드포인트로 요청하는지, 어떤 응답을 받는지, 그 응답이 어디에서 가공되는지, 화면은 어떤 값을 참조하는지 따라갔다. 그러면서 API 명세서와 JSON 응답을 읽는 방법을 조금씩 알게 됐다.
연동에는 약 3주가 걸렸다. 필요한 공부였지만, 그 공부와 재작업이 일정 후반에 몰리면서 팀의 부담도 커졌다.
이 경험으로 AI를 사용하는 기준이 달라졌다. AI는 내가 이해하지 못한 코드도 빠르게 만들 수 있다. 하지만 결과를 설명하고 검토하는 책임까지 대신 맡아 주지는 않는다.
앞으로는 적어도 내가 맡은 기능에 대해 다음 질문에는 답할 수 있는 상태로 개발하려 한다.
- 데이터는 어디에서 오는가?
- 응답은 어떤 형태로 화면에 전달되는가?
- 사용자의 변경 사항은 어디에 저장되는가?
- 요청이 실패하면 화면은 어떻게 동작하는가?
모든 코드를 외우겠다는 뜻은 아니다. 수정이 필요할 때 어디를 살펴봐야 하는지는 알고 있어야 한다는 뜻이다.
5. 피드백을 받은 뒤, 필요한 요청까지 피했다
배포 시기가 가까워졌을 때도 백엔드에 응답 데이터를 바꿔 달라는 요청을 자주 했다.
내 입장에서는 화면에 연결하기 귀찮은 부분을 해결하려는 요청이었다. 하지만 팀원들의 입장에서는 이미 공개된 공간에서 논의하고 결정한 내용을 뒤늦게 바꿔 달라는 요구였다.
그 점을 지적받고 나서야 내가 초반에 논의를 확인하고 의견을 냈어야 한다는 사실을 제대로 받아들였다.
그런데 그다음에 또 잘못 판단했다.
‘이제는 더 부담을 주지 말고 내가 알아서 해결해야겠다....’
나는 변경 요청을 신중하게 하는 대신, 필요한 논의 자체를 피하려 했다. 그 선택이 배포 이후의 문제로 이어졌다.
발생 빈도와 데이터의 성격을 혼동했다
어떤 데이터를 저장하는 기능에서 백엔드 수정과 테이블 컬럼 추가가 필요했다. 하지만 나는 다시 수정을 요청하는 것이 부담스러워 프론트엔드에서 로컬로 저장하는 방식을 선택했다.
그 결과 같은 계정으로 접속하더라도 다른 기기에서는 해당 데이터가 유지되지 않았다.
나는 여러 기기로 서비스를 사용하는 경우가 많지 않을 것이라고 생각했다. 문제가 생길 수 있다는 사실을 알고 있었지만, 드문 상황일 것이라고 판단한 채 완성됐다고 하고 배포했다.
그런데 일주일도 지나지 않아 실제로 문제가 발견됐다.
돌아보니 나는 서로 다른 두 질문을 섞어 생각했다.
‘여러 기기로 같은 계정을 사용하는 사람이 과연 많을까?’
‘이 정보는 같은 계정이라면 어디서든 유지돼야 하는가?’
첫 번째 질문에 대한 내 예상만으로 두 번째 질문의 답을 바꿀 수는 없었다. 계정에 따라 유지돼야 하는 정보라면, 기기에만 저장했을 때 생기는 제약을 팀과 논의해야 했다.
이번에는 데이터가 유지돼야 하는 범위와 내가 선택한 저장 방식이 맞지 않았다.
내가 피했어야 했던 것은 필요한 변경 요청이 아니라, 사용자에게 생길 영향을 혼자 괜찮다고 결정하는 일이었다.
앞으로 변경이 필요하면 현재 동작, 사용자에게 생기는 문제, 가능한 대안과 일정 영향을 정리해 논의하려 한다. 내 구현 편의를 위한 변경인지, 합의한 기능을 제대로 제공하기 위한 변경인지도 구분해야 한다. 이부분이 사실 앞으로 가장 고쳐야하면서도 고칠 자신이 있는 부분이다. (당연히 나머지 실수도 덜(?) 자신있지만 고칠 것이다.)
6. 테스트하면서 화면 밖의 흐름을 보기 시작했다
프로젝트 후반에는 테스트를 더 꼼꼼하게 했다.
직접 기능을 사용하면서 문제를 재현하고, 요청과 응답을 확인했다. 그러자 화면에 드러난 오류가 프론트엔드의 처리 과정에서 생긴 것인지, 백엔드 응답을 더 확인해야 하는 것인지 어느 정도 구분할 수 있게 됐다.
처음에는 ‘화면이 이상하다’고만 느꼈던 문제를 조금 더 구체적으로 설명할 수 있게 된 것이다.
어떤 순서로 사용했을 때 문제가 생겼는지, 어떤 요청을 보냈는지, 응답은 무엇이었는지 확인하면 팀원과 대화할 때도 도움이 됐다.
테스트를 마지막에 남는 시간으로 해서는 안 된다는 것도 체감했다. 특히 저장 기능은 버튼을 누른 직후 화면이 바뀌는 것만으로 검증이 끝나지 않았다. 새로고침하거나 다시 로그인했을 때도 유지되는지, 계정에 속한 정보라면 다른 기기에서도 같은 결과를 볼 수 있는지 확인해야 했다.
알려진 문제가 있다고 해서 모든 배포를 무조건 중단해야 한다고 생각하지는 않는다. 다만 그 문제를 알고 있다면 영향과 제약을 공유하고, 수정하거나 기능을 제한하거나 다음 배포로 미룰지 함께 결정해야 한다.
나는 그 판단 과정을 혼자 건너뛰었다. 다음에는 완료를 보고할 때 동작하는 부분과 함께 남아 있는 제약도 설명하려 한다.
7. 이번 프로젝트를 통해 배운 역할과 기술
프로젝트 초반에는 프론트엔드 개발자의 역할을 화면 중심으로 생각했다. 디자인대로 구현하고, 사용하기 편하게 만드는 일이 가장 먼저 떠올랐다.
이제는 그 화면이 실제로 성립하는 조건까지 확인해야 한다고 생각한다.
어떤 데이터가 필요한지 설명하고, API로 제공되는 범위를 확인하고, 사용자의 행동이 어디에 저장되는지 이해해야 한다. 구현 과정에서 차이가 발견되면 팀과 조정하고, 실패하는 상황에서도 서비스가 어떻게 동작하는지 검증해야 한다.
백엔드의 일을 모두 알아야 한다는 뜻은 아니다. 내 화면과 연결되는 논의는 내 일이기도 하다는 뜻이다.
그 과정에서 기술적으로도 배운 것이 많았다.
- 피그마로 앱 화면을 설계하고 구체화하는 방법
- API 명세서와 JSON 응답을 읽고 화면에 연결하는 방법
- 엔드포인트와 요청·응답의 흐름
- 테스트를 통해 문제의 발생 지점을 좁혀 가는 방법
- Docker 이미지 빌드와 Kubernetes 환경에서의 배포 과정
- DataGrip으로 데이터를 추가하고 수정하는 방법
- 개발 환경과 운영 환경 사이에 작업 내용을 반영하는 과정
아직 이 모든 것을 능숙하게 할 수 있는 것은 아니다. 그래도 예전에는 화면 밖의 일로만 여겼던 과정들이 하나의 서비스로 연결돼 있다는 것을 경험했다.
갈등을 겪고 피드백을 받아들이는 경험도 남았다. 특히 반성한다는 이유로 소통을 줄이면 또 다른 문제가 생길 수 있다는 점을 배웠다.
8. 다음 프로젝트에서 다시 꺼내 볼 원칙
이번 회고를 ‘다음에는 잘하자’는 다짐으로 끝내고 싶지는 않다. 작업 중에 스스로 확인할 수 있는 질문으로 남겨 두려고 기재한다.
| 시점 | 나에게 물을 질문 | 지킬 행동 |
| 디자인을 시작할 때 | 이 기능은 내 구상인가, 팀이 합의한 범위인가? | 필요한 데이터와 동작을 먼저 확인한다. |
| 일정이 밀리기 시작할 때 | 이 지연이 이후 작업에 어떤 영향을 주는가? | 남은 작업과 예상 일정을 공유하고 범위를 조정한다. |
| 목 데이터로 구현할 때 | 이 데이터는 실제 API에서도 받을 수 있는가? | 합의된 응답 구조를 따르고 미확정 사항을 남긴다. |
| 핵심 화면을 만들었을 때 | 실제 데이터로도 이 흐름이 성립하는가? | 전체 화면이 끝나기 전에 핵심 기능부터 연동한다. |
| AI에게 수정을 맡길 때 | 나는 변경 결과를 검토할 수 있는가? | 데이터 흐름을 확인하고 작은 단위로 수정한다. |
| 변경이 필요할 때 | 편의를 위한 변경인가, 올바른 동작을 위한 변경인가? | 사용자 영향과 대안을 근거로 논의한다. |
| 데이터를 저장할 때 | 화면, 기기, 계정 중 어디까지 유지돼야 하는가? | 필요한 유지 범위에 맞는 저장 방식을 확인한다. |
| 완료를 보고할 때 | 알고 있는 문제와 제약을 팀도 알고 있는가? | 테스트 결과와 남은 문제를 함께 공유한다. |
이번 프로젝트에서 가장 돌아보게 되는 순간은 내가 ‘이 정도는 괜찮겠지’라고 혼자 판단했을 때다.
디자인이 늦어질 때도, 화면과 API가 맞지 않을 때도, 기기마다 데이터가 달라질 수 있다는 것을 알았을 때도 나는 확인과 논의를 미뤘다. 그때 해결하지 않은 차이는 나중에 더 많은 수정과 대화가 필요한 문제로 돌아왔다.
다음 프로젝트에서는 잘 모르는 부분을 일찍 드러내고 싶다. 내가 맡은 화면이 실제로 동작하는지 확인하고, 혼자 결정하기 어려운 문제는 근거를 갖춰 팀과 이야기하고 싶다.
그렇게 행동하고 있는지 돌아보기 위해 이 글을 남긴다.
끄읏 진지한 회고글 끝까지 읽어주셔서 정말 감사합니다😊
앞으로는 더욱 성장된 손희창이 되길...
이런 잘못 꼭 줄이길...
여러분도 화이팅하세요!😉