Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,5 @@ jobs:
- name: Type check
run: pnpm tsc --noEmit

- name: Build
run: pnpm build

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-output
path: out/
retention-days: 1
- name: Run tests
run: pnpm test:run
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"biome.requireConfiguration": true,
"editor.codeActionsOnSave": {
"source.fixAll.biome": "explicit",
"source.organizeImports.biome": "explicit"
"source.fixAll.eslint": "never"
},
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
Expand Down
26 changes: 20 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
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.

**IMPORTANT**:
- Do NOT run `pnpm build` during development tasks unless specifically requested by the user. The build process is mainly for final deployment verification.
- 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.
- 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.
- Do NOT create UI structures arbitrarily. Always ask the user for specific requirements and approval before implementing any UI design or structure.

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

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

### Domain Architecture

This project follows Domain-Driven Design principles with entities organized in `src/entities/`:

- `src/entities/posts/` - Blog post domain logic
- Repository pattern for data access
- Post entity with type definitions
- Business logic for post operations
- `src/entities/tags/` - Tag system domain logic
- Tag entity and graph relationships
- Tag operations and queries
- Graph-based tag analysis

### Content Management

Blog posts are stored as MDX files in `src/contents/`. The `src/api/posts.ts` module handles:
- Reading MDX files from the contents directory
- Parsing frontmatter with gray-matter
- Generating static routes for blog posts
Blog posts are stored as MDX files in `src/contents/`. Each MDX file contains:
- **Frontmatter**: YAML metadata with `title`, `date`, `slug`, and `tags` information
- **Content**: Markdown content with JSX component support

The post entity in `src/entities/posts/` handles parsing and processing of these MDX files.

### Static Generation

Expand Down
6 changes: 6 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import createMDX from '@next/mdx'
import type { NextConfig } from 'next'
import rehypePrettyCode, { type Options } from 'rehype-pretty-code'
import remarkFrontmatter from 'remark-frontmatter'
import remarkMdxFrontmatter from 'remark-mdx-frontmatter'

const nextConfig: NextConfig = {
pageExtensions: [
Expand All @@ -17,6 +19,10 @@ const nextConfig: NextConfig = {
const withMDX = createMDX({
extension: /\.(mdx)$/,
options: {
remarkPlugins: [
remarkFrontmatter,
remarkMdxFrontmatter,
],
rehypePlugins: [
[
rehypePrettyCode,
Expand Down
13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "vitest",
"test:ui": "vitest --ui",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage",
"biome:check": "biome check --verbose",
"biome:fix": "biome check --write --verbose",
"biome:staged": "biome check --write --staged"
Expand All @@ -19,12 +23,16 @@
"@types/mdx": "^2.0.13",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"graphology": "^0.26.0",
"graphology-types": "^0.24.8",
"gray-matter": "^4.0.3",
"lucide-react": "^0.525.0",
"next": "15.3.5",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"rehype-pretty-code": "^0.14.1",
"remark-frontmatter": "^5.0.0",
"remark-mdx-frontmatter": "^5.2.0",
"tailwind-merge": "^3.3.1"
},
"devDependencies": {
Expand All @@ -34,10 +42,13 @@
"@types/node": "^20.19.7",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@vitest/coverage-v8": "3.2.4",
"@vitest/ui": "^3.2.4",
"lefthook": "^1.12.2",
"tailwindcss": "^4.1.11",
"tw-animate-css": "^1.3.5",
"typescript": "^5.8.3"
"typescript": "^5.8.3",
"vitest": "^3.2.4"
},
"packageManager": "[email protected]+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad"
}
Loading