diff --git a/README.md b/README.md index 8196f9c..551c683 100644 --- a/README.md +++ b/README.md @@ -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) + +그래프 라이브러리 구현 및 배포 저장소는 여기서 확인해주세요. + + + + + + + + -[그래프 라이브러리 구현 및 배포 저장소](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) ## 📚 기술 스택 @@ -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) ## 👨‍👨‍👦 팀원 소개 diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 6ce775a..0e0f3c6 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -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" } @@ -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 { diff --git a/android/app/src/main/java/app/priceguard/ui/additem/link/RegisterItemLinkViewModel.kt b/android/app/src/main/java/app/priceguard/ui/additem/link/RegisterItemLinkViewModel.kt index 15c4659..ebfec19 100644 --- a/android/app/src/main/java/app/priceguard/ui/additem/link/RegisterItemLinkViewModel.kt +++ b/android/app/src/main/java/app/priceguard/ui/additem/link/RegisterItemLinkViewModel.kt @@ -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) } } diff --git a/android/app/src/main/java/app/priceguard/ui/login/LoginViewModel.kt b/android/app/src/main/java/app/priceguard/ui/login/LoginViewModel.kt index 737f9d5..2bc1b53 100644 --- a/android/app/src/main/java/app/priceguard/ui/login/LoginViewModel.kt +++ b/android/app/src/main/java/app/priceguard/ui/login/LoginViewModel.kt @@ -43,7 +43,7 @@ class LoginViewModel @Inject constructor( private val emailPattern = """^[\w.+-]+@((?!-)[A-Za-z0-9-]{1,63}(?|\-\[\]\\/]*\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() val event: SharedFlow = _event.asSharedFlow() diff --git a/android/app/src/main/java/app/priceguard/ui/signup/SignupViewModel.kt b/android/app/src/main/java/app/priceguard/ui/signup/SignupViewModel.kt index 1ed9b68..987b3be 100644 --- a/android/app/src/main/java/app/priceguard/ui/signup/SignupViewModel.kt +++ b/android/app/src/main/java/app/priceguard/ui/signup/SignupViewModel.kt @@ -50,7 +50,7 @@ class SignupViewModel @Inject constructor( private val emailPattern = """^[\w.+-]+@((?!-)[A-Za-z0-9-]{1,63}(?|\-\[\]\\/]*\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 = MutableStateFlow(SignupUIState()) val state: StateFlow = _state.asStateFlow() diff --git a/android/release_notes.txt b/android/release_notes.txt index 2e6a1f3..3910c5c 100644 --- a/android/release_notes.txt +++ b/android/release_notes.txt @@ -1,12 +1,12 @@ -December 14, 2023 -v1.0.0 +December 15, 2023 +v1.0.1 🚀 Feature Updates -- 앱이 Foreground에 있어도 알림이 오게끔 지원 +- 차트 라이브러리 버전 업그레이드 🔧 Bug Fixes -- 목표 가격 설정 범위가 0~999999999 사이에서 설정되도록 수정 -- 상품 상세 페이지 제목 최대 줄 수를 3줄로 변경 +- 회원가입 시 비밀번호에 특수문자가 없어도 회원가입 가능한 오류 수정 +- 링크가 비어있을 시 등록 버튼 비활성화되도록 수정