Skip to content

Commit 7d41935

Browse files
kickbelldevclaude
andauthored
feat: 엔티티 비즈니스 로직 분리 및 테스트 커버리지 개선 (#7)
* config: MDX frontmatter 처리를 위한 remark 플러그인 추가 - remark-frontmatter: MDX frontmatter 파싱 지원 - remark-mdx-frontmatter: MDX 컴포넌트에서 frontmatter 사용 가능 - next.config.ts에 remarkPlugins 설정 추가 - package.json에 필요한 의존성 추가 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * refactor: API 레이어를 엔티티 기반 아키텍처로 변경 - src/entities/posts/ 엔티티 추가 - index.ts: 게시물 관련 비즈니스 로직 - types.ts: 게시물 타입 정의 - src/api/posts.ts 삭제하여 도메인 로직 분리 - 블로그 페이지에서 새로운 엔티티 import 경로 적용 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * docs: 테스트 MDX 파일들에 frontmatter 추가 * docs: Claude Code 아키텍처 가이드 확장 - 도메인 엔티티 기반 아키텍처 - 컨텐츠 관리 섹션 수정 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * config: Vitest 테스트 환경 및 커버리지 도구 설정 - Vitest 테스트 프레임워크 추가 - @vitest/ui 및 @vitest/coverage-v8 커버리지 도구 설정 - 엔티티 테스트를 위한 테스트 스크립트 추가 - src/entities/** 파일 커버리지 타겟 설정 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * test: Posts 엔티티 테스트 구현 - getAllPosts, getPostBySlug, getPostsByTag 함수 테스트 - 파일 시스템 mocking 및 gray-matter 파싱 테스트 - 에러 처리 및 엣지 케이스 테스트 포함 - 빈 디렉토리, 잘못된 날짜 형식 등 예외 상황 검증 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * test: Tags 엔티티 그래프 기반 테스트 구현 - getAllTags, getTagByName, getTagGraph, getTagRelationships 함수 테스트 - graphology 기반 그래프 구조 검증 - 태그 공동 출현 분석 및 관계 계산 테스트 - 클러스터링 알고리즘 및 중심성 계산 테스트 - 통계 분석 및 에지 케이스 검증 포함 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * test: 통합 테스트 및 타입 검증 테스트 추가 - Posts와 Tags 엔티티 간의 통합 테스트 구현 - 실제 블로그 데이터 시뮬레이션 시나리오 테스트 - 타입 인터페이스 구조 검증 테스트 - 테스트 환경 설정 파일 추가 - 엔티티 간 상호작용 및 데이터 흐름 검증 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * feat: graphology 기반 태그 엔티티 구현 및 타입 정의 - graphology 라이브러리를 이용한 태그 그래프 구조 구현 - 태그 공동 출현 관계 분석 및 유사도 계산 - 중심성 기반 태그 클러스터링 알고리즘 - 태그 통계 분석 기능 (most used, least used, average) - TypeScript 타입 정의 및 인터페이스 구현 - UndirectedGraph 타입을 활용한 태그 그래프 정의 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * chore: 개발 환경 설정 업데이트 - 프로젝트 VSCode 설정에서 eslint 동작 방지 - CLAUDE.md에 개발 중 불필요한 개벌서버 실행 방지 지침 추가 - types.ts 파일 테스트 방지 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * fix: 테스트 코드 타입 안정성 개선 및 불필요한 타입 테스트 제거 * ci: CI 설정에서 빌드 단계 제거 및 테스트 실행 단계 추가 * refactor: 엔티티 비즈니스 로직을 별도 파일로 분리 - Posts 엔티티 로직 분리 및 테스트 개선 - parsePostData, sortPostsByDate, filterPostsByTag, filterMdxFiles 함수 추출 - 외부 의존성 없는 순수 함수로 분리하여 테스트 용이성 향상 - PostGrayMatter 타입 정의 개선 - Tags 엔티티 로직 분리 및 테스트 완성 - extractTagsFromPosts, createTagGraph, analyzeTagRelationships 등 모든 로직 분리 - 100% 테스트 커버리지 달성 (22개 테스트 케이스) - undefined tags 처리, 강한/약한 관계 임계값 등 edge case 테스트 추가 - 통합 테스트 파일 제거 - 기존 entities.integration.test.ts 제거 - 각 엔티티별 독립적인 단위 테스트로 전환 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * remove: 통합 테스트 파일 제거 - entities.integration.test.ts 삭제 - 각 엔티티별 독립적인 단위 테스트로 대체됨 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent f5ad3b1 commit 7d41935

File tree

20 files changed

+2891
-57
lines changed

20 files changed

+2891
-57
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,5 @@ jobs:
3232
- name: Type check
3333
run: pnpm tsc --noEmit
3434

35-
- name: Build
36-
run: pnpm build
37-
38-
- name: Upload build artifacts
39-
uses: actions/upload-artifact@v4
40-
with:
41-
name: build-output
42-
path: out/
43-
retention-days: 1
35+
- name: Run tests
36+
run: pnpm test:run

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"biome.requireConfiguration": true,
33
"editor.codeActionsOnSave": {
44
"source.fixAll.biome": "explicit",
5-
"source.organizeImports.biome": "explicit"
5+
"source.fixAll.eslint": "never"
66
},
77
"editor.defaultFormatter": "biomejs.biome",
88
"editor.formatOnSave": true,

CLAUDE.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
1616
This project uses Biome for formatting and linting. Always run `pnpm biome:check` before committing changes. The project has a pre-commit hook (lefthook) that automatically runs Biome on staged files.
1717

1818
**IMPORTANT**:
19-
- Do NOT run `pnpm build` during development tasks unless specifically requested by the user. The build process is mainly for final deployment verification.
19+
- Do NOT run `pnpm dev` or `pnpm build` during development tasks unless specifically requested by the user. The build process is mainly for final deployment verification.
2020
- When implementing new pages or components, use placeholders instead of actual content. Show what type of content should go in each position rather than writing fake content.
2121
- Do NOT create UI structures arbitrarily. Always ask the user for specific requirements and approval before implementing any UI design or structure.
2222

@@ -163,7 +163,7 @@ All client-side code is organized under `src/app/` following Next.js App Router
163163
- `page.tsx` - Home page
164164
- `not-found.tsx` - 404 error page
165165
- `globals.css` - Global styles
166-
- `src/api/` - Server-side utilities (outside app directory)
166+
- `src/entities/` - Domain entities and business logic (outside app directory)
167167
- `src/contents/` - MDX blog posts (*.mdx files)
168168

169169
**Naming Convention:**
@@ -173,12 +173,26 @@ All client-side code is organized under `src/app/` following Next.js App Router
173173
- Page/Feature scope: `src/app/[route]/_components/`, `src/app/[route]/_hooks/`
174174
- This ensures components and logic are co-located with their usage while maintaining clear boundaries
175175

176+
### Domain Architecture
177+
178+
This project follows Domain-Driven Design principles with entities organized in `src/entities/`:
179+
180+
- `src/entities/posts/` - Blog post domain logic
181+
- Repository pattern for data access
182+
- Post entity with type definitions
183+
- Business logic for post operations
184+
- `src/entities/tags/` - Tag system domain logic
185+
- Tag entity and graph relationships
186+
- Tag operations and queries
187+
- Graph-based tag analysis
188+
176189
### Content Management
177190

178-
Blog posts are stored as MDX files in `src/contents/`. The `src/api/posts.ts` module handles:
179-
- Reading MDX files from the contents directory
180-
- Parsing frontmatter with gray-matter
181-
- Generating static routes for blog posts
191+
Blog posts are stored as MDX files in `src/contents/`. Each MDX file contains:
192+
- **Frontmatter**: YAML metadata with `title`, `date`, `slug`, and `tags` information
193+
- **Content**: Markdown content with JSX component support
194+
195+
The post entity in `src/entities/posts/` handles parsing and processing of these MDX files.
182196

183197
### Static Generation
184198

next.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import createMDX from '@next/mdx'
22
import type { NextConfig } from 'next'
33
import rehypePrettyCode, { type Options } from 'rehype-pretty-code'
4+
import remarkFrontmatter from 'remark-frontmatter'
5+
import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
46

57
const nextConfig: NextConfig = {
68
pageExtensions: [
@@ -17,6 +19,10 @@ const nextConfig: NextConfig = {
1719
const withMDX = createMDX({
1820
extension: /\.(mdx)$/,
1921
options: {
22+
remarkPlugins: [
23+
remarkFrontmatter,
24+
remarkMdxFrontmatter,
25+
],
2026
rehypePlugins: [
2127
[
2228
rehypePrettyCode,

package.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
"dev": "next dev",
77
"build": "next build",
88
"start": "next start",
9+
"test": "vitest",
10+
"test:ui": "vitest --ui",
11+
"test:run": "vitest run",
12+
"test:coverage": "vitest run --coverage",
913
"biome:check": "biome check --verbose",
1014
"biome:fix": "biome check --write --verbose",
1115
"biome:staged": "biome check --write --staged"
@@ -19,12 +23,16 @@
1923
"@types/mdx": "^2.0.13",
2024
"class-variance-authority": "^0.7.1",
2125
"clsx": "^2.1.1",
26+
"graphology": "^0.26.0",
27+
"graphology-types": "^0.24.8",
2228
"gray-matter": "^4.0.3",
2329
"lucide-react": "^0.525.0",
2430
"next": "15.3.5",
2531
"react": "^19.1.0",
2632
"react-dom": "^19.1.0",
2733
"rehype-pretty-code": "^0.14.1",
34+
"remark-frontmatter": "^5.0.0",
35+
"remark-mdx-frontmatter": "^5.2.0",
2836
"tailwind-merge": "^3.3.1"
2937
},
3038
"devDependencies": {
@@ -34,10 +42,13 @@
3442
"@types/node": "^20.19.7",
3543
"@types/react": "^19.1.8",
3644
"@types/react-dom": "^19.1.6",
45+
"@vitest/coverage-v8": "3.2.4",
46+
"@vitest/ui": "^3.2.4",
3747
"lefthook": "^1.12.2",
3848
"tailwindcss": "^4.1.11",
3949
"tw-animate-css": "^1.3.5",
40-
"typescript": "^5.8.3"
50+
"typescript": "^5.8.3",
51+
"vitest": "^3.2.4"
4152
},
4253
"packageManager": "[email protected]+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad"
4354
}

0 commit comments

Comments
 (0)