발급 제한 확인과 생성 작업을 요청 단위 트랜잭션 문맥으로 묶음
만나로 ·
대치4동 산등성길
서울신용보증재단 골목상권 활성화 사업에서 제휴 상점을 소개하고 5천 원 할인 쿠폰으로 오프라인 방문과 결제를 유도한 서비스입니다. 기획·정책·UI 디자인·상점 콘텐츠를 제외하고 기술 설계, Next.js 프론트, NestJS·Prisma/MySQL API, 관리자·상점 기능, 알림, Jenkins·Docker 배포와 운영 도구를 1인 개발했습니다.
노량진 만나로 · 대치4동 산등성길 쿠폰 공개 아카이브
사용자·상점·운영자가 함께 쓰는 쿠폰 서비스
사용자에게 보이는 핵심은 지도에서 상점을 찾고 5천 원 쿠폰을 받아 현장에서 사용하는 일이었습니다. 하지만 실제로 서비스를 운영하려면 상점 계정, 발급 제한, 예산, 쿠폰 사용·취소, 관리자 통계와 리포트까지 함께 움직여야 했습니다.
상점 검색·지도·상황별 맛집 추천과 함께 관리자 예산, 주차별 발급·사용·만료 통계, 상점 계정과 RBAC, PWA, S3 이미지, 쿠폰 취소·사용 관리와 리포트를 구현했습니다. 사용자·상점·운영팀이 각기 다른 권한으로 같은 쿠폰 상태를 관리하도록 구성했습니다.
중복 발급 문제를 반영한 트랜잭션 적용
이전 동작구 쿠폰에서 발생한 중복 발급 문제를 반영해, 후속 시스템에 `nestjs-cls`와 Prisma 요청 단위 트랜잭션을 적용했습니다. 사용자 생성, 발급 제한 확인과 실제 쿠폰 발급을 같은 문맥에 묶었습니다.
만나로에는 Serializable이나 명시적 락을 적용하지 않아 동시 요청 사이의 경쟁 조건이 남아 있었습니다. 이후 2025 동작42에서 더 강한 격리와 상태 전이 검증을 적용했습니다.
만나로에는 요청 단위 트랜잭션을 적용하고, 대치에서는 상점별 발급 정책을 운영 중 조정할 수 있도록 확장했습니다.
만나로를 만들고, 대치에서 정책을 고쳤다
만나로에서는 상점마다 같은 수량을 고정 배정했습니다. 운영해보니 상점별 소진 속도 차이가 컸고, 어떤 곳은 빨리 소진되는 반면 다른 곳에는 예산이 남았습니다. 후속 대치4동 시스템에서는 관리자가 상점별 최대 발급량을 숫자로 바꾸고, 서버의 발급 가드가 최신 값을 즉시 반영하도록 개선했습니다.
`maximumCouponCount` 변경값을 append-only로 쌓고 생성일 기준 가장 최근 값을 현재 정책으로 사용했습니다. 이전 배정값과 변경 시각을 보존해 정책 변화를 추적할 수 있게 했습니다. 변경한 관리자 ID는 기록하지 않았습니다.
한 건의 CS를 범용 설정으로
GS25 한 상점에서는 부부가 함께 운영하고 있었지만 쿠폰 사업 참여 의사가 서로 달랐습니다. 아내가 근무하는 요일과 시간에만 쿠폰 사용을 받고 싶다는 요청이 들어왔습니다. 특정 상점만을 위한 조건문을 추가하는 대신 상점마다 사용 요일·시간·주의사항·확인 비밀번호를 설정할 수 있도록 일반화했습니다.
요일과 시간은 서버가 강제로 사용을 막는 hard rule로 만들기보다 발급 전 모달과 상점 화면에 조건을 노출하는 방식이었습니다. 정책의 성격에 따라 시스템이 강제해야 하는 규칙과 현장에서 안내해야 하는 규칙을 구분한 것입니다.
개별 민원을 예외 코드로 쌓지 않고, 다른 상점에도 쓸 수 있는 운영 설정으로 번역한다.
알림은 구현됐지만 정착하지 않았다
이전 사업에서 상점주가 “쿠폰이 사용된 사실을 바로 알기 어렵다”고 했기 때문에 웹 푸시로 상점과 관리자에게 즉시 알림을 보내는 기능도 만들었습니다. 하지만 구독 절차가 어렵고 운영팀의 현장 안내도 충분하지 않아 상점 도구로는 정착하지 못했습니다. 결과적으로 개발자가 운영 상황을 확인하는 수단으로 더 많이 쓰였습니다.
웹 푸시는 구현됐지만 현장에서 사용할 수 있도록 구독 절차와 안내를 충분히 지원하지 못했습니다. 실제 활용 범위는 개발자의 운영 모니터링에 머물렀습니다.
예산 소진과 운영 정책 개선
두 사업 모두 배정된 쿠폰 예산을 전액 소진했습니다. 참여 상점 수는 보관 데이터의 누락 가능성이 있어 확정하지 않았습니다.
DB 트랜잭션과 외부 문자·웹 푸시를 별도 문맥에서 처리해 알림 실패가 DB 작업에 영향을 주지 않도록 했습니다. 상점별 고정 배정은 수정 가능한 정책으로, 개별 상점의 요청은 재사용 가능한 설정으로 반영했습니다.
고정 배정을 조정 가능한 정책과 변경 이력으로 발전시킴
현장 CS를 다른 상점에도 재사용 가능한 운영 설정으로 일반화
운영에서 나온 문제를 다음 버전의 정책과 구조로 바꾸는 방식.
만나로의 상점별 소진 편차를 대치의 발급량 조정 기능에 반영했습니다. 현장에서 받은 쿠폰 사용 요일·시간 요청도 여러 상점이 함께 쓸 수 있는 설정으로 구현했습니다.
만나로 결과물 보기 ↗