1 minute read

예전 글에서 레거시 리팩토링 이야기를 했었는데, 그 프로젝트가 어디까지 갔는지 후속편을 쓸 때가 됐습니다. 결론부터: 실운영에 들어갔습니다.

무엇을 만들었나

스터디카페·독서실·세차장·골프연습장 같은 무인매장을 위한 키오스크 + 프랜차이즈 원격관제 SaaS입니다. 13개 업종을 하나의 플랫폼이 감당합니다. 원래는 PHP 모놀리스 1,500개 파일이었고, 지금은:

  • Spring Boot 마이크로서비스 15개 + 공용 모듈 3개 (Eureka + Gateway)
  • Java 소스 1,432개, 컨트롤러 139개, JPA 엔티티 135개
  • Flyway 마이그레이션 457개 (스키마 진화의 역사가 그대로 담겨 있습니다)
  • Electron 키오스크(TS/TSX 271개) + Next.js 어드민
  • Terraform 36개 파일로 AWS 인프라 전체 코드화

업종 13개를 어떻게 하나의 코드로

레거시의 최대 문제는 업종별 if-else였습니다. 세차장 로직과 스터디카페 로직이 같은 함수 안에서 분기되고, 새 업종이 들어올 때마다 분기가 늘어나는 구조. 이걸 Plugin Architecture로 바꿨습니다.

IndustryPlugin 인터페이스를 정의하고 Spring auto-configuration으로 업종별 플러그인을 조립합니다. Feature 플래그 23종, 상품 타입 22종을 플러그인이 선언하고, 코어는 업종을 모릅니다. 신규 업종 추가 = 플러그인 클래스 1개 구현. 실제로 이후 업종 추가 작업이 며칠 단위로 줄었습니다.

하드웨어의 세계

키오스크는 소프트웨어만으로 끝나지 않습니다. Electron 메인 프로세스에 하드웨어 드라이버 계층을 직접 만들었습니다. 카드 디스펜서, 현금 호퍼, 동전 호퍼, RF카드 리더, 바코드 스캐너, 릴레이, 영수증 프린터(ESC/POS), VAN 결제 모듈까지. 오프라인 모드, 하트비트, 원격 명령, 자동 업데이트 채널 분리(dev/prod)도 이 계층에서 처리합니다.

배리어프리 — 법이 만든 마감

2026년부터 무인정보단말기 접근성 의무화가 단계적으로 적용됩니다. 고대비, 색 반전, 폰트 스케일, 캡션, 음성 안내, 시각 경보를 키오스크 런타임에 직접 구현했습니다. 접근성 대응 코드만 40KB가 넘습니다. 솔직히 처음엔 “규제 대응”으로 시작했는데, 만들고 나니 생각이 바뀌었습니다. 무인매장은 점원이 없습니다. 키오스크가 안 되면 그 손님은 그냥 돌아가야 합니다. 접근성은 무인 비즈니스에서 기능이 아니라 전제조건이었습니다.

운영은 다른 종목이다

만드는 것과 운영하는 것은 정말 다릅니다. 이 프로젝트에서 운영 안전장치로 만든 것들:

  • RDS 삭제 보호 + Terraform apply 가드
  • 배포 시 CONFIRM_PROD=YES 명시적 확인
  • 결제 서비스 롤백 런북 (사고 나기 전에 미리 씁니다)
  • Saga 분산 트랜잭션 + 결제 중복 방지 처리 — 같은 결제 요청이 두 번 와도 한 번만 처리되도록 (분산 시스템에서 “정확히 한 번”은 공짜가 아닙니다)

실제 결제가 흐르고 실제 매출이 도는 시스템은 코드 품질과는 또 다른 종류의 긴장감을 줍니다. 그 긴장감이 저는 좋습니다. 코드가 현실과 만나는 지점이니까요.

Updated: