-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
π :: (Meogo-42) post good #43
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.meogo.domain.bookmark | ||
|
||
import org.meogo.domain.user.domain.User | ||
import org.meogo.global.base.BaseUUIDEntity | ||
import java.util.UUID | ||
import javax.persistence.Entity | ||
import javax.persistence.FetchType | ||
import javax.persistence.JoinColumn | ||
import javax.persistence.ManyToOne | ||
|
||
@Entity | ||
class Bookmark( | ||
id: UUID? = null, | ||
|
||
val schoolId: Int? = 0, | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user_id", nullable = false) | ||
val user: User | ||
) : BaseUUIDEntity(id) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.meogo.domain.bookmark | ||
|
||
import org.meogo.domain.user.domain.User | ||
import org.springframework.data.jpa.repository.JpaRepository | ||
import java.util.UUID | ||
|
||
interface BookmarkRepository : JpaRepository<Bookmark, UUID> { | ||
fun findAllBySchoolId(schoolId: Int): List<Bookmark>? | ||
|
||
fun existsBySchoolIdAndUser(schoolId: Int, user: User): Boolean | ||
|
||
fun deleteBySchoolIdAndUser(schoolId: Int, user: User) | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,42 @@ | ||||||||||||||||||||||||
package org.meogo.domain.bookmark | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
import org.meogo.domain.post.domain.PostRepository | ||||||||||||||||||||||||
import org.meogo.domain.user.exception.UserNotFoundException | ||||||||||||||||||||||||
import org.meogo.domain.user.facade.UserFacade | ||||||||||||||||||||||||
import org.springframework.stereotype.Service | ||||||||||||||||||||||||
import org.springframework.transaction.annotation.Transactional | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
@Service | ||||||||||||||||||||||||
class BookmarkService( | ||||||||||||||||||||||||
private val bookmarkRepository: BookmarkRepository, | ||||||||||||||||||||||||
private val userFacade: UserFacade, | ||||||||||||||||||||||||
private val postRepository: PostRepository | ||||||||||||||||||||||||
) { | ||||||||||||||||||||||||
Comment on lines
+9
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. μ¬μ©λμ§ μλ μμ‘΄μ± μ κ±° νμ
λ€μκ³Ό κ°μ΄ μμ νλ κ²μ΄ μ’μ΅λλ€: @Service
class BookmarkService(
private val bookmarkRepository: BookmarkRepository,
- private val userFacade: UserFacade,
- private val postRepository: PostRepository
+ private val userFacade: UserFacade
) { λ§μ½ π Committable suggestion
Suggested change
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
@Transactional | ||||||||||||||||||||||||
fun execute(schoolId: Int) { | ||||||||||||||||||||||||
val user = userFacade.currentUser() ?: throw UserNotFoundException | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
bookmarkRepository.save( | ||||||||||||||||||||||||
Bookmark( | ||||||||||||||||||||||||
schoolId = schoolId, | ||||||||||||||||||||||||
user = user | ||||||||||||||||||||||||
) | ||||||||||||||||||||||||
) | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+16
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. μ€λ³΅ λΆλ§ν¬ μ²λ¦¬ λ‘μ§ μΆκ° νμ νμ¬ κ΅¬νμ λμΌν λΆλ§ν¬ μμ± μ μ μ΄λ―Έ μ‘΄μ¬νλμ§ νμΈνλ λ‘μ§μ μΆκ°νλ κ²μ΄ μ’μ΅λλ€. μλ₯Ό λ€μ΄: @Transactional
fun execute(schoolId: Int) {
val user = userFacade.currentUser() ?: throw UserNotFoundException
if (!bookmarkRepository.existsBySchoolIdAndUser(schoolId, user)) {
bookmarkRepository.save(
Bookmark(
schoolId = schoolId,
user = user
)
)
} else {
// μ΄λ―Έ μ‘΄μ¬νλ λΆλ§ν¬μ λν μ²λ¦¬ (μ: μμΈ λ°μ λλ 무μ)
}
} μ΄λ κ² νλ©΄ μ€λ³΅ λΆλ§ν¬λ₯Ό λ°©μ§νκ³ λ°μ΄ν° μΌκ΄μ±μ μ μ§ν μ μμ΅λλ€. |
||||||||||||||||||||||||
|
||||||||||||||||||||||||
fun queryBookmarkedPost(schoolId: Int): Int { | ||||||||||||||||||||||||
val posts = bookmarkRepository.findAllBySchoolId(schoolId) | ||||||||||||||||||||||||
return posts?.size ?: 0 | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+28
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion λ©μλ μ΄λ¦ λ³κ²½ λ° μΏΌλ¦¬ μ΅μ ν νμ νμ¬ λ©μλ μ΄λ¦ λ€μκ³Ό κ°μ΄ κ°μ ν μ μμ΅λλ€:
fun countBookmarksBySchoolId(schoolId: Int): Int {
return bookmarkRepository.countBySchoolId(schoolId)
}
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
fun queryIsBookmarked(schoolId: Int): Boolean { | ||||||||||||||||||||||||
val user = userFacade.currentUser() ?: throw UserNotFoundException | ||||||||||||||||||||||||
return bookmarkRepository.existsBySchoolIdAndUser(schoolId, user) | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+33
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion μμΈ μ²λ¦¬ μΌκ΄μ± κ°μ νμ
μμΈ μ²λ¦¬λ₯Ό μλΉμ€ λ 벨 μμμμ ν΅μΌμ μΌλ‘ μ²λ¦¬νλ κ²μ΄ μ’μ΅λλ€. μλ₯Ό λ€μ΄: fun queryIsBookmarked(schoolId: Int): Boolean {
val user = userFacade.currentUser()
return bookmarkRepository.existsBySchoolIdAndUser(schoolId, user)
} κ·Έλ¦¬κ³ |
||||||||||||||||||||||||
|
||||||||||||||||||||||||
fun deleteBookmark(schoolId: Int) { | ||||||||||||||||||||||||
val user = userFacade.currentUser() ?: throw UserNotFoundException | ||||||||||||||||||||||||
bookmarkRepository.deleteBySchoolIdAndUser(schoolId, user) | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+38
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. νΈλμμ μ²λ¦¬ λ° μμΈ μν© κ³ λ € νμ
λ€μκ³Ό κ°μ΄ μμ νλ κ²μ΄ μ’μ΅λλ€: @Transactional
fun deleteBookmark(schoolId: Int) {
val user = userFacade.currentUser()
val deleted = bookmarkRepository.deleteBySchoolIdAndUser(schoolId, user)
if (deleted == 0) {
// λΆλ§ν¬κ° μ‘΄μ¬νμ§ μλ κ²½μ°μ λν μ²λ¦¬
// μ: throw BookmarkNotFoundException(schoolId, user.id)
}
} μ΄λ κ² νλ©΄ νΈλμμ μ²λ¦¬κ° 보μ₯λκ³ , μ‘΄μ¬νμ§ μλ λΆλ§ν¬λ₯Ό μμ νλ €λ μλλ₯Ό μ μ ν μ²λ¦¬ν μ μμ΅λλ€. |
||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,24 @@ | ||
package org.meogo.domain.good | ||
package org.meogo.domain.good.domain | ||
|
||
import org.meogo.domain.post.domain.Post | ||
import org.meogo.domain.user.domain.User | ||
import org.meogo.global.base.BaseUUIDEntity | ||
import java.util.UUID | ||
import javax.persistence.Entity | ||
import javax.persistence.FetchType | ||
import javax.persistence.JoinColumn | ||
import javax.persistence.ManyToOne | ||
import org.meogo.domain.post.domain.Post | ||
import org.meogo.domain.user.domain.User | ||
import org.meogo.global.base.BaseUUIDEntity | ||
|
||
@Entity | ||
class Bookmark ( | ||
class Good( | ||
id: UUID? = null, | ||
|
||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "post_id", nullable = true) | ||
val post: Post? = null, | ||
|
||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user_id", nullable = false) | ||
val user: User | ||
|
||
) : BaseUUIDEntity(id) | ||
) : BaseUUIDEntity(id) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.meogo.domain.good.domain | ||
|
||
import org.meogo.domain.post.domain.Post | ||
import org.meogo.domain.user.domain.User | ||
import org.springframework.data.jpa.repository.JpaRepository | ||
import java.util.UUID | ||
|
||
interface GoodRepository : JpaRepository<Good, UUID> { | ||
fun findByUserAndPost(user: User, post: Post): Good | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
νμ¬ λ©μλ μ μμλ λ κ°μ§ μ μ¬μ μΈ λ¬Έμ κ° μμ΅λλ€:
λ€μκ³Ό κ°μ΄ μμ νλ κ²μ κ³ λ €ν΄λ³΄μΈμ: -fun findByUserAndPost(user: User, post: Post): Good
+fun findByUserAndPost(user: User, post: Post): Good? λλ μ¬λ¬ μν°ν°λ₯Ό λ°ννλλ‘ λ³κ²½: -fun findByUserAndPost(user: User, post: Post): Good
+fun findAllByUserAndPost(user: User, post: Post): List<Good> μ νν μ κ·Ό λ°©μμ λ°λΌ μλΉμ€ λ μ΄μ΄μμ μ μ ν μ²λ¦¬ν΄μΌ ν©λλ€.
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.meogo.domain.good.presentation | ||
|
||
import lombok.RequiredArgsConstructor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lombok μ΄λ Έν μ΄μ μ κ±° νμ Kotlinμμλ Lombokμ΄ νμνμ§ μμ΅λλ€. λ€μκ³Ό κ°μ΄ μμ ν΄μ£ΌμΈμ: -import lombok.RequiredArgsConstructor
-
import org.meogo.domain.good.service.GoodService
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.DeleteMapping
@@ -10,7 +9,6 @@ import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestController
-@RequiredArgsConstructor
@RestController
@RequestMapping("/good")
class GoodController( Also applies to: 13-13 |
||
import org.meogo.domain.good.service.GoodService | ||
import org.springframework.http.HttpStatus | ||
import org.springframework.web.bind.annotation.DeleteMapping | ||
import org.springframework.web.bind.annotation.PostMapping | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RequestParam | ||
import org.springframework.web.bind.annotation.ResponseStatus | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping("/good") | ||
class GoodController( | ||
private val goodService: GoodService | ||
) { | ||
@ResponseStatus(HttpStatus.CREATED) | ||
@PostMapping | ||
fun addGood(@RequestParam(name = "post_id")postId: Long) = | ||
goodService.addGood(postId) | ||
Comment on lines
+19
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion addGood λ©μλ κ°μ μ μ
λ€μκ³Ό κ°μ΄ μμ ν΄λ³΄μΈμ: @ResponseStatus(HttpStatus.CREATED)
@PostMapping
fun addGoodToPost(@RequestParam(name = "post_id") postId: Long): ResponseEntity<Any> {
return try {
goodService.addGood(postId)
ResponseEntity.status(HttpStatus.CREATED).build()
} catch (e: Exception) {
ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Failed to add good: ${e.message}")
}
} |
||
|
||
@ResponseStatus(HttpStatus.NO_CONTENT) | ||
@DeleteMapping | ||
fun deleteGood(@RequestParam(name = "post_id")postId: Long) = | ||
goodService.deleteGood(postId) | ||
Comment on lines
+24
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion deleteGood λ©μλ κ°μ μ μ
λ€μκ³Ό κ°μ΄ μμ ν΄λ³΄μΈμ: @DeleteMapping
fun removeGoodFromPost(@RequestParam(name = "post_id") postId: Long): ResponseEntity<Any> {
return try {
goodService.deleteGood(postId)
ResponseEntity.noContent().build()
} catch (e: Exception) {
ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Failed to remove good: ${e.message}")
}
} μ΄λ κ² μμ νλ©΄ |
||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
package org.meogo.domain.good.service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import org.meogo.domain.good.domain.Good | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import org.meogo.domain.good.domain.GoodRepository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import org.meogo.domain.post.domain.PostRepository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import org.meogo.domain.user.exception.UserNotFoundException | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import org.meogo.domain.user.facade.UserFacade | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import org.springframework.stereotype.Service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import org.springframework.transaction.annotation.Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class GoodService( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private val goodRepository: GoodRepository, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private val userFacade: UserFacade, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private val postRepository: PostRepository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fun addGood(postId: Long) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val user = userFacade.currentUser() ?: throw UserNotFoundException | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val post = postRepository.findById(postId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
post.addGood() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goodRepository.save( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Good( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
post = post, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
user = user | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+18
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addGood λ©μλμ λͺ κ°μ§ κ°μ μ΄ νμν©λλ€. λ©μλμ κΈ°λ³Έ ꡬ쑰λ μ’μ§λ§, λ€μ μ¬νλ€μ κ°μ νλ©΄ μ’κ² μ΅λλ€:
λ€μκ³Ό κ°μ΄ μ½λλ₯Ό μμ ν΄ λ³΄μΈμ: @Transactional
fun addGood(postId: Long) {
- val user = userFacade.currentUser() ?: throw UserNotFoundException
- val post = postRepository.findById(postId)
+ val user = userFacade.currentUser() ?: throw UserNotFoundException()
+ val post = postRepository.findById(postId).orElseThrow { PostNotFoundException(postId) }
+
+ if (goodRepository.existsByUserAndPost(user, post)) {
+ throw AlreadyGoodException(postId)
+ }
post.addGood()
goodRepository.save(
Good(
post = post,
user = user
)
)
} μ΄ λ³κ²½μ¬νλ€μ μμΈ μ²λ¦¬λ₯Ό κ°μ νκ³ , μ€λ³΅ "μ’μμ"λ₯Ό λ°©μ§ν©λλ€. π Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fun deleteGood(postId: Long) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val user = userFacade.currentUser() ?: throw UserNotFoundException | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val post = postRepository.findById(postId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val good = goodRepository.findByUserAndPost(user, post) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
post.deleteGood() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
goodRepository.delete(good) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+32
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. deleteGood λ©μλλ κ°μ μ΄ νμν©λλ€. μ΄ λ©μλλ addGoodκ³Ό μ μ¬ν λ¬Έμ μ λ€μ΄ μμ΅λλ€:
λ€μκ³Ό κ°μ΄ μ½λλ₯Ό μμ ν΄ λ³΄μΈμ: @Transactional
fun deleteGood(postId: Long) {
- val user = userFacade.currentUser() ?: throw UserNotFoundException
- val post = postRepository.findById(postId)
- val good = goodRepository.findByUserAndPost(user, post)
+ val user = userFacade.currentUser() ?: throw UserNotFoundException()
+ val post = postRepository.findById(postId).orElseThrow { PostNotFoundException(postId) }
+ val good = goodRepository.findByUserAndPost(user, post) ?: throw GoodNotFoundException(postId)
post.deleteGood()
goodRepository.delete(good)
} μ΄ λ³κ²½μ¬νλ€μ μμΈ μ²λ¦¬λ₯Ό κ°μ νκ³ , μ‘΄μ¬νμ§ μλ "μ’μμ"λ₯Ό μμ νλ €λ μλλ₯Ό λ°©μ§ν©λλ€. π Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -62,5 +62,9 @@ class Post( | |||||||||||||||||
this.good += 1 | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
fun deleteGood() { | ||||||||||||||||||
this.good -= 1 | ||||||||||||||||||
} | ||||||||||||||||||
Comment on lines
+65
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. μμ κ° μ²΄ν¬ μΆκ° νμ
λ€μκ³Ό κ°μ΄ μμ νλ κ²μ κ³ λ €ν΄λ³΄μΈμ: fun deleteGood() {
- this.good -= 1
+ if (this.good > 0) {
+ this.good -= 1
+ }
} π Committable suggestion
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
fun format(date: LocalDateTime) = date.format(DateTimeFormatter.ofPattern("yy.MM.dd HH:mm"))!! | ||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
schoolId
μμ±μ λ νμ© μ¬λΆμ κΈ°λ³Έκ°μ μ¬κ³ ν΄ λ³΄μΈμ.schoolId
κ° λμ νμ©νκ³ κΈ°λ³Έκ°μΌλ‘ 0μ μ¬μ©νλ κ²μ΄ μλλ μ€κ³μΈμ§ νμΈν΄ μ£ΌμΈμ. λ§μ½schoolId
κ° νμ νλλΌλ©΄, λμ νμ©νμ§ μλλ‘ λ³κ²½νκ³ μλ―Έ μλ κΈ°λ³Έκ°μ μ€μ νκ±°λ κΈ°λ³Έκ° μμ΄ νμ νλΌλ―Έν°λ‘ λ§λλ κ²μ΄ μ’μ΅λλ€.λ€μκ³Ό κ°μ΄ λ³κ²½μ κ³ λ €ν΄ λ³΄μΈμ:
λλ μλ―Έ μλ κΈ°λ³Έκ°μ΄ μλ€λ©΄:
κ·Έλ¦¬κ³ μμ±μμμ
schoolId
λ₯Ό νμ νλΌλ―Έν°λ‘ λ°λλ‘ λ³κ²½νμΈμ.π Committable suggestion