This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Weeth Server is a community platform backend built with Spring Boot 3.5.10. The codebase has completed Java → Kotlin migration — all code is Kotlin.
./gradlew clean build # Full build
./gradlew test # Run all tests
./gradlew test --tests "*UseCaseTest" # Run tests by pattern
./gradlew test --tests "CreateUserUseCaseTest" # Run specific test class
./gradlew ktlintFormat # Auto-format with ktlint
./gradlew ktlintCheck # Check formatting only
./gradlew bootRun # Run locally (default profile)
./gradlew bootRun --args='--spring.profiles.active=dev' # Run with specific profilePrerequisites: JDK 21, MySQL 8.0, Redis 7.0+, environment variables configured in .env
Profiles: local (default dev), local-monitoring (local + monitoring stack), dev (dev server, ddl-auto: update), prod (Swagger disabled, ddl-auto: validate)
presentation → application → domain ← infrastructure
- presentation/: Controllers, ResponseCode enums
- application/: UseCase (command/query), DTOs, Mappers, Exceptions, Validators
- domain/: Entities (Rich Domain Model), VO, Enums, Repositories, Ports, Domain Services
- infrastructure/: Port implementations (Adapters for S3, external APIs, etc.)
Each of the 13 domains (user, attendance, session, schedule, board, comment, file, penalty, account, cardinal, club, dashboard, university) follows:
domain/{name}/
├── application/
│ ├── dto/request/, dto/response/
│ ├── mapper/
│ ├── usecase/command/ # @Transactional, state-changing
│ ├── usecase/query/ # @Transactional(readOnly=true), returns DTOs
│ └── exception/ # {Domain}ErrorCode enum + exception classes
├── domain/
│ ├── entity/ # JPA entities with business logic
│ ├── enums/
│ ├── repository/ # JpaRepository + Reader interfaces
│ ├── port/ # Interfaces for external systems
│ └── service/ # Multi-entity logic only (no thin wrappers)
├── infrastructure/ # Port implementations
└── presentation/
├── {Domain}Controller.kt
└── {Domain}ResponseCode.kt
- UseCase = orchestration only — business logic lives in Entities (Rich Domain Model)
- No thin wrapper services — UseCases call Repositories directly, no GetService/SaveService
- Port-Adapter — domain owns Port interfaces, infrastructure implements them
- Cross-domain reads via Reader interfaces; cross-domain writes via Repository directly
@Transactionalon UseCase only — Domain Services have no transaction annotations
All API responses wrapped in CommonResponse<T> with code/message/data. 5-digit code format XDDNN: X=category (1=Success, 2=Domain Error, 3=Infra Error, 4=Client Error), DD=domain ID, NN=sequence. See .claude/rules/api-design.md for full domain ID mapping and code ranges.
JWT with symmetric key (JJWT 0.13.0), OAuth2 via Kakao and Apple. @CurrentUser annotation injects authenticated user ID into controller methods.
- Kotest (DescribeSpec default, BehaviorSpec for BDD, StringSpec for simple logic)
- MockK + springmockk for mocking
- Testcontainers for MySQL integration tests
- Fixture pattern:
{Entity}TestFixtureobjects with factory methods infixture/directories - Test architecture mirrors source: mock Repository/Reader/Port in UseCase tests, mock Port (not adapter) in application tests
✅ Complete — 452 Kotlin files (100%)
- Java → Kotlin migration fully complete
- Lombok and MapStruct dependencies removed
- All 16 mappers migrated to manual
@ComponentMapper classes (see.claude/rules/mapper-dto.md) - Entity fields use
private setfor Rich Domain Model pattern (see architecture.md) - OSIV disabled:
spring.jpa.open-in-view: falseinapplication.yml
- Use
?.,?:,requireNotNull— avoid!! - Entities: regular
class(notdata class); DTOs:data class - Entity setters:
private setto enforce business logic via named methods - Example:
var name: String private set fun updateName(newName: String) { require(newName.isNotBlank()) { "Name cannot be empty" } this.name = newName }
Architecture, code style, testing, API design, exception handling, transactions, and git conventions are documented in .claude/rules/. Refer to those files for comprehensive guidance on each topic.