Skip to content

Commit

Permalink
โœจ get recipes by category
Browse files Browse the repository at this point in the history
  • Loading branch information
hyxrxn committed Jul 24, 2024
1 parent 974b29d commit 63377b6
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package net.pengcook.category.controller;

import java.util.List;
import lombok.RequiredArgsConstructor;
import net.pengcook.category.dto.RecipeOfCategoryRequest;
import net.pengcook.category.service.CategoryService;
import net.pengcook.recipe.dto.MainRecipeResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/categories")
public class CategoryController {

private final CategoryService categoryService;

@GetMapping
public List<MainRecipeResponse> readRecipesOfCategory(
@RequestParam String category,
@RequestParam int pageNumber,
@RequestParam int pageSize) {
RecipeOfCategoryRequest request = new RecipeOfCategoryRequest(category, pageNumber, pageSize);
return categoryService.readRecipesOfCategory(request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package net.pengcook.category.dto;

public record RecipeOfCategoryRequest(String category, int pageNumber, int pageSize) {
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
package net.pengcook.category.repository;

import java.util.List;
import net.pengcook.category.domain.CategoryRecipe;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface CategoryRecipeRepository extends JpaRepository<CategoryRecipe, Long> {

@Query("""
SELECT cr.recipe.id
FROM CategoryRecipe cr
JOIN Category c ON cr.category.id = c.id
WHERE c.name = :categoryName
""")
List<Long> findRecipeIdsByCategoryName(String categoryName, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
import lombok.RequiredArgsConstructor;
import net.pengcook.category.domain.Category;
import net.pengcook.category.domain.CategoryRecipe;
import net.pengcook.category.dto.RecipeOfCategoryRequest;
import net.pengcook.category.repository.CategoryRecipeRepository;
import net.pengcook.category.repository.CategoryRepository;
import net.pengcook.recipe.domain.Recipe;
import net.pengcook.recipe.dto.MainRecipeResponse;
import net.pengcook.recipe.dto.RecipeDataResponse;
import net.pengcook.recipe.repository.RecipeRepository;
import net.pengcook.recipe.service.RecipeService;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -15,11 +22,22 @@ public class CategoryService {

private final CategoryRepository categoryRepository;
private final CategoryRecipeRepository categoryRecipeRepository;
private final RecipeRepository recipeRepository;
private final RecipeService recipeService;

public void saveCategories(Recipe recipe, List<String> categories) {
categories.forEach(category -> saveCategoryRecipe(recipe, category));
}

public List<MainRecipeResponse> readRecipesOfCategory(RecipeOfCategoryRequest request) {
String categoryName = request.category();
Pageable pageable = PageRequest.of(request.pageNumber(), request.pageSize());
List<Long> recipeIds = categoryRecipeRepository.findRecipeIdsByCategoryName(categoryName, pageable);

List<RecipeDataResponse> recipeDataResponses = recipeRepository.findRecipeData(recipeIds);
return recipeService.convertToMainRecipeResponses(recipeDataResponses);
}

private void saveCategoryRecipe(Recipe recipe, String name) {
Category category = categoryRepository.findByName(name)
.orElseGet(() -> categoryRepository.save(new Category(name)));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package net.pengcook.category.controller;

import static org.hamcrest.Matchers.is;

import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.context.jdbc.Sql;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Sql(value = "/data/category.sql")
class CategoryControllerTest {

@LocalServerPort
private int port;

@BeforeEach
void setUp() {
RestAssured.port = port;
}

@Test
@DisplayName("๋ ˆ์‹œํ”ผ ๊ฐœ์š” ๋ชฉ๋ก์„ ์กฐํšŒํ•œ๋‹ค.")
void readRecipes() {
RestAssured.given().log().all()
.queryParam("category", "ํ•œ์‹")
.queryParam("pageNumber", 0)
.queryParam("pageSize", 3)
.when()
.get("/api/categories")
.then().log().all()
.body("size()", is(3));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.pengcook.category.repository;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.jdbc.Sql;

@DataJpaTest
@Sql("/data/category.sql")
class CategoryRecipeRepositoryTest {

@Autowired
private CategoryRecipeRepository repository;

@Test
@DisplayName("์š”์ฒญํ•œ ์นดํ…Œ๊ณ ๋ฆฌ์™€ ํŽ˜์ด์ง€์— ํ•ด๋‹นํ•˜๋Š” ๋ ˆ์‹œํ”ผ id ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.")
void findRecipeIds() {
Pageable pageable = PageRequest.of(0, 3);

List<Long> recipeIds = repository.findRecipeIdsByCategoryName("ํ•œ์‹", pageable);

assertThat(recipeIds).containsExactlyInAnyOrder(2L, 3L, 7L);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,31 @@
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Stream;
import net.pengcook.category.dto.RecipeOfCategoryRequest;
import net.pengcook.category.repository.CategoryRecipeRepository;
import net.pengcook.category.repository.CategoryRepository;
import net.pengcook.recipe.domain.Recipe;
import net.pengcook.recipe.dto.MainRecipeResponse;
import net.pengcook.recipe.service.RecipeService;
import net.pengcook.user.domain.User;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.jdbc.Sql;

@DataJpaTest
@Import(CategoryService.class)
@Import({CategoryService.class, RecipeService.class})
@Sql(scripts = "/data/category.sql")
class CategoryServiceTest {

private final long INITIAL_CATEGORY_COUNT = 5;
private final long INITIAL_CATEGORY_RECIPE_COUNT = 0;
private final long INITIAL_CATEGORY_COUNT = 10;
private final long INITIAL_CATEGORY_RECIPE_COUNT = 25;

@Autowired
private CategoryService categoryService;
Expand All @@ -39,11 +45,34 @@ void saveCategories() {
User author = new User("[email protected]", "ela", "์—˜๋ผ", "ela.jpg", LocalDate.of(2024, 7, 22), "KOREA");
Recipe recipe = new Recipe(1L, "๊น€์น˜๋ณถ์Œ๋ฐฅ", author, LocalTime.of(0, 30, 0), "๊น€์น˜๋ณถ์Œ๋ฐฅ์ด๋ฏธ์ง€.jpg", 3, 2, "๊น€์น˜๋ณถ์Œ๋ฐฅ ์กฐ๋ฆฌ๋ฒ•");

categoryService.saveCategories(recipe, List.of("ํ•œ์‹", "๋งค์šด์Œ์‹"));
categoryService.saveCategories(recipe, List.of("๊ฑด๊ฐ•์‹", "๋งค์šด์Œ์‹"));

assertAll(
() -> assertThat(categoryRepository.count()).isEqualTo(INITIAL_CATEGORY_COUNT + 1),
() -> assertThat(categoryRecipeRepository.count()).isEqualTo(INITIAL_CATEGORY_RECIPE_COUNT + 2)
);
}

@ParameterizedTest
@MethodSource("provideParameters")
@DisplayName("ํŠน์ • ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋ ˆ์‹œํ”ผ๋ฅผ ์ฐพ๋Š”๋‹ค.")
void readRecipesOfCategory(int pageNumber, int pageSize, List<Long> expected) {
RecipeOfCategoryRequest request = new RecipeOfCategoryRequest("ํ•œ์‹", pageNumber, pageSize);

List<MainRecipeResponse> mainRecipeResponses = categoryService.readRecipesOfCategory(request);
List<Long> actual = mainRecipeResponses.stream().map(MainRecipeResponse::recipeId).toList();

assertAll(
() -> assertThat(actual.size()).isEqualTo(pageSize),
() -> assertThat(actual).containsAll(expected)
);
}

static Stream<Arguments> provideParameters() {
return Stream.of(
Arguments.of(0, 2, List.of(2L, 3L)),
Arguments.of(1, 2, List.of(7L, 9L)),
Arguments.of(1, 3, List.of(9L, 14L, 15L))
);
}
}
129 changes: 119 additions & 10 deletions backend/src/test/resources/data/category.sql
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
SET REFERENTIAL_INTEGRITY FALSE;
SET
REFERENTIAL_INTEGRITY FALSE;

TRUNCATE TABLE users;
ALTER TABLE users ALTER COLUMN id RESTART;
ALTER TABLE users
ALTER COLUMN id RESTART;

TRUNCATE TABLE category;
ALTER TABLE category ALTER COLUMN id RESTART;
ALTER TABLE category
ALTER COLUMN id RESTART;

TRUNCATE TABLE ingredient;
ALTER TABLE ingredient ALTER COLUMN id RESTART;
ALTER TABLE ingredient
ALTER COLUMN id RESTART;

TRUNCATE TABLE recipe;
ALTER TABLE recipe ALTER COLUMN id RESTART;
ALTER TABLE recipe
ALTER COLUMN id RESTART;

TRUNCATE TABLE category_recipe;
ALTER TABLE category_recipe ALTER COLUMN id RESTART;
ALTER TABLE category_recipe
ALTER COLUMN id RESTART;

TRUNCATE TABLE ingredient_recipe;
ALTER TABLE ingredient_recipe ALTER COLUMN id RESTART;
ALTER TABLE ingredient_recipe
ALTER COLUMN id RESTART;

SET REFERENTIAL_INTEGRITY TRUE;
SET
REFERENTIAL_INTEGRITY TRUE;

INSERT INTO users (email, username, nickname, image, birth, region)
VALUES ('[email protected]', 'ela', '์—˜๋ผ', 'ela.jpg', '2024-07-22', 'KOREA');
Expand All @@ -28,7 +36,108 @@ VALUES ('ํ•œ์‹'),
('์–‘์‹'),
('์ฑ„์‹'),
('๊ฑด๊ฐ•์‹'),
('๊ฐ„ํŽธ์‹');
('๊ฐ„ํŽธ์‹'),
('๋””์ €ํŠธ'),
('ํ•ด์‚ฐ๋ฌผ'),
('๋ฉด์š”๋ฆฌ'),
('์ƒ๋Ÿฌ๋“œ'),
('์Šคํ”„');

INSERT INTO recipe (title, author_id, cooking_time, thumbnail, difficulty, like_count, description)
VALUES ('๊น€์น˜๋ณถ์Œ๋ฐฅ', 1, '00:30:00', '๊น€์น˜๋ณถ์Œ๋ฐฅ์ด๋ฏธ์ง€.jpg', 3, 2, '๊น€์น˜๋ณถ์Œ๋ฐฅ ์กฐ๋ฆฌ๋ฒ•');
VALUES ('๊น€์น˜๋ณถ์Œ๋ฐฅ', 1, '00:30:00', '๊น€์น˜๋ณถ์Œ๋ฐฅ์ด๋ฏธ์ง€.jpg', 3, 2, '๊น€์น˜๋ณถ์Œ๋ฐฅ ์กฐ๋ฆฌ๋ฒ•'),
('๊น€๋ฐฅ', 1, '01:00:00', '๊น€๋ฐฅ์ด๋ฏธ์ง€.jpg', 8, 1, '๊น€๋ฐฅ ์กฐ๋ฆฌ๋ฒ•'),
('๊น€์น˜์ฐŒ๊ฐœ', 1, '00:30:00', '๊น€์น˜์ฐŒ๊ฐœ์ด๋ฏธ์ง€.jpg', 3, 2, '๊น€์น˜์ฐŒ๊ฐœ ์กฐ๋ฆฌ๋ฒ•'),
('ํ† ๋งˆํ† ์ŠคํŒŒ๊ฒŒํ‹ฐ', 1, '00:30:00', 'ํ† ๋งˆํ† ์ŠคํŒŒ๊ฒŒํ‹ฐ์ด๋ฏธ์ง€.jpg', 3, 2, 'ํ† ๋งˆํ† ์ŠคํŒŒ๊ฒŒํ‹ฐ ์กฐ๋ฆฌ๋ฒ•'),
('๊ฐ„์žฅ๊ณ„๋ž€๋ฐฅ', 1, '00:10:00', '๊ฐ„์žฅ๊ณ„๋ž€๋ฐฅ์ด๋ฏธ์ง€.jpg', 1, 3, '๊ฐ„์žฅ๊ณ„๋ž€๋ฐฅ ์กฐ๋ฆฌ๋ฒ•'),
('ํ”ผ์ž', 1, '00:30:00', 'ํ”ผ์ž์ด๋ฏธ์ง€.jpg', 3, 2, 'ํ”ผ์ž ์กฐ๋ฆฌ๋ฒ•'),
('๋œ์žฅ์ฐŒ๊ฐœ', 1, '00:30:00', '๋œ์žฅ์ฐŒ๊ฐœ์ด๋ฏธ์ง€.jpg', 3, 2, '๋œ์žฅ์ฐŒ๊ฐœ ์กฐ๋ฆฌ๋ฒ•'),
('ํ–„๋ฒ„๊ฑฐ', 1, '00:30:00', 'ํ–„๋ฒ„๊ฑฐ์ด๋ฏธ์ง€.jpg', 3, 2, 'ํ–„๋ฒ„๊ฑฐ ์กฐ๋ฆฌ๋ฒ•'),
('ํฐ์Œ€๋ฐฅ', 1, '00:40:00', 'ํฐ์Œ€๋ฐฅ์ด๋ฏธ์ง€.jpg', 2, 4, 'ํฐ์Œ€๋ฐฅ ์กฐ๋ฆฌ๋ฒ•'),
('์ƒ๋Ÿฌ๋“œ', 1, '00:15:00', '์ƒ๋Ÿฌ๋“œ์ด๋ฏธ์ง€.jpg', 1, 5, '์ƒ๋Ÿฌ๋“œ ์กฐ๋ฆฌ๋ฒ•'),
('์—ฐ์–ด์Šคํ…Œ์ดํฌ', 1, '00:45:00', '์—ฐ์–ด์Šคํ…Œ์ดํฌ์ด๋ฏธ์ง€.jpg', 4, 3, '์—ฐ์–ด์Šคํ…Œ์ดํฌ ์กฐ๋ฆฌ๋ฒ•'),
('์ดˆ์ฝœ๋ฆฟ ์ผ€์ดํฌ', 1, '01:20:00', '์ดˆ์ฝœ๋ฆฟ์ผ€์ดํฌ์ด๋ฏธ์ง€.jpg', 5, 6, '์ดˆ์ฝœ๋ฆฟ ์ผ€์ดํฌ ์กฐ๋ฆฌ๋ฒ•'),
('๋ฒ ์ง€ํ„ฐ๋ธ” ์Šคํ”„', 1, '00:50:00', '๋ฒ ์ง€ํ„ฐ๋ธ”์Šคํ”„์ด๋ฏธ์ง€.jpg', 3, 2, '๋ฒ ์ง€ํ„ฐ๋ธ” ์Šคํ”„ ์กฐ๋ฆฌ๋ฒ•'),
('์นด๋ ˆ๋ผ์ด์Šค', 1, '00:30:00', '์นด๋ ˆ๋ผ์ด์Šค์ด๋ฏธ์ง€.jpg', 3, 2, '์นด๋ ˆ๋ผ์ด์Šค ์กฐ๋ฆฌ๋ฒ•'),
('์ƒˆ์šฐ๋ณถ์Œ๋ฐฅ', 1, '00:25:00', '์ƒˆ์šฐ๋ณถ์Œ๋ฐฅ์ด๋ฏธ์ง€.jpg', 2, 3, '์ƒˆ์šฐ๋ณถ์Œ๋ฐฅ ์กฐ๋ฆฌ๋ฒ•');

INSERT INTO category_recipe (category_id, recipe_id)
VALUES (1, 2), -- ๊น€๋ฐฅ์€ ํ•œ์‹
(3, 2), -- ๊น€๋ฐฅ์€ ์ฑ„์‹
(1, 3), -- ๊น€์น˜์ฐŒ๊ฐœ๋Š” ํ•œ์‹
(5, 3), -- ๊น€์น˜์ฐŒ๊ฐœ๋Š” ๊ฐ„ํŽธ์‹
(2, 4), -- ํ† ๋งˆํ† ์ŠคํŒŒ๊ฒŒํ‹ฐ๋Š” ์–‘์‹
(4, 5), -- ๊ฐ„์žฅ๊ณ„๋ž€๋ฐฅ์€ ๊ฑด๊ฐ•์‹
(5, 5), -- ๊ฐ„์žฅ๊ณ„๋ž€๋ฐฅ์€ ๊ฐ„ํŽธ์‹
(2, 6), -- ํ”ผ์ž๋Š” ์–‘์‹
(5, 6), -- ํ”ผ์ž๋Š” ๊ฐ„ํŽธ์‹
(1, 7), -- ๋œ์žฅ์ฐŒ๊ฐœ๋Š” ํ•œ์‹
(5, 7), -- ๋œ์žฅ์ฐŒ๊ฐœ๋Š” ๊ฐ„ํŽธ์‹
(2, 8), -- ํ–„๋ฒ„๊ฑฐ๋Š” ์–‘์‹
(5, 8), -- ํ–„๋ฒ„๊ฑฐ๋Š” ๊ฐ„ํŽธ์‹
(1, 9), -- ํฐ์Œ€๋ฐฅ์€ ํ•œ์‹
(9, 10), -- ์ƒ๋Ÿฌ๋“œ๋Š” ์ƒ๋Ÿฌ๋“œ
(4, 10), -- ์ƒ๋Ÿฌ๋“œ๋Š” ๊ฑด๊ฐ•์‹
(7, 11), -- ์—ฐ์–ด์Šคํ…Œ์ดํฌ๋Š” ํ•ด์‚ฐ๋ฌผ
(2, 11), -- ์—ฐ์–ด์Šคํ…Œ์ดํฌ๋Š” ์–‘์‹
(6, 12), -- ์ดˆ์ฝœ๋ฆฟ ์ผ€์ดํฌ๋Š” ๋””์ €ํŠธ
(10, 13),-- ๋ฒ ์ง€ํ„ฐ๋ธ” ์Šคํ”„๋Š” ์Šคํ”„
(3, 13), -- ๋ฒ ์ง€ํ„ฐ๋ธ” ์Šคํ”„๋Š” ์ฑ„์‹
(1, 14), -- ์นด๋ ˆ๋ผ์ด์Šค๋Š” ํ•œ์‹
(5, 14), -- ์นด๋ ˆ๋ผ์ด์Šค๋Š” ๊ฐ„ํŽธ์‹
(7, 15), -- ์ƒˆ์šฐ๋ณถ์Œ๋ฐฅ์€ ํ•ด์‚ฐ๋ฌผ
(1, 15); -- ์ƒˆ์šฐ๋ณถ์Œ๋ฐฅ์€ ํ•œ์‹

INSERT INTO ingredient (name)
VALUES ('๊น€'),
('์Œ€'),
('๊ณ„๋ž€'),
('๊น€์น˜'),
('์˜ค์ด'),
('ํ›„์ถ”'),
('๊ฐ„์žฅ'),
('์†Œ๊ธˆ'),
('ํ–„'),
('ํ† ๋งˆํ† '),
('๋ฐ€๊ฐ€๋ฃจ'),
('์ƒˆ์šฐ'),
('๋ฒ„ํ„ฐ'),
('์„คํƒ•'),
('์ดˆ์ฝœ๋ฆฟ'),
('๋ฒ„์„ฏ'),
('์–‘ํŒŒ'),
('ํ”ผ๋ง');

INSERT INTO ingredient_recipe (ingredient_id, recipe_id, requirement)
VALUES (1, 1, 'REQUIRED'), -- ๊น€์น˜๋ณถ์Œ๋ฐฅ
(2, 1, 'REQUIRED'), -- ๊น€์น˜๋ณถ์Œ๋ฐฅ
(3, 1, 'ALTERNATIVE'), -- ๊น€์น˜๋ณถ์Œ๋ฐฅ
(4, 1, 'OPTIONAL'), -- ๊น€์น˜๋ณถ์Œ๋ฐฅ
(2, 2, 'REQUIRED'), -- ๊น€๋ฐฅ
(3, 2, 'OPTIONAL'), -- ๊น€๋ฐฅ
(4, 2, 'REQUIRED'), -- ๊น€๋ฐฅ
(2, 3, 'REQUIRED'), -- ๊น€์น˜์ฐŒ๊ฐœ
(3, 3, 'REQUIRED'), -- ๊น€์น˜์ฐŒ๊ฐœ
(7, 3, 'REQUIRED'), -- ๊น€์น˜์ฐŒ๊ฐœ
(2, 4, 'REQUIRED'), -- ํ† ๋งˆํ† ์ŠคํŒŒ๊ฒŒํ‹ฐ
(5, 4, 'OPTIONAL'), -- ํ† ๋งˆํ† ์ŠคํŒŒ๊ฒŒํ‹ฐ
(8, 5, 'REQUIRED'), -- ๊ฐ„์žฅ๊ณ„๋ž€๋ฐฅ
(3, 5, 'REQUIRED'), -- ๊ฐ„์žฅ๊ณ„๋ž€๋ฐฅ
(9, 6, 'REQUIRED'), -- ํ”ผ์ž
(6, 6, 'OPTIONAL'), -- ํ”ผ์ž
(4, 7, 'REQUIRED'), -- ๋œ์žฅ์ฐŒ๊ฐœ
(2, 7, 'REQUIRED'), -- ๋œ์žฅ์ฐŒ๊ฐœ
(8, 8, 'OPTIONAL'), -- ํ–„๋ฒ„๊ฑฐ
(9, 8, 'REQUIRED'), -- ํ–„๋ฒ„๊ฑฐ
(2, 9, 'REQUIRED'), -- ํฐ์Œ€๋ฐฅ
(1, 9, 'OPTIONAL'), -- ํฐ์Œ€๋ฐฅ
(5, 10, 'REQUIRED'), -- ์ƒ๋Ÿฌ๋“œ
(8, 10, 'OPTIONAL'), -- ์ƒ๋Ÿฌ๋“œ
(10, 4, 'REQUIRED'), -- ํ† ๋งˆํ† ์ŠคํŒŒ๊ฒŒํ‹ฐ
(11, 6, 'REQUIRED'), -- ํ”ผ์ž
(12, 15, 'REQUIRED'), -- ์ƒˆ์šฐ๋ณถ์Œ๋ฐฅ
(13, 15, 'OPTIONAL'), -- ์ƒˆ์šฐ๋ณถ์Œ๋ฐฅ
(14, 12, 'REQUIRED'), -- ์ดˆ์ฝœ๋ฆฟ ์ผ€์ดํฌ
(15, 12, 'REQUIRED'), -- ์ดˆ์ฝœ๋ฆฟ ์ผ€์ดํฌ
(16, 13, 'REQUIRED'), -- ๋ฒ ์ง€ํ„ฐ๋ธ” ์Šคํ”„
(17, 13, 'REQUIRED'), -- ๋ฒ ์ง€ํ„ฐ๋ธ” ์Šคํ”„
(18, 14, 'OPTIONAL'); -- ์นด๋ ˆ๋ผ์ด์Šค

0 comments on commit 63377b6

Please sign in to comment.