diff --git a/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/analysis_results.artifact.md b/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/analysis_results.artifact.md new file mode 100644 index 0000000..69bcff6 --- /dev/null +++ b/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/analysis_results.artifact.md @@ -0,0 +1,68 @@ +# گزارش تحلیل و پیشنهادات بهبود پروژه MonthlyPaymentApp + +این گزارش شامل بررسی فنی ساختار پروژه و ارائه راهکارهای عملی برای بهبود کیفیت کد، نگهداری آسان‌تر و رعایت استانداردهای توسعه اندروید است. + +## ۱. معماری و مدیریت وابستگی‌ها (DI) + +### وضعیت فعلی +پروژه از DI دستی در کلاس `PaymentApplication` استفاده می‌کند. با رشد پروژه، مدیریت کارخانه‌های ViewModel (Factories) دشوار و مستعد خطا خواهد بود. + +### پیشنهاد +استفاده از **Hilt (Dagger)** برای مدیریت وابستگی‌ها. +- **مزیت:** حذف کد‌های تکراری در `Application` و `Activity` و ساده‌سازی فرآیند تست واحد. +- **اقدام:** افزودن کتابخانه‌های Hilt به `build.gradle.kts` و استفاده از آنوتیشن‌های `@HiltAndroidApp` و `@HiltViewModel`. + +--- + +## ۲. بازنگری در ViewModels (اصل Single Responsibility) + +### وضعیت فعلی +فایل [PersonViewModel.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/PersonViewModel.kt) با حدود ۱۰۰۰ خط کد، تبدیل به یک **God Object** شده است. این کلاس همزمان وظایف زیر را انجام می‌دهد: +- مدیریت احراز هویت (Auth) +- مدیریت لیست افراد و پرداخت‌ها +- ارسال پیامک‌های گروهی و تکی +- خروجی اکسل (Excel Export) +- جستجو در مخاطبین گوشی + +### پیشنهاد +تقسیم `PersonViewModel` به کلاس‌های تخصصی‌تر: +- `AuthViewModel`: برای لاگین و ثبت‌نام. +- `PersonListViewModel`: برای نمایش و فیلتر لیست افراد. +- `SmsService` یا `SmsHelper`: برای منطق ارسال پیامک. +- `ExportManager`: برای تولید فایل‌های گزارش. + +--- + +## ۳. جداسازی Context از لایه منطق + +### وضعیت فعلی +در متدهایی مانند `processNextBulkSms(Context)` یا `exportYearlyReport(..., Context)` در ViewModel، از `Context` استفاده شده است. +- **مشکل:** این کار باعث نشت حافظه (Memory Leak) احتمالی می‌شود و تست‌نویسی (Unit Testing) را غیرممکن می‌کند. + +### پیشنهاد +ViewModel نباید هیچ دانشی از `Context` داشته باشد. +- **راهکار:** برای مواردی مثل نمایش Toast یا شروع Intent، از یک `SharedFlow` برای ارسال **UI Events** به Activity استفاده کنید. + +--- + +## ۴. بهبود لایه UI و Compose + +### وضعیت فعلی +فایل‌هایی مثل `PersonScreen.kt` و `MainActivity.kt` بسیار طولانی هستند. کامپوننت‌های UI و منطق ناوبری در هم تنیده شده‌اند. + +### پیشنهاد +- **شکستن کامپوننت‌ها:** بخش‌های مختلف صفحه (مانند SearchBar، PersonItem، Dialogs) را به فایل‌های جداگانه در پکیج `ui.components` منتقل کنید. +- **String Resources:** تمام رشته‌های فارسی هاردکد شده (مانند "آیا از حذف قطعی... مطمئن هستید؟") را به فایل `res/values/strings.xml` منتقل کنید. + +--- + +## ۵. پیشنهادات فنی تکمیلی + +- **نوسازی پکیج‌ها:** پکیج‌های `util` و `utils` را ادغام کنید تا ساختار پروژه تمیزتر شود. +- **Supabase Realtime:** با توجه به استفاده از Supabase، مطمئن شوید که از قابلیت Realtime برای همگام‌سازی آنی داده‌ها بین دستگاه‌های مختلف استفاده می‌کنید. +- **Room Migrations:** برای دیتابیس محلی، استراتژی مهاجرت (Migration) را مشخص کنید تا در آپدیت‌های بعدی، داده‌های کاربر پاک نشود. + +--- + +> [!TIP] +> اگر مایل باشید، می‌توانیم با **راه‌اندازی Hilt** یا **انتقال متون به strings.xml** شروع کنیم که تغییراتی کم‌ریسک اما بسیار موثر در تمیزی پروژه هستند. diff --git a/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/implementation_plan.artifact.md b/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/implementation_plan.artifact.md new file mode 100644 index 0000000..07574bd --- /dev/null +++ b/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/implementation_plan.artifact.md @@ -0,0 +1,57 @@ +# برنامه اجرایی: مدرن‌سازی و استانداردسازی پروژه (فاز ۱) + +این برنامه روی دو محور اصلی تمرکز دارد: پیاده‌سازی **Hilt** برای مدیریت وابستگی‌ها و **استانداردسازی متون** برنامه با استفاده از `strings.xml`. + +## Proposed Changes + +### ۱. زیرساخت و مدیریت وابستگی‌ها (Hilt) + +#### [MODIFY] [libs.versions.toml](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/gradle/libs.versions.toml) +- افزودن نسخه‌ها و کتابخانه‌های مورد نیاز برای Hilt. +- افزودن پلاگین Hilt. + +#### [MODIFY] [build.gradle.kts (Project)](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/build.gradle.kts) +- اعمال پلاگین Hilt. + +#### [MODIFY] [build.gradle.kts (App)](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/build.gradle.kts) +- اعمال پلاگین `dagger.hilt.android.plugin`. +- افزودن وابستگی‌های `hilt-android` و `hilt-navigation-compose`. +- تنظیم KSP برای کامپایلر Hilt. + +#### [MODIFY] [PaymentApplication.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/core/PaymentApplication.kt) +- افزودن آنوتیشن `@HiltAndroidApp`. +- حذف مدیریت دستی Repositoryها و Factoryها. + +#### [NEW] [DatabaseModule.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/core/di/DatabaseModule.kt) +- ایجاد ماژول Hilt برای ارائه (Provide) دیتابیس Room و DAOها. + +#### [NEW] [RepositoryModule.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/core/di/RepositoryModule.kt) +- ایجاد ماژول Hilt برای ارائه Repositoryها. + +#### [MODIFY] [ViewModels](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/viewmodel/) +- افزودن `@HiltViewModel` به `PersonViewModel` و `SettingsViewModel`. +- استفاده از `@Inject constructor` برای تزریق وابستگی‌ها. + +#### [MODIFY] [MainActivity.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/MainActivity.kt) +- افزودن آنوتیشن `@AndroidEntryPoint`. +- استفاده از `hiltViewModel()` به جای دستی ساختن ViewModelها. + +--- + +### ۲. استانداردسازی متون (String Resources) + +#### [MODIFY] [strings.xml](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/res/values/strings.xml) +- استخراج و تعریف متون فارسی از UI به فایل XML. + +#### [MODIFY] [Compose Screens](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/ui/screens/) +- جایگزینی متون هاردکد شده با `stringResource(R.string.id)`. + +## Verification Plan + +### Automated Tests +- اجرای `gradle build` برای اطمینان از صحت پیکربندی Hilt. +- بررسی عدم وجود خطای کامپایل در کدهای تولید شده توسط KSP. + +### Manual Verification +- اجرای برنامه و اطمینان از لود شدن صحیح داده‌ها از دیتابیس و شبکه (تایید کارکرد صحیح DI). +- بررسی نمایش صحیح متون در صفحات مختلف. diff --git a/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/walkthrough.artifact.md b/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/walkthrough.artifact.md new file mode 100644 index 0000000..bce8804 --- /dev/null +++ b/.artifacts/15926d7b-894e-47f6-892f-6114218cde2d/walkthrough.artifact.md @@ -0,0 +1,30 @@ +# گزارش نهایی: بازنگری معماری و بهبود زیرساخت (فاز ۲) + +در این فاز، معماری پروژه از حالت یکپارچه و سنگین به حالتی ماژولار و تفکیک‌شده تغییر یافت. فایل `PersonViewModel` که حدود ۱۰۰۰ خط بود به چندین بخش تخصصی تقسیم شد. + +## تغییرات کلیدی + +### ۱. تفکیک وظایف (ViewModel Splitting) +- **AuthViewModel:** مسئولیت کامل احراز هویت (Login/Register/Logout) را بر عهده گرفت. +- **ContactViewModel:** مدیریت جستجوی مخاطبین گوشی، پیشنهادات شماره تماس و ارسال پیامک (SMS) به این کلاس منتقل شد. +- **PersonViewModel:** اکنون فقط بر روی مدیریت داده‌های افراد، پرداخت‌ها و داشبورد تمرکز دارد (حجم کد حدود ۵۰٪ کاهش یافت). + +### ۲. جداسازی منطق از پلتفرم (Android Context Cleanup) +- **SmsManager:** منطق ایجاد Intentهای پیامک و مدیریت صف ارسال گروهی (Bulk SMS) به این کلاس کمکی منتقل شد. +- **ExportManager:** فرآیند تولید گزارش اکسل (CSV) و اشتراک‌گذاری رسیدها مستقل شد. +- **نتیجه:** ViewModelها اکنون مستقل از `Context` اندروید هستند که تست‌نویسی آن‌ها را بسیار آسان می‌کند. + +### ۳. یکپارچه‌سازی و نظم‌دهی (Cleanup) +- **ادغام پکیج‌ها:** پکیج‌های `util` و `utils` در یک پکیج واحد ادغام شدند. +- **مدل‌های متمرکز:** تمام `Events` و `UiStates` به فایل `UiModels.kt` منتقل شدند تا دسترسی به آن‌ها یکپارچه شود. +- **رفع خطاهای UI:** تمام صفحات برنامه (`AuthScreen`, `PersonScreen`, `PaidListScreen`, `PersonDetailScreen`) برای انطباق با ViewModelهای جدید بازنویسی شدند. + +## وضعیت نهایی پروژه +- **Build Status:** موفقیت‌آمیز (تایید شده با `assembleDebug`). +- **Dependency Injection:** استفاده کامل از Hilt در تمام لایه‌ها. +- **Readability:** افزایش چشمگیر خوانایی کد و سهولت در عیب‌یابی. + +--- + +> [!TIP] +> با این ساختار جدید، افزودن ویژگی‌های جدید (مثل ارسال یادآور از طریق پیام‌رسان‌های دیگر یا افزودن فیلترهای جدید به لیست) بسیار سریع‌تر و با ریسک کمتر انجام خواهد شد. diff --git a/.artifacts/b6b8bd31-26e8-4cfd-8648-5c332ef07ef3/implementation_plan.artifact.md b/.artifacts/b6b8bd31-26e8-4cfd-8648-5c332ef07ef3/implementation_plan.artifact.md new file mode 100644 index 0000000..8c4afa9 --- /dev/null +++ b/.artifacts/b6b8bd31-26e8-4cfd-8648-5c332ef07ef3/implementation_plan.artifact.md @@ -0,0 +1,55 @@ +# سیستم آپدیت اجباری و مدیریت دسترسی‌ها + +این طرح شامل پیاده‌سازی مکانیزم بررسی نسخه جدید اپلیکیشن از طریق فایل JSON در گیتهاب و همچنین الزامی کردن دسترسی‌های مورد نیاز برنامه (مشابه پروژه ابزار فروش) در بدو ورود کاربر است. + +## User Review Required + +- **لینک فایل آپدیت:** فعلاً از لینک `https://raw.githubusercontent.com/oqba26/MonthlyPaymentApp/main/update.json` استفاده شده است. لطفاً مطمئن شوید این فایل در مخزن شما وجود دارد. +- **دسترسی‌های اجباری:** دسترسی‌های Contacts، Camera و Storage (برای نسخه‌های قدیمی) به صورت پیش‌فرض اجباری در نظر گرفته شده‌اند. + +## Proposed Changes + +### [Dependencies] + +#### [MODIFY] [libs.versions.toml](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/gradle/libs.versions.toml) +افزودن کتابخانه‌های Ktor برای Content Negotiation و Serialization جهت پردازش فایل JSON آپدیت. + +#### [MODIFY] [build.gradle.kts](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/build.gradle.kts) +اضافه کردن وابستگی‌های جدید به ماژول اپلیکیشن. + +--- + +### [Update System] + +#### [NEW] [UpdateManager.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/util/UpdateManager.kt) +کلاسی برای چک کردن نسخه جدید، دانلود APK و اجرای فرآیند نصب. + +#### [NEW] [UpdateDialog.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/ui/components/UpdateDialog.kt) +رابط کاربری نمایش وجود نسخه جدید و گزارش پیشرفت دانلود. + +--- + +### [Permissions & Manifest] + +#### [NEW] [PermissionDialogs.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/ui/components/PermissionDialogs.kt) +دیالوگ‌های نمایش دسترسی‌های الزامی و اخطار عدم دسترسی. + +#### [MODIFY] [AndroidManifest.xml](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/AndroidManifest.xml) +افزودن مجوز `REQUEST_INSTALL_PACKAGES` و تعریف `FileProvider` برای نصب خودکار فایل APK. + +#### [NEW] [file_paths.xml](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/res/xml/file_paths.xml) +تعریف مسیرهای مجاز برای `FileProvider`. + +--- + +### [Integration] + +#### [MODIFY] [MainActivity.kt](file:///E:/AndroidStudioProjects/MonthlyPaymentApp/app/src/main/java/com/oqba26/monthlypaymentapp/MainActivity.kt) +یکپارچه‌سازی فرآیند بررسی آپدیت و چک کردن دسترسی‌ها در زمان اجرای برنامه. + +## Verification Plan + +### Manual Verification +1. اجرای برنامه و مشاهده دیالوگ دسترسی‌ها (در صورت عدم تایید قبلی). +2. شبیه‌سازی وجود آپدیت جدید با تغییر دستی `versionCode` در کد و بررسی نمایش دیالوگ آپدیت. +3. تست فرآیند دانلود و باز شدن صفحه نصب اندروید. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a8c0049 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,45 @@ +name: Android Release + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Decode Keystore + run: | + echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -di > app/release-key.jks + + - name: Build Release APK + env: + RELEASE_STORE_FILE: release-key.jks + RELEASE_STORE_PASSWORD: ${{ secrets.RELEASE_STORE_PASSWORD }} + RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }} + RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }} + run: ./gradlew assembleRelease + + - name: Rename APK + run: | + mv app/build/outputs/apk/release/app-release.apk app/build/outputs/apk/release/MonthlyPaymentApp-${{ github.ref_name }}.apk + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: app/build/outputs/apk/release/MonthlyPaymentApp-${{ github.ref_name }}.apk + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index aa724b7..0b7c68d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ .externalNativeBuild .cxx local.properties +keystore.properties +*.jks diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml deleted file mode 100644 index eca3fe9..0000000 --- a/.idea/appInsightsSettings.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index defe597..ca16a99 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,13 +4,6 @@ diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 0f2d2fa..9180c21 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -6,7 +6,6 @@