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 },