From ec8c4345b8eadc6ad80e92953491ff161b9cad4b Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 31 May 2026 15:51:40 +0900 Subject: [PATCH 1/4] =?UTF-8?q?chore(blog):=20/work/blog=20=EB=9D=BC?= =?UTF-8?q?=EC=9A=B0=ED=8A=B8=C2=B7=EC=B0=B8=EC=A1=B0=C2=B7=EB=A9=94?= =?UTF-8?q?=ED=83=80=20=EC=99=84=EC=A0=84=20=EC=A0=9C=EA=B1=B0=20(2026-05-?= =?UTF-8?q?29=20=EC=9E=AC=EC=A0=95=EC=9D=98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app/work/blog/, lib/blog-tools/ 폴더 삭제 - 홈·work 허브 카드/카피, footer 링크에서 블로그 자동화 제거 - layout.tsx keywords·description·JSON-LD Offer 제거 - refund 약관 상품 목록 정리, sitemap /services/blog 엔트리 제거 - next.config: /services/blog·/work/blog → /work 301 리다이렉트 Co-Authored-By: Claude Opus 4.8 (1M context) --- app/components/PublicShell.tsx | 1 - app/layout.tsx | 6 +- app/legal/refund/page.tsx | 2 +- app/page.tsx | 7 +- app/sitemap.ts | 1 - app/work/blog/layout.tsx | 26 ---- app/work/blog/page.tsx | 243 --------------------------------- app/work/layout.tsx | 4 +- app/work/page.tsx | 10 +- lib/blog-tools/generator.ts | 199 --------------------------- lib/blog-tools/types.ts | 61 --------- next.config.ts | 4 +- 12 files changed, 13 insertions(+), 551 deletions(-) delete mode 100644 app/work/blog/layout.tsx delete mode 100644 app/work/blog/page.tsx delete mode 100644 lib/blog-tools/generator.ts delete mode 100644 lib/blog-tools/types.ts diff --git a/app/components/PublicShell.tsx b/app/components/PublicShell.tsx index d07b064..68e5fb0 100644 --- a/app/components/PublicShell.tsx +++ b/app/components/PublicShell.tsx @@ -90,7 +90,6 @@ export default function PublicShell({ children }: { children: React.ReactNode })
  • 외주 개발
  • 웹사이트 제작
  • AI 사주
  • -
  • 블로그 자동화
  • 문의하기
  • diff --git a/app/layout.tsx b/app/layout.tsx index ef54f52..b28c924 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -27,7 +27,6 @@ export const metadata: Metadata = { "유튜브 쇼츠 음악", "AI 뮤비", "음악 프롬프트", - "블로그 자동화", "AI 사주", ], authors: [{ name: "박재오", url: "https://jaengseung-made.com" }], @@ -74,14 +73,14 @@ const jsonLd = { email: 'bgg8988@gmail.com', telephone: '010-3907-1392', knowsAbout: ['Python', 'Java', 'Spring Boot', 'Next.js', 'AI 프롬프트', 'AI 자동화', '업무 자동화', 'ChatGPT', 'Claude'], - description: '현직 엔지니어. AI 음악 구조 설계 팩, 블로그 자동화 팩, AI 사주 분석 등 AI 크리에이티브 도구를 직접 개발·운영합니다.', + description: '현직 엔지니어. AI 음악 생성 개발 가이드 패키지, AI 사주 분석 등 AI 크리에이티브 도구를 직접 개발·운영합니다.', }, { '@type': 'LocalBusiness', '@id': 'https://jaengseung-made.com/#business', name: '쟁승메이드', url: 'https://jaengseung-made.com', - description: 'AI 음악 작곡·뮤비 구조 설계 팩, 블로그 자동화 팩, AI 사주 분석. 현직 엔지니어가 직접 설계·운영하는 AI 크리에이티브 스토어.', + description: 'AI 음악 생성 개발 가이드 패키지, AI 사주 분석. 현직 엔지니어가 직접 설계·운영하는 AI 크리에이티브 스토어.', email: 'bgg8988@gmail.com', telephone: '010-3907-1392', priceRange: '₩', @@ -93,7 +92,6 @@ const jsonLd = { { '@type': 'Offer', price: '39000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 마스터 구조 팩 (입문)', url: 'https://jaengseung-made.com/music/packs', description: 'Suno 프롬프트 + MV 워크플로우 + 저작권 가이드 + 템플릿 PDF + 샘플 프로젝트. 4단계 AI 음악 제작 공정.' } }, { '@type': 'Offer', price: '99000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 마스터 구조 팩 (프로)', url: 'https://jaengseung-made.com/music/packs', description: '입문 전체 + 샘플 프로젝트 1개(.prj · 영상 포함).' } }, { '@type': 'Offer', price: '149000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 마스터 구조 팩 (마스터)', url: 'https://jaengseung-made.com/music/packs', description: '프로 전체 + 샘플 다수 + 우선 업데이트·베타 선공개.' } }, - { '@type': 'Offer', price: '29000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/work/blog', itemOffered: { '@type': 'Product', name: '블로그 자동화 솔루션 팩', url: 'https://jaengseung-made.com/work/blog', description: '쿠팡파트너스·애드포스트 수익화 프롬프트 조합법 + 구조 템플릿 PDF + 샘플.' } }, { '@type': 'Offer', price: '0', priceCurrency: 'KRW', url: 'https://jaengseung-made.com/work/saju', itemOffered: { '@type': 'Service', name: 'AI 사주 분석', url: 'https://jaengseung-made.com/work/saju', description: '생년월일 기반 AI 사주팔자 분석. 무료 체험 가능.' } }, { '@type': 'Offer', diff --git a/app/legal/refund/page.tsx b/app/legal/refund/page.tsx index e3188e2..3b319e3 100644 --- a/app/legal/refund/page.tsx +++ b/app/legal/refund/page.tsx @@ -18,7 +18,7 @@ export default function RefundPage() {

    1. 디지털 콘텐츠 (즉시 제공 상품)

    -

    대상: AI 음악 마스터 구조 팩, 블로그 자동화 솔루션 팩, AI 사주 리포트 등 디지털 콘텐츠 상품 일체

    +

    대상: AI 음악 생성 개발 가이드 패키지, AI 사주 리포트 등 디지털 콘텐츠 상품 일체

    전자상거래법 제17조 제2항 제5호에 따라, 디지털 콘텐츠는 제공이 개시된 이후 청약철회가 제한됩니다. 회사는 구매 전 무료 샘플·미리보기를 제공하고, 구매 시 환불 제한 사항에 대한 소비자 동의를 확인합니다. diff --git a/app/page.tsx b/app/page.tsx index a64a492..9040615 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -47,7 +47,6 @@ const CB_CARDS = [ { href: '/work/freelance', label: '외주 개발', desc: '맞춤 솔루션 · RPA·API 자동화 포함', key: 'freelance' }, { href: '/work/website', label: '웹사이트', desc: '기업·브랜드 사이트', key: 'website' }, { href: '/work/saju', label: 'AI 사주', desc: '12개 항목 무료 해석', key: 'saju' }, - { href: '/work/blog', label: '블로그 자동화', desc: '수익 엔진 팩', key: 'blog' }, ]; export default function Home() { @@ -160,7 +159,7 @@ export default function Home() { 맞춤 개발 사업부

    - 외주 · 웹사이트 · AI 사주 · 블로그 자동화 + 외주 · 웹사이트 · AI 사주

    납품 5건 · 견적 24h 내 답변

    @@ -366,11 +365,11 @@ export default function Home() { 맞춤 개발이 필요하신가요?

    - 7년차 백엔드 개발자가 직접 설계·개발·납품. 외주, 웹사이트, AI 사주, 블로그 자동화까지. + 7년차 백엔드 개발자가 직접 설계·개발·납품. 외주, 웹사이트, AI 사주까지.

    -
    +
    {CB_CARDS.map((card) => ( (0); - - return ( -
    - {/* HERO */} -
    -
    -

    - Blog Automation Pack -

    -

    - 매일 글쓰기 고민, -
    - AI에게 맡기세요. -

    -

    - 쿠팡파트너스 · 네이버 애드포스트 · 브랜드커넥트 수익을 -
    - 자동화하는 프롬프트 · 구조 · 샘플 세트. -

    -
    - ₩29,000 - 한 번 결제 · 12개월 무료 업데이트 -
    -
    - - - 샘플 미리보기 - -
    -
    -
    - - {/* PAIN POINTS */} -
    -
    -

    - 이런 분들을 위한 팩입니다. -

    -
    - {[ - { icon: '🕐', title: '매일 1시간+', desc: '글 소재·구성에 시간 다 쓰고 수익은 제자리' }, - { icon: '📉', title: '수익화 6개월+', desc: '블로그 키워놓고도 수익 구조가 안 잡힘' }, - { icon: '🤖', title: 'AI 글은 어색', desc: 'ChatGPT 그대로 복붙하면 바로 들통' }, - ].map((p) => ( -
    -
    {p.icon}
    -

    {p.title}

    -

    - {p.desc} -

    -
    - ))} -
    -
    -
    - - {/* PACK CONTENT */} -
    -
    -

    - Pack Contents -

    -

    - 구성품 4종 -

    -
    - {PACK_ITEMS.map((it) => ( -
    -
    {it.icon}
    -
    -
    -

    {it.title}

    - - {it.meta} - -
    -

    - {it.desc} -

    -
    -
    - ))} -
    - - {/* Sample preview */} -
    - - 샘플 미리보기 - -

    프롬프트 예시 · 상품 리뷰 글 자동 생성

    -
    {`당신은 [카테고리] 전문 블로거입니다.
    -아래 상품의 [핵심 장점 3개]와 [주의점 1개]를 기반으로
    -C-Rank 알고리즘에 최적화된 1,200자 리뷰 글을 작성하세요.
    -
    -[구조]
    -1. 후킹 도입 (공감형 질문)
    -2. 상품 요약 (스펙 표)
    -3. 실사용 관점 장점·단점
    -4. 대안 비교 (쿠팡 링크 삽입 지점: {LINK})
    -5. 결론 + 재질문 유도
    -
    -[톤앤매너] 친근한 존댓말, 광고 느낌 최소화 ...`}
    -

    - 실제 팩에는 카테고리별 45종의 프롬프트와 최적화 파라미터가 포함됩니다. -

    -
    -
    -
    - - {/* FAQ */} -
    -
    -

    - 자주 묻는 질문 -

    -
    - {FAQS.map((f, i) => ( -
    - - {openFaq === i && ( -
    - {f.a} -
    - )} -
    - ))} -
    -
    -
    - - {/* FINAL CTA */} -
    -
    -

    - 오늘부터 블로그 수익 자동화. -

    -

    ₩29,000 한 번 결제 · 평생 업데이트

    - -

    - 환불 정책 - {' · '} - 이용약관 -

    -
    -
    - - setAgreeOpen(false)} - productName="블로그 자동화 솔루션 팩" - price="₩29,000" - /> -
    - ); -} diff --git a/app/work/layout.tsx b/app/work/layout.tsx index d276e9b..f209bac 100644 --- a/app/work/layout.tsx +++ b/app/work/layout.tsx @@ -1,8 +1,8 @@ import type { Metadata } from 'next'; export const metadata: Metadata = { - title: 'Custom Build — 맞춤 개발 사업부', - description: '7년차 백엔드 개발자가 직접 설계·개발·납품. 외주 · 웹사이트 · AI 사주 · 블로그 자동화.', + title: '커스텀 외주 — 맞춤 개발', + description: '7년차 백엔드 개발자가 직접 설계·개발·납품. 외주 · 웹사이트 · AI 사주.', }; export default function WorkLayout({ children }: { children: React.ReactNode }) { diff --git a/app/work/page.tsx b/app/work/page.tsx index 6ecb218..1f08c80 100644 --- a/app/work/page.tsx +++ b/app/work/page.tsx @@ -25,12 +25,6 @@ const CARDS = [ desc: 'AI 사주팔자 + 12개 항목 해석 (무료)', key: 'saju', }, - { - href: '/work/blog', - label: '블로그 자동화', - desc: '수익 엔진 팩 · 자동화 마케팅 콘텐츠', - key: 'blog', - }, ]; export default function WorkHub() { @@ -67,13 +61,13 @@ export default function WorkHub() { 맞춤 개발 사업부

    - 7년차 백엔드 개발자가 직접 설계·개발·납품. 외주, 웹사이트, AI 사주, 블로그 자동화까지. + 7년차 백엔드 개발자가 직접 설계·개발·납품. 외주, 웹사이트, AI 사주까지.

    -
    +
    {CARDS.map((c) => ( = { - informational: '정보 전달형', - review: '리뷰/후기형', - howto: '방법/튜토리얼형', - listicle: '리스트형 (OO가지)', - comparison: '비교 분석형', - story: '에세이/스토리형', -}; - -const TONE_LABELS: Record = { - professional: '전문적이고 신뢰감 있는', - friendly: '친근하고 대화하듯', - casual: '편한 말투, 구어체', - formal: '격식 있는 존댓말', -}; - -const LENGTH_RANGES: Record = { - short: '800~1200자', - medium: '1500~2500자', - long: '3000~4500자', -}; - -function buildPrompt(req: BlogRequest): string { - return `당신은 네이버 블로그 SEO 전문 작가입니다. - -## 작성 요청 - -- **주제**: ${req.topic} -- **핵심 키워드**: ${req.keywords.join(', ')} -- **글 형식**: ${STYLE_LABELS[req.style] || req.style} -- **톤앤매너**: ${TONE_LABELS[req.tone] || req.tone} -- **목표 분량**: ${LENGTH_RANGES[req.length] || req.length} -- **소제목 수**: ${req.sections}개 -- **이미지 가이드**: ${req.imageGuide ? '포함' : '미포함'} - -## 출력 형식 (반드시 아래 JSON 구조로 출력) - -\`\`\`json -{ - "title": "블로그 제목 (네이버 검색에 최적화된 30자 내외)", - "subtitle": "부제목 또는 한 줄 요약", - "sections": [ - { - "heading": "소제목", - "body": "본문 내용 (마크다운 불릿·볼드 허용)", - "imageSlot": true - } - ], - "tags": ["태그1", "태그2", "태그3", "태그4", "태그5"], - "seoTitle": "검색 노출용 제목 (핵심 키워드 포함 40자 이내)", - "seoDescription": "메타 설명 (120자 이내, 키워드 자연스럽게 포함)", - "imageGuides": [ - { - "position": "섹션 제목 또는 위치", - "description": "어떤 이미지가 적합한지 설명", - "searchKeyword": "이미지 검색 키워드", - "altText": "대체 텍스트" - } - ] -} -\`\`\` - -## 작성 규칙 - -1. 네이버 블로그 검색 상위 노출을 위해 핵심 키워드를 제목·첫 문단·소제목에 자연스럽게 배치 -2. 각 소제목(heading) 아래 본문은 구체적이고 실용적인 정보 포함 -3. 첫 문단은 독자의 공감 또는 궁금증을 유발하는 도입부 -4. 마지막 섹션은 요약 또는 CTA(댓글 유도, 공유 요청 등) -5. 본문에서 핵심 키워드는 전체 글의 2~3% 밀도로 자연스럽게 반복 -6. imageSlot이 true인 섹션에는 반드시 imageGuides에 해당 위치의 이미지 가이드 포함 -7. 태그는 5~8개, 관련 검색어와 롱테일 키워드 조합 -8. JSON만 출력 — 설명이나 마크다운 코드블록 바깥 텍스트 금지`; -} - -export async function generateBlogPost(req: BlogRequest): Promise { - const hasApiKey = !!process.env.ANTHROPIC_API_KEY; - - if (hasApiKey) { - try { - const ai = getClient(); - const response = await ai.messages.create({ - model: 'claude-sonnet-4-20250514', - max_tokens: 4096, - messages: [ - { role: 'user', content: buildPrompt(req) }, - ], - }); - - const text = response.content - .filter((b): b is Anthropic.TextBlock => b.type === 'text') - .map((b) => b.text) - .join(''); - - // JSON 파싱 (코드블록 래핑 제거) - const jsonStr = text.replace(/^```json?\s*/i, '').replace(/\s*```$/i, '').trim(); - const parsed = JSON.parse(jsonStr); - - const sections: BlogSection[] = (parsed.sections || []).map((s: Record) => ({ - heading: String(s.heading || ''), - body: String(s.body || ''), - imageSlot: Boolean(s.imageSlot), - })); - - const imageGuides: ImageGuide[] = (parsed.imageGuides || []).map((g: Record) => ({ - position: String(g.position || ''), - description: String(g.description || ''), - searchKeyword: String(g.searchKeyword || ''), - altText: String(g.altText || ''), - })); - - const totalChars = sections.reduce((sum, s) => sum + s.heading.length + s.body.length, 0); - - return { - success: true, - data: { - title: String(parsed.title || ''), - subtitle: String(parsed.subtitle || ''), - content: sections, - tags: Array.isArray(parsed.tags) ? parsed.tags.map(String) : [], - seoTitle: String(parsed.seoTitle || ''), - seoDescription: String(parsed.seoDescription || ''), - imageGuides, - meta: { - charCount: totalChars, - sectionCount: sections.length, - estimatedReadTime: `${Math.max(1, Math.round(totalChars / 500))}분`, - generatedAt: new Date().toISOString(), - model: 'claude-sonnet-4-20250514', - }, - }, - }; - } catch (err) { - console.error('[BlogGenerator] AI error, using fallback:', err); - } - } - - // Fallback (API 키 없거나 실패 시) - return buildFallback(req); -} - -function buildFallback(req: BlogRequest): BlogResult { - const sections: BlogSection[] = []; - for (let i = 0; i < req.sections; i++) { - if (i === 0) { - sections.push({ - heading: `${req.topic}이란?`, - body: `${req.keywords[0] || req.topic}에 대해 알아보겠습니다. 이 글에서는 ${req.topic}의 핵심 내용을 정리해 드립니다.`, - imageSlot: req.imageGuide, - }); - } else if (i === req.sections - 1) { - sections.push({ - heading: '마치며', - body: `지금까지 ${req.topic}에 대해 알아보았습니다. 도움이 되셨다면 댓글과 공감 부탁드립니다!`, - }); - } else { - sections.push({ - heading: `포인트 ${i}`, - body: `${req.topic} 관련 상세 내용이 이 자리에 들어갑니다. AI API 키 설정 후 실제 콘텐츠가 생성됩니다.`, - imageSlot: i % 2 === 0 && req.imageGuide, - }); - } - } - - return { - success: true, - data: { - title: `${req.topic} — 완벽 가이드`, - subtitle: `${req.keywords.join(', ')} 핵심 정리`, - content: sections, - tags: req.keywords.slice(0, 5), - seoTitle: `${req.topic} ${req.keywords[0] || ''} 총정리`, - seoDescription: `${req.topic}에 대한 핵심 정보를 정리했습니다.`, - imageGuides: req.imageGuide - ? [{ position: '도입부', description: '주제 대표 이미지', searchKeyword: req.keywords[0] || req.topic, altText: req.topic }] - : [], - meta: { - charCount: sections.reduce((s, sec) => s + sec.heading.length + sec.body.length, 0), - sectionCount: sections.length, - estimatedReadTime: '1분', - generatedAt: new Date().toISOString(), - model: 'fallback (no API key)', - }, - }, - }; -} diff --git a/lib/blog-tools/types.ts b/lib/blog-tools/types.ts deleted file mode 100644 index 29fb221..0000000 --- a/lib/blog-tools/types.ts +++ /dev/null @@ -1,61 +0,0 @@ -export interface BlogRequest { - topic: string; - keywords: string[]; - style: BlogStyle; - tone: BlogTone; - length: BlogLength; - imageGuide: boolean; - sections: number; -} - -export type BlogStyle = - | 'informational' // 정보 전달 - | 'review' // 리뷰/후기 - | 'howto' // 방법/튜토리얼 - | 'listicle' // 리스트형 - | 'comparison' // 비교 분석 - | 'story'; // 에세이/스토리 - -export type BlogTone = - | 'professional' // 전문적 - | 'friendly' // 친근한 - | 'casual' // 캐주얼 - | 'formal'; // 격식체 - -export type BlogLength = - | 'short' // 800~1200자 - | 'medium' // 1500~2500자 - | 'long'; // 3000~4500자 - -export interface BlogResult { - success: true; - data: { - title: string; - subtitle: string; - content: BlogSection[]; - tags: string[]; - seoTitle: string; - seoDescription: string; - imageGuides: ImageGuide[]; - meta: { - charCount: number; - sectionCount: number; - estimatedReadTime: string; - generatedAt: string; - model: string; - }; - }; -} - -export interface BlogSection { - heading: string; - body: string; - imageSlot?: boolean; -} - -export interface ImageGuide { - position: string; - description: string; - searchKeyword: string; - altText: string; -} diff --git a/next.config.ts b/next.config.ts index 39b1398..04c2699 100644 --- a/next.config.ts +++ b/next.config.ts @@ -39,7 +39,9 @@ const nextConfig: NextConfig = { { source: '/freelance', destination: '/work/freelance', permanent: true }, { source: '/services/website', destination: '/work/website', permanent: true }, { source: '/services/website/samples/:slug', destination: '/work/website/samples/:slug', permanent: true }, - { source: '/services/blog', destination: '/work/blog', permanent: true }, + // 블로그 자동화 폐기(2026-05-29 재정의): 기존 URL은 제품 라인 허브로 안내 + { source: '/services/blog', destination: '/work', permanent: true }, + { source: '/work/blog', destination: '/work', permanent: true }, // 사주 마이그 (단순 URL, 카탈로그 spec은 보류) { source: '/saju', destination: '/work/saju', permanent: true }, { source: '/saju/input', destination: '/work/saju/input', permanent: true }, From 4eee1b5c31530e4bd3aa779c87f1606c45ebb149 Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 31 May 2026 16:08:28 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat(ia):=20SaaS=20=EC=A0=9C=ED=92=88=20?= =?UTF-8?q?=EC=B9=B4=ED=83=88=EB=A1=9C=EA=B7=B8(/packages)=20+=20=EB=84=A4?= =?UTF-8?q?=EB=B9=84=EB=A5=BC=20SaaS=C2=B7=EC=9D=8C=EC=95=85=C2=B7?= =?UTF-8?q?=EC=99=B8=EC=A3=BC=203=EC=B6=95=EC=9C=BC=EB=A1=9C=20=EC=9E=AC?= =?UTF-8?q?=ED=8E=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - lib/saas-catalog.ts: 확장 가능한 SaaS 제품 데이터 모델(배열에 추가 시 자동 노출) - app/packages: 카탈로그 페이지 — available 카드 그리드 / coming_soon / 빈 상태 예고+출시 알림 수집(ContactModal 재사용) - TopNav·Footer: SaaS 제품(/packages)·AI 음악(/music)·커스텀 외주(/work) 3축 - 홈 Hero·라벨 카피를 새 정체성으로 정렬, 'Custom Build/사업부' 잔재 정리 - sitemap에 /packages 등록, STRATEGY.md에 크몽·숨고 미사용+인스타 유입 정책 명시 - 음악은 카탈로그에 넣지 않고 단품 라인(/music) 유지 Co-Authored-By: Claude Opus 4.8 (1M context) --- STRATEGY.md | 12 ++- app/components/PublicShell.tsx | 15 ++- app/components/TopNav.tsx | 5 +- app/packages/layout.tsx | 18 ++++ app/packages/page.tsx | 173 +++++++++++++++++++++++++++++++++ app/page.tsx | 16 +-- app/sitemap.ts | 1 + app/work/page.tsx | 4 +- lib/saas-catalog.ts | 64 ++++++++++++ next.config.ts | 2 +- 10 files changed, 292 insertions(+), 18 deletions(-) create mode 100644 app/packages/layout.tsx create mode 100644 app/packages/page.tsx create mode 100644 lib/saas-catalog.ts diff --git a/STRATEGY.md b/STRATEGY.md index b66b2af..84c4218 100644 --- a/STRATEGY.md +++ b/STRATEGY.md @@ -1,8 +1,18 @@ # 쟁승메이드 사업 전략 플레이북 -> 최초 작성: 2026-03-24 | 마지막 업데이트: 2026-03-24 +> 최초 작성: 2026-03-24 | 마지막 업데이트: 2026-05-31 > 작성 방식: 마케터 · 인플루언서 · 사업가 3인 원탁 회의 기반 +> **⚠️ 정체성 재정의 (2026-05-29, 본 문서 일부 전제 갱신)** +> 현재 정체성은 **"SaaS 제품 판매(메인) + 커스텀 외주(보조) 병행"**이다. +> - **외주 유입 채널: 크몽·숨고 등 외부 프리랜서 마켓은 사용하지 않는다.** +> 대신 **인스타 카드뉴스(Hedgy75) 직접 유입**으로 전환한다. +> → 아래 "크몽/숨고 AI 자동화 세팅 대행" 등 마켓 전제 섹션은 과거 전략 기록이며, +> 현 방침과 충돌 시 본 정책이 우선한다. +> - SaaS 제품 카탈로그는 `/packages`, AI 음악은 단품 가이드 패키지(`/music`)로 분리. +> - 블로그 자동화는 폐기(2026-05-17 결정, 코드 제거 완료). +> 상세: `docs/superpowers/plans/2026-05-31-saas-pivot-migration.md` + --- ## 📊 현황 진단 — 3인 전문가 평가 diff --git a/app/components/PublicShell.tsx b/app/components/PublicShell.tsx index 68e5fb0..0b0c0a3 100644 --- a/app/components/PublicShell.tsx +++ b/app/components/PublicShell.tsx @@ -75,17 +75,24 @@ export default function PublicShell({ children }: { children: React.ReactNode })
    {/* 우 — Link groups */} -
    +
    -

    Music

    +

    SaaS 제품

      -
    • AI 음악 팩
    • +
    • 제품 카탈로그
    • +
    • 출시 알림 신청
    • +
    +
    +
    +

    AI 음악

    +
      +
    • 음악 가이드 패키지
    • 샘플 갤러리
    • 가격
    -

    Custom Build

    +

    커스텀 외주

    • 외주 개발
    • 웹사이트 제작
    • diff --git a/app/components/TopNav.tsx b/app/components/TopNav.tsx index 57d3b04..b720fb8 100644 --- a/app/components/TopNav.tsx +++ b/app/components/TopNav.tsx @@ -7,8 +7,9 @@ import { createClient } from '@/lib/supabase/client'; import type { User } from '@supabase/supabase-js'; const LINKS = [ - { href: '/music', label: 'Music' }, - { href: '/work', label: 'Custom Build' }, + { href: '/packages', label: 'SaaS 제품' }, + { href: '/music', label: 'AI 음악' }, + { href: '/work', label: '커스텀 외주' }, ]; export default function TopNav() { diff --git a/app/packages/layout.tsx b/app/packages/layout.tsx new file mode 100644 index 0000000..5b1e30c --- /dev/null +++ b/app/packages/layout.tsx @@ -0,0 +1,18 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'SaaS 제품 · 월 구독 패키지', + description: + '현직 엔지니어가 실제 운영하며 검증한 자동화를 월 구독 SaaS 제품으로 제공합니다. 첫 제품 준비 중 — 출시 알림을 신청하세요.', + keywords: ['SaaS', '자동화 구독', '월 구독 자동화', 'AI 자동화 제품', '쟁승메이드'], + openGraph: { + title: 'SaaS 제품 · 월 구독 패키지 | 쟁승메이드', + description: + '검증된 자동화를 SaaS로. 현직 엔지니어가 직접 운영·검증한 자동화 제품 카탈로그.', + url: 'https://jaengseung-made.com/packages', + }, +}; + +export default function PackagesLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/app/packages/page.tsx b/app/packages/page.tsx new file mode 100644 index 0000000..f8a465f --- /dev/null +++ b/app/packages/page.tsx @@ -0,0 +1,173 @@ +'use client'; + +import { useState } from 'react'; +import Link from 'next/link'; +import ContactModal from '@/app/components/ContactModal'; +import { trackCTAClick } from '@/lib/gtag'; +import { + getAvailablePackages, + getComingSoonPackages, + type SaasCatalogItem, +} from '@/lib/saas-catalog'; + +const WAITLIST_SERVICE = 'SaaS 출시 알림 신청'; + +function PackageCard({ pkg, dimmed }: { pkg: SaasCatalogItem; dimmed?: boolean }) { + const inner = ( + <> +
      +

      + {pkg.category} +

      + {pkg.badge && ( + + {pkg.badge} + + )} + {dimmed && !pkg.badge && ( + + Coming Soon + + )} +
      +

      {pkg.name}

      +

      {pkg.tagline}

      +

      {pkg.description}

      +
        + {pkg.features.map((f) => ( +
      • + · + {f} +
      • + ))} +
      +
      + {pkg.priceLabel ? ( + {pkg.priceLabel} + ) : ( + 가격 준비 중 + )} + {!dimmed && } +
      + + ); + + const base = + 'group rounded-2xl border p-6 flex flex-col transition'; + if (dimmed) { + return ( +
      {inner}
      + ); + } + return ( + trackCTAClick(`packages_card_${pkg.slug}`)} + className={`${base} border-white/15 bg-white/[0.02] hover:border-white/40 hover:bg-white/[0.05]`} + style={{ textDecoration: 'none' }} + > + {inner} + + ); +} + +export default function PackagesPage() { + const [modalOpen, setModalOpen] = useState(false); + const available = getAvailablePackages(); + const comingSoon = getComingSoonPackages(); + const isEmpty = available.length === 0; + + return ( +
      + setModalOpen(false)} + service={WAITLIST_SERVICE} + checklist={['관심 있는 업무·자동화 분야', '연락받을 이메일', '현재 겪는 반복 업무(선택)']} + /> + + {/* Hero */} +
      +
      +
      +

      + SaaS Products +

      +

      + 검증된 자동화를 +
      SaaS로 만듭니다. +

      +

      + 현직 엔지니어가 실제로 운영하며 검증한 자동화를 월 구독 제품으로. + {isEmpty ? ' 첫 제품을 준비하고 있습니다.' : ''} +

      + {isEmpty && ( + + )} +
      +
      + + {/* Available 카탈로그 */} + {available.length > 0 && ( +
      +
      + {available.map((pkg) => ( + + ))} +
      +
      + )} + + {/* Coming Soon 예고 */} + {comingSoon.length > 0 && ( +
      +
      +

      + Coming Soon +

      +

      + 곧 만나볼 제품 +

      +
      + {comingSoon.map((pkg) => ( + + ))} +
      +
      +
      + )} + + {/* 출시 알림 CTA — 항상 노출(빈 상태 아닐 때도 대기자 수집) */} +
      +
      +

      + 새 제품이 나오면 가장 먼저 알려드릴까요? +

      +

      + 관심 분야를 남겨주시면 출시 시 이메일로 안내드립니다. 원하는 자동화 제안도 환영합니다. +

      + +
      +
      +
      + ); +} diff --git a/app/page.tsx b/app/page.tsx index 9040615..3a5308a 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -92,11 +92,11 @@ export default function Home() { className="kx-display text-4xl md:text-6xl lg:text-7xl font-bold mb-5 leading-[1.1]" style={{ wordBreak: 'keep-all', letterSpacing: '-0.02em' }} > - 현직 엔지니어가 만드는 -
      두 가지. + 현직 엔지니어가 +
      직접 만듭니다.

      - AI 제품, 그리고 맞춤 개발. + 검증된 자동화는 SaaS로. AI 음악 가이드와 커스텀 외주까지.

    @@ -140,7 +140,7 @@ export default function Home() { - {/* Custom Build 카드 */} + {/* 커스텀 외주 카드 */} trackCTAClick('home_v7_card_work')} @@ -153,10 +153,10 @@ export default function Home() { >

    - Custom Build + Custom Work

    - 맞춤 개발 사업부 + 커스텀 외주

    외주 · 웹사이트 · AI 사주 @@ -351,12 +351,12 @@ export default function Home() {

    - {/* 4. Custom Build 섹션 — 4 카드 + 5건 사례 + 견적 CTA */} + {/* 4. 커스텀 외주 섹션 — 카드 + 5건 사례 + 견적 CTA */}

    - Custom Build + Custom Work

    - Custom Build + Custom Work

    - 맞춤 개발 사업부 + 커스텀 외주

    7년차 백엔드 개발자가 직접 설계·개발·납품. 외주, 웹사이트, AI 사주까지. diff --git a/lib/saas-catalog.ts b/lib/saas-catalog.ts new file mode 100644 index 0000000..77f484f --- /dev/null +++ b/lib/saas-catalog.ts @@ -0,0 +1,64 @@ +// SaaS 제품 카탈로그 (/packages) +// +// 확장 규칙: 새 SaaS 제품을 출시하면 SAAS_CATALOG 배열에 객체 하나만 추가하면 +// /packages 페이지에 카드가 자동으로 노출된다. 결제는 productId로 lib/products.ts의 +// PRODUCTS 정의와 subscriptions 인프라에 연결한다. +// +// 음악(AI 음악 생성 개발 가이드 패키지)은 단품 라인이므로 여기에 넣지 않는다(/music 유지). + +export type SaasStatus = 'available' | 'coming_soon'; + +export interface SaasCatalogItem { + /** /packages 내 식별자 (향후 /packages/[slug] 상세에 사용) */ + slug: string; + /** 카드 제목 */ + name: string; + /** 한 줄 요약 (카드 상단) */ + tagline: string; + /** 카드 본문 설명 */ + description: string; + /** 가격 표시용 라벨 (예: "월 ₩29,000"). 미정이면 생략 */ + priceLabel?: string; + /** 과금 형태 */ + billing: 'monthly' | 'one_time'; + /** 노출 상태 — available: 구매 가능 / coming_soon: 예고 */ + status: SaasStatus; + /** 핵심 기능 목록 */ + features: string[]; + /** 분류 라벨 (예: '자동화') */ + category: string; + /** lib/products.ts PRODUCTS 키 참조 (결제 연결, available일 때) */ + productId?: string; + /** available일 때 상세/결제 경로 */ + href?: string; + /** 카드 강조 뱃지 (예: 'NEW') */ + badge?: string; +} + +/** + * 등록된 SaaS 제품 목록. + * + * 2026-05-31 현재 비어 있다. 메이킹 스페이스에서 검증된 자동화가 1개 확정되면 + * 아래 형태로 항목을 추가한다: + * + * { + * slug: 'making-verify', + * name: '메이킹 검증 자동화', + * tagline: '...', + * description: '...', + * priceLabel: '월 ₩29,000', + * billing: 'monthly', + * status: 'available', + * features: ['...'], + * category: '자동화', + * productId: 'making_verify_monthly', // lib/products.ts에 함께 추가 + * href: '/packages/making-verify', + * } + */ +export const SAAS_CATALOG: SaasCatalogItem[] = []; + +export const getAvailablePackages = () => + SAAS_CATALOG.filter((p) => p.status === 'available'); + +export const getComingSoonPackages = () => + SAAS_CATALOG.filter((p) => p.status === 'coming_soon'); diff --git a/next.config.ts b/next.config.ts index 04c2699..1163232 100644 --- a/next.config.ts +++ b/next.config.ts @@ -35,7 +35,7 @@ const nextConfig: NextConfig = { { source: '/services/music', destination: '/music/packs', permanent: true }, { source: '/services/music/samples', destination: '/music/samples', permanent: true }, { source: '/studio', destination: '/music/studio', permanent: true }, - // Custom Build 사업부 마이그 + // 커스텀 외주 마이그 { source: '/freelance', destination: '/work/freelance', permanent: true }, { source: '/services/website', destination: '/work/website', permanent: true }, { source: '/services/website/samples/:slug', destination: '/work/website/samples/:slug', permanent: true }, From a9d6091d1abe5a1d2c229ce340ddeead1cf15403 Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 31 May 2026 16:08:36 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat(music):=20=EC=9D=8C=EC=95=85=20?= =?UTF-8?q?=ED=8C=A9=EC=9D=84=20'AI=20=EC=9D=8C=EC=95=85=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EA=B0=9C=EB=B0=9C=20=EA=B0=80=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80'=20=EB=8B=A8=ED=92=88=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=94=94=EB=B2=A8=EB=A1=AD=20(=EA=B5=AC=EB=8F=85?= =?UTF-8?q?=20=ED=8F=90=EA=B8=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TIERS desc·productName을 '개발 가이드' 정체성으로 재서술 (가격·1회 결제 유지) - music/packs/layout 메타 + layout.tsx JSON-LD Offer를 가이드 패키지로 갱신 - 구독 인프라(products.ts monthly·subscriptions·cron)는 보존 - 기존 1회 구매자 0명 — 별도 처리 없음(종결 기록) Co-Authored-By: Claude Opus 4.8 (1M context) --- app/layout.tsx | 6 +++--- app/music/packs/layout.tsx | 8 ++++---- app/music/packs/page.tsx | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/layout.tsx b/app/layout.tsx index b28c924..74cb6ec 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -89,9 +89,9 @@ const jsonLd = { '@type': 'OfferCatalog', name: '쟁승메이드 AI 도구 · 서비스', itemListElement: [ - { '@type': 'Offer', price: '39000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 마스터 구조 팩 (입문)', url: 'https://jaengseung-made.com/music/packs', description: 'Suno 프롬프트 + MV 워크플로우 + 저작권 가이드 + 템플릿 PDF + 샘플 프로젝트. 4단계 AI 음악 제작 공정.' } }, - { '@type': 'Offer', price: '99000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 마스터 구조 팩 (프로)', url: 'https://jaengseung-made.com/music/packs', description: '입문 전체 + 샘플 프로젝트 1개(.prj · 영상 포함).' } }, - { '@type': 'Offer', price: '149000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 마스터 구조 팩 (마스터)', url: 'https://jaengseung-made.com/music/packs', description: '프로 전체 + 샘플 다수 + 우선 업데이트·베타 선공개.' } }, + { '@type': 'Offer', price: '39000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 생성 개발 가이드 패키지 (입문)', url: 'https://jaengseung-made.com/music/packs', description: 'Suno 프롬프트 조합법 + MV 워크플로우 + 저작권 가이드 + 템플릿 PDF + 샘플 프로젝트. AI 음악 생성 개발 가이드 (1회 결제).' } }, + { '@type': 'Offer', price: '99000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 생성 개발 가이드 패키지 (프로)', url: 'https://jaengseung-made.com/music/packs', description: '입문 전체 + 샘플 프로젝트 1개(.prj · 영상 포함). 1회 결제.' } }, + { '@type': 'Offer', price: '149000', priceCurrency: 'KRW', availability: 'https://schema.org/InStock', url: 'https://jaengseung-made.com/music/packs', itemOffered: { '@type': 'Product', name: 'AI 음악 생성 개발 가이드 패키지 (마스터)', url: 'https://jaengseung-made.com/music/packs', description: '프로 전체 + 샘플 다수 + 우선 업데이트·베타 선공개. 1회 결제.' } }, { '@type': 'Offer', price: '0', priceCurrency: 'KRW', url: 'https://jaengseung-made.com/work/saju', itemOffered: { '@type': 'Service', name: 'AI 사주 분석', url: 'https://jaengseung-made.com/work/saju', description: '생년월일 기반 AI 사주팔자 분석. 무료 체험 가능.' } }, { '@type': 'Offer', diff --git a/app/music/packs/layout.tsx b/app/music/packs/layout.tsx index 6ae0ace..4750c6c 100644 --- a/app/music/packs/layout.tsx +++ b/app/music/packs/layout.tsx @@ -1,9 +1,9 @@ import type { Metadata } from 'next'; export const metadata: Metadata = { - title: 'AI 음악 마스터 구조 팩 | Suno · MV · 유튜브 쇼츠', + title: 'AI 음악 생성 개발 가이드 패키지 | Suno · MV · 유튜브 쇼츠', description: - '엔지니어가 설계한 4단계 AI 음악 제작 공정. Suno 프롬프트 조합법 + MV 비디오 생성 워크플로우 + 저작권 가이드 + 템플릿 PDF + 샘플 프로젝트. 입문 ₩39k / 프로 ₩99k / 마스터 ₩149k.', + '엔지니어가 설계한 AI 음악 생성 개발 가이드. Suno 프롬프트 조합법 + MV 비디오 생성 워크플로우 + 저작권 가이드 + 템플릿 PDF + 샘플 프로젝트. 1회 결제 · 입문 ₩39k / 프로 ₩99k / 마스터 ₩149k.', keywords: [ 'AI 음악 만들기', 'Suno 프롬프트', @@ -16,9 +16,9 @@ export const metadata: Metadata = { 'Runway AI 비디오', ], openGraph: { - title: 'AI 음악 마스터 구조 팩 | 쟁승메이드', + title: 'AI 음악 생성 개발 가이드 패키지 | 쟁승메이드', description: - '네 사연을 노래로. 쇼츠까지 한 번에. 4단계 AI 음악 공정 · Suno Pro 검증 · 평생 업데이트.', + '네 사연을 노래로. 쇼츠까지 한 번에. AI 음악 생성 개발 가이드 · Suno Pro 검증 · 평생 업데이트.', url: 'https://jaengseung-made.com/music/packs', }, }; diff --git a/app/music/packs/page.tsx b/app/music/packs/page.tsx index 5a4a9ad..05f3afd 100644 --- a/app/music/packs/page.tsx +++ b/app/music/packs/page.tsx @@ -13,7 +13,7 @@ const TIERS: Record setSelectedTier(null)} - productName={`AI 음악 마스터 팩 · ${TIERS[selectedTier].name}`} + productName={`AI 음악 생성 개발 가이드 · ${TIERS[selectedTier].name}`} price={TIERS[selectedTier].price} /> )} From 4cbc56341158a022535ea22b9cccfe0570f26c38 Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 31 May 2026 16:09:43 +0900 Subject: [PATCH 4/4] =?UTF-8?q?docs(plan):=20SaaS=20=EC=A0=84=ED=99=98=20?= =?UTF-8?q?=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20P1?= =?UTF-8?q?=C2=B7P2=C2=B7P4=20=EC=99=84=EB=A3=8C=20+=20P3=20=EA=B3=A8?= =?UTF-8?q?=EA=B2=A9=20=EA=B5=AC=ED=98=84=20=EC=83=81=ED=83=9C=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../plans/2026-05-31-saas-pivot-migration.md | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-31-saas-pivot-migration.md diff --git a/docs/superpowers/plans/2026-05-31-saas-pivot-migration.md b/docs/superpowers/plans/2026-05-31-saas-pivot-migration.md new file mode 100644 index 0000000..c3ff510 --- /dev/null +++ b/docs/superpowers/plans/2026-05-31-saas-pivot-migration.md @@ -0,0 +1,266 @@ +# 쟁승메이드 SaaS 전환 — 단계별 마이그레이션 계획 + +> **For agentic workers:** 이 문서는 **단계별 마이그레이션 계획**이다(엄격한 TDD task-by-task 아님). Phase 단위로 목표·변경 항목·영향 파일·검증·완료조건을 정의한다. 각 Phase는 독립적으로 배포 가능한 단위가 되도록 설계했다. 체크박스(`- [ ]`)로 진행을 추적한다. + +**Goal:** 2026-05-29 정체성 재정의("Music + Custom Build 두 사업부" → **"SaaS 제품 판매 + 커스텀 외주 병행"**)를 실제 코드베이스에 단계적으로 반영한다. + +**Architecture:** 기존 IA(상단 `/music` · `/work` 2분할)를 **SaaS 패키지(월 구독) + 커스텀 외주(1회 직판)** 구조로 재편한다. 블로그 자동화는 완전 제거, **AI 음악은 구독으로 가지 않고 "AI 음악 생성 개발 가이드 패키지" 단품으로 디벨롭**, 사주는 별도 도메인으로 분리한다. 구독 인프라(`subscriptions` 테이블 · `subscription-expiry` cron · `products.ts` 의 `monthly` 타입)는 **이미 존재**하므로, 향후 메이킹 검증 자동화가 나올 때 재활용한다(음악 이탈로 첫 구독 패키지는 미정). + +**Tech Stack:** Next.js 16 (App Router, TS) · Tailwind v4 · Supabase(Postgres + RLS) · Resend · Vercel · Toss/Portone 결제 + +**상태:** 초안 (2026-05-31). Phase 1·2는 즉시 실행 가능. Phase 3·4는 "7월 본격" 의존. Phase 5는 대상 도메인 결정 후 착수. + +--- + +## 0. 배경 & 출처 + +- 의사결정 출처: Obsidian 위키 `wiki/사업-쟁승메이드.md` "정체성 재정의 (2026-05-29)" 섹션 + [[프로젝트-쟁승메이드-Co]]. +- 4단계 brainstorming 결과(박재오 명시): + - 정체성: **SaaS 제품 판매 + 커스텀 외주 병행** + - 블로그 자동화: **❌ 완전 삭제** (2026-05-17 폐기 결정의 코드 흔적 정리) + - AI 음악 39k/99k/149k 1회 직판 → ~~SaaS 월 구독 흡수~~ → **2026-05-31 정정: 구독 폐기, "AI 음악 생성 개발 가이드 패키지" 단품으로 디벨롭** + - 사주 카탈로그: **별도 도메인 마이그레이션** ([[프로젝트-쟁승메이드-Co]]의 갈래 2 도전 줄기) + - 외주: **❌ 크몽·숨고 절대 안 함** → 인스타 카드뉴스(Hedgy75) 직접 유입 + - 수익 모델: **1(SaaS 구독) 메인 + 5(외주 직판) 보조** + +--- + +## 1. 현재 상태 진단 (코드 기준 갭 분석) + +| 영역 | 현재 코드 상태 | 목표 | Phase | +|------|--------------|------|-------| +| 블로그 자동화 | `/work/blog` 라우트 + 9개 파일 참조 + JSON-LD Offer + sitemap 잔존 | 완전 제거 | **P1** | +| IA / 네비게이션 | TopNav `Music`·`Custom Build`, footer 2그룹 | SaaS 제품 / 커스텀 외주 구조 | **P2** | +| 외부 마켓 문구 | `STRATEGY.md` 등에 프리랜서 마켓 전제 | 크몽·숨고 미사용 + 인스타 유입 명시 | **P2** | +| SaaS 패키지 카탈로그 | 없음 (개별 서비스 페이지만) | 월 구독 패키지 카탈로그 (첫 패키지 후보 미정) | **P3 (대기)** | +| 구독 인프라 | `subscriptions` 테이블·cron·`products.ts(monthly)` **존재** | 보존, 향후 검증 자동화에 재활용 | P3 | +| AI 음악 | `/music/packs` 3티어 1회 결제 | **단품 유지 + "개발 가이드 패키지"로 디벨롭** (구독 ❌) | **P4** | +| 사주 | `/work/saju` + API 4종 + lib 3종, 사이트 내장 | 별도 도메인 분리 + 301 | **P5** | + +### 죽은 코드 / 즉시 정리 가능 +- `lib/blog-tools/generator.ts` — **어디서도 import 안 됨**(grep 확인). 삭제 안전. + +### 의사결정 — 2026-05-31 박재오 확정 (5건) +> 2026-05-31 박재오 결정으로 보류 5항목을 아래와 같이 해소·갱신. + +1. ✅ **음악 = 구독 안 함** — 월 구독 폐기. **"AI 활용 음악 생성 개발 가이드 패키지"로 디벨롭하여 단품(1회) 판매 유지.** → P4 재정의(구독 전환 → 단품 디벨롭). +2. ✅ **기존 1회 구매자 = 0명** — 실제 구매 이력 없음. grandfathering 불필요. "구매자 없음" 사실만 기록하고 **다시 논점으로 떠오르지 않도록** 처리. → P4. +3. ⏸ **사주 분리 대상 도메인 = 대기** — 도메인 미구매. **구매 완료 전까지 P5 착수 보류.** 도메인 확정이 P5 유일 블로커. +4. 🔍 **사주 DB = 기존 Supabase 기본 + NAS 셀프호스팅 검토** — 일단 현 Supabase 유지. 단, **NAS(Postgres) 자체 호스팅으로 옮기는 안을 별도 검토**(비용·백업·외부 접근·RLS 대체). → P5 내 검토 작업으로 편입. +5. ✅ **사주 결제 이력 = 전부 이전** — `orders`/`subscriptions`의 사주(`saju_detail` 등) 결제·주문 데이터를 **신규 도메인 DB로 전량 마이그레이션**. → P5. + +--- + +## Phase 1 — 블로그 자동화 완전 삭제 ✅ (2026-05-31 완료) + +**목표:** `/work/blog` 라우트와 모든 코드/메타/마케팅 흔적을 제거하고, 기존 URL은 안전하게 처리한다. + +**영향 파일 (모두 확인됨):** +- 삭제: `app/work/blog/page.tsx`, `app/work/blog/layout.tsx`, `app/work/blog/` 폴더 +- 삭제: `lib/blog-tools/generator.ts` (+ 빈 `lib/blog-tools/` 폴더) +- 수정: `app/components/PublicShell.tsx` — footer "Custom Build" 그룹의 `블로그 자동화` 링크 제거 +- 수정: `app/work/page.tsx` — line 29~32 `blog` 카드 객체 제거, line 70 카피에서 "블로그 자동화" 제거 +- 수정: `app/page.tsx` — line 50 `blog` 카드 제거, line 163·369 카피에서 "블로그 자동화" 제거 +- 수정: `app/layout.tsx` — line 30 keywords "블로그 자동화" 제거, line 77·84 description 수정, line 96 JSON-LD `블로그 자동화 솔루션 팩` Offer 객체 제거 +- 수정: `app/legal/refund/page.tsx` — line 21 환불 대상 목록에서 "블로그 자동화 솔루션 팩" 제거 +- 수정: `app/sitemap.ts` — line 10 `/services/blog` 엔트리 제거 (+ `/work/blog` 엔트리 있으면 제거) +- 수정: `next.config.ts` — `/services/blog → /work/blog` 리다이렉트 처리 (아래 정책 참조) +- 유지(변경 X): `app/work/website/page.tsx:106` "개인 블로그…" = 웹사이트 제작 예시 카피일 뿐 블로그 자동화 상품 아님. `app/admin/marketing/page.tsx:79·81` "블로그/SNS" = 배너 활용처 설명. 둘 다 **건드리지 않음**. + +**리다이렉트 정책:** +- `next.config.ts`의 `{ source: '/services/blog', destination: '/work/blog', permanent: true }` → `/work/blog`가 사라지므로 **목적지를 `/work`로 변경** (제품 라인 허브로 안내). 410(Gone)보다 301→`/work`가 SEO·UX상 안전. + +**작업 체크리스트:** +- [ ] 1-1. `app/work/blog/` 폴더 전체 삭제 +- [ ] 1-2. `lib/blog-tools/` 폴더 전체 삭제 +- [ ] 1-3. 위 "수정" 파일 7개에서 블로그 참조 제거 (정확 라인은 작업 시점 재확인 — 리팩터로 이동 가능) +- [ ] 1-4. `next.config.ts` 리다이렉트 목적지 `/services/blog → /work` 로 변경 +- [ ] 1-5. 검증: `grep -rn "work/blog\|블로그 자동화\|blog-tools" app lib components` → **0건** (단 1-3 유지 항목 제외) +- [ ] 1-6. 검증: `npm run build` 성공 (타입·링크 깨짐 없음) +- [ ] 1-7. 검증: 로컬에서 `/work/blog` 접속 시 404, `/services/blog` 접속 시 `/work`로 301 +- [ ] 1-8. 커밋: `chore(blog): /work/blog 라우트·참조·메타 완전 제거 (2026-05-29 재정의)` + +**완료 조건:** 블로그 자동화의 라우트·UI 링크·구조화 데이터·sitemap·환불약관·죽은 lib가 모두 사라지고, 빌드 성공 + 기존 URL 301 처리됨. + +--- + +## Phase 2 — IA 재편: "SaaS 제품 + 커스텀 외주 병행" ✅ (2026-05-31 완료) + +> **실제 구현 메모:** TopNav를 2탭이 아니라 **3탭(SaaS 제품 `/packages` · AI 음악 `/music` · 커스텀 외주 `/work`)**으로 구성했다. 음악이 단품으로 분리되면서 "SaaS 제품" 라벨이 음악을 가리키는 모순을 피하고 음악 발견성을 유지하기 위함(박재오 결정). Footer도 동일 3그룹 + Legal로 정렬. + +**목표:** 상단/푸터 네비게이션과 홈 카피를 새 정체성에 맞게 재편한다. 코드 라우트 대규모 이동 없이 **라벨·그룹핑·카피 수준**에서 먼저 정렬한다(라우트 실이동은 P3에서). + +**핵심 결정:** `/music`·`/work` 라우트 경로는 **유지**(301 리다이렉트 누적 회피). 사용자 노출 라벨만 SaaS/커스텀 프레이밍으로 변경. + +| 위치 | 현재 라벨 | 변경안 | +|------|---------|--------| +| TopNav | `Music` / `Custom Build` | `SaaS 제품` / `커스텀 외주` (경로는 `/music`·`/work` 유지) | +| Footer 그룹 | `Music` / `Custom Build` | `SaaS 제품` / `커스텀 외주` | +| 홈 Hero/카피 | "두 사업부" 뉘앙스 | "검증된 자동화를 SaaS로 + 필요 시 커스텀 외주" 한 문장 | + +**영향 파일:** +- 수정: `app/components/TopNav.tsx` — line 10~11 `NAV` 배열 라벨 (`Music`→`SaaS 제품`, `Custom Build`→`커스텀 외주`). `href`는 유지. +- 수정: `app/components/PublicShell.tsx` — footer 그룹 헤더 라벨 2곳 +- 수정: `app/page.tsx` — Hero·소개 카피 (line 163·369 인근, 새 정체성 1문장) +- 수정: `app/work/page.tsx` — 허브 카피 (line 70 인근) +- 수정(문구): `STRATEGY.md` — "프리랜서 마켓/숨고/크몽" 전제 문장에 **"크몽·숨고 미사용 — 인스타 카드뉴스(Hedgy75) 직접 유입"** 정책 주석 추가 (전체 재작성은 P6/별도) + +**작업 체크리스트:** +- [ ] 2-1. TopNav·Footer 라벨 SaaS/커스텀 프레이밍으로 변경 (경로 불변) +- [ ] 2-2. 홈·work 허브 카피를 새 정체성 1문장으로 정렬 +- [ ] 2-3. `STRATEGY.md`에 외주 유입 채널 정책(크몽·숨고 ❌ / 인스타 ⭕) 주석 추가 +- [ ] 2-4. 검증: `grep -rn "Custom Build\|두 사업부" app components` → 의도된 잔존만 남음 +- [ ] 2-5. 검증: `npm run build` 성공 + 헤더/푸터 라벨 육안 확인 +- [ ] 2-6. 커밋: `refactor(ia): 네비게이션·카피를 SaaS+커스텀 외주 정체성으로 재편` + +**완료 조건:** 방문자가 보는 1차 프레이밍이 "SaaS 제품 + 커스텀 외주"로 통일되고, 외부 마켓 미사용 정책이 문서에 명시됨. 라우트 경로는 불변이라 회귀 위험 최소. + +--- + +## Phase 3 — SaaS 패키지 카탈로그 구조 도입 🟡 (골격 구현됨 — 첫 패키지만 대기) + +**목표:** "검증된 자동화 → SaaS 월 구독 패키지" 구조를 담을 **카탈로그 페이지 + 데이터 모델**을 만든다. 결제는 기존 `subscriptions` 인프라에 연결한다. + +> 🟡 **상태: 골격 구현 완료(2026-05-31), 첫 제품만 대기.** 박재오 결정으로 P3의 **확장 골격을 먼저 구현**했다(빈 카탈로그도 깨지지 않고, 제품 추가 시 자동 노출). 남은 것은 **첫 SaaS 제품 1개 확정 + 등록**뿐이다. 메이킹 스페이스에서 검증된 자동화가 나오면 `SAAS_CATALOG` 배열에 항목 1개 추가 + `lib/products.ts`에 `monthly` 상품 추가하면 된다. 구독 인프라는 보존됨. +> +> **구현 완료분 (2026-05-31):** +> - 경로명 **`/packages` 확정** (결정 포인트 해소). +> - `lib/saas-catalog.ts` — `SaasCatalogItem` 데이터 모델 + `SAAS_CATALOG` 배열(현재 빈 배열) + `getAvailablePackages()`/`getComingSoonPackages()` 헬퍼. +> - `app/packages/page.tsx` + `layout.tsx` — available 카드 그리드 / coming_soon 흐린 카드 / **available 0개일 때 예고 히어로 + "출시 알림 받기"**(기존 `ContactModal` 재사용, `service='SaaS 출시 알림 신청'`). +> - TopNav·Footer "SaaS 제품" → `/packages` 연결, sitemap 등록. +> +> **남은 것 (첫 제품 확정 후):** `SAAS_CATALOG`에 `status:'available'` 항목 추가, `lib/products.ts` `monthly` 상품 추가, `/api/subscription` product_id 처리 확인, 결제→`subscriptions` row→mypage→cron 만료 end-to-end 검증, `/packages/[slug]` 상세(필요 시). + +**전제:** 메이킹 검증 자동화 1개 확정 후 착수. (음악은 더 이상 첫 패키지 아님 — P4 단품 라인으로 분리.) + +**영향 파일:** +- 신규: `app/saas/page.tsx` (또는 `/packages`) — SaaS 패키지 카탈로그(월 구독 카드 그리드). 경로명 확정 필요(아래 결정 포인트). +- 신규: `app/saas/layout.tsx` — 메타데이터 +- 수정: `lib/products.ts` — SaaS 패키지 상품 정의(`type: 'monthly'`) 추가. 기존 `monthly` 타입 패턴(`stock_starter_monthly` 등) 그대로 따름. +- 수정: `app/api/subscription/route.ts` — 신규 패키지 product_id 처리(기존 흐름 재활용 확인) +- 수정: `app/components/TopNav.tsx` — `SaaS 제품` 항목 목적지를 `/music` → `/saas`로 전환(P4 완료 시점에 맞춰) +- 참조(변경 X): `supabase/migrations/004_subscriptions.sql`, `app/api/cron/subscription-expiry/route.ts` — 그대로 사용 + +**결정 포인트:** +- 경로명: `/saas` vs `/packages` vs `/products` — 1개 확정. (권장: `/packages` — 한국어 노출 "패키지"와 자연 매칭) +- 첫 패키지 = 음악 1개로 시작할지, 메이킹 검증 자동화 1~2개를 동시 등판할지. + +**작업 체크리스트:** +- [ ] 3-1. 경로명·첫 패키지 범위 확정 (박재오) +- [ ] 3-2. `lib/products.ts`에 SaaS 패키지 상품 추가(`monthly`) +- [ ] 3-3. 카탈로그 페이지 + layout 생성 (구독 카드 → `subscription` API 연결) +- [ ] 3-4. 기존 `subscriptions` 테이블·만료 cron으로 신규 패키지 생명주기 동작 확인 +- [ ] 3-5. 검증: 테스트 결제 → `subscriptions` row 생성 → mypage 노출 → cron 만료 처리 +- [ ] 3-6. 검증: `npm run build` 성공 +- [ ] 3-7. 커밋: `feat(saas): SaaS 월 구독 패키지 카탈로그 + 구독 연결` + +**완료 조건:** SaaS 패키지를 카탈로그에서 구독 결제 → `subscriptions`에 기록 → mypage에서 확인 → 만료 cron 동작까지 end-to-end 성립. + +--- + +## Phase 4 — AI 음악: "음악 생성 개발 가이드 패키지" 단품으로 디벨롭 ✅ (2026-05-31 완료) + +**목표:** `/music/packs`를 **월 구독으로 전환하지 않는다.** 기존 39k/99k/149k **1회 결제 구조를 유지**하되, 상품의 정체성을 **"AI를 활용한 음악 생성 개발 가이드 패키지"**로 디벨롭(포지셔닝·콘텐츠 강화)한다. 구독 인프라는 건드리지 않는다. + +> 2026-05-31 결정: 구독 폐기. 음악은 SaaS 라인이 아니라 **디지털 상품(가이드 패키지) 단품 라인**으로 확정. + +**기존 구매자 처리 (결정 #2):** 실제 구매자 **0명** 확인. grandfathering·마이그레이션 불필요. → 본 Phase에서 **"기존 1회 구매자 0명 — 별도 처리 없음"을 명시 기록**하고, 향후 계획에서 이 논점이 다시 떠오르지 않도록 종결한다(이 문장이 그 종결 기록). + +**영향 파일:** +- 수정: `app/music/packs/page.tsx` — `TIERS`의 가격/주기는 **1회 결제 유지**. `name`·`desc`·`features`를 "개발 가이드 패키지" 정체성으로 재서술(예: "프롬프트 조합·반복 가능한 워크플로우 설계 가이드"). line 295~296 `productName`을 "AI 음악 생성 개발 가이드 · {티어}"로. +- (선택) 수정: `app/music/packs/layout.tsx` — 메타 title/description을 "음악 생성 개발 가이드"로 갱신 +- 수정: `app/layout.tsx` — JSON-LD 음악 Offer의 `Product.name`/`description`을 "개발 가이드 패키지"로 갱신(가격·1회 결제 유지) +- 수정: `app/legal/refund/page.tsx` — "AI 음악 마스터 구조 팩" 표기를 신규 패키지명과 일치하게 정리(1회 디지털 콘텐츠 환불 규정은 유지) +- 변경 **불가**(보존): `lib/products.ts`의 `monthly` 패턴, `subscriptions` 테이블, `subscription-expiry` cron — 음악과 무관하게 P3용으로 보존 +- 콘텐츠 작업: `CONTENT/` 하위 음악 패키지 카피·가이드 본문 디벨롭(코드 외 산출물) + +**작업 체크리스트:** +- [ ] 4-1. 패키지 정체성·티어별 신규 카피/구성 확정 (박재오 — "개발 가이드" 관점 features) +- [ ] 4-2. `/music/packs` `TIERS` 메타(name/desc/features) 재서술 — **가격·1회 결제 유지** +- [ ] 4-3. `layout.tsx` JSON-LD + `music/packs/layout.tsx` 메타를 가이드 패키지로 갱신 +- [ ] 4-4. `refund/page.tsx` 상품명 표기 정합화 +- [ ] 4-5. "기존 1회 구매자 0명 — 처리 없음" 종결 기록(본 문서로 충족) +- [ ] 4-6. 검증: `grep -rn "월 구독\|구독.*음악\|music.*monthly" app lib` → 음악-구독 결합 흔적 0건 +- [ ] 4-7. 검증: `npm run build` 성공 + `/music/packs` 1회 결제 흐름 정상 +- [ ] 4-8. 커밋: `feat(music): 음악 팩을 "AI 음악 생성 개발 가이드 패키지" 단품으로 디벨롭 (구독 폐기)` + +**완료 조건:** 음악 팩이 "개발 가이드 패키지" 정체성으로 1회 판매되고, 구독 결합 흔적이 코드/메타/약관에 없으며, 기존 구매자 0명 사실이 종결 기록됨. + +--- + +## Phase 5 — 사주 카탈로그 별도 도메인 분리 + +**목표:** `/work/saju` 및 사주 전용 API·lib를 **별도 도메인 프로젝트**로 이관하고, 현 사이트에서 제거 + 외부 안내/301 처리한다. + +> ⏸ **상태: 대기 (블로커 = 도메인 미구매).** 2026-05-31 기준 분리 대상 도메인을 아직 구매하지 않음. **도메인 구매 완료가 P5 착수의 단일 선결 조건.** 그 전까지 사주는 현 사이트에 그대로 둔다. + +**DB 방침 (결정 #4):** 기본은 **기존 Supabase 유지**. 단, **NAS(Postgres) 자체 호스팅 이전 안을 별도 검토**한다 — 검토 포인트: 월 비용 절감 vs. 외부 접근성/가용성, 백업·복구, Supabase RLS·Auth 대체(직접 구현 부담), Vercel→NAS 네트워크 레이턴시. 검토 결과로 "Supabase 유지" 또는 "NAS 이전" 택1. + +**결제 이력 방침 (결정 #5):** `orders`/`subscriptions`의 사주 관련 결제·주문 데이터를 **신규 도메인 DB로 전량 이전**(누락 없이). + +**전제:** 도메인 구매 완료(블로커). DB 호스팅(Supabase vs NAS)은 착수 시점에 검토 결과로 확정. + +**이관 대상 (현 코드 기준 전수):** +- 라우트: `app/work/saju/` 전체 (`page.tsx`, `input/`, `result/`, `components/SajuForm.tsx`, `result/SajuAISection.tsx`, `result/SajuFortuneSection.tsx`, `layout.tsx`) +- API: `app/api/saju/analyze/`, `app/api/saju/calculate/`, `app/api/saju/lotto/`, `app/api/saju/save-interpretation/` +- 라이브러리: `lib/ai-interpretation.ts`, `lib/daeun-calculator.ts`, `lib/saju-ai-prompt.ts`, `saju-engine/` (루트) +- 상품: `lib/products.ts` `saju_detail` (이관 또는 신규 도메인 재정의) +- DB: `subscriptions`/`orders`에 묶인 사주 결제 이력 — 결정 #5에 따라 이전/유지 + +**현 사이트 정리:** +- 제거: 위 라우트/API/lib (단, `lotto`가 사주와 공유되면 의존성 확인 — `app/api/saju/lotto` vs `app/api/saju/analyze`의 lib 공유 점검) +- 수정: `app/components/PublicShell.tsx` footer `AI 사주` 링크 → 외부 도메인 링크로 교체 또는 제거 +- 수정: `app/page.tsx`(line 50·163·369), `app/work/page.tsx`(사주 카드), `app/mypage/page.tsx`(사주 참조), `app/sitemap.ts`, `app/layout.tsx`(사주 JSON-LD/keywords) — 사주 참조 제거 또는 외부 링크화 +- 수정: `next.config.ts` — `/saju`·`/saju/input`·`/saju/result` 리다이렉트 3종을 **외부 도메인 301**로 변경(현재는 `/work/saju`로 내부 리다이렉트) + +**작업 체크리스트:** +- [ ] 5-0. **도메인 구매 완료** (P5 착수 블로커 — 미완료 시 이하 진행 금지) +- [ ] 5-1. DB 호스팅 검토: Supabase 유지 vs NAS(Postgres) 이전 — 비용·가용성·RLS/Auth 대체·백업 평가 후 택1 +- [ ] 5-2. 신규 도메인 프로젝트로 사주 라우트/API/lib/엔진 이관 + 동작 검증 +- [ ] 5-3. 사주 결제·주문 이력 **전량** 신규 DB로 마이그레이션 + 건수 대조 검증 +- [ ] 5-4. 현 사이트에서 사주 라우트/API/lib 제거 + 공유 의존성(예: lotto) 분리 확인 +- [ ] 5-5. footer/홈/mypage/sitemap/layout 사주 참조를 외부 링크화 또는 제거 +- [ ] 5-6. `next.config.ts` 사주 리다이렉트를 외부 도메인 301로 변경 +- [ ] 5-7. 검증: 현 사이트 `npm run build` 성공 + 사주 잔존 참조 0건(외부 링크 제외) +- [ ] 5-8. 검증: 신규 도메인에서 사주 전 기능(입력→계산→AI해석→결제) 동작 +- [ ] 5-9. 검증: `/saju*` 기존 URL이 신규 도메인으로 301 +- [ ] 5-10. 커밋(현 사이트): `chore(saju): 사주 카탈로그 별도 도메인 분리 + 참조 제거` + +**완료 조건:** 사주가 별도 도메인에서 독립 동작하고, 현 사이트에는 사주 코드가 남지 않으며, 기존 사주 URL이 신규 도메인으로 안전하게 연결됨. + +--- + +## 리다이렉트 정책 종합 + +| 기존 URL | 현재 동작 | 변경 후 (Phase) | +|---------|----------|----------------| +| `/services/blog` | → `/work/blog` (301) | → `/work` (301) **[P1]** | +| `/work/blog` | 페이지 존재 | 404 **[P1]** | +| `/services/music`, `/services/music/samples`, `/studio` | → `/music/*` | 유지 | +| `/freelance`, `/services/website*` | → `/work/*` | 유지 | +| `/saju`, `/saju/input`, `/saju/result` | → `/work/saju*` (내부) | → 외부 사주 도메인 (301) **[P5]** | + +--- + +## 롤백 전략 + +- 각 Phase = 독립 커밋(+ 가급적 PR). 문제 시 해당 커밋 revert로 단일 Phase만 되돌림. +- P1(블로그): 라우트 삭제는 git에서 복원 가능. 리다이렉트만 우선 배포해 트래픽 영향 관찰 후 코드 삭제하는 2단 배포도 가능. +- P4(음악 단품 디벨롭): 가격·타입 변경 없음(1회 결제 유지). 카피/메타 변경은 커밋 revert로 즉시 원복. 기존 구매자 0명이라 데이터 백업 불필요. +- P5(사주): 신규 도메인 안정화 **확인 후** 현 사이트 코드 삭제(삭제-먼저 금지). 이전 기간 동안 양쪽 병행 운영. + +--- + +## 실행 순서 요약 + +1. **지금** → P1(블로그 삭제) → P2(IA 라벨/카피 재편) → P4(음악을 "개발 가이드 패키지" 단품으로 디벨롭). 셋 다 위험 낮고 즉시 가능(P4는 구독 전환이 아니라 카피/메타 디벨롭이라 가벼움). +2. **메이킹 검증 자동화 1개 확정 후** → P3(SaaS 카탈로그). 음악 이탈로 첫 패키지 후보가 없어 그때까지 대기. 인프라는 보존. +3. **도메인 구매 후** → P5(사주 분리). 도메인 미구매가 단일 블로커. 가장 무겁고 외부 인프라 의존 → 마지막. + +--- + +## 변경 이력 + +- 2026-05-31: 초안 생성. 위키 `사업-쟁승메이드.md` 2026-05-29 재정의를 코드 마이그레이션 5-Phase로 분해. 현재 코드베이스 갭 분석 + 의사결정 보류 5항목 명시. +- 2026-05-31: 박재오 결정 5건 반영 — ①음악 구독 폐기→"AI 음악 생성 개발 가이드 패키지" 단품 디벨롭(P4 전면 재작성), ②기존 1회 구매자 0명 종결 기록, ③사주 분리 도메인 미구매로 P5 대기(블로커=도메인), ④사주 DB는 Supabase 유지 기본 + NAS 셀프호스팅 검토 편입, ⑤사주 결제 이력 전량 이전. 음악 이탈로 P3(SaaS 카탈로그) 첫 패키지 후보 공백 → P3 대기로 변경, 구독 인프라는 보존. +- 2026-05-31 (구현): **P1·P2·P4 실행 완료** + **P3 확장 골격 선구현**. 커밋 3건 — `chore(blog)`(블로그 완전 제거), `feat(ia)`(SaaS 카탈로그 `/packages` + 네비 3축 재편), `feat(music)`(음악 가이드 패키지 단품). 박재오 결정으로 P3 골격(`/packages` 경로 확정 + `lib/saas-catalog.ts` 확장 데이터 모델 + 빈 상태 예고/출시 알림 수집)을 먼저 구현 — 첫 SaaS 제품만 확정되면 배열 추가로 등판. 빌드 성공, 음악-구독 결합 흔적 0건. 브랜치 `feat/saas-pivot-migration`. P5(사주 분리)는 도메인 미구매로 미착수.