Conversation
feat: Subscription, Summary, API κ°μ
feat: flywayμ€μ
Summary of ChangesHello @wlgusqkr, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! μ΄ PRμ λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§ κ΄λ¦¬μ κ²¬κ³ μ±μ λμ΄κ³ , μλ¦Ό λ° κ΅¬λ κ΄λ ¨ λΉμ¦λμ€ λ‘μ§μ 리ν©ν λ§νμ¬ μμ€ν μ μ μ°μ±κ³Ό νμ₯μ±μ κ°μ νλ λ° μ€μ μ λ‘λλ€. νΉν, μλ¦Όμ 'κΈ΄κΈ μ¬λΆ' κ°λ μ 'ν€μλ μΌμΉ μ¬λΆ'μ 'μλ¦Ό νμ±ν μ¬λΆ'λ‘ μΈλΆννμ¬ μ¬μ©μμκ² λ μ ννκ³ λ§μΆ€νλ μλ¦Ό κ²½νμ μ 곡ν μ μλλ‘ κΈ°λ°μ λ§λ ¨νμ΅λλ€. λν, 컨νΈλ‘€λ¬μ μ± μ λΆλ¦¬μ ꡬλ μ λ°μ΄νΈ κΈ°λ₯ λμ μ ν΅ν΄ μ½λμ μ μ§λ³΄μμ±μ ν₯μμμΌ°μ΅λλ€. Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with π and π on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Test Results1 testsβββ1 β
ββ0s β±οΈ Results for commit 6ccedf8. |
There was a problem hiding this comment.
Code Review
μ΄λ² ν 리νμ€νΈλ isUrgent νλλ₯Ό μ κ±°νκ³ isKeywordMatched νλλ₯Ό λμ
νλ λ± μ€μν 리ν©ν λ§μ ν¬ν¨νκ³ μμ΅λλ€. Flywayλ₯Ό ν΅ν λ°μ΄ν°λ² μ΄μ€ λ§μ΄κ·Έλ μ΄μ
μ΄ μΆκ°λμκ³ , μλ¦Ό λ° νΌλ κ΄λ ¨ 컨νΈλ‘€λ¬μ μλΉμ€ λ‘μ§μ΄ μ¬κ΅¬μ±λμμ΅λλ€. μ λ°μ μΌλ‘ μ½λλ² μ΄μ€λ₯Ό κ°μ νλ €λ λ
Έλ ₯μ΄ μΏλ³΄μ΄μ§λ§, λͺ κ°μ§ μ€μν μμ μ¬νμ΄ νμν©λλ€. νΉν isKeywordMatched νλμ μ©λμ λ°μ΄ν°λ² μ΄μ€ μ΄κΈ° μ€ν¬λ¦½νΈμ μ€λ₯λ μκΈν ν΄κ²°ν΄μΌ ν λ¬Έμ μ
λλ€. λν, ν
μ€νΈ μ½λμ μ£Όμ μ²λ¦¬μ μ¬μ©λμ§ μλ μμ‘΄μ± μ£Όμ
λ κ°μ μ΄ νμν©λλ€.
| // μ½μ§ μμ Summaryλ§ νν°λ§ | ||
| List<Summary> unreadSummaries = subscription.getSummaries().stream() | ||
| .filter(summary -> !summary.isRead()) | ||
| .filter(summary -> !summary.isKeywordMatched()) |
There was a problem hiding this comment.
!summary.isKeywordMatched()λ₯Ό μ¬μ©νμ¬ μ½μ§ μμ μμ½μ νν°λ§νκ³ μμ΅λλ€. isKeywordMatchedλ ν€μλ μΌμΉ μ¬λΆλ₯Ό λνλ΄λ νλλ‘, μμ½μ 'μ½μ' μνλ₯Ό λνλ΄λ λ° μ¬μ©λλ κ²μ μ μ νμ§ μμ΅λλ€. μ΄ λ‘μ§μ΄ μλλ λμμ΄λΌλ©΄ νλ μ΄λ¦μ΄ isRead λλ isUnreadμ κ°μ΄ λͺ
ννκ² λ³κ²½λμ΄μΌ ν©λλ€. νμ¬λ‘μλ νλ μ΄λ¦κ³Ό μ¬μ© λͺ©μ μ΄ μΌμΉνμ§ μμ νΌλμ μΌκΈ°ν μ μμ΅λλ€. λ§μ½ 'μ½μ' μνλ₯Ό μΆμ ν΄μΌ νλ€λ©΄ λ³λμ isRead νλλ₯Ό μ μ§νλ κ²μ΄ μ’μ΅λλ€.
| } | ||
|
|
||
|
|
||
| //κ·Έλ¦¬κ³ μ§κΈ μ’ λ²νΌμ ν λ²νΌμ λ§λ€μ΄μ μμ νμ΄μ§λ‘ λμ΄κ° μ μκ² ν΄μ€λ UIλ Createνμ΄μ§λ κ°μ§λ§ urlμ μ¬μ€μ ν μ μκ³ λ³μΉμ΄λ keywordλ μλ λ°μμ§λ§ μ€μ ν μ μμ΄ μ μΌλ¨ μ΄ μ μ νμ¬ κΈ΄κΈ μλμΈμ§ No newline at end of file |
| @Column(name = "is_keyword_matched", nullable = false) | ||
| private boolean isKeywordMatched; |
There was a problem hiding this comment.
is_read 컬λΌμ΄ is_keyword_matchedλ‘ λ³κ²½λμμ΅λλ€. μ΄ νλ μ΄λ¦μ μμ½μ΄ ν€μλμ μν΄ λ§€μΉλμλμ§ μ¬λΆλ₯Ό λνλ΄λ κ²μΌλ‘ 보μ
λλ€. νμ§λ§ markAsRead() λ©μλμμ μ΄ νλλ₯Ό trueλ‘ μ€μ νλ κ²μ μμ½μ΄ 'μ½νλ€'λ μλ―Έλ‘ μ¬μ©λλ κ²μΌλ‘ 보μ
λλ€. νλ μ΄λ¦κ³Ό μ¬μ© λͺ©μ μ΄ μΌμΉνμ§ μμ νΌλμ μΌκΈ°ν μ μμ΅λλ€. λ§μ½ 'μ½μ' μνλ₯Ό μΆμ ν΄μΌ νλ€λ©΄ isRead νλλ₯Ό μ μ§νκ±°λ, isKeywordMatchedμ μλ―Έλ₯Ό λͺ
νν νκ³ markAsReadμ κ°μ λ©μλ μ΄λ¦μ λ³κ²½ν΄μΌ ν©λλ€. νμ¬λ‘μλ isKeywordMatchedκ° 'μ½μ' μνλ₯Ό λνλ΄λ κ²μΌλ‘ μ€μ©λ κ°λ₯μ±μ΄ λμ΅λλ€.
| // Summaryλ₯Ό μ½μ μ²λ¦¬ | ||
| public void markAsRead() { | ||
| this.isRead = true; | ||
| this.isKeywordMatched = true; |
There was a problem hiding this comment.
markAsRead() λ©μλκ° isKeywordMatched νλλ₯Ό trueλ‘ μ€μ νκ³ μμ΅λλ€. isKeywordMatchedλ μμ½μ΄ ν€μλμ μν΄ λ§€μΉλμλμ§ μ¬λΆλ₯Ό λνλ΄λ νλμ¬μΌ ν©λλ€. μμ½μ΄ 'μ½νλ€'λ μνλ₯Ό λνλ΄κΈ° μν΄ μ΄ νλλ₯Ό μ¬μ©νλ κ²μ νλμ μλ―Έλ₯Ό μ곑νκ³ νΌλμ μΌκΈ°ν μ μμ΅λλ€. λ§μ½ 'μ½μ' μνλ₯Ό μΆμ ν΄μΌ νλ€λ©΄ λ³λμ isRead νλλ₯Ό μ¬μ©νκ±°λ, markAsRead λ©μλμ μ΄λ¦μ markAsKeywordMatched λ±μΌλ‘ λ³κ²½νμ¬ νλμ μλ―Έμ μΌμΉμμΌμΌ ν©λλ€.
| content varchar(255) not null, | ||
| created_at datetime(6) not null, | ||
| hash_tag varchar(255) not null, | ||
| is_read bit d not null, |
| .fetchJoin().where(subscription.user.id.eq(userId), summary.isRead.eq(false)) | ||
| .orderBy(subscription.isUrgent.desc(), summary.updatedAt.desc(), summary.id.desc()) | ||
| return queryFactory.selectFrom(summary).innerJoin(summary.subscription, subscription).fetchJoin() | ||
| .where(subscription.user.id.eq(userId)).orderBy(summary.updatedAt.desc(), summary.id.desc()) |
There was a problem hiding this comment.
μ΄μ μ½λμμλ summary.isRead.eq(false) 쑰건μ μ¬μ©νμ¬ μ½μ§ μμ μμ½λ§ κ°μ Έμμ§λ§, νμ¬λ μ΄ μ‘°κ±΄μ΄ μ κ±°λμμ΅λλ€. μ΄λ νΌλμ μ½μ μμ½λ ν¬ν¨λ μ μμμ μλ―Έν©λλ€. λ§μ½ νΌλκ° 'μ½μ§ μμ' μμ½λ§ 보μ¬μ£Όλ κ²μ΄ μλμλ€λ©΄, μ΄ λ³κ²½μ κΈ°λ₯μ μ€λ₯λ‘ μ΄μ΄μ§ μ μμ΅λλ€. μλλ λ³κ²½μΈμ§ νμΈνκ³ , λ§μ½ μ½μ§ μμ μμ½λ§ 보μ¬μ€μΌ νλ€λ©΄ ν΄λΉ 쑰건μ λ€μ μΆκ°ν΄μΌ ν©λλ€.
| .fetchJoin().where(subscription.user.id.eq(userId), summary.isRead.eq(false)) | ||
| .orderBy(subscription.isUrgent.desc(), summary.updatedAt.desc(), summary.id.desc()) | ||
| .fetch(); | ||
| return queryFactory.selectFrom(summary).innerJoin(summary.subscription, subscription).fetchJoin() |
There was a problem hiding this comment.
μ΄μ μ½λμμλ summary.isRead.eq(false) 쑰건μ μ¬μ©νμ¬ μ½μ§ μμ μμ½λ§ κ°μ Έμμ§λ§, νμ¬λ μ΄ μ‘°κ±΄μ΄ μ κ±°λμμ΅λλ€. μ΄λ ν νΌλμ μ½μ μμ½λ ν¬ν¨λ μ μμμ μλ―Έν©λλ€. λ§μ½ ν νΌλκ° 'μ½μ§ μμ' μμ½λ§ 보μ¬μ£Όλ κ²μ΄ μλμλ€λ©΄, μ΄ λ³κ²½μ κΈ°λ₯μ μ€λ₯λ‘ μ΄μ΄μ§ μ μμ΅λλ€. μλλ λ³κ²½μΈμ§ νμΈνκ³ , λ§μ½ μ½μ§ μμ μμ½λ§ 보μ¬μ€μΌ νλ€λ©΄ ν΄λΉ 쑰건μ λ€μ μΆκ°ν΄μΌ ν©λλ€.
| // @Test | ||
| // void μ κ·_ꡬλ μ_λ±λ‘νλ€() throws Exception { | ||
| // // given | ||
| // SubscriptionCreateRequestDto request = new SubscriptionCreateRequestDto( | ||
| // 1L, | ||
| // List.of(1L, 2L), | ||
| // "λμλ§μ", | ||
| // true | ||
| // ); | ||
| // | ||
| // given(subscriptionCommandService.createSubscription(anyString(), anyString(), any(SubscriptionCreateRequestDto.class))) | ||
| // .willReturn(SubscriptionCreationResponseDto.builder() | ||
| // .subscriptionId(1L) | ||
| // .build() | ||
| // ); | ||
| // | ||
| // // when then | ||
| // mockMvc.perform( | ||
| // post("/api/subscriptions") | ||
| // .content(objectMapper.writeValueAsString(request)) | ||
| // .header("X-User-ID", "test-user-uuid") | ||
| // .header("X-Device-Secret", "test-device-secret") | ||
| // .contentType(MediaType.APPLICATION_JSON) | ||
| // ) | ||
| // .andDo(print()) | ||
| // .andExpect(status().isOk()) | ||
| // .andDo(restDocsHandler.document( | ||
| // requestFields( | ||
| // fieldWithPath("urlId").type(JsonFieldType.NUMBER) | ||
| // .description("ꡬλ ν URLμ ID"), | ||
| // fieldWithPath("keywordIds").type(JsonFieldType.ARRAY) | ||
| // .optional() | ||
| // .description("ꡬλ μ μ°κ΄λ ν€μλ ID 리μ€νΈ"), | ||
| // fieldWithPath("alias").type(JsonFieldType.STRING) | ||
| // .description("ꡬλ λ³μΉ"), | ||
| // fieldWithPath("isUrgent").type(JsonFieldType.BOOLEAN) | ||
| // .description("κΈ΄κΈ μλ¦Ό μ¬λΆ") | ||
| // ), | ||
| // responseFields( | ||
| // fieldWithPath("errorCode").type(JsonFieldType.NULL) | ||
| // .description("μλ¬ μ½λ, μ±κ³΅ μ null"), | ||
| // fieldWithPath("message").type(JsonFieldType.STRING) | ||
| // .description("μλ΅ λ©μμ§"), | ||
| // fieldWithPath("result").type(JsonFieldType.OBJECT) | ||
| // .description("μλ΅ λ°μ΄ν°"), | ||
| // fieldWithPath("result.subscriptionId").type(JsonFieldType.NUMBER) | ||
| // .description("μμ±λ ꡬλ μ ID") | ||
| // ) | ||
| // )); | ||
| // } | ||
| } |
There was a problem hiding this comment.
μ κ·_ꡬλ
μ_λ±λ‘νλ€() ν
μ€νΈ λ©μλκ° μ£Όμ μ²λ¦¬λμ΄ μμ΅λλ€. ν΅μ¬ κΈ°λ₯μ λν ν
μ€νΈκ° λΉνμ±νλλ©΄ μ½λ λ³κ²½ μ νκ·λ₯Ό κ°μ§νκΈ° μ΄λ ΅μ΅λλ€. μ΄ ν
μ€νΈλ₯Ό λ€μ νμ±ννκ³ , λ³κ²½λ λ‘μ§μ λ§μΆ° μ
λ°μ΄νΈν΄μΌ ν©λλ€. ν
μ€νΈ 컀λ²λ¦¬μ§λ₯Ό μ μ§νλ κ²μ μ½λ νμ§μ λ§€μ° μ€μν©λλ€.
| public class AlarmQueryController implements AlarmApi { | ||
|
|
||
| private final AlarmQueryService alarmQueryService; | ||
| private final SummaryCommandService summaryCommandService; |
There was a problem hiding this comment.
SummaryCommandServiceκ° μ£Όμ
λμμ§λ§ μ΄ ν΄λμ€ λ΄μμ μ¬μ©λμ§ μμ΅λλ€. μ¬μ©νμ§ μλ μμ‘΄μ±μ μ κ±°νμ¬ μ½λμ λͺ
νμ±μ λμ΄κ³ λΆνμν μμ ν λΉμ λ°©μ§νλ κ²μ΄ μ’μ΅λλ€.
| private final SummaryCommandService summaryCommandService; | |
| private final AlarmQueryService alarmQueryService; |
| alias varchar(255) not null, | ||
| created_at datetime(6) not null, | ||
| is_alarm_enabled bit not null, | ||
| is_urgent bit not null, |
There was a problem hiding this comment.
subscriptions ν
μ΄λΈμ is_urgent 컬λΌμ΄ μ μλμ΄ μμ΅λλ€. νμ§λ§ V2__update_schema.sqlμμ μ΄ μ»¬λΌμ μμ νκ³ μμ΅λλ€. μ΄κΈ° μ€ν€λ§(V1)λ μ΅μ’
μ μΌλ‘ μ¬μ©λ μ€ν€λ§λ₯Ό λ°μνλ κ²μ΄ μ’μ΅λλ€. λ§μ½ is_urgentκ° λ μ΄μ νμ μλ νλλΌλ©΄ V1 μ€ν¬λ¦½νΈμμλΆν° μ κ±°νκ±°λ, V1 μ€ν¬λ¦½νΈκ° μ΄λ―Έ λ°°ν¬λ μνλΌλ©΄ V2μμ μμ νλ κ²μ΄ λ§μ΅λλ€. νμ¬ μν©μμλ V1 μ€ν¬λ¦½νΈκ° μ΅μ μν°ν° λͺ¨λΈμ λ°μνμ§ λͺ»νκ³ μλ κ²μΌλ‘ 보μ
λλ€.
Related issue π
μ΄λ€ λ³κ²½μ¬νμ΄ μμλμ?
Work Description βοΈ
μμ λ΄μ©μ μμ±ν΄μ£ΌμΈμ.
Uncompleted Tasks π
To Reviewers π’
리뷰μ΄κ° μλ©΄ μ’μ λ΄μ©μ μμ±ν΄μ£ΌμΈμ.