# 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 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 --project Infrastructure --startup-project Admin --context AppDbContext dotnet ef database update --project Infrastructure --startup-project Admin --context AppDbContext ``` ## Key Patterns - Result Pattern: `Result` / `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 저장 (암호화)