Skip to content

[Feat/replace enum with type entity] - Enum 을 Type Entity로 교체#67

Merged
ekgns33 merged 12 commits intomainfrom
feat/replace-enum-with-TypeEntity
Apr 26, 2025
Merged

[Feat/replace enum with type entity] - Enum 을 Type Entity로 교체#67
ekgns33 merged 12 commits intomainfrom
feat/replace-enum-with-TypeEntity

Conversation

@ekgns33
Copy link
Contributor

@ekgns33 ekgns33 commented Apr 23, 2025

작업내역

Enum to Enitity

  • Enum으로 정의되어 있던 알 종류 데이터를 Entity로 변경했습니다.
  • EggTypeEgg, RunimoDefinition 에 1:N 대응됩니다.
    • @ManyToOne사용, FK 미적용

기존 로직에서 Enum 제거

  • Enum이 활용되는 패키지는 다음과 같았습니다.

  • hatch, item, reward runimo

해당 패키지에서 Enum을 사용하던 부분을 EggType 또는 EggType의 PK를 사용하도록 변경했습니다.

러니모 그룹 리스트 반환 로직 수정

  • 기존 dto 클래스의 매핑로직을 서비스 코드로 이전했습니다. (임시)
  • 클라이언트의 요구사항에 따라 각 그룹마다 해금하기 위한 달리기 거리를 함께 반환하도록 했습니다.

보상 응답 필드 추가

  • 보상을 받지 못한경우에 이를 나타내는 isRewarded 필드를 추가했습니다.

주의깊게 볼점

  • 매핑 로직 변경점
  • EggType으로 변경한점
  • 아직 RunimoType은 미변경

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added a new egg type management system using a dedicated entity and database table for more flexible and scalable handling of egg types.
    • Grouped runimo types by egg type in the runimo type list response, including required distance information.
  • Improvements

    • Updated reward responses to explicitly indicate whether an egg was rewarded and to use egg type names instead of enums.
    • Enhanced test coverage and updated test data to reflect the new egg type structure.
  • Bug Fixes

    • Fixed inconsistencies in query parameter naming and repository method signatures.
  • Refactor

    • Replaced enum-based egg type logic with entity-based and database-driven approaches throughout the application.
    • Simplified and clarified data models and DTOs for runimo and egg types.
    • Shifted runimo selection logic to use database queries instead of in-memory enums.
  • Database

    • Introduced a new egg_type table and updated related tables and test data to use foreign key relationships.
    • Updated SQL scripts to reflect schema and data changes.

@ekgns33 ekgns33 added enhancement New feature or request 🔨 refactor 🔨 labels Apr 23, 2025
@ekgns33 ekgns33 requested a review from jeeheaG April 23, 2025 13:16
@ekgns33 ekgns33 self-assigned this Apr 23, 2025
@coderabbitai
Copy link

coderabbitai bot commented Apr 23, 2025

"""

Walkthrough

This change refactors the handling of egg types and their associations throughout the codebase, migrating from enum-based representations to fully normalized JPA entity models and database-driven logic. The EggType enum is replaced by an EggType entity, with corresponding updates to domain models, repositories, service logic, and SQL schema/data. All references to egg types and their relationships in eggs, runimos, and rewards are updated to use entity associations and foreign key IDs. Service and repository methods are revised to query and manage egg types and runimo definitions via the database. Related test code and SQL test data are modified to align with the new structure.

Changes

File(s) Change Summary
src/main/java/org/runimo/runimo/item/domain/EggType.java Refactored from enum to JPA entity; added fields, builder, validation, static EMPTY, and factory method.
src/main/java/org/runimo/runimo/item/domain/Egg.java Changed eggType from enum to lazy-loaded entity association; updated EMPTY; added isEmpty().
src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java New repository for EggType with queries by distance, level, and ordering.
src/main/java/org/runimo/runimo/item/repository/ItemRepository.java Query parameter for egg type changed from enum to entity; updated method signature.
src/main/java/org/runimo/runimo/item/service/EggFactory.java Now retrieves the greeting egg by ID instead of egg type.
src/main/java/org/runimo/runimo/hatch/service/HatchClient.java,
src/main/java/org/runimo/runimo/hatch/service/HatchContext.java,
src/main/java/org/runimo/runimo/hatch/service/strategy/EqualRandom.java
Refactored runimo pool generation from enum-based to DB-driven by egg type level; updated context to work with runimo IDs.
src/main/java/org/runimo/runimo/rewards/service/RewardService.java,
src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java
Reward response now includes a boolean for egg presence and uses string egg type; updated construction logic.
src/main/java/org/runimo/runimo/rewards/service/eggs/EggGrantService.java Unlocked egg types now retrieved from repository, not static method; repository injected.
src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java Egg type field changed from enum column to entity association with foreign key.
src/main/java/org/runimo/runimo/runimo/repository/RunimoDefinitionRepository.java Old enum-based query removed; added queries returning IDs and DTOs by egg type entity list.
src/main/java/org/runimo/runimo/runimo/service/dto/RunimoTypeSimpleModel.java Changed from record to class; fields updated, static methods removed, now a plain data holder.
src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeGroup.java Added field for egg required distance in meters.
src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeInfo.java Added static factory method to convert from simple models.
src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java Now groups runimo types by egg type entity; returns grouped DTOs; uses repository.
src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java,
src/main/java/org/runimo/runimo/user/service/UserItemFinder.java
Egg lookup changed from type to code; methods updated/removed accordingly.
src/main/resources/sql/schema.sql,
src/test/resources/sql/schema.sql
Added egg_type table; updated item and runimo_definition to use foreign key; adjusted constraints and inserts.
src/test/resources/sql/egg_data.sql,
src/test/resources/sql/incubating_egg_test_data.sql,
src/test/resources/sql/main_view_data.sql
Test data updated to use egg_type IDs and normalized schema.
src/test/resources/sql/get_my_runimo_list_test_data.sql,
src/test/resources/sql/hatch_test_data.sql,
src/test/resources/sql/set_main_runimo_test_data.sql,
src/test/resources/sql/user_item_test_data.sql,
src/test/resources/sql/user_mypage_test_data.sql
Static data for enums removed or updated to match new schema.
src/test/java/org/runimo/runimo/item/service/EggEnumRandomGeneratorTest.java Test class renamed; now uses explicit entity instances instead of static methods.
src/test/java/org/runimo/runimo/rewards/RewardTest.java,
src/test/java/org/runimo/runimo/rewards/service/RewardServiceTest.java,
src/test/java/org/runimo/runimo/rewards/api/RewardAcceptanceTest.java
Tests updated for new reward response structure and egg type handling.
src/test/java/org/runimo/runimo/runimo/controller/RunimoControllerTest.java Added assertions for new group field in runimo type list response.
src/main/java/org/runimo/runimo/hatch/controller/HatchController.java,
src/main/java/org/runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java,
src/test/java/org/runimo/runimo/hatch/controller/HatchControllerTest.java
Minor import or whitespace reordering; no logic changes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RewardService
    participant EggGrantService
    participant EggTypeRepository
    participant ItemRepository

    User->>RewardService: claimReward(command)
    RewardService->>EggGrantService: grantRandomEggToUser(user)
    EggGrantService->>EggTypeRepository: findEggTypeByRequiredDistanceInMetersLessThanEqual(distance)
    EggTypeRepository-->>EggGrantService: List<EggType>
    EggGrantService->>ItemRepository: findByEggType(eggType)
    ItemRepository-->>EggGrantService: Optional<Egg>
    EggGrantService-->>RewardService: Egg
    RewardService-->>User: RewardResponse(isRewarded, eggCode, eggTypeName, lovePointAmount)
Loading
sequenceDiagram
    participant HatchClient
    participant EggTypeRepository
    participant RunimoDefinitionRepository
    participant HatchContext

    HatchClient->>EggTypeRepository: findEggTypeByLevelLessThan(eggLevel)
    EggTypeRepository-->>HatchClient: List<EggType>
    HatchClient->>RunimoDefinitionRepository: findIdInEggTypes(eggTypes)
    RunimoDefinitionRepository-->>HatchClient: List<Long> (runimo IDs)
    HatchClient->>HatchContext: setHatchContext(runimoIdPool)
    HatchContext->>HatchClient: execute() (returns runimoId)
    HatchClient->>RunimoDefinitionRepository: findById(runimoId)
    RunimoDefinitionRepository-->>HatchClient: RunimoDefinition
Loading

Possibly related PRs

  • Run-Us/Runimo#49: Refactored runimo type retrieval and grouping, moving from enum to entity-based models and grouping by egg type, which directly relates to this PR's database-driven approach and entity normalization.

Suggested labels

:rocket: feature :rocket:

Suggested reviewers

  • jeeheaG

Poem

In burrows deep, I nibbled code,
And found where enums used to dwell—
Now eggs and runimos, entity-mode,
Linked by keys, their stories tell.
With queries swift and schema neat,
This bunny’s work is quite complete!
🥚🐇
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8e3b10 and f66deb1.

📒 Files selected for processing (2)
  • src/main/java/org/runimo/runimo/item/domain/Egg.java (3 hunks)
  • src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java
  • src/main/java/org/runimo/runimo/item/domain/Egg.java
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (13)
src/main/java/org/runimo/runimo/item/service/EggFactory.java (1)

16-16: Consider using a named constant from a configuration class instead of a hard-coded ID

While defining GREETING_EGG_ID as a constant is better than using a magic number directly, hard-coded IDs can be problematic if database records change. Consider:

  1. Defining this constant in a central configuration class for all special egg IDs
  2. Using a named query or finder method that retrieves the egg by a more stable attribute like code or name
  3. Storing this ID in an application property for easier configuration management
src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java (2)

31-34: Consider adding validation for eggCode values

Moving from enum to string-based codes loses compile-time type safety. Consider adding validation to ensure the eggCode parameter contains valid values, perhaps through a validation service or using constants for common egg codes.


31-34: Evaluate the performance impact of the join query

The new query joins with the Egg table, which may have performance implications compared to directly filtering by an enum value. For high-frequency calls, consider adding an index on the egg's itemCode field if not already present.

src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java (1)

5-5: Consider using primitive boolean instead of Boolean wrapper

Using Boolean wrapper type rather than primitive boolean allows for null values, which could lead to NullPointerExceptions. Unless null is a meaningful state for this field, consider using the primitive type instead.

-    Boolean isRewarded,
+    boolean isRewarded,
src/test/java/org/runimo/runimo/item/service/EggEnumRandomGeneratorTest.java (1)

9-9: Class name seems inconsistent with the migration direction.

While the code changes correctly reflect the move from enum to entity, the class name change to include "Enum" seems contrary to the migration direction away from enums. Consider renaming to better reflect the entity-based approach.

-class EggEnumRandomGeneratorTest {
+class EggTypeRandomGeneratorTest {
src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java (1)

33-36: Good refactoring from enum to entity relationship

The change from what was likely an enum-based field to a proper @OneToOne JPA relationship with the EggType entity is a good improvement for database normalization and flexibility.

However, consider adding FetchType.LAZY to the @OneToOne annotation to prevent unnecessary eager loading:

-    @OneToOne
+    @OneToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "egg_type_id", nullable = false)
     private EggType type;
src/main/java/org/runimo/runimo/rewards/service/RewardService.java (1)

38-40: Updated reward response construction to use entity properties

The changes to the RewardResponse construction appropriately reflect the conversion from enum-based to entity-based EggType, including:

  1. Using a boolean flag to indicate if a reward was given
  2. Using the item code from the egg
  3. Using the name from the EggType entity instead of the enum value

However, there's a potential null pointer risk if getEggType() returns null. Consider adding a null check:

-        return new RewardResponse(!grantedEgg.isEmpty(), grantedEgg.getItemCode(),
-            grantedEgg.getEggType().getName(),
+        return new RewardResponse(!grantedEgg.isEmpty(), grantedEgg.getItemCode(),
+            grantedEgg.isEmpty() ? "EMPTY" : grantedEgg.getEggType().getName(),
             grantedLoveAmount);
src/main/java/org/runimo/runimo/item/domain/Egg.java (1)

38-40: Consider enhancing isEmpty() implementation

The current isEmpty() method checks for object identity (this == EMPTY), which works as long as the EMPTY constant is properly managed. For more robustness, consider adding null checks or other criteria that would define an empty egg.

public boolean isEmpty() {
-    return this == EMPTY;
+    return this == EMPTY || (this.getItemCode() != null && this.getItemCode().equals(EMPTYFIELD));
}
src/main/java/org/runimo/runimo/hatch/service/HatchContext.java (1)

8-18: Type change from RunimoType enum to Long ID is appropriate, but add null checks

The transition from using RunimoType enums to Long IDs aligns well with the PR objective. However, consider adding null and empty checks to prevent potential NullPointerExceptions or IndexOutOfBoundsExceptions.

private List<Long> runimoPool;
private HatchRandomStrategy hatchRandomStrategy;

public Long execute() {
+    if (runimoPool == null || runimoPool.isEmpty()) {
+        return null; // Or throw a custom exception
+    }
    int chosenIdx = hatchRandomStrategy.generateNumber();
    return runimoPool.get(chosenIdx);
}

public void setHatchContext(List<Long> runimoIdPool) {
+    if (runimoIdPool == null) {
+        runimoIdPool = List.of(); // Or throw an exception
+    }
    this.runimoPool = runimoIdPool;
}
src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java (1)

13-15: Rename finder methods to conform to Spring‑Data naming conventions

findEggTypeByRequiredDistanceInMetersLessThanEqual reads redundantly.
The canonical form is findByRequiredDistanceInMetersLessThanEqual (same for Level). Aligning with the convention:

-    List<EggType> findEggTypeByRequiredDistanceInMetersLessThanEqual(Long totalDistanceInMeters);
-    List<EggType> findEggTypeByLevelLessThan(Integer level);
+    List<EggType> findByRequiredDistanceInMetersLessThanEqual(Long totalDistanceInMeters);
+    List<EggType> findByLevelLessThan(Integer level);

This keeps repository APIs predictable and self‑documenting.

src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java (1)

67-71: Variable name does not reflect its content

runimoTypeInfos actually stores RunimoTypeSimpleModel lists, not RunimoTypeInfo. Consider runimoTypeModelsByEggId to avoid confusion.

src/main/java/org/runimo/runimo/item/domain/EggType.java (2)

22-29: Consider adding uniqueness constraints on business‑key columns

name and especially code look like natural identifiers. To enforce data integrity at the DB level:

-    @Column(name = "code", nullable = false)
+    @Column(name = "code", nullable = false, unique = true, length = 50)

Similarly add unique = true (and perhaps a sensible length) to name.


35-41: Minor: reuse validation utility to reduce duplication

You repeat “value must be ≥ 0” checks. Extracting a small requireNonNegative(long value, String fieldName) utility keeps entity constructors concise.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 056d745 and 22359a8.

📒 Files selected for processing (37)
  • src/main/java/org/runimo/runimo/hatch/controller/HatchController.java (1 hunks)
  • src/main/java/org/runimo/runimo/hatch/service/HatchClient.java (3 hunks)
  • src/main/java/org/runimo/runimo/hatch/service/HatchContext.java (1 hunks)
  • src/main/java/org/runimo/runimo/hatch/service/strategy/EqualRandom.java (1 hunks)
  • src/main/java/org/runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java (1 hunks)
  • src/main/java/org/runimo/runimo/item/domain/Egg.java (3 hunks)
  • src/main/java/org/runimo/runimo/item/domain/EggType.java (1 hunks)
  • src/main/java/org/runimo/runimo/item/repository/EggTypeRepository.java (1 hunks)
  • src/main/java/org/runimo/runimo/item/repository/ItemRepository.java (1 hunks)
  • src/main/java/org/runimo/runimo/item/service/EggFactory.java (1 hunks)
  • src/main/java/org/runimo/runimo/rewards/service/RewardService.java (1 hunks)
  • src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java (1 hunks)
  • src/main/java/org/runimo/runimo/rewards/service/eggs/EggGrantService.java (3 hunks)
  • src/main/java/org/runimo/runimo/runimo/domain/RunimoDefinition.java (2 hunks)
  • src/main/java/org/runimo/runimo/runimo/repository/RunimoDefinitionRepository.java (2 hunks)
  • src/main/java/org/runimo/runimo/runimo/service/dto/RunimoTypeSimpleModel.java (1 hunks)
  • src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeGroup.java (1 hunks)
  • src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeInfo.java (2 hunks)
  • src/main/java/org/runimo/runimo/runimo/service/usecase/RunimoUsecaseImpl.java (3 hunks)
  • src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java (1 hunks)
  • src/main/java/org/runimo/runimo/user/service/UserItemFinder.java (1 hunks)
  • src/main/resources/sql/schema.sql (5 hunks)
  • src/test/java/org/runimo/runimo/hatch/controller/HatchControllerTest.java (1 hunks)
  • src/test/java/org/runimo/runimo/item/service/EggEnumRandomGeneratorTest.java (1 hunks)
  • src/test/java/org/runimo/runimo/rewards/RewardTest.java (1 hunks)
  • src/test/java/org/runimo/runimo/rewards/api/RewardAcceptanceTest.java (2 hunks)
  • src/test/java/org/runimo/runimo/rewards/service/RewardServiceTest.java (4 hunks)
  • src/test/java/org/runimo/runimo/runimo/controller/RunimoControllerTest.java (1 hunks)
  • src/test/resources/sql/egg_data.sql (1 hunks)
  • src/test/resources/sql/get_my_runimo_list_test_data.sql (0 hunks)
  • src/test/resources/sql/hatch_test_data.sql (0 hunks)
  • src/test/resources/sql/incubating_egg_test_data.sql (1 hunks)
  • src/test/resources/sql/main_view_data.sql (2 hunks)
  • src/test/resources/sql/schema.sql (5 hunks)
  • src/test/resources/sql/set_main_runimo_test_data.sql (0 hunks)
  • src/test/resources/sql/user_item_test_data.sql (0 hunks)
  • src/test/resources/sql/user_mypage_test_data.sql (0 hunks)
💤 Files with no reviewable changes (5)
  • src/test/resources/sql/user_item_test_data.sql
  • src/test/resources/sql/get_my_runimo_list_test_data.sql
  • src/test/resources/sql/set_main_runimo_test_data.sql
  • src/test/resources/sql/user_mypage_test_data.sql
  • src/test/resources/sql/hatch_test_data.sql
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/main/java/org/runimo/runimo/item/domain/EggType.java (3)
src/main/java/org/runimo/runimo/item/domain/Egg.java (1)
  • Entity (16-41)
src/main/java/org/runimo/runimo/item/domain/Item.java (1)
  • Table (17-49)
src/main/java/org/runimo/runimo/common/GlobalConsts.java (1)
  • NoArgsConstructor (8-21)
src/main/java/org/runimo/runimo/hatch/service/HatchClient.java (1)
src/main/java/org/runimo/runimo/hatch/exception/HatchException.java (1)
  • HatchException (6-19)
🔇 Additional comments (47)
src/test/java/org/runimo/runimo/hatch/controller/HatchControllerTest.java (1)

69-69: LGTM: Minor formatting adjustment.

This whitespace change doesn't affect functionality and appears to be a minor code style adjustment.

src/main/java/org/runimo/runimo/hatch/controller/HatchController.java (1)

10-10: LGTM: Import reordering.

Import statement reordering doesn't affect functionality.

src/main/java/org/runimo/runimo/hatch/service/usecase/HatchUsecaseImpl.java (2)

7-7: LGTM: Import reordering.

Import statement reordering doesn't affect functionality.


30-60:

Details

✅ Verification successful

Verify implementation with new EggType entity.

The execute method appears unchanged despite the conversion from enum to entity types. Verify that egg.getEggType() on line 37 correctly returns the new EggType entity and that HatchClient.getRandomRunimoDefinition() properly handles it.


🏁 Script executed:

#!/bin/bash
# Search for the definition of EggType and how it's handled in HatchClient
echo "Checking Egg class for getEggType method:"
rg -A 5 "getEggType" --glob "*/item/domain/Egg.java"

echo -e "\nChecking HatchClient for getRandomRunimoDefinition method:"
rg -A 10 "getRandomRunimoDefinition" --glob "*/hatch/service/HatchClient.java"

Length of output: 655


🏁 Script executed:

#!/bin/bash
set -e

echo "Locating Egg.java files:"
find . -type f -name Egg.java

echo -e "\nInspecting getEggType usage in Java sources:"
rg -A5 "getEggType" --glob "*.java" || true

echo -e "\nLocating EggType.java files:"
find . -type f -name EggType.java || echo "EggType.java not found"

echo -e "\nInspecting EggType class definitions:"
rg -A5 "class EggType" --glob "*.java" || true

echo -e "\nLocating HatchClient.java files:"
find . -type f -name HatchClient.java || echo "HatchClient.java not found"

echo -e "\nInspecting getRandomRunimoDefinition usage in Java sources:"
rg -A5 "getRandomRunimoDefinition" --glob "*.java" || true

Length of output: 4881


🏁 Script executed:

#!/bin/bash
set -e

echo "=== Egg.java (getEggType) ==="
rg -A3 -B3 "getEggType" --glob "src/main/java/**/*.java"

echo -e "\n=== EggType.java (fields & methods) ==="
sed -n '1,200p' src/main/java/org/runimo/runimo/item/domain/EggType.java

echo -e "\n=== HatchClient.java (getRandomRunimoDefinition signature) ==="
rg -A5 -B3 "getRandomRunimoDefinition" --glob "src/main/java/**/*.java"

Length of output: 5842


🏁 Script executed:

#!/bin/bash
set -e

echo "=== Displaying Egg.java (first 200 lines) ==="
sed -n '1,200p' src/main/java/org/runimo/runimo/item/domain/Egg.java

Length of output: 1458


Implementation correctly uses the EggType entity

I’ve confirmed that

  • Egg#getEggType() (generated by Lombok’s @Getter) returns the JPA‐mapped EggType entity, and
  • HatchClient.getRandomRunimoDefinition(EggType eggType) now accepts the entity (not an enum), uses its properties (e.g. level) to build the pool, and resolves the definition via RunimoDefinitionRepository.

No changes are needed here.

src/test/resources/sql/incubating_egg_test_data.sql (1)

21-22:

Details

✅ Verification successful

LGTM: Updated column from enum to entity ID reference.

Column name change from egg_type to egg_type_id and value change from string to integer correctly reflects the migration from enum to entity-based approach.


🏁 Script executed:

#!/bin/bash
# Verify if egg_type table is populated in test data
echo "Checking for egg_type table population in SQL files:"
rg -l "INSERT INTO egg_type" --glob "*/test/resources/sql/*.sql"

echo -e "\nChecking egg_type table structure:"
fd "egg_type.java" -i

Length of output: 358


egg_type test data population confirmed
The test SQL files (schema.sql and egg_data.sql in src/test/resources/sql/) include the necessary INSERT INTO egg_type statements, so the new egg_type_id = 1 reference will resolve correctly. LGTM.

src/test/java/org/runimo/runimo/runimo/controller/RunimoControllerTest.java (2)

92-92: LGTM: Minor formatting adjustment.

This whitespace change doesn't affect functionality and appears to be a minor code style adjustment.


99-102: LGTM: Added assertions for new egg unlock distance field.

The added assertions correctly verify the new egg_required_distance_in_meters field in the response payload, ensuring that:

  • The first runimo group (마당/Madang) requires 0 meters (immediately available)
  • The second runimo group (숲/Forest) requires 30,000 meters (approx. 30km)

This change aligns with the PR objective of including running distance needed to unlock each runimo group.

src/test/java/org/runimo/runimo/rewards/RewardTest.java (1)

103-107: Method correctly updated to use code-based lookup instead of type-based lookup

The change from findEggByUserIdAndEggType to findEggByUserIdAndEggCode properly aligns with the PR's objective of replacing enum types with entity types. This update ensures the test stays consistent with the domain model changes.

src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeGroup.java (1)

10-11: Good addition of distance requirement information

The new eggRequiredDistanceInMeters field with proper Swagger documentation enhances the API response with the distance needed to unlock each Runimo group, as mentioned in the PR objectives.

src/main/java/org/runimo/runimo/hatch/service/strategy/EqualRandom.java (1)

9-9: Good practice making size field final

Making the size field final is a good practice as it ensures immutability after initialization, enhancing code reliability.

src/main/java/org/runimo/runimo/runimo/service/dto/response/RunimoTypeInfo.java (1)

21-25: Well-implemented static factory method for conversion

The addition of the from method provides a clean way to convert between model and DTO objects, using Java streams for efficient mapping. This supports the PR objective of modifying the mapping logic.

src/main/java/org/runimo/runimo/item/service/EggFactory.java (2)

20-23: Verify that GREETING_EGG_ID will consistently map to the correct egg

The change from finding by EggType to finding by ID aligns with the entity-based approach. However, ensure that ID 1L will consistently map to the greeting egg across all environments and database migrations.

Consider adding a comment in the code explaining that ID 1L corresponds to the greeting egg type to improve code maintainability.


26-30:

Details

✅ Verification successful

Confirm that createEggRandomly still works with EggType as an entity

This method still uses EggType objects. Ensure that eggTypeRandomGenerator.generateRandomEggType and itemFinder.findEggByEggType have been updated to work with EggType as an entity rather than an enum.


🏁 Script executed:

#!/bin/bash
# Check how EggTypeRandomGenerator and ItemFinder use EggType
rg -A 3 "EggTypeRandomGenerator|generateRandomEggType" src/
rg -A 3 "findEggByEggType" src/

Length of output: 3841


🏁 Script executed:

#!/bin/bash
# Display ItemFinder and EggTypeRandomGenerator implementations
sed -n '1,200p' src/main/java/org/runimo/runimo/item/service/ItemFinder.java
echo -e "\n---\n"
sed -n '1,200p' src/main/java/org/runimo/runimo/item/service/EggTypeRandomGenerator.java

Length of output: 1906


🏁 Script executed:

#!/bin/bash
# Inspect EggType entity definition
sed -n '1,200p' src/main/java/org/runimo/runimo/item/domain/EggType.java
echo -e "\n---\n"
# Inspect repository method signature for findByEggType
sed -n '1,200p' src/main/java/org/runimo/runimo/item/repository/ItemRepository.java

Length of output: 2578


🏁 Script executed:

#!/bin/bash
# Inspect BaseEntity to see equals/hashCode implementation
sed -n '1,200p' src/main/java/org/runimo/runimo/common/BaseEntity.java

Length of output: 1029


Confirmed: createEggRandomly works with EggType as a JPA entity
I’ve verified that EggTypeRandomGenerator.generateRandomEggType returns domain EggType instances (not enums) and that ItemFinder.findEggByEggType binds the entity in its JPA query (where e.eggType = :eggType), so the method correctly handles EggType as an entity.

src/main/java/org/runimo/runimo/item/repository/ItemRepository.java (1)

18-19: LGTM: Improved parameter naming consistency

Good update to make the query parameter name :eggType match the method parameter eggType. This improves code readability and maintains consistent naming conventions.

src/main/java/org/runimo/runimo/user/repository/UserItemRepository.java (1)

31-34:

Details

✅ Verification successful

Verify that all callers of the previous findByUserIdAndEggType method have been updated

The introduction of findByUserIdAndEggCode to replace what was likely findByUserIdAndEggType (using EggType enum) is a good approach for the entity conversion. However, ensure all code that previously called the removed method has been updated to use this new method.


🏁 Script executed:

#!/bin/bash
# Check for any remaining references to findByUserIdAndEggType
rg "findByUserIdAndEggType" src/

Length of output: 32


No remaining references to findByUserIdAndEggType

  • Verified via rg "findByUserIdAndEggType" src/—no occurrences found.

All callers have been updated to use the new findByUserIdAndEggCode method.

src/main/java/org/runimo/runimo/rewards/service/dto/RewardResponse.java (2)

7-7: LGTM: Changed eggType from enum to String

Good change converting the eggType field from EggType enum to String. This properly decouples the DTO from the domain model, which is especially important now that EggType is an entity.


4-9:

Details

✅ Verification successful

Verify all constructors of RewardResponse have been updated

Adding a new field to the record requires updates to all places where RewardResponse is constructed. Ensure that all service methods that create RewardResponse objects have been updated to provide the new isRewarded field.


🏁 Script executed:

#!/bin/bash
# Find all places where RewardResponse is constructed
rg -A 2 -B 2 "new RewardResponse\(" src/

Length of output: 681


All RewardResponse constructor calls include the new isRewarded field

The only usage of new RewardResponse(...) is in:

  • src/main/java/org/runimo/runimo/rewards/service/RewardService.java
    return new RewardResponse(!grantedEgg.isEmpty(), grantedEgg.getItemCode(), grantedEgg.getEggType().getName(), grantedLoveAmount);

No other constructor invocations found—no further updates required.

src/main/java/org/runimo/runimo/rewards/service/eggs/EggGrantService.java (2)

7-7: Dependencies added correctly for the new EggTypeRepository.

The import and dependency injection for EggTypeRepository are correctly added to support the transition from enum-based to entity-based egg types.

Also applies to: 23-23


36-37: Repository query replaces static method call appropriately.

The change from EggType.getUnLockedEggTypes static method to a repository query is aligned with the migration from enums to entities. The repository method name clearly indicates its purpose.

src/test/java/org/runimo/runimo/rewards/api/RewardAcceptanceTest.java (2)

187-189: Test assertions updated for new response field.

The test assertions have been correctly updated to validate the new is_rewarded field and the change from a null value to the "EMPTY" string for the egg_type field.


263-263: New assertion validates isRewarded field.

The added assertion correctly validates that when a user doesn't meet the distance requirement, the is_rewarded field is set to false, which aligns with the new response field requirements.

src/main/java/org/runimo/runimo/user/service/UserItemFinder.java (1)

23-25: Method signature updated to use string code instead of enum type.

The method has been appropriately updated to use a string egg code rather than the EggType enum, which aligns with the migration from enum to entity-based approach. The method name clearly reflects its updated purpose.

src/test/java/org/runimo/runimo/item/service/EggEnumRandomGeneratorTest.java (2)

17-30: Test data updated correctly for entity-based approach.

The test now properly creates EggType entities with appropriate attributes instead of relying on enum values. This correctly supports testing the random generator with the new entity model.


32-32: Method call updated for entity-based input.

The method call has been updated to work with the new entity-based approach, which is good. The test still validates that the random generator works correctly with the new EggType entities.

src/test/resources/sql/egg_data.sql (1)

2-13: Proper test data setup for the new entity model

The SQL has been properly updated to support the new entity relationship model with:

  1. Truncating the new egg_type table
  2. Adding inserts for the egg types with appropriate attributes
  3. Updating the item table inserts to use foreign key references

This change aligns well with the entity-relationship refactoring.

src/test/java/org/runimo/runimo/rewards/service/RewardServiceTest.java (4)

77-82: Updated test mock to use entity factory method

The test correctly uses EggType.of() factory method to create an EggType entity instead of using an enum constant, which aligns with the domain model changes.


86-87: Updated assertions for new response structure

The test properly verifies the new isRewarded boolean flag and compares the egg type string name instead of an enum constant.


101-106: Consistent use of EggType factory method

The code consistently uses the EggType.of() factory method to create test data, which is good for maintainability.


124-126: Updated negative case assertion

Test for the negative case has been correctly updated to check the isRewarded flag and empty egg properties.

src/test/resources/sql/main_view_data.sql (2)

14-18: Enum to Entity transition looks good for the item table

The change from string-based egg types to numeric foreign key references (egg_type_id) aligns well with the PR objective of replacing enums with entity types. The item table now properly references egg type IDs 1 and 2 instead of string values.


21-30: Runimo definitions properly expanded with egg type references

The runimo_definition table now correctly uses egg_type_id foreign key references instead of string-based egg types. The expansion from 4 to 8 entries provides good coverage for the different egg types (4 for egg_type_id 1 and 4 for egg_type_id 2).

src/main/java/org/runimo/runimo/item/domain/Egg.java (1)

24-26:

Details

✅ Verification successful

JPA OneToOne relationship properly configured with lazy loading

The one-to-one relationship with EggType is correctly set up with lazy loading, which is good for performance. However, be cautious with the lazy fetch type to avoid potential LazyInitializationExceptions if the eggType is accessed outside of a transactional context.

Run this script to check if there are potential places where eggType might be accessed outside a transaction:


🏁 Script executed:

#!/bin/bash
# Search for places where eggType is accessed
rg "\.getEggType\(\)" --type java src/main -C 2
# Search for @Transactional annotations
rg "@Transactional" --type java src/main

Length of output: 5930


No LazyInitializationException risk detected for eggType access

All occurrences of getEggType() are invoked inside methods annotated with @Transactional (including @Transactional(readOnly = true)) in both RewardService.java and HatchUsecaseImpl.java, ensuring the persistence context remains open for lazy loading. No further changes are required.

src/main/java/org/runimo/runimo/runimo/repository/RunimoDefinitionRepository.java (1)

15-19: New query method for finding runimo IDs by egg types looks good

The new JPQL query correctly filters runimo definitions by egg types, returning only the IDs. This method will be useful for performance when only IDs are needed.

src/main/resources/sql/schema.sql (7)

3-3: Good addition of DROP TABLE statement.

Adding explicit DROP TABLE statement for the new egg_type table ensures clean schema migrations and prevents potential conflicts when rerunning scripts.


119-119: Properly normalized database structure.

Replacing the string-based enum column with a foreign key reference to the new egg_type table is a good normalization practice. This improves data integrity and flexibility.


126-137: Well-structured egg_type entity table.

The new egg_type table provides a robust structure with all necessary fields:

  • Primary key and identification fields (id, name, code)
  • Domain-specific fields (required_distance_in_meters, level)
  • Audit timestamps for proper tracking

This change allows for more flexible egg type management without code changes.


182-182: Consistent foreign key implementation.

The foreign key in runimo_definition properly links to the egg_type table, maintaining the relationship between these entities.


213-222: Correctly updated runimo_definition data inserts.

The inserts have been properly updated to reference egg_type_id instead of the previous string-based egg type. The data maintains the same logical groupings (runimos 1-4 belong to egg type 1, and 5-8 belong to egg type 2).


224-229: Consistent item data updates with egg type references.

The item data inserts have been correctly updated to use foreign key references to the egg_type table (egg_type_id) instead of string enum values, maintaining data integrity.


208-210:

Details

❓ Verification inconclusive

Verify foreign key constraint implementation.

While the data structure is properly normalized, I notice that there are no explicit foreign key constraints defined between item.egg_type_id/runimo_definition.egg_type_id and egg_type.id. This appears intentional based on the PR description mentioning "without applying a foreign key constraint", but consider whether this omission might impact data integrity.


🏁 Script executed:

#!/bin/bash
# Check if foreign key constraints exist between tables
mysql -e "SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'egg_type';" || echo "No foreign key constraints found for egg_type table"

Length of output: 405


🏁 Script executed:

#!/bin/bash
echo "Searching for egg_type_id in schema.sql"
rg -n "egg_type_id" src/main/resources/sql/schema.sql || echo "No egg_type_id occurrences"

echo "Searching for REFERENCES egg_type in schema.sql"
rg -n "REFERENCES egg_type" src/main/resources/sql/schema.sql || echo "No REFERENCES egg_type occurrences"

echo "Searching for foreign key declarations in schema.sql"
rg -n "foreign key" src/main/resources/sql/schema.sql || echo "No foreign key declarations"

Length of output: 901


No foreign key constraints found for egg_type relations

I confirmed that egg_type_id appears in both runimo_definition (line 182) and item (line 119) but there are no REFERENCES egg_type or FOREIGN KEY declarations in schema.sql. Please verify that omitting these constraints is intentional and won’t compromise data integrity. If you intend to enforce referential integrity at the database level, consider adding:

ALTER TABLE runimo_definition
  ADD CONSTRAINT fk_runimo_egg_type
    FOREIGN KEY (egg_type_id) REFERENCES egg_type(id);

ALTER TABLE item
  ADD CONSTRAINT fk_item_egg_type
    FOREIGN KEY (egg_type_id) REFERENCES egg_type(id);
src/test/resources/sql/schema.sql (1)

3-3: Consistent schema definition across environments.

The test schema has been updated with identical changes to the production schema, ensuring consistency between environments. This includes:

  1. Adding the egg_type table with the same structure
  2. Updating foreign key references in item and runimo_definition tables
  3. Updating data inserts to use the new relation structure

This maintains proper test environment fidelity to production.

Also applies to: 119-119, 126-137, 182-182, 208-229

src/main/java/org/runimo/runimo/runimo/service/dto/RunimoTypeSimpleModel.java (3)

3-8: Appropriate use of Lombok annotations.

The class now uses Lombok annotations to reduce boilerplate code while maintaining encapsulation. The protected no-args constructor ensures proper JPA compatibility while preventing direct instantiation without parameters.


9-15: Properly refactored model to use entity references.

The model has been correctly updated to reference egg types by ID (eggTypeId: Long) rather than by string name, aligning with the database normalization changes. This provides more efficient and type-safe references.


17-24: Complete constructor implementation.

The all-args constructor properly initializes all fields, maintaining the class's functionality after the conversion from what appears to have been a record type previously.

src/main/java/org/runimo/runimo/hatch/service/HatchClient.java (3)

10-11: Proper repository dependency injection.

Added dependency on EggTypeRepository to support the new entity-based approach. This allows fetching egg types by level criteria for the hatching logic.

Also applies to: 20-20


26-26: Improved runimo selection using database-driven approach.

The hatching logic has been refactored to use database IDs instead of in-memory objects:

  1. Now works with a list of runimo IDs (Long) instead of type objects
  2. Uses direct database lookups by ID, which is more efficient
  3. Properly handles errors with appropriate exception throwing

This approach is more scalable and maintainable than the previous enum-based implementation.

Also applies to: 36-39


43-46: Well-designed database query pattern for egg type filtering.

The method now:

  1. Finds all egg types with levels lower than the current egg type's level
  2. Retrieves all runimo IDs associated with those egg types

This database-driven approach is more flexible and maintainable than the previous enum-based logic, allowing for dynamic egg type and runimo management without code changes.

Copy link
Contributor

@jeeheaG jeeheaG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!
우려되는 부분 한가지만 적었어요
RunimoType enum 도 차차 탈enum 해보아요..~

@ekgns33 ekgns33 merged commit c558d20 into main Apr 26, 2025
4 checks passed
@ekgns33 ekgns33 deleted the feat/replace-enum-with-TypeEntity branch April 26, 2025 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request 🔨 refactor 🔨

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants