링크 치환 및 카운트 추적 로직 개선
🗓️ 11/10/2025 👤 Role: System Architect
FastAPIPostgreSQL
Problem & Condition
캠페인 KPI에 링크 클릭 수를 반영하려면, 캡션 내 URL을 우리 public redirect로 바꾸고 방문 수를 DB에 기록해야 했다.
컴파일 파이프라인은 persona 정책 주입 → 플랫폼 규칙 적용 → 결과 저장 순인데, 링크 치환은 컴파일 결과(텍스트)도 바꾸고 DB에도 row를 남겨야 했다.
기존 persona injector/compile 엔진은 상태 없는 텍스트 변환만 담당했기에, 어디서 DB 세션을 활용해야 할지 결정이 필요했다.
Candidates
1. 사후 처리
Injector/compile 끝난 뒤 compile_variant 반환 결과에서 URL을 다시 돌면서 DB에 tracking 링크 만들고 텍스트 교체.
장점:
- 기존 파이프라인 건드리지 않음
단점:
- 엔진이 만든 요약/메트릭과 최종 텍스트가 어긋남
- replay 시에도 다시 치환해야 해서 일관성 깨짐
2. PersonaInjector 내부에서 처리 시도
persona directives를 주입할 때 URL을 교체하면서 DB row 생성.
장점:
persona정책과 붙어 있어서 자연스러워 보임
단점:
- Injector는 DB 세션을 모르고 단순 데이터 변환만 수행함
- 토큰 충돌 검사/저장/에러 처리를 할 수 없어서 구조적으로 불가능
3. TrackingLinkAllocator 계층
링크 발급/저장을 담당하는 allocator 인터페이스를 두고, 컴파일 엔진은 allocator만 호출. DB 세션은 worker가 allocator 구현에 주입.
장점:
- 엔진은 여전히 순수한 텍스트 처리, DB 지식은
allocator에 국한 - replay 시에도 동일한
allocator를 주입하면 동일한 링크를 재사용
단점:
compile_variant시그니처,InjectorContext, engine 계층에allocator전달 로직을 추가해야 함
Decision
3번 TrackingLinkAllocator 방식을 선택.
엔진에 새 의존성만 주입하면 persona 정책 흐름을 깨지 않으면서 DB 연동 요구를 해결할 수 있음. Allocator는 allocate(original_url)만 받으므로 테스트/추후 mock도 쉽고, DB 세션 관리가 worker 쪽에 그대로 남는다.
Effects
- 링크 치환이
_apply_link_policy단계에서 실행되며, compile 결과 요약/metrics와 항상 일치 TrackingLinkAllocator가 기존 링크를 재사용하도록 로직을 갖추면서 중복 레코드/토큰 발급 문제 감소- 캠페인 KPI에서
LINK_CLICKS를tracking_links.visit_count기반으로 집계할 수 있게 되어 CTR 산출 준비 완료