AI 블로그 자동화에서 공개 계약 스모크 테스트를 운영하는 법
Futory의 Next.js Markdown 발행 루틴에서 상세 페이지와 목록 페이지가 같은 날짜, slug, 카테고리 계약을 지키는지 짧게 확인하는 공개 스모크 테스트 방법을 정리했습니다.
요약
Futory처럼 Next.js와 Markdown으로 운영되는 AI 블로그는 새 글 파일을 만드는 순간보다 공개 화면에서 제대로 보이는 순간이 더 중요합니다. content/posts에 Markdown이 생기고 npm run build가 통과해도, 상세 페이지와 목록 페이지가 같은 계약을 해석하지 못하면 독자는 새 글을 발견하지 못합니다. 그래서 무인 발행 루틴에는 긴 회귀 테스트와 별개로 공개 계약을 빠르게 확인하는 스모크 테스트가 필요합니다.
공개 계약 스모크 테스트는 복잡한 브라우저 자동화가 아닙니다. 새 slug의 상세 URL이 200을 반환하는지, 홈과 /posts와 /vibe-coding 목록에서 오늘 날짜나 slug가 보이는지, 캐시가 오래된 응답을 돌려주지 않도록 no-cache 요청을 쓰는지 확인하면 됩니다. 이 작은 절차는 Futory의 바이브코딩 발행 루틴에서 “파일은 있다”와 “서비스에 반영됐다” 사이의 빈틈을 줄여 줍니다.
공개 계약이란 무엇인가
공개 계약은 Markdown frontmatter, 빌드 산출물, 라우팅, 목록 렌더링이 같은 글을 같은 방식으로 보여 주겠다는 약속입니다. 새 글의 date, category, tags, 파일명 slug는 각각 작은 데이터처럼 보이지만, 실제로는 여러 페이지가 공유하는 운영 신호입니다.
상세 페이지 계약
상세 페이지 계약은 가장 직접적입니다. /posts/<slug>가 HTTP 200을 반환하고, 본문 제목과 날짜가 기대한 값으로 렌더링되어야 합니다. 이 단계가 실패하면 원인은 보통 파일명, Markdown 파싱, 정적 생성 경로, 빌드 산출물 중 하나입니다. 따라서 PM2 재시작 뒤에도 상세 URL이 404라면 목록 페이지를 보기 전에 slug와 .next 산출물부터 확인하는 편이 빠릅니다.
목록 페이지 계약
목록 페이지 계약은 조금 더 넓습니다. 홈 화면은 최신 글을 보여 주고, /posts는 전체 글 목록을 보여 주며, /vibe-coding은 category: "바이브코딩" 계약을 기준으로 글을 포함합니다. 상세 페이지가 열리더라도 카테고리 값이 틀리거나 날짜 정렬이 깨지면 목록에서 빠질 수 있습니다. 그래서 Futory의 자동 발행 보고서에는 세 목록을 따로 확인한 결과가 필요합니다.
Futory 루틴에 스모크 테스트를 넣는 방법
스모크 테스트는 빌드 성공 이후, PM2 재시작 이후, 공개 URL 검증 단계에서 수행하는 것이 좋습니다. 빌드 전에 공개 페이지를 확인하면 아직 이전 런타임을 보고 있을 수 있고, PM2 재시작 전에 확인하면 새 산출물이 반영되지 않았을 수 있습니다.
캐시를 우회해서 확인한다
공개 검증에는 cache-busting query string과 Cache-Control: no-cache 헤더를 함께 사용합니다. 예를 들어 상세 페이지는 /posts/ai-blog-public-contract-smoke-test-routine?ts=<현재시각>처럼 요청합니다. 목록 페이지도 같은 방식으로 확인해야 합니다. 이렇게 하면 CDN이나 브라우저 캐시 때문에 이전 HTML을 성공으로 착각하는 일을 줄일 수 있습니다.
신호는 제목보다 slug와 날짜를 우선한다
한국어 제목은 HTML escaping, 줄바꿈, 메타 태그 위치에 따라 단순 문자열 검색이 흔들릴 수 있습니다. 반면 slug와 YYYY-MM-DD 날짜는 비교적 안정적입니다. Futory의 공개 검증은 상세 페이지에서 200 상태를 먼저 보고, 목록 페이지에서는 새 slug 또는 오늘 날짜가 들어 있는지 확인하는 방식이 실용적입니다. 제목 검색은 보조 신호로만 사용하면 됩니다.
실패 단계는 즉시 멈춘다
npm run test:content, npm run test:theme, npm run build 중 하나라도 실패하면 PM2를 재시작하지 않습니다. 빌드가 실패한 산출물을 서비스에 반영하려고 하면 장애 범위가 커질 수 있기 때문입니다. 반대로 빌드와 산출물 확인은 통과했지만 공개 URL이 실패한다면, 파일 생성 자체보다 런타임 재시작, 프록시, 캐시 계층을 의심해야 합니다. 스모크 테스트는 이 경계를 빠르게 알려 주는 안전장치입니다.
운영 보고서에 남길 증거
무인 크론의 결과는 짧아도 재현 가능해야 합니다. 선택된 KST 시간, 중복 검사 결과, 백업 경로, 새 파일 경로, 테스트와 빌드 상태, .next slug 확인, PM2 재시작 결과, 공개 상세과 목록 페이지 확인 결과를 남기면 다음 운영자가 같은 순서로 문제를 추적할 수 있습니다.
콘텐츠 자체의 계약도 함께 기록한다
공개 검증만으로는 글의 형식 요구사항을 모두 설명하기 어렵습니다. 따라서 본문 글자 수, H2와 H3 개수, ## 요약, ## 자주 묻는 질문, ## 결론 존재 여부도 함께 기록하면 좋습니다. 이 증거는 사람이 내용을 다시 세지 않아도 이번 발행이 콘텐츠 계약을 만족했는지 확인하게 해 줍니다.
자주 묻는 질문
스모크 테스트와 전체 테스트는 어떻게 다른가요?
전체 테스트는 콘텐츠 파싱, 테마 규칙, 빌드 안정성을 넓게 확인합니다. 스모크 테스트는 배포 후 공개 표면에서 새 글이 보이는지 빠르게 확인합니다. 둘 중 하나만으로는 부족합니다. Futory에서는 내부 테스트가 통과한 뒤 공개 스모크 테스트로 마지막 반영 상태를 확인하는 흐름이 안전합니다.
목록 페이지마다 모두 확인해야 하나요?
네. 상세 페이지, 홈, 전체 글 목록, 바이브코딩 목록은 서로 다른 계약을 사용합니다. 특히 /vibe-coding은 카테고리 값에 의존하므로 frontmatter가 조금만 틀려도 상세 페이지는 열리지만 카테고리 목록에는 빠질 수 있습니다.
공개 검증에서 날짜만 보이면 충분한가요?
날짜는 좋은 신호지만 같은 날짜에 다른 글이 있거나 캐시된 일부 영역이 남아 있을 가능성을 완전히 배제하지는 못합니다. 가능하면 slug와 날짜를 함께 확인하고, 최소한 상세 URL의 200 상태와 목록 페이지의 slug 포함 여부를 같이 보는 편이 좋습니다.
결론
Futory의 바이브코딩 자동화는 Markdown 하나를 쓰는 단순한 작업처럼 보이지만, 실제 성공은 공개 페이지들이 같은 계약을 지킬 때 완성됩니다. 공개 계약 스모크 테스트는 상세 URL 200, 목록 페이지 노출, no-cache 검증, slug와 날짜 확인을 짧게 묶어 발행의 마지막 빈틈을 막습니다. 이 절차를 매일 같은 장부 형식으로 남기면 무인 발행은 더 조용하고, 실패했을 때는 더 빨리 설명 가능한 운영 루틴이 됩니다.