Skip to content

Commit

Permalink
v1.0.1
Browse files Browse the repository at this point in the history
πŸš€ Feature Updates

- 차트 라이브러리 버전 μ—…κ·Έλ ˆμ΄λ“œ

πŸ”§ Bug Fixes

- νšŒμ›κ°€μž… μ‹œ λΉ„λ°€λ²ˆν˜Έμ— νŠΉμˆ˜λ¬Έμžκ°€ 없어도 νšŒμ›κ°€μž… κ°€λŠ₯ν•œ 였λ₯˜ μˆ˜μ •
- 링크가 λΉ„μ–΄μžˆμ„ μ‹œ 등둝 λ²„νŠΌ λΉ„ν™œμ„±ν™”λ˜λ„λ‘ μˆ˜μ •

Co-Authored-By: EunhoKang <[email protected]>
Co-Authored-By: ootr47 <[email protected]>
Co-Authored-By: 손문기 <[email protected]>
Co-Authored-By: ByeongIk Choi <[email protected]>
  • Loading branch information
5 people committed Dec 14, 2023
1 parent 88d9dc1 commit f818ce8
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 24 deletions.
91 changes: 78 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,93 @@ PriceGuardλŠ” κ΅­λ‚΄ μƒκ±°λž˜ μ‚¬μ΄νŠΈλ“€μ˜ μƒν’ˆ 가격을 μΆ”μ ν•©λ‹ˆλ‹€.

우리 νŒ€μ€ 이 ν”„λ‘œμ νŠΈμ—μ„œ λ‹€μŒκ³Ό 같은 기술적 도전 과제λ₯Ό ν•΄κ²°ν•˜λ € ν•©λ‹ˆλ‹€.

1. κ·Έλž˜ν”„ μž‘μ„±μ„ μœ„ν•œ λŒ€μš©λŸ‰μ˜ μ‹œκ³„μ—΄ 데이터λ₯Ό μ •μ˜ν•˜κ³  이λ₯Ό 효율적으둜 μ²˜λ¦¬ν•˜λŠ” 방법을 κ³ μ•ˆν•œλ‹€.
2. λ‹€μˆ˜μ˜ μ‚¬μš©μžμ— λŒ€ν•΄ 짧은 주기둜 데이터λ₯Ό μˆ˜μ§‘ν•΄μ•Όν•˜λŠ” μ‹œλ‚˜λ¦¬μ˜€μ— λŒ€ν•œ 효율적인 해결책을 μ°ΎλŠ”λ‹€.
3. κ°œλ°œν•œ κΈ°λŠ₯을 보닀 일반적인 상황에 μ“Έ 수 μžˆλ„λ‘ λΌμ΄λΈŒλŸ¬λ¦¬ν™”ν•œλ‹€.
1. κ·Έλž˜ν”„λ₯Ό 그릴 수 μžˆλŠ” κΈ°λŠ₯을 κ°œλ°œν•˜κ³  이λ₯Ό 보닀 일반적인 상황에 μ“Έ 수 μžˆλ„λ‘ λΌμ΄λΈŒλŸ¬λ¦¬ν™”ν•œλ‹€.
2. λ‹€μ–‘ν•œ μ•ˆλ“œλ‘œμ΄λ“œ ν…Œλ§ˆμ— λŒ€μ‘ν•  수 μžˆλŠ” μ•ˆλ“œλ‘œμ΄λ“œ 앱을 κ°œλ°œν•œλ‹€.
3. 주기적으둜 데이터λ₯Ό μˆ˜μ§‘ν•˜κ³ , λ‹€μˆ˜μ˜ μ‚¬μš©μžμ—κ²Œ λŒ€λŸ‰μ˜ 데이터λ₯Ό 전달 및 μ²˜λ¦¬ν•˜λŠ” 과정에 λŒ€ν•œ 효율적인 해결책을 μ°ΎλŠ”λ‹€.

이와 같은 기술적 도전을 ν•΄κ²°ν•˜λŠ” 과정은 μ•„λž˜ λ§ν¬μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

1. [κ·Έλž˜ν”„ 라이브러리 κ΅¬ν˜„](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/%EA%B7%B8%EB%9E%98%ED%94%84-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EA%B0%9C%EB%B0%9C-%EA%B8%B0%EB%A1%9D)
2. [데이터 캐싱](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/Cache-%EC%A0%81%EC%9A%A9%EA%B8%B0)
3. [DB 쿼리 κ°œμ„ ](https://velog.io/@kdogs/MongoDB%EC%97%90%EC%84%9C-%EC%BF%BC%EB%A6%AC-%EC%84%B1%EB%8A%A5-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0)
2. [μ•ˆλ“œλ‘œμ΄λ“œ ν…Œλ§ˆ 적용](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%ED%85%8C%EB%A7%88-%EC%A0%81%EC%9A%A9)
3. [데이터 캐싱](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/Cache-%EC%A0%81%EC%9A%A9%EA%B8%B0)

κ·Έλž˜ν”„ 라이브러리 κ΅¬ν˜„ 및 배포 μ €μž₯μ†ŒλŠ” μ—¬κΈ°μ„œ ν™•μΈν•΄μ£Όμ„Έμš”.

<a href="https://central.sonatype.com/artifact/app.priceguard/materialchart/overview">
<img src="https://img.shields.io/maven-central/v/app.priceguard/materialchart?color=0096FF" />
</a>

<a href="https://github.com/Taewan-P/material-android-chart/">
<img src="https://img.shields.io/badge/materialchart-181717?logo=github&logoColor=FFFFFF" />
</a>

[κ·Έλž˜ν”„ 라이브러리 κ΅¬ν˜„ 및 배포 μ €μž₯μ†Œ](https://github.com/Taewan-P/material-android-chart)λŠ” μ—¬κΈ°μ„œ ν™•μΈν•΄μ£Όμ„Έμš”.

## ❓ 문제 ν•΄κ²°

ν”„λ‘œμ νŠΈ 진행 κ³Όμ •μ—μ„œ λ§Œλ‚œ μ΄μŠˆλ“€κ³Ό ν•΄κ²° 방법에 λŒ€ν•΄ κΈ°μˆ ν•©λ‹ˆλ‹€. μ•„λž˜ λ§ν¬μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

1. [μ•ˆλ“œλ‘œμ΄λ“œ ν…Œλ§ˆ 적용](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%ED%85%8C%EB%A7%88-%EC%A0%81%EC%9A%A9)
2. [λ©”λͺ¨λ¦¬ λˆ„μˆ˜](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/TroubleShooting-%E2%80%90-Memory-Leak)
3. [JWT 인증 처리](https://velog.io/@mks1103/JWT%EB%A1%9C-%EC%9D%B8%EC%A6%9D-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0)
4. [HTTPS](https://velog.io/@kdogs/HTTPS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0feat.-Lets-Encrypt)
5. [Navigation λ°±μŠ€νƒ 였λ₯˜](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/TroubleShooting-%E2%80%90-Navigation-%EB%B0%B1%EC%8A%A4%ED%83%9D-%EC%98%A4%EB%A5%98)
6. [ν…Œλ§ˆ λ³€κ²½](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/ν…Œλ§ˆ-λ³€κ²½-(compose-vs-xml))
**DB 쿼리 κ°œμ„ **
> 가격 κ·Έλž˜ν”„ λ°μ΄ν„°λŠ” DBμ—μ„œ 자주 쑰회되며, 1κ°œμ›”, 3κ°œμ›” λ‹¨μœ„λ‘œ 넓은 λ²”μœ„λ₯Ό 가진 데이터λ₯Ό 뢈러였기 λ•Œλ¬Έμ— 양이 λ§ŽμŠ΅λ‹ˆλ‹€.
>
> ν˜„μž¬ ν”„λ‘œμ νŠΈ κ΅¬μ‘°μ—μ„œ 데이터 쑰회 μ„±λŠ₯을 ν–₯μƒμ‹œν‚€κΈ° μœ„ν•΄ μ–΄λ–€ λ…Έλ ₯을 ν–ˆλŠ”μ§€ κΈ°λ‘ν–ˆμŠ΅λ‹ˆλ‹€.
>
> [λ°”λ‘œκ°€κΈ°](https://velog.io/@kdogs/MongoDB%EC%97%90%EC%84%9C-%EC%BF%BC%EB%A6%AC-%EC%84%B1%EB%8A%A5-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0)
**λ©”λͺ¨λ¦¬ λˆ„μˆ˜**
> μ•ˆλ“œλ‘œμ΄λ“œ μ•± 개발 κ³Όμ •μ—μ„œ 발견된 μ—¬λŸ¬ λ©”λͺ¨λ¦¬ λˆ„μˆ˜ 상황에 λŒ€ν•΄ μ†Œκ°œν•©λ‹ˆλ‹€.
>
> μ–΄λ–»κ²Œ λ°œκ²¬ν–ˆλŠ”μ§€, μ™œ λ°œμƒν•˜λŠ”μ§€, μ–΄λ–»κ²Œ ν•΄κ²°ν–ˆλŠ”μ§€ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.
>
> [λ°”λ‘œκ°€κΈ°](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/TroubleShooting-%E2%80%90-Memory-Leak)
**RecyclerView κ°±μ‹  였λ₯˜**
> μ•Œλ¦Ό ν† κΈ€μ˜ 값을 λ³€κ²½ν•˜κ³ , μŠ€ν¬λ‘€μ„ λ‚΄λ Έλ‹€κ°€ λ‹€μ‹œ λŒμ•„μ˜€λ©΄ ν•΄λ‹Ή ν† κΈ€μ˜ 값이 λ³€κ²½ μ΄μ „μ˜ κ°’μœΌλ‘œ λ˜λŒμ•„κ°€λŠ” ν˜„μƒμ΄ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.
>
> μ–΄λ–€ 뢀뢄이 잘λͺ»λ˜μ—ˆκ³  μ–΄λ–»κ²Œ ν•΄κ²°ν–ˆλŠ”μ§€λ₯Ό λ‹€λ£¨λŠ” λ¬Έμ„œμž…λ‹ˆλ‹€.
>
> [λ°”λ‘œκ°€κΈ°](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/Troubleshooting-%E2%80%90-RecyclerView%EC%9D%98-View%EA%B0%80-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%B0%96%EC%9C%BC%EB%A1%9C-%EB%B2%97%EC%96%B4%EB%82%98%EB%A9%B4-%EA%B0%92%EC%9D%B4-%EB%B0%94%EB%80%8C%EB%8A%94-%ED%98%84%EC%83%81)
**JWT 인증 처리**
> ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν•˜λ©° μ‚¬μš©μž 인증을 κ΅¬ν˜„ν–ˆλ˜ 과정에 λŒ€ν•΄ μ μ–΄λ³΄κ³ μž ν•©λ‹ˆλ‹€.
>
> JWT 인증 처리λ₯Ό ν•˜λ©΄μ„œ ν–ˆλ˜ κ³ λ―Όκ³Ό 선택 이유λ₯Ό κΈ°λ‘ν–ˆμŠ΅λ‹ˆλ‹€.
>
> [λ°”λ‘œκ°€κΈ°](https://velog.io/@mks1103/JWT%EB%A1%9C-%EC%9D%B8%EC%A6%9D-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0)
**HTTPS**
> app 루트 도메인은 λͺ¨λ“  연결에 HTTPSλ₯Ό μš”κ΅¬ν•©λ‹ˆλ‹€.
>
> Let's Encryptλ₯Ό ν™œμš©ν•΄ μ–΄λ–»κ²Œ ν•΄λ‹Ή ν”„λ‘œμ νŠΈμ— HTTPSλ₯Ό μ μš©ν–ˆλŠ”μ§€ κΈ°μˆ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
>
> [λ°”λ‘œκ°€κΈ°](https://velog.io/@kdogs/HTTPS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0feat.-Lets-Encrypt)
**DeepLink 지원 및 DeepLink용 μ›ΉνŽ˜μ΄μ§€ κ΅¬ν˜„**
> 앱이 κΉ”λ¦° 두 μ‚¬λžŒμ΄ μ„œλ‘œ μƒν’ˆ 정보λ₯Ό ν…μŠ€νŠΈλ‘œ κ³΅μœ ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όλ κΉŒμš”?
>
> Deeplink 와 Deeplink μ΄λ™μš© μ›ΉνŽ˜μ΄μ§€μ˜ κ΅¬ν˜„ 과정을 μ†Œκ°œν•©λ‹ˆλ‹€.
>
> [λ°”λ‘œκ°€κΈ°](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/Deeplink-%EC%A7%80%EC%9B%90-%EB%B0%8F-Deeplink-%EC%9D%B4%EB%8F%99%EC%9A%A9-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0)
**Navigation λ°±μŠ€νƒ 였λ₯˜**
> Jetpack Navigateμ—μ„œ λ°œμƒν–ˆλ˜ μ—λŸ¬μ— λŒ€ν•΄ μ†Œκ°œν•©λ‹ˆλ‹€.
>
> 그리고 ν•΄λ‹Ή μ—λŸ¬μ˜ 원인과 ν•΄κ²° 방법도 μ†Œκ°œν•©λ‹ˆλ‹€.
>
> [λ°”λ‘œκ°€κΈ°](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/TroubleShooting-%E2%80%90-Navigation-%EB%B0%B1%EC%8A%A4%ED%83%9D-%EC%98%A4%EB%A5%98)
**ν…Œλ§ˆ λ³€κ²½**
> ν…Œλ§ˆ λ³€κ²½ λ‹€μ΄μ–Όλ‘œκ·Έλ₯Ό λ§Œλ“€ λ•Œ μ°Έκ³ ν–ˆλ˜ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ Now in Androidμž…λ‹ˆλ‹€.
>
> ν•΄λ‹Ή κΈ°λŠ₯κ³Ό λ˜‘κ°™μ€ μΈν„°λ ‰μ…˜μ„ κ΅¬ν˜„ν•˜λ € ν–ˆμœΌλ‚˜ 잘 λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. κ·Έ μ΄μœ μ— λŒ€ν•΄ κΈ°μˆ ν•©λ‹ˆλ‹€.
>
> [ν…Œλ§ˆ λ³€κ²½](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/ν…Œλ§ˆ-λ³€κ²½-(compose-vs-xml))
**NestJSμ—μ„œ Redis μ‚¬μš©ν•˜κΈ°**
>캐싱을 μœ„ν•΄ Redisλ₯Ό NestJS에 μ μš©ν•˜λ©° κ²ͺ은 μ΄μŠˆλ“€μ— λŒ€ν•΄ μ μ–΄λ³΄κ³ μž ν•©λ‹ˆλ‹€.
>
>Redisλ₯Ό μ μš©ν•˜λ©° λͺ¨λ“ˆμ„ 2λ²ˆμ΄λ‚˜ λ³€κ²½ν•˜κ³ , μ½”λ“œλ₯Ό μˆ˜μ •ν–ˆλ˜ 과정에 λŒ€ν•΄ μ†Œκ°œν•©λ‹ˆλ‹€.
>
>[λ°”λ‘œκ°€κΈ°](https://github.com/boostcampwm2023/and09-PriceGuard/wiki/NestJS%EC%97%90%EC%84%9C-Redis-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)
## πŸ“š 기술 μŠ€νƒ

Expand Down Expand Up @@ -117,7 +182,7 @@ PriceGuardλŠ” κ΅­λ‚΄ μƒκ±°λž˜ μ‚¬μ΄νŠΈλ“€μ˜ μƒν’ˆ 가격을 μΆ”μ ν•©λ‹ˆλ‹€.

## πŸ›οΈ μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜

![μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜](https://github.com/boostcampwm2023/and09-PriceGuard/assets/39708676/f7a943cd-5226-43dd-9130-9928f27067c4)
![system_architecture](https://github.com/boostcampwm2023/and09-PriceGuard/assets/39708676/21b9516b-3c01-49bf-8805-824b92c94500)


## πŸ‘¨β€πŸ‘¨β€πŸ‘¦ νŒ€μ› μ†Œκ°œ
Expand Down
6 changes: 3 additions & 3 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ android {
applicationId = "app.priceguard"
minSdk = 29
targetSdk = 34
versionCode = 7
versionName = "1.0.0"
versionCode = 8
versionName = "1.0.1"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down Expand Up @@ -111,7 +111,7 @@ dependencies {
kapt("androidx.hilt:hilt-compiler:1.1.0")

// Material chart
implementation("app.priceguard:materialchart:0.2.0")
implementation("app.priceguard:materialchart:0.2.1")
}

kapt {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ class RegisterItemLinkViewModel
}

fun updateLink(link: String) {
_state.value = state.value.copy(isLinkError = false, isNextReady = true, link = link)
_state.value = state.value.copy(isLinkError = false, isNextReady = link.isNotEmpty(), link = link)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class LoginViewModel @Inject constructor(
private val emailPattern =
"""^[\w.+-]+@((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,6}$""".toRegex()
private val passwordPattern =
"""^(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*\d)(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[a-z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[A-Z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/])[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]{8,16}$""".toRegex()
"""^(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*\d)(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[a-z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[A-Z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/])[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]{8,16}$""".toRegex()

private var _event = MutableSharedFlow<LoginEvent>()
val event: SharedFlow<LoginEvent> = _event.asSharedFlow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class SignupViewModel @Inject constructor(
private val emailPattern =
"""^[\w.+-]+@((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,6}$""".toRegex()
private val passwordPattern =
"""^(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*\d)(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[a-z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[A-Z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/])[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]{8,16}$""".toRegex()
"""^(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*\d)(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[a-z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[A-Z])(?=[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]*[!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/])[A-Za-z\d!@#$%^&*()_+={};:'"~`,.?<>|\-\[\]\\/]{8,16}$""".toRegex()

private val _state: MutableStateFlow<SignupUIState> = MutableStateFlow(SignupUIState())
val state: StateFlow<SignupUIState> = _state.asStateFlow()
Expand Down
10 changes: 5 additions & 5 deletions android/release_notes.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
December 14, 2023
v1.0.0
December 15, 2023
v1.0.1

πŸš€ Feature Updates

- 앱이 Foreground에 μžˆμ–΄λ„ μ•Œλ¦Όμ΄ μ˜€κ²Œλ” 지원
- 차트 라이브러리 버전 μ—…κ·Έλ ˆμ΄λ“œ


πŸ”§ Bug Fixes

- λͺ©ν‘œ 가격 μ„€μ • λ²”μœ„κ°€ 0~999999999 μ‚¬μ΄μ—μ„œ μ„€μ •λ˜λ„λ‘ μˆ˜μ •
- μƒν’ˆ 상세 νŽ˜μ΄μ§€ 제λͺ© μ΅œλŒ€ 쀄 수λ₯Ό 3μ€„λ‘œ λ³€κ²½
- νšŒμ›κ°€μž… μ‹œ λΉ„λ°€λ²ˆν˜Έμ— νŠΉμˆ˜λ¬Έμžκ°€ 없어도 νšŒμ›κ°€μž… κ°€λŠ₯ν•œ 였λ₯˜ μˆ˜μ •
- 링크가 λΉ„μ–΄μžˆμ„ μ‹œ 등둝 λ²„νŠΌ λΉ„ν™œμ„±ν™”λ˜λ„λ‘ μˆ˜μ •

0 comments on commit f818ce8

Please sign in to comment.