From 4eee1b5c31530e4bd3aa779c87f1606c45ebb149 Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 31 May 2026 16:08:28 +0900 Subject: [PATCH] =?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 },