From e5ff5ec84f1ff38f810dc3b7577c30b3e8919376 Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 2 Jul 2026 15:01:43 +0900 Subject: [PATCH] =?UTF-8?q?feat(phase1):=20showcase=20=EB=8D=B0=EB=AA=A8?= =?UTF-8?q?=20=EB=A9=94=ED=83=80=20=EB=8B=A8=EC=9D=BC=20=EC=86=8C=EC=8A=A4?= =?UTF-8?q?=20+=20=EB=AC=B4=EA=B2=B0=EC=84=B1=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /showcase 제작 사례 허브가 소비할 데모 8종 메타 모듈화 - slug/title/description/tags 필수 필드 검증 테스트 3건 - Task 2(showcase 라우트)가 SHOWCASE_SAMPLES import 가능 Co-Authored-By: Claude Opus 4.8 (1M context) --- lib/__tests__/showcase-samples.test.ts | 27 ++++++++++++++++++++++++++ lib/showcase-samples.ts | 18 +++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 lib/__tests__/showcase-samples.test.ts create mode 100644 lib/showcase-samples.ts diff --git a/lib/__tests__/showcase-samples.test.ts b/lib/__tests__/showcase-samples.test.ts new file mode 100644 index 0000000..bc402f2 --- /dev/null +++ b/lib/__tests__/showcase-samples.test.ts @@ -0,0 +1,27 @@ +import { describe, it, expect } from 'vitest'; +import { SHOWCASE_SAMPLES } from '../showcase-samples'; + +const EXPECTED_SLUGS = [ + 'bakery', 'corporate', 'dashboard', 'game', + 'interior', 'portfolio', 'reading', 'shopping', +]; + +describe('SHOWCASE_SAMPLES', () => { + it('데모 8종의 slug가 정확히 존재한다', () => { + expect(SHOWCASE_SAMPLES.map((s) => s.slug).sort()).toEqual([...EXPECTED_SLUGS].sort()); + }); + + it('모든 항목에 title/description/tags가 채워져 있다', () => { + for (const s of SHOWCASE_SAMPLES) { + expect(s.title.length).toBeGreaterThan(0); + expect(s.description.length).toBeGreaterThan(0); + expect(s.tags.length).toBeGreaterThan(0); + } + }); + + it('demo 경로는 /work/website/samples/[slug] 형식이다', () => { + for (const s of SHOWCASE_SAMPLES) { + expect(`/work/website/samples/${s.slug}`).toMatch(/^\/work\/website\/samples\/[a-z]+$/); + } + }); +}); diff --git a/lib/showcase-samples.ts b/lib/showcase-samples.ts new file mode 100644 index 0000000..be2a5db --- /dev/null +++ b/lib/showcase-samples.ts @@ -0,0 +1,18 @@ +/** /showcase 제작 사례 허브의 데모 카드 단일 소스. 데모 실체는 app/work/website/samples/[slug]. */ +export type ShowcaseSample = { + slug: string; + title: string; + description: string; + tags: string[]; +}; + +export const SHOWCASE_SAMPLES: ShowcaseSample[] = [ + { slug: 'corporate', title: '기업 홈페이지', description: 'IT 기업 소개·서비스·문의까지 담은 반응형 공식 홈페이지.', tags: ['기업', '반응형', 'SEO'] }, + { slug: 'shopping', title: '쇼핑몰', description: '상품 목록·상세·장바구니 흐름을 갖춘 커머스 데모.', tags: ['커머스', '결제 흐름'] }, + { slug: 'dashboard', title: 'SaaS 대시보드', description: '지표 카드·차트·테이블로 구성한 관리자 대시보드.', tags: ['대시보드', '차트'] }, + { slug: 'bakery', title: '베이커리 브랜드', description: '메뉴·매장·브랜드 스토리를 담은 로컬 비즈니스 사이트.', tags: ['브랜드', '로컬'] }, + { slug: 'interior', title: '인테리어 포트폴리오', description: '시공 사례 중심의 갤러리형 인테리어 회사 사이트.', tags: ['갤러리', '포트폴리오'] }, + { slug: 'portfolio', title: '디자이너 포트폴리오', description: '작업물·경력·연락처를 담은 개인 포트폴리오.', tags: ['개인', '포트폴리오'] }, + { slug: 'game', title: '게임 프로모션', description: '출시 게임을 소개하는 인터랙티브 프로모션 페이지.', tags: ['프로모션', '랜딩'] }, + { slug: 'reading', title: '도서 콘텐츠', description: '책 소개·리뷰 중심의 콘텐츠 페이지.', tags: ['콘텐츠', '블로그'] }, +];