01 · 졸업작품 · 문제 → 해결

PULSE

외식업 사장님을 위한 AI 마케팅 자동화 플랫폼

마케팅을 공부하지 않아도, 리뷰에서 다음 행동까지 한 번에 이어집니다.

2026 · 졸업작품영상 생성 로직 · 인플루언서 매칭 · 인증/가입 흐름Main Project
  • React
  • Spring Boot
  • FastAPI
  • MySQL
  • MongoDB
  • Playwright
  • Kiwi · Ko-SBERT
  • BERTopic
  • VEO3

Project Brief

무엇을, 누구를 위해, 어디까지.

타겟
마케팅에 쓸 시간이 없는 외식업 사장님
문제 정의
리뷰는 쌓이는데 그게 누구의 목소리인지, 그래서 뭘 해야 하는지로 이어지지 않는다
내 역할
영상 생성 로직 · 인플루언서 매칭 · 인증/가입 흐름
기간
2026 · 졸업작품
팀 구성
팀 프로젝트확인 필요
현재 상태
리뷰 수집·분석 파이프라인과 손님 분석 화면은 실연동. 영상 생성·리뷰 답변·인플루언서 매칭은 화면과 로직은 완성, 실 API 연결이 남은 단계

Screens

썸네일을 누르거나 좌우 화살표로 넘기고, 큰 이미지를 누르면 확대됩니다.

랜딩 — 리뷰 분석부터 숏폼 제작까지의 흐름을 한 화면에 제시

By the numbers

구조를 설명하는 숫자들.

0계층

React · Spring Boot · FastAPI 역할 분리

0개 소스

네이버 · 카카오 리뷰를 병렬 수집 (각 최대 80건)

0점

업종·지역·키워드·성과·예산 5개 항목 매칭 모델

Problem

외식업 사장님은 마케팅을 따로 공부할 시간이 없습니다. 리뷰는 쌓이는데 그 리뷰가 누구의 목소리인지, 그래서 다음에 무엇을 해야 하는지로는 이어지지 않습니다. 분석 도구와 제작 도구가 따로 놀면 결국 아무것도 실행되지 않습니다.

Key Decisions

  1. 01

    분석과 제작을 한 줄로 잇는다

    릴스 제작 화면을 빈 입력창에서 시작하지 않게 했습니다. 이미 만들어진 페르소나와 매장 요약, 액션 제안을 프롬프트 초기값으로 넘겨 사장님이 무엇을 찍을지 정하는 부담을 줄였습니다.

  2. 02

    무거운 작업은 task_id로 떼어낸다

    리뷰 수집과 토픽 분석은 응답을 기다리게 하면 안 되는 작업입니다. FastAPI가 요청 즉시 task_id를 발급하고 백그라운드에서 처리하도록 나눴습니다. 사용자는 진행률을 polling으로 확인합니다.

  3. 03

    수익 기능을 핵심 루프에서 분리한다

    인플루언서 매칭은 모든 사장님에게 필요하지 않습니다. 핵심 마케팅 루프를 복잡하게 만들지 않으려고 Pro 확장 기능으로 떼어놓고, 추천 결과에 왜 어울리는지를 함께 보여주는 구조로 잡았습니다.

Validation

가입 → 분석 생성 → 진행률 확인 → 결과 화면까지 한 사이클이 끊기지 않고 도는지를 기준으로 잡았습니다. 새로고침하면 저장된 taskId로 결과를 복구하고, 그것도 없으면 매장의 최신 결과로 떨어집니다. 리뷰가 거의 없는 매장, LLM 응답이 깨진 경우처럼 실패하는 길도 각각 다른 상태로 끝나도록 확인했습니다.

How it's built

구조를 그렇게 잡은 이유.

  1. 01

    책임에 따라 서버를 셋으로 나눴다

    React는 사장님이 보는 화면, Spring Boot는 인증과 가게 정보 그리고 AI 서버 호출의 관문, FastAPI는 리뷰 수집·분석과 영상 생성을 맡습니다. 성격이 다른 작업(요청-응답 / 장기 배치 / LLM 호출)을 한 서버에 섞지 않는 것이 첫 결정이었습니다.

  2. 02

    분석은 요청과 처리를 떼어놨다

    리뷰 수집과 토픽 분석은 응답을 붙들고 기다릴 수 없는 작업입니다. FastAPI가 요청 즉시 task_id를 내주고 백그라운드에서 돌리며, 프론트는 그 id로 진행률을 polling합니다. 사용자는 대기 중에도 무엇이 진행되는지 봅니다.

  3. 03

    분석 결과를 다음 단계의 입력으로 넘겼다

    페르소나, 매장 요약, 액션 제안을 릴스 제작 화면의 프롬프트 초기값으로 전달합니다. 분석과 제작이 각각의 섬이 되지 않도록 데이터가 흘러가는 방향을 먼저 고정했습니다.

  4. 04

    재계산을 막는 저장 지점을 뒀다

    수집한 원본 리뷰는 매장명과 주소를 SHA-1로 묶은 store_key 기준으로 매장당 한 벌만 upsert합니다. 작업마다 전체 리뷰를 다시 쌓지 않고, 분석 로직을 고쳐도 같은 입력으로 다시 돌려볼 수 있습니다.

  5. 05

    매장 식별은 요청 본문을 믿지 않는다

    분석 API는 요청에 담겨 온 매장 id를 그대로 쓰지 않고, JWT의 이메일로 매장을 다시 조회해 store_id를 정합니다. 상태·결과 조회도 task_id와 store_id를 함께 봅니다. 남의 분석 결과가 열리지 않게 하는 경계가 여기입니다.

  6. 06

    실패해도 화면이 비지 않게 했다

    리뷰가 3건 미만이면 임베딩 대신 빈도 기반 단일 토픽으로 떨어지고, LLM이 페르소나 JSON을 못 만들면 리뷰 기반 규칙으로 채웁니다. 분석은 성공하되 품질이 낮아진 상태를 따로 기록하는 쪽을 택했습니다.

My Contribution

팀 프로젝트에서 제가 맡은 세 갈래입니다.

  1. 01Smart Reels

    한국어 입력을 VEO3 프롬프트로 번역하는 규칙

    왜

    사장님이 가장 막히는 지점은 촬영이 아니라 "무엇을 어떻게 찍을지" 정하는 일입니다. 빈 입력창을 주면 아무것도 만들어지지 않습니다.

    어떻게

    손님 분석에서 나온 페르소나와 분위기를 릴스 화면의 초기값으로 넘기고, 한국어 맥락을 VEO3가 읽는 영어 JSON으로 바꾸는 규칙을 정했습니다. 9:16 세로, 8~10초, HOOK·BODY·OUTRO 세 장면 구조를 고정값으로 두었습니다.

    • 장면 묘사는 [Shot] + [Subject] + [Action] + [Context] 공식으로 통일
    • "맛있는" 같은 추상 형용사 대신 "김이 올라오는"처럼 눈에 보이는 증거로 기술
    • Energy · Premium · Mood 세 분위기를 카메라 무빙과 톤 키워드로 매핑
    • 자막·워터마크·로고는 negative_prompts에 고정해 원천 차단
  2. 02Influencer Match

    점수만이 아니라 이유까지 내려주는 추천

    왜

    팔로워 수로 고르면 우리 가게 손님층과 어긋납니다. 로컬 매장에는 유명한 사람보다 실제로 방문할 수 있고 손님층이 겹치는 사람이 맞습니다.

    어떻게

    업종·지역·키워드·성과·예산 다섯 축을 100점으로 나눠 합산하고, 총점과 함께 항목별 점수와 추천 문장을 같이 내려줍니다. 손님 분석에서 이미 뽑아둔 페르소나와 리뷰 토픽 키워드를 매칭 기준으로 다시 씁니다.

    • 키워드는 해시태그·공백을 지우고 부분 포함까지 인정 (감성 ↔ 감성카페)
    • 성과는 팔로워가 아니라 평균 조회수와 참여율로 계산
    • 예산은 최소 단가와 비교해 실제 제안 가능성까지 점수에 반영
    • Spring 추천 API가 실패해도 같은 계산을 프론트에서 돌려 화면을 유지
  3. 03Auth & Onboarding

    가입 버튼이 곧 첫 분석 시작 버튼

    왜

    가입만 시키면 사장님은 빈 대시보드를 보게 됩니다. 반대로 처음부터 입력을 많이 받으면 그 자리에서 이탈합니다.

    어떻게

    회원가입을 기본정보와 가게정보 두 단계로 쪼개고, 가입이 끝나는 순간 Spring이 가게를 저장한 뒤 FastAPI에 리뷰 분석을 비동기로 요청하게 했습니다. 사장님이 첫 화면에 도착했을 때 이미 분석이 돌고 있습니다.

    • 가입 직후 진행률을 polling으로 보여줘 빈 화면 대기를 없앰
    • 분석 요청은 본문의 매장 id 대신 JWT 이메일로 매장을 재조회
    • 인증 실패 시 accessToken과 저장된 taskId를 함께 정리

Analysis Pipeline

가입 버튼 한 번에서 페르소나가 나오기까지.

  1. 리뷰 수집

    네이버와 카카오를 동시에 훑습니다. 카카오는 Playwright로 DOM을 타고 들어가고, 수집 직후 UI 노이즈를 걷어내고 중복을 지웁니다.

    각 소스 최대 80건 · progress 10 → 40

  2. 스냅샷 저장

    매장명과 주소를 SHA-1로 묶은 store_key로 매장당 최신 한 벌만 남깁니다. 작업 문서는 건수와 출처 집계만 들고 스냅샷을 참조합니다.

    raw_review_snapshots · upsert

  3. 전처리

    Kiwi로 일반명사와 고유명사만 뽑고, 한 글자 단어와 불용어를 지웁니다. 남는 문서가 하나도 없으면 여기서 작업을 실패로 끝냅니다.

    Kiwi · 한국어 불용어

  4. 토픽 군집

    리뷰가 3건 미만이면 임베딩 없이 빈도 상위 단어로 단일 토픽을 만들고, 3건 이상이면 Ko-SBERT 임베딩 위에 BERTopic을 돌립니다. 아웃라이어 토픽은 페르소나 대상에서 뺍니다.

    Ko-SBERT · BERTopic · KMeans fallback · progress 70

  5. 페르소나 생성

    토픽 키워드와 비중, 평균 평점, 리뷰 샘플을 LLM에 넘겨 매장 한 줄 요약과 페르소나, 고객 여정 4단계를 만듭니다. 세 개가 안 나오면 리뷰 기반 그룹으로 채웁니다.

    요약 리뷰 10건 · 페르소나 리뷰 20건

  6. 결과 제공

    결과를 저장하고 작업을 성공으로 닫습니다. 프론트는 1.5초 간격으로 상태를 묻고, 새로고침하면 저장된 taskId로, 그것도 없으면 매장의 최신 결과로 복구합니다.

    polling 1.5s · analysis_results

Matching Model

인플루언서 추천 점수를 나눈 방식입니다. 가장 큰 비중은 팔로워가 아니라 키워드입니다.

  • 키워드 적합도

    30/ 100점

    손님 분석에서 나온 키워드와 콘텐츠 키워드가 겹치는가

  • 업종 적합도

    25/ 100점

    직접 일치 25점, 인접 분야 20점, 넓은 음식 범주 18점

  • 지역 적합도

    20/ 100점

    가게의 구 단위와 인플루언서 활동권이 겹치는가

  • 성과 지표

    15/ 100점

    평균 조회수 8점 + 참여율 7점. 팔로워 수는 직접 세지 않는다

  • 예산 적합도

    10/ 100점

    최소 단가가 제안 예산 안에 드는가. 실제 성사 가능성을 반영

Key Specs

설명에 근거가 되는 숫자와 규격입니다.

분석 API 경계

공개 API
POST /api/v1/analysis/jobs (Bearer JWT · OWNER)
상태 조회
GET /api/v1/analysis/jobs/{taskId}
내부 호출
POST /internal/v1/analysis/request
내부 인증
X-Pulse-Service-Token · 미설정 503 / 불일치 401
타임아웃
connect 3s · read 60s
폴링 간격
1.5초

영상 프롬프트 규격

비율 · 길이
9:16 세로 · 8~10초
장면 구조
HOOK 0-3s / BODY 3-7s / OUTRO 7-10s
묘사 공식
[Shot] + [Subject] + [Action] + [Context]
분위기
Energy · Premium · Mood
화질 모드
Standard 4K · High-Def 8K
고정 차단
text · subtitles · watermark · logo

저장 구조

MySQL
User · Shop — 인증과 권한 경계
jobs
상태 · 진행률 · 실패 코드 (완료 30일 TTL)
raw_review_snapshots
store_key 기준 매장당 최신 1벌
analysis_results
매장 요약 · 평점 · 페르소나 3개

Current State

어디까지 실제로 돌아가는지 구분해 적었습니다.

실 데이터로 동작

  • 회원가입 → 가게 저장 → 분석 비동기 트리거
  • 네이버·카카오 리뷰 수집과 정규화
  • Kiwi · Ko-SBERT · BERTopic 토픽 분석
  • LLM 매장 요약 · 페르소나 · 고객 여정 생성
  • 최신 분석 결과 기반 손님 분석 화면
  • 카카오 지도 기반 상권 분석

화면과 로직은 완성, 실 API 연결 전

  • 홍보 영상 생성 — 프롬프트 설계와 UX는 끝, 생성 엔드포인트가 아직 서버에 없음
  • 리뷰 답변 — Python에 생성 함수는 있으나 프론트가 목업 답변 사용
  • 인플루언서 매칭 — 점수 모델은 동작, 후보는 50명 시드/목업
  • 대시보드 V2 · 구독 · 마이페이지 — 시뮬레이션 응답

남은 일은 기능을 더 만드는 것이 아니라, 이미 만들어 둔 화면을 실 API로 끝까지 잇는 것입니다.