Paljalab
팔자연구소
결제가 끝났다고, 사용자가 결과를 받은 건 아니었다.
출발점과 담당 범위
LLM 유료 리포트 서비스
맡은 범위
제품 구성과 사용자 흐름을 정하고, AI 코딩 도구와 함께 프런트엔드·PHP API·DB·생성 제어를 구축했습니다. 실제 로그인·결제·결과 확인과 운영 중 막힌 리포트 복구까지 맡았습니다.
시작할 때의 상태
회사 TF의 유료 콘텐츠 서비스.
개발 범위 · 기술 · 협업 자세히 읽기
시작할 때의 상태
회사 TF의 유료 콘텐츠 서비스. 상품별 입력과 생성 방식이 달라, 새 상품을 추가할 때 화면·주문·생성 경로를 함께 연결해야 했습니다.
작업 개요
상품 선택부터 분석 입력, 로그인, 결제, 리포트 생성·조회까지 연결했습니다. 모델의 응답만 보지 않고 사용자가 작성하던 내용을 되찾고, 구매한 결과를 끝까지 읽을 수 있는지 확인했습니다.
개발·개선 범위
- 상품·분석 입력·로그인 복귀·결과 화면
- 계산 데이터와 LLM 해석의 연결
- 차트·주문·결제·리포트 저장 및 조회
- 분할 생성·백그라운드 실행·상태 폴링
- 구매 복원·재생성·인쇄 경로
- 사용한 기술
- PHP · JavaScript · MySQL · LLM API · CLI workers · Toss Payments
기존 자산 · 외부 서비스 · AI 활용
회사 TF 프로젝트입니다. Claude Code·Codex를 구현과 진단에 활용하고, 외부 LLM·인증·Toss 결제 API를 연결했습니다. 모델 사전학습이나 결제 엔진 자체를 개발한 경험은 아닙니다.
제품 화면과 구조 요약

제품 화면과 구조 요약 보기
구매한 결과를
끝까지 읽도록.

문제 해결
재시도해도 잘리는 리포트: 실행 장소를 바꿨다
- 결제·문맥 확인
구매 상품과 저장된 분석 입력을 조회
- 생성 접수
GENERATING 저장 후 202 응답; 완성 의미 아님
- 별도 실행
상품 필수 입력 확인 뒤 CLI에서 청크 생성
- 결과 확인
저장 상태를 조회하고 완료 본문을 화면에 표시
문제
긴 유료 리포트가 생성 도중 끊겼습니다.
바꾼 점
상품 분기를 연결하고 내용을 청크로 나눠 제한된 병렬 호출·재시도·부족분 추가 생성을 적용했습니다.
확인한 것
당시 기록에서 상품별 실제 생성 시간·출력과 실패 항목을 함께 확인했습니다.
조사·판단·검증 과정 읽기
마주한 문제
긴 유료 리포트가 생성 도중 끊겼습니다. 같은 요청을 다시 보내도 HTTP 실행 제한을 넘기면 결과는 달라지지 않았고, 일부 상품은 생성 분기 자체가 빠져 있었습니다.
확인한 과정
상품별 진입 경로와 모델 호출 시간을 따로 확인했습니다. 공급자의 출력 시간뿐 아니라 공유호스팅의 PHP 실행 방식도 제약이었습니다. 응답을 먼저 돌려주는 것과 웹서버 작업자를 실제로 돌려주는 것은 달랐습니다.
선택한 방법
상품 분기를 연결하고 내용을 청크로 나눠 제한된 병렬 호출·재시도·부족분 추가 생성을 적용했습니다. 이후 CLI 백그라운드 실행으로 옮기고, 화면은 DB의 생성 상태를 조회하도록 구성했습니다.
어떻게 확인했는가
당시 기록에서 상품별 실제 생성 시간·출력과 실패 항목을 함께 확인했습니다. 접수 응답이나 CLI 종료 문구를 완료로 보지 않고 저장된 리포트 상태와 본문을 대조했습니다. 분량 기준도 실제 결과물을 보고 조정했습니다.
단계별 처리와 경계
결제·문맥 확인
구매 상품과 저장된 분석 입력을 조회
생성 접수
GENERATING 저장 후 202 응답; 완성 의미 아님
별도 실행
상품 필수 입력 확인 뒤 CLI에서 청크 생성
결과 확인
저장 상태를 조회하고 완료 본문을 화면에 표시
구조도와 처리 경계 자세히 보기
결제는 끝났는데, 생성은 어디서 멈출 수 있나?
결제 승인과 생성 접수, 응답 뒤 검증, 별도 CLI 실행, 결과 조회를 서로 다른 단계로 나눴습니다.
- 처리·명시된 호출
- 비동기·별도 요청
- 데이터 읽기·참조
- 실패·제한 분기
- 재요청을 억제하는 조건
- 완료 승인은 동일 결제키·금액에만 재사용합니다. 생성은 차트 잠금과 최근 5분 상태 조회로 중복을 억제합니다. 상품별 영구 멱등성 키는 아닙니다.
- 접수 응답 대신 저장된 결과 확인
- 6/4 추가 입력 복원 뒤 유료 리포트 재생성 기록과 현재 소스를 대조했습니다. CLI 종료 문구나 HTTP 202만으로 완료를 판단하지 않습니다.
- 입력이 전달됐다는 전제
- 추가정보가 포함된 분석 요청의 흐름입니다. 기본 /analyze와 v2의 연결은 미확인이며, 추가정보 저장·복원 예외를 무시하는 경로가 남아 있습니다.
이 구조의 한계PG 승인·DB 기록·생성은 비원자적이며, 요청 전달·CLI 기동 성공과 프로세스 종료 뒤 중간 지점부터의 자동 재개를 보장하지 않습니다.
단계별 설명 · 구조도를 글로 읽기
상품별 입력
추가정보가 전달된 요청 · 상품·폼에 따라 분기
- 차트·추가정보 (데이터 읽기·참조)
차트·추가정보
계산 결과와 추가정보 · DB 저장은 별도 단계
- 주문 대기 (데이터 읽기·참조)
주문 대기
상품·차트·금액 연결 · 대기 주문 생성·재사용
- 승인·PG 호출 (처리·명시된 호출)
승인·PG 호출
본인 주문·금액 검사 후 · 동일 완료는 반환·종료
- 주문·결제 저장 (데이터 읽기·참조)
주문·결제 저장
PG 성공 뒤 별도 저장 · 주문과 결제 기록은 함께
- 생성 요청 (별도 HTTP)
생성 요청
서버 HTTP 또는 화면 · 서버 호출 응답은 미확인
- 입력·결제 조회 (처리·명시된 호출)
입력·결제 조회
빠진 추가정보 DB 복원 · 완료 주문과 상품 조회
- 생성 중 선점 (처리·명시된 호출)
- 202 응답 (기존 완료·최근 생성 재사용 후 종료)
생성 중 선점
차트 잠금·최근 상태 검사 · 생성 중 저장 후 커밋
- 202 응답 (처리·명시된 호출)
202 응답
신규 접수면 후속 검증 · 기존 결과 재사용은 종료
- 상품 필수 검증 (처리·명시된 호출)
상품 필수 검증
상대·이별 정보 존재 검사 · 누락되면 실패 상태 기록
- 별도 CLI (비동기·별도 요청)
- 결과·상태 저장 (필수 입력 누락 → 실패)
별도 CLI
생성 중 리포트만 실행 · DB와 전달 인자로 재구성
- 외부 LLM (비동기·별도 요청)
외부 LLM
청크 병렬 요청·재시도 · 응답 실패·시간 제한 존재
- 검사·병합 (데이터 읽기·참조)
검사·병합
핵심 누락·전체 실패 판정 · 비핵심 일부 실패는 허용
- 결과·상태 저장 (데이터 읽기·참조)
결과·상태 저장
완료 또는 실패 상태 · 일부 실패도 완료 가능
- 조회·재요청 (데이터 읽기·참조)
조회·재요청
결제 권한·완료 결과 확인 · 화면 진입·버튼으로 재요청
- 생성 요청 (비동기·별도 요청)
구조 탐색과 실제 소스 대조를 바탕으로 편집한 작동도입니다. 런타임 전체의 자동 검증을 뜻하지 않습니다.
문제 해결
수동 생성은 되는데, 결제 직후에는 안 되는 이유
문제
결제 후 자동 생성은 실패했지만 추가 입력 폼에서 다시 요청하면 정상 진행됐습니다.
바꾼 점
생성 요청에 추가 정보가 없을 때 저장된 분석 입력을 복원하도록 연결했습니다.
확인한 것
당시 막혀 있던 유료 리포트의 재생성과 완료 상태를 확인했습니다.
조사·판단·검증 과정 읽기
마주한 문제
결제 후 자동 생성은 실패했지만 추가 입력 폼에서 다시 요청하면 정상 진행됐습니다. 결제는 끝났는데 사용자는 구매한 리포트를 받지 못하는 상태였습니다.
확인한 과정
두 요청의 차이를 비교하니 자동 경로에는 상품별 추가 정보가 빠져 있었습니다. 그 정보는 분석 단계 DB에 이미 저장돼 있어, 모델 성능이나 결제 승인보다 요청 사이의 문맥 전달이 문제였습니다.
선택한 방법
생성 요청에 추가 정보가 없을 때 저장된 분석 입력을 복원하도록 연결했습니다. 필수값 검증을 없애거나 모델에게 누락 내용을 추정시키지 않고, 원래 입력을 찾아 같은 상품의 생성에 전달했습니다.
어떻게 확인했는가
당시 막혀 있던 유료 리포트의 재생성과 완료 상태를 확인했습니다. 입력 저장·자동 트리거·생성 API의 복원 분기를 소스와 대조해, 어느 요청에서 정보가 빠지는지 설명할 수 있게 남겼습니다.
구조도와 처리 경계 자세히 보기
결제는 끝났는데, 생성은 어디서 멈출 수 있나?
결제 승인과 생성 접수, 응답 뒤 검증, 별도 CLI 실행, 결과 조회를 서로 다른 단계로 나눴습니다.
- 처리·명시된 호출
- 비동기·별도 요청
- 데이터 읽기·참조
- 실패·제한 분기
- 재요청을 억제하는 조건
- 완료 승인은 동일 결제키·금액에만 재사용합니다. 생성은 차트 잠금과 최근 5분 상태 조회로 중복을 억제합니다. 상품별 영구 멱등성 키는 아닙니다.
- 접수 응답 대신 저장된 결과 확인
- 6/4 추가 입력 복원 뒤 유료 리포트 재생성 기록과 현재 소스를 대조했습니다. CLI 종료 문구나 HTTP 202만으로 완료를 판단하지 않습니다.
- 입력이 전달됐다는 전제
- 추가정보가 포함된 분석 요청의 흐름입니다. 기본 /analyze와 v2의 연결은 미확인이며, 추가정보 저장·복원 예외를 무시하는 경로가 남아 있습니다.
이 구조의 한계PG 승인·DB 기록·생성은 비원자적이며, 요청 전달·CLI 기동 성공과 프로세스 종료 뒤 중간 지점부터의 자동 재개를 보장하지 않습니다.
단계별 설명 · 구조도를 글로 읽기
상품별 입력
추가정보가 전달된 요청 · 상품·폼에 따라 분기
- 차트·추가정보 (데이터 읽기·참조)
차트·추가정보
계산 결과와 추가정보 · DB 저장은 별도 단계
- 주문 대기 (데이터 읽기·참조)
주문 대기
상품·차트·금액 연결 · 대기 주문 생성·재사용
- 승인·PG 호출 (처리·명시된 호출)
승인·PG 호출
본인 주문·금액 검사 후 · 동일 완료는 반환·종료
- 주문·결제 저장 (데이터 읽기·참조)
주문·결제 저장
PG 성공 뒤 별도 저장 · 주문과 결제 기록은 함께
- 생성 요청 (별도 HTTP)
생성 요청
서버 HTTP 또는 화면 · 서버 호출 응답은 미확인
- 입력·결제 조회 (처리·명시된 호출)
입력·결제 조회
빠진 추가정보 DB 복원 · 완료 주문과 상품 조회
- 생성 중 선점 (처리·명시된 호출)
- 202 응답 (기존 완료·최근 생성 재사용 후 종료)
생성 중 선점
차트 잠금·최근 상태 검사 · 생성 중 저장 후 커밋
- 202 응답 (처리·명시된 호출)
202 응답
신규 접수면 후속 검증 · 기존 결과 재사용은 종료
- 상품 필수 검증 (처리·명시된 호출)
상품 필수 검증
상대·이별 정보 존재 검사 · 누락되면 실패 상태 기록
- 별도 CLI (비동기·별도 요청)
- 결과·상태 저장 (필수 입력 누락 → 실패)
별도 CLI
생성 중 리포트만 실행 · DB와 전달 인자로 재구성
- 외부 LLM (비동기·별도 요청)
외부 LLM
청크 병렬 요청·재시도 · 응답 실패·시간 제한 존재
- 검사·병합 (데이터 읽기·참조)
검사·병합
핵심 누락·전체 실패 판정 · 비핵심 일부 실패는 허용
- 결과·상태 저장 (데이터 읽기·참조)
결과·상태 저장
완료 또는 실패 상태 · 일부 실패도 완료 가능
- 조회·재요청 (데이터 읽기·참조)
조회·재요청
결제 권한·완료 결과 확인 · 화면 진입·버튼으로 재요청
- 생성 요청 (비동기·별도 요청)
구조 탐색과 실제 소스 대조를 바탕으로 편집한 작동도입니다. 런타임 전체의 자동 검증을 뜻하지 않습니다.
결과와 현재의 경계
결과, 그리고 지금.
브라우저 요청 안에서 긴 생성을 끝내려던 구조를 별도 실행과 상태 조회로 나눴습니다. 결제 후 사라진 추가 입력을 복원해 막힌 유료 리포트의 재생성을 확인한 운영 기록을 남겼습니다.
주요 유료 생성 경로와 당시 운영 복구를 설명합니다. 모든 상품의 최신 동작·품질을 보장하지 않으며, 후속 렌더러 수정의 운영 반영 여부는 별도 확인 대상입니다.
작성 기준: 2026년 9월 작업 기록·소스 대조. 과거 검증 결과를 현재의 모든 동작에 대한 보증으로 사용하지 않습니다.
역할과 협업 이야기하기