회고 & 기록/프로젝트 경험기

[프로젝트 회고] 옥외 광고 중개 플랫폼 개발

yubi5050 2026. 5. 20. 18:16

개요

아이브 코리아 입사 후 첫 진행한 프로젝트(옥외 광고 중개 플랫폼)에 대한 회고입니다.

약 1년 3개월(23년 3월 ~ 24년 5월) 동안  동안의 신규 웹 서비스 설계 및 구축부터 배포, 유지보수 및 안정화 과정을 기록하였습니다. 

 

평소 일하며 매일의 데일리를 메모에 적어두는데, 그 내용을 바탕으로 + 머리 구석구석의 작은 메모리 파편들을 영끌하여.. 역 구성? 하였습니다. 그래서 다만.. 현재는 시간이 좀 지났다 보니, 다수의 메모리들이 기억 왜곡 등으로 인해 살짝 미화? 되어 있을 수 있음은 감안을... 필요할 것 같습니다. 

 

개인적으로는 우리팀이 꾸려진 후 모두의 첫 프로젝트라 모든 팀원들이 서비스의 성공을 위해, 한 마음으로 큰 열정을 다 같이 쏟았던 그런 뜻 깊은 시간으로 기억하고 있습니다 (물론 이것도 저만의 '기억 왜곡에 의한 미화' 일 수도 있음)

 

 

찾아옥외 프로젝트 개요

한줄소개 : 옥외 광고 시장의 정보 비대칭 문제를 해결하고, 광고 청약부터 운영·관리까지의 전 과정을 디지털화한 옥외 광고 중개 플랫폼

주요 대상 사용자 : 광고대행사, 광고주, 일반 사용자 / 매체사 / 운영자

주요 기능

  1. 옥외 광고 매체 탐색: 지도 기반 UI를 통해 광고 가능한 전국 옥외 매체 한눈에 확인, 위치·조건별 손쉽게 탐색
  2. 간편 견적 및 청약 프로세스 지원: 광고주는 여러 매체에 대한 견적을 한 번에 요청하고 비교, 청약 과정 간편하게 진행 가능
  3. 매체 소개서 및 견적서 생성 기능: 매체사는 손쉬운 등록·수정 UI를 통해, 매체 소개서 및 견적서를 손쉽게 제안·관리 (+PDF 화)
  4. 매체 운영 및 빈 시간대 관리: 매체사는 CMS를 통해 광고 가능 빈 시간대를 확인하고, 효율적인 운영 관리
  5. 어드민 운영 관리 플랫폼 : 유저 회원 가입 승인 및 반려, 대용량 CSV 파일을 활용한 매체 일괄 등록 등 서비스 전반을 통합 관리

 

프로젝트 진행 

1.  서비스 기반 구축 및 팀 ground rules 정립

기간 : 23년 3월 ~ 6월 (4개월)

사용 기술 : Django, Django Ninja, PostgreSQL

핵심 내용 

  • 도메인 모델링: 유저, 캠페인, 광고주 캠페인, 매체 정보(위치·조건), 견적 등 핵심 비즈니스 도메인 간의 데이터 모델링 설계 
  • 기능 구현 : 지도 기반 탐색의 바탕이 되는 전국 옥외 매체 정보와 하위 모델들의 핵심 CRUD 개발
  • 기능 구현 : 광고주가 여러 매체를 묶어 한 번에 견적을 요청하고 청약을 진행할 수 있는 로직 구축 
  • 개발 문화 및 협업 기틀 마련: 초기 코드 베이스가 없는 백지상태였기에 프로젝트 구조 설계와 Git PR 프로세스 정립을 진행, 팀 내 소통 비용과 혼선을 최소화하기 위한 문서화 작업을 수행

 

회고

  • 초반에 막 열심히 달렸던 기억. 
  • 당시 광고 도메인에 대한 경험이 없어, 가끔 기획서에서 모델간의 관계를 잘못 이해하여 어제 작성한 걸 다음날 고치는 재작업 등을 하기도 했었다. 아! 하면서 많이 깨달았던 시기로 이후에는 내가 이해한 것이 맞는지 기획자에게 물어보는 시간도 많이 갖고, 설명도 직접 해보며 이해한 것이 맞는지 확인하는 시간을 항상 가졌던 것 같다. 그로 인해 역으로 놓쳤던 예외사항들도 발견되고 보완될 수 있었다. 
  • 파이썬으로 기존에 작성된 코드가 없었다 보니, '우리 팀'이 쓸 프로젝트 구조를 잡고, 코드 스타일 등을 맞추기 위해 소통하는 것이 좋았지만, 한편으로는 다소 비용이 좀 들기도 했던 것 같다. 평소 나만의 어떤 방식이나 주관도 있는 편이라, 많이 꺼내놓고 얘기하게 되었는데. 결론적으로 상대방의 생각을 이해하는 과정에서 유연하게 사고 하는 것에 대해 많이 돌아보게 되는 계기가 된 것 같다.

2.  배포 환경 개선 및 어드민 시스템 구축

기간 : 23년 7월 ~ 8월 (2개월)

사용 기술 : Reflex, Jenkins, AWS ECR

핵심 내용

  • Reflex 기반 어드민 시스템 구축: Reflex를 활용해 대시보드 UI/UX를 구현하고, 대용량 Excel 업로드 기능 및 매체 그룹 관리 CRUD를 완성하여 운영 효율성 제고를 수행함
  • CI/CD 파이프라인 자동화 및 API 고도화: Jenkins와 AWS ECR을 연동하여 기존의 수동 배포 과정을 자동화 파이프라인으로 전환하였으며, 지속적인 API 유지보수와 문서 고도화를 진행함

 

회고

  • 가벼운 운영/CS 처리를 위해서 왠만한 서비스는 어드민 제품이 꼭 필요한 것 같다. 이왕이면 서비스 API 만들 때 예상되는 부분은 같이 만들어 두는 것도 좋은 것 같음
  • 첨엔 파이썬 기반 UI도 써볼겸, 받아와서 백엔드에서 진행하였는데 (작성하다가 마가 꼈는지, 컴포넌트 가운데 정렬이 안먹길래 야근했는데, 옆에서 보던 프런트 개발자가 딸깍 해결해 버려서 현타옴) 바쁜 FE 개발자 일정 기다려 받느니, 어차피 어드민 도구 없으면 백엔드로 CS 처리 요청이 오니까. 그냥 스스로를 위해 백엔드에서 가볍게 만들어서 기능으로 빨리 내 주어 업무 요청이 안오게 처리하는 것도 좋은 것 같다.  (버그 수정 등에도 추가 소통 비용 등 없이 바로바로 하면 되니까)
  • Reflex와 Streamlit 중에 고민했는데, 개인적으론 다음 부턴 Streamlit 쓸 것 같다. (한창 하다가 Reflex 버전이 0.2.0 매우 초기라 제공 기능이 적음을 너무 늦게 알아서, 쉬운 것도 어렵게 같던..)

3. 맵 성능 개선 및 리팩토링 

기간 : 23년 9월 ~ 11월 (3개월)

핵심 내용

 

  • 지도(Map) 서비스 성능 최적화: 빠른 매체 데이터 증가(15,000개 이상의 마커) 증가로 인한 쿼리 속도 저하 문제를 해결하기 위해 Query Debugger 데코레이터 및 미들웨어를 직접 구현하여 병목 지점 모니터링 및 쿼리 최적화를 진행함 
  • 기술적 한계 극복을 위한 UX 중심의 대안 제안: 단순 쿼리 개선만으로는 대량의 마커를 한 번에 내리는 부하를 완벽히 해결하기 어렵다고 판단. 이를 극복하기 위해 초기 로딩 데이터 반경 축소(20km → 5km) 및 네이버 지도를 벤치마킹한 페이지네이션 기반 UI 도입을 제품 팀에 선제적으로 제안하여 반영하였다.
  • DB 스키마 개선 및 API 버저닝 규칙 수립: 데이터 정합성 확보를 위해 Null 표현 및 Required 필드를 재정립하는 전면 리팩토링 진행. 기존 API 사용 혼선을 줄이기 위해 토스페이먼츠 등의 레퍼런스를 참고하여 팀 내 API 버저닝 규칙을 새롭게 확립하고 합의를 도출하였다.

 

회고

  • 광고 도메인 특성상 '매체 그룹(1) > 매체(N) > 주소(N)'로 이어지는 복잡한 모델 관계가 있었다. 심지어 매체 1개에 주소가 100개씩 엮여 있는 경우도 있었다. (예를 들면 지하철 7호선 출구마다 설치된 디지털 매체들은 1000개에 달함)
  • 이러다 보니 데이터 수가 예상보다 빠르게 불어났고, 결국 지도 API 호출 응답 시간에 극심한 병목 현상이 발생했고, 백엔드 쿼리 개선만으로는 근본적인 해결이 불가능한 한계 상황이었다.
  • 이때 무조건 "기술적으로 안 될 것 같아요"라고 하기보다 해결을 위해서, 타 서비스들 (중 네이버 지도)은 이 문제를 어떻게 풀었을지 레퍼런스들을 이해해보게 되었고, 그리고 초기 반경 축소와 페이지네이션이라는 대안을 준비해 기획자분을 조심스레 설득했고, 감사하게도 아이디어가 채택되어 최종 반영까지 이어졌다 => 이건 평소 습관으로 가지면 좋을 것 같아서, 다른 서비스 개발자 입장에서 '그들은 왜 이렇게 만들었을까?', '기술적 한계를 어떻게 우회했을까?'를 넓은 시선으로 바라보면 좋을 것 같다 => 이 뒤로 서비스를 보면 뽀개보려는? 분석? 부터 하려는 뇌의 트랜지스터가 먼저 튀어 나오는 직업병 같은게 생긴 것도 같다.
  • 초반에는 기능 구현 속도와 백엔드 팀 내부 협업에만 너무 몰두했던 것 인지, 그러다 보니 API 개수가 늘어남에 따라 관리 (문서화)가 아쉽다는 피드백을 FE(프론트엔드) 개발자분들로부터 받게 되었다. 더불어 특히  FE 파트와 'Null 처리' 관점에 대해 여러번 토론하면서 프론트 개발자 입장을 이해하게 되었다. => 이 때 부터 백엔드의 첫번째 우선 고객은 프론트이다라는 생각이 있다. 고객놈?을 만족 시키면 내 자아가 만족을 느끼더라는 (이 사람이 API 짜주면 좀 편하던데의 평가를 받는 것 또한 나름 개인의 목표, 이젠 근데 AI 때매 살짝 글른 것 같기도 하다.)

4. 패키지 매체 확장 및 결제/프로모션 기능 개발

기간 : 23년 12월 ~ 24년 1월 (2개월)

핵심 내용

  • 제품 고도화 : 비즈니스 모델 확장(패키지/종속 매체 등) 발맞추어 웹서비스 및 어드민 제품을 확장 및 수정함
  • 결제 및 프로모션 시스템 도입: 포트원(PortOne) API를 연동한 충전형 결제 시스템과 프로모션 기능을 신규 도입
  • 테스트 코드 추가 신뢰성 확보 : 복잡한 비즈니스 로직(예산 및 포인트 검증, 결제/정산 로직 등 예외 케이스가 많은)을 안전하게 유지 하기 위한 테스트 코드 작성, 외부 API 통신 격리한 Mocking 기반 단위 테스트 구축
  • 테스트 프레임워크 효율화: 효율적인 테스트 환경을 위해 Fixture(가짜 데이터) 관리 책임을 각 앱 단위로 위임 및 서비스 시나리오와 테스트 시나리오 간의 차이를 정립하여 전체 테스트 수행 속도 및 작성 비용 효율화 등

 

회고

  • 서비스 규모가 커지면서 제품 안정화를 위해 테스트 코드가 필요하다는 니즈가 생겼다. 하지만 모든 API의 모든 예외 케이스를 다 작성하기에는 비용이 컸기에, "무엇을 우선순위로 두고 먼저 작성할 것인가"에 대해 팀원과 논의했고, 그 결과 우리 팀만의 '테스트 코드 작성 규칙 문서'를 정립할 수 있었다. 결론적으로는 핵심 코어 로직들에 대해서 우선 코드 신뢰성을 확보하는 방향으로 진행하게 되었다. 그 과정에서 같이 고민하고 배운 것들이 많아 블로그에도 정리하게 되었다.
  • 관련 블로그 정리 내용 : https://yubi5050.tistory.com/322

5. 비동기 처리 아키텍처 및 CMS 설계·개발

기간 : 24년 2월 ~ 3월 (2개월)

사용 기술 : RabbitMQ, Celery

핵심 내용

  • 비동기 메시지 큐(MQ) 및 Celery 도입 : 메인 서버의 부하를 경감하고 알림 시스템(알림톡, 문자, Slack, 메일)의 실시간 비동기 처리를 위해 AWS의 RabbitMQ 및 docker 기반의 Celery 환경을 설계하여 도입함
  • CMS(콘텐츠 관리 시스템) 일정 동기화: 매체사 운영을 위한 CMS 개발의 일환으로, 매체 일정 생성 시 이와 엮인 세부 견적들의 일정까지 자동으로 연동 동기화 되는 다소 복잡한 연쇄 로직을 구현함

 

회고

  • API 만 만들다가, 추가 기술 공부하고, 그걸로 시스템 설계하고 구현해서 붙이는게 꽤 재밌었다.

6. 플랫폼 운영 안정화 및 프로젝트 마무리

기간 : 24년 4월 ~ 5월 (2개월)

핵심 내용

  • 포트원 결제/환불 연동 및 웹훅 중복 방어: 가상(Stage) 및 실제(Live) 결제 환경을 철저히 분리 / 부분 환불 발생 시 내부 포인트 시스템에 반영 되도록 로직 개선 / 외부 PG사에서 불규칙 수신 웹훅(Webhook) 중복 호출 문제 방어등 멱등성 로직 구현등을 함
  • 지속적인 테스트 코드 작성 : 정한 우선순위를 바탕으로 테스트 코드 일정을 틈틈히 확보해, 핵심 비즈니스 코드 거의 95% 이상 달성 및 전체 개수 200+ 달성함
  • 배치(Cron) 작업 장애시 백업 개발 : 자동 배치 작업이 예기치 못하게 중단/실패를 대비 하여, 정산 데이터등을 수동으로 복구할 수 있는 백업 API 개발함
  • 내부 복잡한 로직 시퀀스 플로우 차트 문서화 하여

 

회고

  • 추후 다른 프로젝트에 팔려 갔다, 유지보수 하러 누가 돌아오더라도, 흐름이 이어서 진행될 수 있도록. 마무리 작업의 느낌 (노션의 mermaid)로 작업

시퀀스 플로우 차트

 

마치며

이 회사에서 처음으로 마주한 프로젝트 였던 만큼, 무엇보다 여러 사람들이랑 같이 고민하고 협업하는 과정이 가장 기억에 남는다. 서로 소통하고 입장을 이해하면서, 하나하나씩 차근히 정리하며 뿌셔 가는 과정이 재미있었던 것 같다. 서비스가 비즈니스 적으로 조금 더 성공했으면 좋았겠지만, 그래도 오프라인 세계에 머물러 있던, 옥외 광고 도메인을 온라인으로 전환하고 디지털 화 하는 과정 속에서 개발자로서 긍정적인 가치를 느낄 수 있었던 것 같음.

 

1년 넘는 기간 동안 많이 고생한 팀원들에게 큰 respect를!