-
Notifications
You must be signed in to change notification settings - Fork 5
๐ฆ chore: ์๋น์ค๋ณ AI instruction ๋ฌธ์ ์ถ๊ฐ ๋ฐ ๋ฃจํธ CLAUDE.md ์ ๋ฆฌ #528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Jo-Minseok
merged 10 commits into
boostcampwm-2024:main
from
Jo-Minseok:feat/ai-instruction
Feb 11, 2026
+882
โ95
Merged
Changes from 6 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
37d1a6f
โจ feat: email worker instructions add
Jo-Minseok c39fac8
โจ feat: feed-crawler instructions add
Jo-Minseok 625bd78
โจ feat: server instructions add
Jo-Minseok 459e99e
โจ feat: client instructions add
Jo-Minseok c3e2e14
โจ feat: main instructions add
Jo-Minseok 1c6741d
๐ฆ chore: given when then ํจํด ์ฃผ์
Jo-Minseok 92eed37
๐ fix: aAA Pattern -\> GWT Pattern
Jo-Minseok 6e4e59e
๐งผ clean: cLAUDE.md ์ผ๊ด์ฑ ํต์ผ ๋ฐ ๊ณตํต ์ญํ ์ ์์๋ก ์ด๋
Jo-Minseok 4fe40f0
๐งผ clean: test ai instructions ์ผ๊ด์ฑ ํต์ผ
Jo-Minseok daf88ad
โจ feat: data topology add
Jo-Minseok File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,121 +1,67 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Project Overview | ||
| # Project Overview | ||
|
|
||
| **Denamu (๋ฐ๋๋ฌด)** is an RSS-based tech blog curation platform. It aggregates developer blog content from multiple platforms (Tistory, Velog, Medium) into a single service with real-time trending, search, and developer chat features. | ||
|
|
||
| - **Production URL**: https://denamu.dev | ||
| - **Architecture**: Monorepo with microservices (Docker Compose orchestration) | ||
|
|
||
| ## Repository Structure | ||
| # Repository Structure | ||
|
|
||
| ``` | ||
| server/ # NestJS backend API (port 8080) | ||
| client/ # React + Vite frontend (port 5173) | ||
| server/ # NestJS backend API (Dev port 8080) | ||
| client/ # React + Vite frontend (Dev port 5173) | ||
| feed-crawler/ # RSS feed crawler with AI tagging | ||
| email-worker/ # Email processing via RabbitMQ | ||
| docker-compose/ # Infrastructure configs (local, dev, prod) | ||
| nginx/ # Reverse proxy configuration | ||
| ``` | ||
|
|
||
| ## Common Commands | ||
|
|
||
| ### Root Level | ||
| ```bash | ||
| npm run start:local # Start all services locally (no watch) | ||
| npm run start:dev # Start dev environment with hot reload | ||
| npm run start:was-dev # Start backend services only | ||
| npm run commit # Commitizen for structured commits | ||
| ``` | ||
|
|
||
| ### Server (NestJS) | ||
| ```bash | ||
| cd server | ||
| npm run start:dev # Development with watch mode | ||
| npm run build # Production build | ||
| npm run lint # ESLint | ||
| npm run test:unit # Unit tests | ||
| npm run test:e2e # E2E tests (uses Testcontainers) | ||
| npm run test:dto # DTO validation tests | ||
| npm run migration:create # Create DB migrations | ||
| ``` | ||
|
|
||
| ### Client (React) | ||
| ```bash | ||
| cd client | ||
| npm run dev # Development server | ||
| npm run build # Production build | ||
| npm run lint # ESLint | ||
| npm run test # Vitest unit tests | ||
| npm run test:coverage # Coverage report | ||
| ``` | ||
|
|
||
| ### Feed Crawler | ||
| ```bash | ||
| cd feed-crawler | ||
| npm run start:dev # Development mode | ||
| npm run test:unit # Unit tests | ||
| npm run test:e2e # Integration tests | ||
| ``` | ||
|
|
||
| ## Tech Stack | ||
|
|
||
| - **Backend**: NestJS, TypeORM, MySQL 8.0, Redis 7.2, RabbitMQ 3.13 | ||
| - **Frontend**: React 18, TypeScript, Vite, TanStack Query, Zustand, Tailwind CSS, Radix UI | ||
| - **Real-time**: Socket.IO (WebSocket chat) | ||
| - **AI**: Anthropic Claude SDK (automatic content tagging in feed-crawler) | ||
| - **Monitoring**: Prometheus, Grafana, Winston logging | ||
| - **Auth**: JWT + OAuth (Google, GitHub) via Passport.js | ||
|
|
||
| ## Architecture Notes | ||
| # Commands | ||
|
|
||
| ### Backend (Server) | ||
| - Module-based NestJS architecture: each feature has Module, Controller, Service | ||
| - TypeORM with MySQL for data persistence | ||
| - Redis for caching and session management | ||
| - Global exception filters and interceptors for consistent error handling | ||
| - Swagger API documentation available | ||
| npm run start:local # Start all services locally (no watch) | ||
| npm run start:dev # Start dev environment with hot reload | ||
| npm run start:dev:was # Start backend services only | ||
| npm run start:dev:feed # Start feed crawler services only | ||
| npm run start:dev:email # Start email worker services only | ||
| npm run commit # Commitizen for structured commits | ||
|
|
||
| ### Frontend (Client) | ||
| - TanStack Query for server state, Zustand for client state | ||
| - Custom hooks pattern for logic reuse | ||
| - Socket.IO client for real-time chat | ||
| # Commit Message | ||
|
|
||
| ### Feed Crawler | ||
| - tsyringe for dependency injection (not NestJS) | ||
| - Scheduled jobs via node-schedule for RSS polling | ||
| - Claude AI integration for automatic tag generation | ||
| - RabbitMQ for event publishing | ||
| Reference `.cz-config.js` | ||
|
|
||
| ### Email Worker | ||
| - RabbitMQ consumer for async email processing | ||
| - Nodemailer for email delivery | ||
|
|
||
| ## Code Review Convention | ||
| # Code Review Convention | ||
|
|
||
| Uses Pn-level system (Korean language reviews): | ||
|
|
||
| - **P1**: Critical - security issues, business logic errors (must fix before deploy) | ||
| - **P2**: Important - code quality/functionality issues (must fix) | ||
| - **P3**: Medium - potential bug risks, improvements (strongly consider) | ||
| - **P4**: Light - readability suggestions (optional) | ||
| - **P5**: Questions - optional suggestions | ||
|
|
||
| ## Environment Variables | ||
| # CI/CD | ||
|
|
||
| Key environment variable groups (see `.env.example` files): | ||
| - Database: `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME` | ||
| - Redis: `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD` | ||
| - RabbitMQ: `RABBITMQ_HOST`, `RABBITMQ_PORT`, `RABBITMQ_USER`, `RABBITMQ_PASSWORD` | ||
| - JWT: `JWT_ACCESS_SECRET`, `JWT_REFRESH_SECRET` | ||
| - OAuth: `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | ||
| GitHub Actions workflows deploy to self-hosted runner via GHCR: | ||
| `.github/workflows` | ||
|
|
||
| ## CI/CD | ||
| - Deploy Application | ||
| - `deploy_server.yml` - NestJS backend | ||
| - `deploy_client.yml` - React frontend | ||
| - `deploy_feed-crawler.yml` - Crawler service | ||
| - `deploy_email-worker.yml` - Email worker | ||
| - `deploy_nginx.yml` - NGINX Conf Apply | ||
| - Test workflows run on PR | ||
| - `test_server_dto.yml` | ||
| - `test_server_e2e.yml` | ||
| - `test_feed-crawler.yml` | ||
| - `test_email-worker.yml` | ||
|
|
||
| GitHub Actions workflows deploy to self-hosted runner via GHCR: | ||
| - `deploy_server.yml` - NestJS backend | ||
| - `deploy_client.yml` - React frontend | ||
| - `deploy_feed-crawler.yml` - Crawler service | ||
| - `deploy_email-worker.yml` - Email worker | ||
| - Test workflows run on PR: `test_server_dto.yml`, `test_server_e2e.yml`, `test_feed-crawler.yml` | ||
| # Docker Compose | ||
|
|
||
| All Docker Compose files are located in the `docker-compose/` directory. | ||
|
|
||
| Use the appropriate compose file based on the target environment (local, dev, prod). | ||
|
|
||
| - `local`: docker-compose.local.yml + docker-compose.infra.yml | ||
| - `dev`: docker-compose.dev.yml + docker-compose.infra.yml | ||
| - `prod`: docker-compose.prod.yml + docker-compose.prod.infra.yml | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # System Purpose | ||
|
|
||
| The client is the user-facing React SPA for Denamu. It consumes the server API and renders RSS-aggregated blog content with features including trending feeds, search, developer chat, and user authentication. | ||
|
|
||
| # Architecture | ||
|
|
||
| - **Framework**: React 18 + Vite (SWC) | ||
| - **Routing**: React Router v6 with code splitting (lazy + Suspense) | ||
| - **State**: Zustand v5 (global UI state), TanStack React Query v5 (server state + caching) | ||
| - **HTTP**: Axios with credentials | ||
| - **Real-time**: Socket.io-client (chat, trending) | ||
| - **UI**: Tailwind CSS + shadcn/ui (Radix UI) + Framer Motion | ||
| - **Testing**: Vitest + Testing Library | ||
|
|
||
| # Directory Structure | ||
|
|
||
| | Directory | Role | | ||
| | --- | --- | | ||
| | src/pages/ | Page-level components, one per route | | ||
| | src/routes/ | React Router route definitions | | ||
| | src/components/ | Feature components (auth, admin, chat, common, ui) | | ||
| | src/store/ | Zustand stores (auth, search, sidebar, chat, filter, etc.) | | ||
| | src/hooks/ | Custom hooks: auth/, queries/, common/ | | ||
| | src/api/services/ | Axios service layer per domain | | ||
| | src/api/mocks/ | MSW handlers for development | | ||
| | src/constants/ | API endpoint constants | | ||
| | src/types/ | TypeScript type definitions | | ||
| | src/providers/ | React context providers (TanStack Query) | | ||
| | src/components/ui/ | shadcn/ui base components | | ||
|
|
||
| # Routing | ||
|
|
||
| Background Location pattern is used: PostDetailPage renders as a modal overlay on the feed list, or as a full page on direct navigation. | ||
|
|
||
| Pages are lazy-loaded via React.lazy() for code splitting. | ||
|
|
||
| # State Management | ||
|
|
||
| | Store | Purpose | | ||
| | --- | --- | | ||
| | useAuthStore | User role (guest / user / admin), token state | | ||
| | useSearchStore | Search params, filter type, pagination | | ||
| | useSidebarStore | Sidebar visibility | | ||
| | useChatStore | WebSocket chat state | | ||
| | useRegisterModalStore | RSS registration modal | | ||
| | React Query | Server data fetching, caching, refetch | | ||
|
|
||
| # Build Configuration | ||
|
|
||
| Vite manual chunks split vendor libraries to optimize bundle size: radix-ui, charts (recharts), vendor (react core), animation (framer-motion), query, socket, utils. | ||
|
|
||
| Dev server uses `usePolling: true` for file system compatibility in Docker/WSL. | ||
|
|
||
| # Commands | ||
|
|
||
| npm run dev - Development server (port 5173) | ||
| npm run build - Production build (tsc + vite build) | ||
| npm run lint - ESLint | ||
| npm run test - Vitest | ||
| npm run test:coverage - Vitest with coverage report |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # System Purpose | ||
|
|
||
| The Email Worker exists to offload SMTP delivery from the API path and eliminate latency caused by synchronous email transmission. | ||
|
|
||
| Email sending MUST be processed asynchronously to: | ||
|
|
||
| - protect API response times | ||
| - isolate failures | ||
| - improve observability | ||
| - reduce operational coupling with the application server | ||
|
|
||
| Embedding SMTP logic inside the server is forbidden due to poor failure visibility and debugging complexity. | ||
|
|
||
| # Architectural Role | ||
|
|
||
| The Email Worker is a **message-driven infrastructure component** responsible for reliable email dispatch. | ||
|
|
||
| Design goals: | ||
|
|
||
| - failure containment | ||
| - retry-safe processing | ||
| - deterministic logging | ||
| - operational clarity | ||
|
|
||
| The API MUST never send emails directly. | ||
|
|
||
| # Processing Workflow | ||
|
|
||
| 1. Listen to RabbitMQ queues continuously. | ||
| 2. Upon message receipt, validate payload integrity. | ||
| 3. Attempt email delivery via the configured SMTP relay. | ||
| 4. If delivery fails: | ||
| - emit structured error logs (Winston) | ||
| - route the message to a RabbitMQ Dead Letter Queue (DLQ) | ||
|
|
||
| # Environment & Stack | ||
|
|
||
| Stack: Node.js 22, RabbitMQ, Winston. | ||
| Infra: Docker, AWS EC2. | ||
|
|
||
| # Reference Docs | ||
|
|
||
| | File | Authority | | ||
| | ---------------------------------- | ---------------- | | ||
| | agent_docs/service_architecture.md | Service patterns | | ||
| | agent_docs/test_design.md | Test contracts | | ||
|
|
||
| # Commands | ||
|
|
||
| npm run build - Production build | ||
| npm run start - Production start | ||
| npm run start:dev - Development start |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| ## Component Diagram | ||
|
|
||
| ```mermaid | ||
| graph LR | ||
| subgraph RabbitMQ | ||
| SendQ["email.send.queue"] | ||
| Wait5["email.send.wait.5s"] | ||
| Wait10["email.send.wait.10s"] | ||
| Wait20["email.send.wait.20s"] | ||
| DLQ["email.deadLetter.queue"] | ||
| end | ||
|
|
||
| subgraph EmailWorker | ||
| RMQMgr["RabbitMQManager\nConnection"] | ||
| RMQSvc["RabbitMQService\nChannel Ops"] | ||
| Consumer["EmailConsumer\nDispatch & Error"] | ||
| EmailSvc["EmailService\nSMTP Send"] | ||
| Content["email.content\nTemplates"] | ||
| end | ||
|
|
||
| SMTP["SMTP Server"] | ||
|
|
||
| SendQ -->|consume| RMQSvc | ||
| RMQSvc -->|onMessage| Consumer | ||
| Consumer -->|dispatch by type| EmailSvc | ||
| EmailSvc --> Content | ||
| EmailSvc -->|send| SMTP | ||
|
|
||
| Consumer -->|transient, retry=0| Wait5 | ||
| Consumer -->|transient, retry=1| Wait10 | ||
| Consumer -->|transient, retry=2| Wait20 | ||
| Consumer -->|permanent or retry>=3| DLQ | ||
|
|
||
| Wait5 -->|TTL expire| SendQ | ||
| Wait10 -->|TTL expire| SendQ | ||
| Wait20 -->|TTL expire| SendQ | ||
|
|
||
| RMQMgr --> RMQSvc | ||
| ``` | ||
|
|
||
| ## Module Responsibilities | ||
|
|
||
| | Module | Responsibility | | ||
| | --------------- | ---------------------------------------------------------------------------------------------------------- | | ||
| | EmailConsumer | Consume queue messages, dispatch by type, classify errors, retry or route to DLQ, handle graceful shutdown | | ||
| | EmailService | Send emails via Nodemailer/SMTP, provide methods per email type | | ||
| | email.content | Generate HTML templates for each email type | | ||
| | RabbitMQService | Publish/consume messages via AMQP channels, handle ack/nack | | ||
| | RabbitMQManager | Manage AMQP connections and channel creation | | ||
|
|
||
| ## Email Types | ||
|
|
||
| | Type | Trigger | Description | | ||
| | ------------------ | ---------------------- | ---------------------------------------- | | ||
| | USER_CERTIFICATION | User registration | Send email verification code | | ||
| | RSS_REGISTRATION | RSS approval/rejection | Send approval result or rejection reason | | ||
| | RSS_REMOVAL | RSS removal request | Send deletion confirmation code | | ||
| | PASSWORD_RESET | Password reset | Send reset code | | ||
| | ACCOUNT_DELETION | Account deletion | Send deletion confirmation code | | ||
|
|
||
| ## Queue Topology | ||
|
|
||
| ```mermaid | ||
| graph LR | ||
| EmailExchange["EmailExchange\n(Direct)"] | ||
| EmailExchange -->|"email.send"| SendQ["email.send.queue"] | ||
|
|
||
| SendQ -->|fail, retry < 3| WaitQueues | ||
| subgraph WaitQueues | ||
| W5["email.send.wait.5s\nTTL: 5000ms"] | ||
| W10["email.send.wait.10s\nTTL: 10000ms"] | ||
| W20["email.send.wait.20s\nTTL: 20000ms"] | ||
| end | ||
|
|
||
| WaitQueues -->|"TTL expires โ x-dead-letter-exchange"| SendQ | ||
| SendQ -->|permanent or retry >= 3| DLQ["email.deadLetter.queue"] | ||
| ``` | ||
|
|
||
| ## Error Classification | ||
|
|
||
| | Category | Errors | Action | | ||
| | -------------------- | ------------------------------------------------------ | ---------------------------- | | ||
| | Transient (Network) | ECONNREFUSED, ETIMEDOUT, ESOCKETNOTFOUND, Socket close | Retry via Wait Queue (max 3) | | ||
| | Transient (SMTP 4xx) | 421, 450, 451, 452 | Retry via Wait Queue (max 3) | | ||
| | Permanent (SMTP 5xx) | 550, 552, 553, 554 | Immediate DLQ | | ||
| | Unknown | Unclassified | Immediate DLQ | | ||
| | Max Retry | retryCount >= 3 | DLQ (MAX_RETRIES_EXCEEDED) | | ||
|
|
||
| ## DLQ Header Schema | ||
|
|
||
| All DLQ messages include debugging headers: | ||
|
|
||
| | Header | Description | | ||
| | --------------- | ------------------------------------------------------------- | | ||
| | x-retry-count | Number of retries | | ||
| | x-error-code | SMTP / Node error code | | ||
| | x-error-message | Error message | | ||
| | x-failed-at | Failure timestamp (ISO 8601) | | ||
| | x-failure-type | SMTP_PERMANENT_FAILURE / MAX_RETRIES_EXCEEDED / UNKNOWN_ERROR | | ||
| | x-response-code | SMTP response code (optional) | | ||
| | x-error-stack | Stack trace (optional) | | ||
|
|
||
| ## Graceful Shutdown | ||
|
|
||
| 1. Receive SIGINT/SIGTERM | ||
| 2. `stopConsuming()` โ Stop receiving new messages | ||
| 3. `waitForPendingTasks()` โ Wait for in-progress tasks to complete | ||
| 4. `close()` โ Clean up consumers and connections |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.