# CLAUDE.md

## Project Overview

DPOT - Clean Architecture 기반 Creators Support and donate platform (.NET 10.0)

- **Framework**: .NET 10.0, ASP.NET Core
- **CQRS**: MediatR 14.0
- **ORM**: Entity Framework Core 10.0 (SQL Server)
- **Cache**: StackExchange.Redis 10.0
- **Logging**: Serilog 10.0

## Solution Structure

```
Admin/           → Razor Pages 관리자 패널 (https://localhost:5000)
Web.Api/         → RESTful Minimal API (https://localhost:4000)
Application/     → CQRS Handler (MediatR)
  └── Features/
      ├── Api/   → Auth, Banner, Channel, Crew, Document, Donation, DonationAlert, DonationRemote, Faq, Forum, Member, MyPage, Note, Notification, Payment, Popup
      └── Admin/ → Banner, Cache, Channel, Document, Faq, Forum, Member, MemberGrade, Popup, ReferenceData
Domain/          → Entity, ValueObject
  └── Entities/
      ├── Common/         → Config, Document, etc.
      ├── Members/        → Member, Channel, RefreshToken, MemberOAuthToken
      ├── Wallets/        → Wallet, WalletBalance, WalletTransaction
      ├── Donations/      → Donation, DonationAlert, DonationMeta, Settlement, Crew, CrewSession
      ├── Notes/          → Note (쪽지)
      ├── Notifications/  → Notification (알림)
      ├── Payments/       → PaymentOrder, PaymentConfirm, PaymentCancel, PaymentLog
      └── Forum/          → Board, Post, Comment
Infrastructure/  → DB, Auth, Storage, Email
  ├── Authentication/ → JWT, Identity, GoogleOAuth
  ├── Cache/          → Redis
  ├── Hubs/           → AppHub (전역 실시간), DonationHub (후원 위젯/리모콘)
  ├── Notification/   → NotificationService (쪽지/알림 발송)
  ├── YouTube/        → YouTubeApiService, PubSub, LiveChat, ChannelCache
  ├── Payment/        → DanalPayService (PG 결제)
  ├── Forum/          → 게시판 비즈니스 로직
  ├── Messaging/      → Email (SMTP, MimeKit)
  ├── Persistence/    → AppDbContext, IdentityDbContext, Migrations
  ├── Storage/        → 파일 업로드
  └── Extensions/     → 확장 메서드
SharedKernel/    → AppSettings, Result Pattern
Database/        → SQL 배포 스크립트 (deploy-app.sql, deploy-identity.sql, deploy-missing.sql)
```

## API Endpoints (Web.Api/Endpoints/)

Auth, Banner, Channel, Config, Document, Donation, Faq, Forum, MyPage, Note, Notification, Payment, Popup, Wallet

## Code Style Rules

- PK/ID 변수명: `memberID`, `userID` (camelCase + 대문자 ID)
- if 문은 반드시 `{}` 사용
- Tuple 속성은 각 필드를 별도 줄에 작성
- 외부 라이브러리 대신 순수 C# 우선 (FluentValidation 등 사용 안 함)
- 배열 패턴 사용 (체이닝 `||` 대신)
- Handler에서 직접 유효성 검사 (Data Annotation 사용 안 함)
- 파일 내용의 마지막 줄 제거
- EF Core 문은 항상 한 줄로 작성(단, 객체나 data 사용 시 여러 줄로 표시)

## Architecture Rules
- Domain layer has ZERO external dependencies
- Application layer defines interfaces, Infrastructure implements them
- All database access goes through EF Core DbContext (no repository pattern)
- Use Mediator for all command/query handling
- API layer is thin — endpoint definitions only

## Code Conventions

### Patterns We Use
- Primary constructors for DI
- Records for DTOs and commands
- Result<T> pattern for error handling (no exceptions for flow control)
- File-scoped namespaces
- Always pass CancellationToken to async methods (단, StackExchange.Redis 등 CancellationToken을 지원하지 않는 라이브러리는 예외)

### Patterns We DON'T Use (Never Suggest)
- Repository pattern (use EF Core directly)
- AutoMapper (write explicit mappings)
- Exceptions for business logic errors
- Stored procedures

## Architecture

- CQRS: MediatR (Command/Query → Handler)
- Auth: API는 Member 엔티티 + PBKDF2 해싱, Admin은 ASP.NET Identity
- DB: SQL Server (AppDbContext + IdentityDbContext)
- Cache: Redis (StackExchange.Redis)
- Real-time: SignalR WebSocket
  - AppHub (`/hubs/app`) — 전역 (접속자 추적, 알림, 쪽지, 채팅, 크루 초대/동의)
  - DonationHub (`/hubs/donation`) — 후원 위젯/리모콘 (OBS용, channelSID 기반)
- YouTube: YouTubeApiService, PubSubHubbub, LiveChatService (폴링)
- Payment: 다날(DanalPay) PG 결제 연동
- DI: 각 레이어별 DependencyInjection.cs
  - `AddApplication()` → MediatR 전체 Handler 등록
  - `AddApiInfrastructure()` → API 전용 (JWT Bearer + 모든 서비스)
  - `AddAdminInfrastructure()` → Admin 전용 (Identity + 모든 서비스)
  - `AddPresentation()` → Swagger, ExceptionHandler

## Build & Run

```bash
# Solution build
dotnet build Admin/Admin.slnx

# API 실행
dotnet run --project Web.Api

# Admin 실행
dotnet run --project Admin

# Migration
dotnet ef migrations add <Name> --project Infrastructure --startup-project Admin --context AppDbContext
dotnet ef database update --project Infrastructure --startup-project Admin --context AppDbContext
```

## Key Patterns

- Result Pattern: `Result<T>` / `Error` (SharedKernel/Results/)
- ErrorType: Validation(400), Problem(400), Unauthorized(401), NotFound(404), Forbidden(403), Conflict(409), MethodNotAllowed(405)
- Endpoint: `IEndpoint` 인터페이스 → `MapEndpoint()` 구현
- Feature 구조: `Application/Features/{Domain}/{Action}/Command.cs, Handler.cs, Response.cs`

## 사용 Domain
- https://dpot.web.or.kr -> 사용자 단 사용 URL
- https://admin.dpot.web.or.kr  -> 관리자 단 사용 URL
- https://api.dpot.web.or.kr -> 사용자 단 통신 API URL

## Code Style Rules (추가)

- C# 람다 `) => {` 한 줄에 붙여 작성 (개행 금지)
- button 태그에 submit type이 아니면 `type="button"` 필수
- Endpoint 파일 = 1 class = 1 액션 (예: `Send.cs`, `History.cs`)
- inline CSS 사용 금지 → SCSS 또는 Tailwind 사용
- BEM 네이밍: `block__element--modifier`

## 용어 규칙

- **POINT (포인트)**: 후원 가능한 금액 (PG 충전 → PgCharged 잔액)
- **머니 (Money)**: 후원 받은 금액 (Donation 잔액 → 출금 가능)

## Payment Gateway (다날 PG)

- SDK: `@danalpay/javascript-sdk` (Frontend)
- Server: `Infrastructure/Payment/DanalPayService.cs`
- 테이블: PaymentOrder → PaymentConfirm → PaymentCancel, PaymentLog
- 결제수단: Card, VirtualAccount, Mobile, Transfer, NaverPay, KakaoPay, Payco
- Config: DB Config.Payment에 CPID, ClientKey, SecretKey 저장 (암호화)