프리랜서 제품 개발
캠페인 운영·고객 협업 플랫폼
흩어져 있던 광고 대행 업무를 캠페인 단위 워크플로우로 통합한 SaaS. 요구사항 정리부터 배포까지 단독 개발.
맥락과 문제
- 견적 → 콘텐츠 검수 → 게재보고 → 일정·업무일지가 서로 다른 도구에 분산. 동일 정보를 반복 입력하고, 광고주는 진행 상황을 전화로 확인.
- 광고주 노출 범위가 핵심 난제. 결과물 확인과 의견 등록은 필요하나 내부 견적·담당자 메모는 비공개 유지 필요.
- 화면 완전 분리 시 데이터 불일치, 통합 시 비공개 항목 노출. 그 사이 설계가 과제.
- 단독 진행이라 결정 근거와 결과가 릴리스 노트·커밋 이력에 모두 기록됨.
역할·기간·범위
시스템 지도
내부 백오피스
캠페인, 견적, 검수, 게재보고, 일정, 업무일지를 한 곳에서 다루는 운영 화면입니다.
고객 접점
고객이 결과물을 확인하고 의견을 남기는 제한된 화면입니다. 내부 정보는 이 표면에 도달하지 않습니다.
연결 흐름
두 표면이 같은 상태를 읽도록 묶는 요약과 상태 전이 규칙입니다.
권한 계층
페이지 단위로 정의하고 변경 시 일괄 재적용할 수 있는 접근 규칙입니다.
중요한 판단
피드백을 결과물 위에 남기기
개인 수행
- 문제
- 영상과 이미지 피드백이 메신저와 메일로 오가면서 위치를 말로 설명해야 했고, 어느 버전에 대한 이야기인지 흐려졌습니다.
- 판단
- 피드백 위치를 글로 옮겨 적는 단계를 없애기로 했습니다.
- 행동
- 영상에는 재생 시점에 고정되는 타임스탬프 댓글을, 이미지에는 좌표에 붙는 드로잉 마크업을 붙였습니다. 두 방식 모두 대상 버전에 묶었습니다.
- 검증
- 검수 회의에서 나온 피드백을 이 화면에서 그대로 재현해 보며, 위치를 말로 설명해야 하는 경우가 남아 있는지 확인했습니다.
내부 검수 링크와 고객 공유 링크 분리
개인 수행
- 문제
- 하나의 링크를 상황에 따라 다르게 쓰면, 고객에게 보내려던 주소가 내부 검수 화면을 여는 사고가 언제든 가능했습니다.
- 판단
- 화면 안에서 조건으로 권한을 나누는 것보다 주소 자체를 분리하는 편이 안전하다고 판단했습니다.
- 행동
- 내부 검수용 링크와 고객 공유용 링크를 별개 경로로 발급하고, 공유 링크는 만료와 접근 범위를 따로 관리하게 했습니다.
- 검증
- 공유 링크에서 내부 전용 화면에 도달할 수 있는 경로가 있는지 직접 훑고, 링크 종류별로 접근 가능한 화면 목록을 대조했습니다.
고객 보기와 검수 모드의 노출 규칙 분리
개인 수행
- 문제
- 같은 데이터를 고객과 내부가 함께 보되 드러나야 하는 항목은 서로 다릅니다. 화면마다 조건을 흩어 두면 규칙이 곧 어긋납니다.
- 판단
- 노출 규칙을 화면마다 두지 않고 모드 단위로 한곳에서 관리하기로 했습니다.
- 행동
- 고객 보기와 검수 모드를 명시적인 모드로 정의하고, 각 모드가 어떤 항목을 읽을 수 있는지 한 곳에서 선언하게 했습니다.
- 검증
- 두 모드로 같은 캠페인을 열어 화면별 항목을 나란히 비교하고, 고객 모드에 내부 항목이 남아 있는지 확인했습니다.
페이지 단위 권한 정의와 일괄 재적용
개인 수행
- 문제
- 역할이 늘어날 때마다 권한을 화면마다 손으로 고치면, 새로 추가한 페이지 하나가 조용히 빠집니다.
- 판단
- 권한을 페이지 단위로 선언하고, 정의가 바뀌면 전체에 일괄 재적용하는 방식으로 정했습니다.
- 행동
- 페이지 단위로 권한을 정의하고, 정의가 바뀌면 기존 사용자와 역할에 일괄 재적용하는 절차를 만들었습니다.
- 검증
- 역할을 바꿔 가며 접근 가능한 페이지 목록을 뽑아 권한 정의와 대조했습니다.
백엔드와 프론트엔드의 경계 다시 긋기
개인 수행
- 문제
- 기능이 붙을수록 어느 파일이 어떤 업무를 책임지는지 흐려졌고, 한 곳을 고치면 관계없어 보이던 화면이 깨졌습니다.
- 판단
- 업무 도메인이 코드 구조에 드러나야 수정 범위를 예측할 수 있다고 판단했습니다.
- 행동
- 백엔드를 업무 도메인 단위로 나누고 공통 코드를 별도 경계로 분리했습니다. 프론트엔드도 기능 단위와 공용 단위로 다시 묶었습니다.
- 검증
- 재구성 뒤 모든 화면 경로를 직접 열어 데이터와 표시가 그대로인지 확인하고 타입 검사를 다시 돌렸습니다.
- 백엔드를 9개 도메인으로, 50개가 넘는 프론트엔드 파일을 기능·공용 경계로 재구성
흩어진 상태를 잇는 요약 API
개인 수행
- 문제
- 지금 이 캠페인이 어디까지 왔는지 알려면 견적, 검수, 게재보고를 각각 열어 봐야 했습니다.
- 판단
- 상태를 화면마다 조합하면 결과가 달라지므로, 서버에서 한 번만 정의하기로 했습니다.
- 행동
- 캠페인, 견적, 검수, 게재보고 상태를 하나로 묶어 돌려주는 요약 API를 만들고 각 화면이 같은 응답을 읽게 했습니다.
- 검증
- 여러 진행 단계의 캠페인을 만들어 요약 결과가 각 상세 화면의 상태와 어긋나지 않는지 대조했습니다.
게재 이후를 남기는 보고 카드
개인 수행
- 문제
- 게재가 끝나면 결과 확인이 사람의 기억에 맡겨졌고, 언제 무엇을 수집했는지 흔적이 남지 않았습니다.
- 판단
- 수집 시점을 미리 정해 두고 그 시점의 상태를 기록으로 남기기로 했습니다.
- 행동
- 플랫폼별 게시 상태 배지와 예약된 수집 시점을 카드 형태로 정리해 게재보고 화면에 배치했습니다.
- 검증
- 수집 시점별 상태가 실제 게시 결과와 맞는지, 누락된 플랫폼이 빠짐없이 표시되는지 확인했습니다.
- D+0, D+1, D+7, D+14 시점의 수집 상태
업무일지와 월간 캘린더 대시보드
개인 수행
- 문제
- 일정은 캘린더에, 무엇을 했는지는 각자의 메모에 있었습니다. 두 가지를 함께 보지 못하니 돌아볼 근거가 없었습니다.
- 판단
- 일정과 업무 기록을 같은 화면에 두면 별도 정리 없이 운영 기록이 된다고 봤습니다.
- 행동
- 업무일지 모듈을 만들고 월간 캘린더 대시보드에서 캠페인 일정과 함께 보이게 했습니다.
- 검증
- 한 달 치 데이터를 넣어 날짜 경계, 반복 일정, 비어 있는 날의 표시가 의도대로 나오는지 확인했습니다.
겹치는 모달을 우측 패널로
개인 수행
- 문제
- 검수 중에 상세를 열면 모달 위에 모달이 쌓였고, 뒤 화면의 맥락을 잃은 채로 판단해야 했습니다.
- 판단
- 본문 맥락을 유지해야 하는 작업이라, 화면을 덮는 모달 방식은 맞지 않는다고 판단했습니다.
- 행동
- 겹치던 모달을 우측 패널로 옮겨 본문을 계속 보면서 상세를 확인하고 되돌아올 수 있게 했습니다.
- 검증
- 키보드만으로 패널을 열고 닫으며 포커스가 원래 위치로 돌아오는지, 좁은 화면에서 본문이 가려지지 않는지 확인했습니다.
서버리스 환경의 데이터베이스 연결 안정화
개인 수행
- 문제
- 서버리스 환경에서 연결이 예고 없이 끊기거나 마이그레이션 상태가 환경마다 달라지는 문제가 반복됐습니다.
- 판단
- 재현되지 않는 연결 오류를 그때그때 넘기지 않고 원인부터 정리하기로 했습니다.
- 행동
- 연결 수명과 재시도 방식을 환경에 맞게 정리하고, 마이그레이션 적용 순서를 하나의 경로로 통일했습니다.
- 검증
- 배포 직후와 유휴 시간 이후를 나눠 반복 호출하며 연결 오류가 재현되는지, 마이그레이션 상태가 환경 간에 일치하는지 확인했습니다.
여러 캘린더의 표시 규칙 통일
개인 수행
- 문제
- 캘린더가 여러 화면에 흩어져 있었고 휴일 표시와 강조 규칙이 조금씩 달라, 같은 날이 화면마다 다르게 보였습니다.
- 판단
- 표시 규칙을 화면마다 복제하지 않고 공통 로직으로 모으기로 했습니다.
- 행동
- 휴일 판정과 강조 렌더링을 공통 로직으로 끌어내고, 흩어져 있던 캘린더가 모두 같은 규칙을 쓰게 했습니다.
- 검증
- 공휴일과 주말이 섞인 달을 기준으로 모든 캘린더 화면을 나란히 열어 표시가 일치하는지 확인했습니다.
- 휴일 표시 6곳과 굵은 글씨 렌더링 8곳을 공통 로직으로 통합
구현 근거
합성 데이터로 재구성해 촬영. 고객·캠페인·계정 식별 정보와 원본 메타데이터는 제거.






측정 가능한 결과
- 약 7주 만에 제품 하나를 단독으로 완성
- 설계와 구현을 혼자 맡고도 제품이 배포까지 도달했습니다.
- 버전 1.0.0부터 1.6.0까지 출시
- 기능을 한 번에 몰아 넣지 않고 작동하는 상태를 유지하면서 범위를 늘렸습니다.
- 릴리스 노트 13건으로 변경 사항을 공유
- 무엇이 언제 바뀌었는지 의뢰인이 직접 확인할 수 있게 남겼습니다.
- 저장소 전체 커밋 636건 가운데 629건을 직접 작성
- 작업의 대부분이 제 손에서 나왔다는 사실이 변경 이력으로 남아 있습니다.
- 아키텍처 재구성 후 65개 경로를 직접 열어 점검
- 구조를 바꾼 뒤 화면이 그대로인지 하나씩 열어 확인했습니다.
- 검증 시점 TypeScript 컴파일러 오류 0건
- 타입 검사를 통과한 상태에서 검증을 마쳤습니다.
- 회의에서 받은 피드백 62건을 반영
- 회의에서 나온 요청을 흘려보내지 않고 제품에 반영한 결과입니다.
회고
- 단독 개발은 결정이 빠른 대신 검토자가 없음. 판단 근거를 릴리스 노트와 변경 이력에 기록해 대체.
- 동일 과제 재수행 시 권한·노출 규칙을 더 이른 단계에 통합할 것. 화면 증가 후 규칙 정리에 가장 많은 시간 소요.