Skip to content

Latest commit

 

History

History
110 lines (84 loc) · 3.76 KB

File metadata and controls

110 lines (84 loc) · 3.76 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

GoodGame is a happiness diary service ("행복 저금통") backend that allows users to record happy moments and receive AI-powered activity recommendations using Gemini 2.5 Flash-Lite. Built with Java 21 and Spring Boot 3.4.

Build & Run Commands

# Start MySQL container
docker compose up -d

# Run Spring Boot
./gradlew bootRun

# Build with tests
./gradlew build

# Build without tests
./gradlew build -x test

# Run tests
./gradlew test

# Swagger UI: http://localhost:8080/api/swagger-ui.html

Architecture

Package Structure

src/main/java/com/umc/goodgame/
├── domain/                    # Domain modules (DDD-style)
│   ├── auth/                  # Google OAuth authentication
│   │   ├── controller/
│   │   ├── service/
│   │   └── dto/
│   ├── user/                  # User management
│   ├── memory/                # Happy memories (diary entries)
│   ├── condition/             # User conditions
│   └── recommendation/        # AI recommendations
└── global/                    # Cross-cutting concerns
    ├── config/                # SecurityConfig, SwaggerConfig, QueryDslConfig
    ├── entity/                # BaseEntity, BaseTimeEntity
    ├── exception/             # CustomException, GlobalExceptionHandler
    ├── response/              # ApiResponse, ErrorCode, SuccessCode
    └── security/jwt/          # JWT token handling

Key Patterns

API Response: All endpoints return ApiResponse<T> wrapper with standardized structure:

ApiResponse.success(SuccessCode.OK, data);
ApiResponse.error(ErrorCode.NOT_FOUND);

Exception Handling: Throw CustomException with ErrorCode:

throw new CustomException(ErrorCode.USER_NOT_FOUND);

DTOs: Use Java records for Request/Response DTOs with nested static classes:

public class MemberResponse {
    public record Detail(Long id, String name) {
        public static Detail from(Member m) { ... }
    }
}

Entity Conventions:

  • Extend BaseEntity or BaseTimeEntity for audit fields
  • Use @Builder only on private constructors
  • @ManyToOne(fetch = FetchType.LAZY) is mandatory
  • @Enumerated(EnumType.STRING) is mandatory

Database Schema (6 tables)

  • users - Google OAuth users
  • happy_memories - Diary entries (max 1000 chars)
  • happy_memories_images - Memory images (max 4 per memory)
  • user_conditions - User mood/energy tracking
  • default_recommendations - Default suggestions for new users
  • user_recommendations - AI-generated personalized recommendations

Code Style Requirements

  • record DTO: Use records for all Request/Response DTOs
  • Lombok: Only in Entity (@Getter, @NoArgsConstructor(PROTECTED)) and Service/Controller (@RequiredArgsConstructor)
  • Validation: Format validation in DTO (@NotBlank, @Size), business validation in Service
  • Transactions: @Transactional(readOnly = true) on class level, @Transactional only on write methods
  • Logging: log.info("[ClassName.methodName] param: {}", value)

Prohibited:

  • @Setter, @Data, @AllArgsConstructor
  • @ManyToOne without fetch = LAZY
  • @Enumerated without EnumType.STRING
  • Class-level @Builder

Git Conventions

Branch: <type>/<description>-#<issue_number> (e.g., feat/signup-api-#14)

Commit: <type>: <subject> (#<issue_number>) (e.g., feat: 회원가입 API 구현 (#14))

Types: feat, fix, docs, refactor, test, chore, rename, remove

Workflow: develop branch for integration, feat/* branches merge to develop, develop merges to main for deployment.