diff --git a/.github/workflows/ci_pipeline.yml b/.github/workflows/ci_pipeline.yml index df4c3ac5..11d92f11 100644 --- a/.github/workflows/ci_pipeline.yml +++ b/.github/workflows/ci_pipeline.yml @@ -24,31 +24,18 @@ jobs: DATA_ANDROID: ${{ secrets.GOOGLE_SERVICES_JSON }} run: echo "$DATA_ANDROID" > android/app/google-services.json - # ๐Ÿ”ฅ .env.dev ํŒŒ์ผ ์ƒ์„ฑ - - name: Create .env.dev file - run: echo "${{ secrets.ENV_DEV }}" > .env.dev + # ๐Ÿ”ฅ .env.dev.android ํŒŒ์ผ ์ƒ์„ฑ + - name: Create .env.dev.android file + run: echo "${{ secrets.ENV_DEV_ANDROID }}" > .env.dev.android + + # ๐Ÿ”ฅ .env.dev.ios ํŒŒ์ผ ์ƒ์„ฑ + - name: Create .env.dev.ios file + run: echo "${{ secrets.ENV_DEV_IOS }}" > .env.dev.ios # ๐Ÿ”ฅ .env.prod ํŒŒ์ผ ์ƒ์„ฑ - name: Create .env.prod file run: echo "${{ secrets.ENV_PROD }}" > .env.prod - # ๐Ÿ”ฅ ๋ธŒ๋žœ์น˜ ์กฐ๊ฑด์— ๋”ฐ๋ผ .env ์„ ํƒ - - name: Select .env file based on branch - run: | - TARGET_BRANCH="${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }}" - echo "Target branch: $TARGET_BRANCH" - - if [[ "$TARGET_BRANCH" == "develop" ]]; then - echo "Using .env.dev" - cp .env.dev .env - elif [[ "$TARGET_BRANCH" == "main" || "$TARGET_BRANCH" == release/* ]]; then - echo "Using .env.prod" - cp .env.prod .env - else - echo "No environment matched for this branch ($TARGET_BRANCH)" - exit 1 - fi - # ๐Ÿ”ฅ Flutter SDK ์„ค์น˜ ๋ฐ ์บ์‹œ ํ™œ์„ฑํ™” - name: Install Flutter SDK uses: subosito/flutter-action@v2 @@ -97,31 +84,18 @@ jobs: DATA_IOS: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST }} run: echo "$DATA_IOS" > ios/Runner/GoogleService-Info.plist - # ๐Ÿ”ฅ .env.dev ํŒŒ์ผ ์ƒ์„ฑ - - name: Create .env.dev file - run: echo "${{ secrets.ENV_DEV }}" > .env.dev + # ๐Ÿ”ฅ .env.dev.android ํŒŒ์ผ ์ƒ์„ฑ + - name: Create .env.dev.android file + run: echo "${{ secrets.ENV_DEV_ANDROID }}" > .env.dev.android + + # ๐Ÿ”ฅ .env.dev.ios ํŒŒ์ผ ์ƒ์„ฑ + - name: Create .env.dev.ios file + run: echo "${{ secrets.ENV_DEV_IOS }}" > .env.dev.ios # ๐Ÿ”ฅ .env.prod ํŒŒ์ผ ์ƒ์„ฑ - name: Create .env.prod file run: echo "${{ secrets.ENV_PROD }}" > .env.prod - # ๐Ÿ”ฅ ๋ธŒ๋žœ์น˜ ์กฐ๊ฑด์— ๋”ฐ๋ผ .env ์„ ํƒ - - name: Select .env file based on branch - run: | - TARGET_BRANCH="${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }}" - echo "Target branch: $TARGET_BRANCH" - - if [[ "$TARGET_BRANCH" == "develop" ]]; then - echo "Using .env.dev" - cp .env.dev .env - elif [[ "$TARGET_BRANCH" == "main" || "$TARGET_BRANCH" == release/* ]]; then - echo "Using .env.prod" - cp .env.prod .env - else - echo "No environment matched for this branch ($TARGET_BRANCH)" - exit 1 - fi - # ๐Ÿ”ฅ Flutter ํด๋ฆฐ ๋ฐ ์˜์กด์„ฑ ์„ค์น˜ - name: Clean and Install Flutter dependencies run: | @@ -133,8 +107,8 @@ jobs: run: | cd ios pod repo update - pod install --repo-update pod update Firebase/CoreOnly + pod install --repo-update cd .. # ๐Ÿ”ฅ iOS ๋นŒ๋“œ diff --git a/android/app/build.gradle b/android/app/build.gradle index bbda811e..f29c47cc 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -47,7 +47,7 @@ android { buildTypes { debug { - signingConfig = signingConfigs.release + signingConfig = signingConfigs.debug minifyEnabled false shrinkResources false } diff --git a/claude.md b/claude.md new file mode 100644 index 00000000..73bab926 --- /dev/null +++ b/claude.md @@ -0,0 +1,138 @@ +# Claude Project Rules (DebateSeason Frontend) + +์ด ์ €์žฅ์†Œ์˜ ์‹œ๋‹ˆ์–ด ํ”Œ๋Ÿฌํ„ฐ ์—”์ง€๋‹ˆ์–ด๋กœ์„œ ๋‹ค์Œ ๊ทœ์น™์„ ์—„๊ฒฉํžˆ ์ค€์ˆ˜ํ•˜์‹ญ์‹œ์˜ค. ์ •๋ณด๊ฐ€ ๋ถ€์กฑํ•  ๊ฒฝ์šฐ ์ถ”์ธกํ•˜์ง€ ๋ง๊ณ  ์ตœ์†Œํ•œ์˜ ์งˆ๋ฌธ(1~3๊ฐœ)์„ ํ•˜์‹ญ์‹œ์˜ค. + +## 0) ์ถœ๋ ฅ ๊ณ„์•ฝ (Hard rules) + +- **์„ค๋ช…์ด๋‚˜ ๋ถˆ๋ › ํฌ์ธํŠธ ์—†์ด ์ฝ”๋“œ๋งŒ ์ถœ๋ ฅํ•˜์‹ญ์‹œ์˜ค.** +- ๋ชจ๋“  ํŒŒ์ผ์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œํ•˜์‹ญ์‹œ์˜ค: `// filename: .dart` +- ๊ธฐ์กด ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ ๋‚ด์—์„œ ์ปดํŒŒ์ผ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋งŒ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค. ์ƒˆ๋กœ์šด ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. +- API ์—”๋“œํฌ์ธํŠธ, JSON ํ•„๋“œ, ๋ผ์šฐํŠธ ์ด๋ฆ„ ๋“ฑ์„ ์ž„์˜๋กœ ์ƒ์„ฑํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๋ชจ๋ฅผ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ์งˆ๋ฌธํ•˜์‹ญ์‹œ์˜ค. + +## 1) ์•„ํ‚คํ…์ฒ˜ ๋ฐ ๊ธฐ์ˆ  ์Šคํƒ (Hard rules) + +- **Architecture:** Feature-based Clean Architecture + MVVM. +- **State Management:** GetX (Obx, Rx variables). + - **์ค‘์š”:** ๋‹จ์ˆœ ์ƒํƒœ ๊ด€๋ฆฌ๋Š” Controller ์—†์ด `Rx` ๋ณ€์ˆ˜๋‚˜ `ValueNotifier`๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋ณต์žกํ•œ ๊ฒฝ์šฐ์—๋งŒ ViewModel(Controller)์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +- **Networking:** Dio + Retrofit. +- **Data Modeling:** Freezed + JsonSerializable. +- **DI:** GetX Bindings๋ฅผ ํ†ตํ•ด ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค. +- **Layer Boundaries:** + - `presentation`์€ `domain`์—๋งŒ ์˜์กดํ•˜๋ฉฐ, `data` ๋ ˆ์ด์–ด์˜ DTO๋ฅผ ์ ˆ๋Œ€ ์ฐธ์กฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + - `data`๋Š” `domain/repositories`๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , ๋ฐ˜๋“œ์‹œ Mapper๋ฅผ ํ†ตํ•ด `DTO` โ†” `Entity` ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. + +## 2) ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ๋ฐ ๋„ค์ด๋ฐ (Hard rules) + +์‹ค์ œ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ(`snake_case` ํด๋”๋ช…)๋ฅผ ์—„๊ฒฉํžˆ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์€ `lib/features//` ํ•˜์œ„์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค. + +``` +lib/ +โ”œโ”€โ”€ core/ # ํ•ต์‹ฌ ์ธํ”„๋ผ (๋„คํŠธ์›Œํฌ, ๋ผ์šฐํŒ…, ์ƒ์ˆ˜, ์„œ๋น„์Šค) +โ”‚ โ”œโ”€โ”€ constants/ # DeColors, DeFonts, DeGaps, DeIcons, DeDimensions +โ”‚ โ”œโ”€โ”€ errors/ # ์˜ˆ์™ธ ์ฒ˜๋ฆฌ +โ”‚ โ”œโ”€โ”€ model/ # ๊ณต์œ  ๋ชจ๋ธ (CursorPaginationModel ๋“ฑ) +โ”‚ โ”œโ”€โ”€ network/ # DioClient(์‹ฑ๊ธ€ํ„ด), DioInterceptor +โ”‚ โ”œโ”€โ”€ routers/ # GetRouter, GetRouterName +โ”‚ โ””โ”€โ”€ services/ # StompService, SecureStorageService, PipController +โ”œโ”€โ”€ features// # ๊ธฐ๋Šฅ ๋ชจ๋“ˆ +โ”‚ โ”œโ”€โ”€ domain/entities/ # Freezed Entity (~Entity) +โ”‚ โ”œโ”€โ”€ domain/repositories/ # abstract class (~Repository) +โ”‚ โ”œโ”€โ”€ data/models/ # Request DTO (~Req), Response DTO (~Res) +โ”‚ โ”œโ”€โ”€ data/data_sources/ # Retrofit API ์ธํ„ฐํŽ˜์ด์Šค (~DataSource, .g.dart) +โ”‚ โ”œโ”€โ”€ data/mappers/ # DTO โ†” Entity ๋ณ€ํ™˜ (๋˜๋Š” ๋ชจ๋ธ ๋‚ด toEntity()) +โ”‚ โ”œโ”€โ”€ data/repository_impls/ # Repository ๊ตฌํ˜„์ฒด (~RepositoryImpl) +โ”‚ โ”œโ”€โ”€ bindings/ # GetX Binding ํด๋ž˜์Šค +โ”‚ โ””โ”€โ”€ presentation/ +โ”‚ โ”œโ”€โ”€ view_models/ # GetxController (~ViewModel) +โ”‚ โ”œโ”€โ”€ views/ # UI ์Šคํฌ๋ฆฐ (~Screen) +โ”‚ โ”œโ”€โ”€ widgets/ # ๊ธฐ๋Šฅ ์ „์šฉ ์œ„์ ฏ +โ”‚ โ””โ”€โ”€ _constants.dart # ํ•ด๋‹น ๊ธฐ๋Šฅ ์ „์šฉ ๋ฌธ์ž์—ด ์ƒ์ˆ˜ +โ”œโ”€โ”€ common/ # ๊ณต์œ  ์ƒ์ˆ˜, Enum (OpinionType ๋“ฑ) +โ”œโ”€โ”€ utils/ # ์œ ํ‹ธ๋ฆฌํ‹ฐ +โ”‚ โ””โ”€โ”€ base/ # BaseRes, NullableBaseRes, UiState +โ””โ”€โ”€ widgets/ # ๊ณต์šฉ ์œ„์ ฏ (De* ์ ‘๋‘์‚ฌ) +``` + +### ๋„ค์ด๋ฐ ๊ทœ์น™ + +| ๋Œ€์ƒ | ๊ทœ์น™ | ์˜ˆ์‹œ | +|------|------|------| +| ํŒŒ์ผ๋ช… | snake_case | `auth_view_model.dart` | +| ViewModel | `*ViewModel` (extends GetxController) | `ChatViewModel` | +| Screen | `*Screen` (extends GetView / StatelessWidget) | `ChatRoomScreen` | +| Repository (์ธํ„ฐํŽ˜์ด์Šค) | `*Repository` (abstract) | `UsersLoginRepository` | +| Repository (๊ตฌํ˜„์ฒด) | `*RepositoryImpl` | `UsersLoginRepositoryImpl` | +| DataSource | `*DataSource` (Retrofit) | `UsersLoginDataSource` | +| Entity | `*Entity` (Freezed) | `ChatMessageEntity` | +| Request DTO | `*Req` | `LoginReq` | +| Response DTO | `*Res` | `LoginRes` | +| ๊ณต์šฉ ์œ„์ ฏ | `De*` ์ ‘๋‘์‚ฌ | `DeScaffold`, `DeButton`, `DeCachedImage` | +| ๋””์ž์ธ ์ƒ์ˆ˜ | `De*` ์ ‘๋‘์‚ฌ | `DeColors`, `DeFonts`, `DeGaps` | +| ๊ธฐ๋Šฅ๋ณ„ ๋ฌธ์ž์—ด ์ƒ์ˆ˜ | `_constants.dart` | `home_constants.dart` | + +## 3) ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™ ๋ฐ ์šฉ์–ด + +- **Classes:** PascalCase / **Files:** snake_case +- **Constants:** + - ๋””์ž์ธ ์‹œ์Šคํ…œ ์ƒ์ˆ˜(์ƒ‰์ƒยทํฐํŠธยท๊ฐ„๊ฒฉ)๋Š” `lib/core/constants/`์— ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. + - ๊ฐ ํ™”๋ฉด์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ƒ์ˆ˜๋Š” ํ•ด๋‹น ๊ธฐ๋Šฅ์˜ `presentation/constants/` ๋‚ด์—์„œ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. `lib/core/constants/`์— ํ˜ผ์šฉ ๊ธˆ์ง€. + +## 4) ์ฝ”๋“œ ์Šคํƒ€์ผ ๋ฐ ์œ ํ‹ธ๋ฆฌํ‹ฐ + +- **Base Classes ํ™œ์šฉ:** + - ์ƒํƒœ ๊ด€๋ฆฌ: `lib/utils/base/ui_state.dart`์˜ `UiState`๋ฅผ ์ ๊ทน ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. + - API ์‘๋‹ต: `BaseRes` ๋˜๋Š” `NullableBaseRes` ๋ž˜ํผ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +- **Immutability:** ๋ณ€์ˆ˜๋Š” `final`, ์ƒ์„ฑ์ž๋Š” ๊ฐ€๋Šฅํ•œ `const`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +- **Null-safety:** `!` ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ์„ ์—„๊ฒฉํžˆ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค. `?.` ๋ฐ `??` ์—ฐ์‚ฐ์ž๋ฅผ ํ™œ์šฉํ•˜์‹ญ์‹œ์˜ค. +- **Code Generator:** Freezed/Retrofit ์‚ฌ์šฉ ์‹œ `part` ๊ตฌ๋ฌธ๊ณผ `factory` ๋ฉ”์„œ๋“œ ํ…œํ”Œ๋ฆฟ์„ ์ •ํ™•ํžˆ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค. +- **Constraints:** + - ํŒŒ์ผ๋‹น 100์ค„ ์ด๋‚ด ์œ ์ง€ (์ดˆ๊ณผ ์‹œ ํŒŒ์ผ ๋ถ„๋ฆฌ). + - ํ•จ์ˆ˜๋Š” 30๋ผ์ธ ์ด๋‚ด ์œ ์ง€ (๋‹จ์ผ ์ฑ…์ž„ ์›์น™). + - `print`, `debugPrint` ์‚ฌ์šฉ ๊ธˆ์ง€ โ†’ `lib/utils/logger.dart`์˜ `log` ์ธ์Šคํ„ด์Šค ์‚ฌ์šฉ (`log.d()`, `log.e()`). + +## 5) ๋ฉ€ํ‹ฐ ํŒŒ์ผ ์ถœ๋ ฅ ์ˆœ์„œ + +ํŒŒ์ผ ์ƒ์„ฑ ์‹œ ์˜์กด์„ฑ์ด ๋‚ฎ์€ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅํ•˜์‹ญ์‹œ์˜ค: +1) `domain/` (entities โ†’ repositories) +2) `data/` (models โ†’ data_sources โ†’ mappers โ†’ repository_impls) +3) `bindings/` +4) `presentation/` (view_models โ†’ views โ†’ widgets) + +## 6) ๋„คํŠธ์›Œํฌ ๋ ˆ์ด์–ด + +- **DioClient:** ์‹ฑ๊ธ€ํ„ด. Base URL์€ ํ”Œ๋žซํผ๋ณ„ ํ™˜๊ฒฝ ํŒŒ์ผ(`.env.dev.android` / `.env.dev.ios` / `.env.prod`)์—์„œ ๋กœ๋“œ (`flutter_dotenv`). +- **DioInterceptor:** Access Token ์ž๋™ ์ฃผ์ž…, ์‘๋‹ต/์—๋Ÿฌ ๋กœ๊น…, 401 ์‹œ ํ† ํฐ ๊ฐฑ์‹  ํ›„ ์š”์ฒญ ์žฌ์‹œ๋„ (์‹คํŒจ ์‹œ ๋กœ๊ทธ์•„์›ƒ). +- **Retrofit DataSource:** `@RestApi`, `@GET`, `@POST` ๋“ฑ. ๋ฐ˜ํ™˜ ํƒ€์ž…์€ `Future>`. +- **WebSocket:** `StompService` (STOMP ํ”„๋กœํ† ์ฝœ). ๊ตฌ๋…: `/topic/room{roomId}`, ๋ฐœํ–‰: `/stomp/chat.room.{roomId}`. +- **ํ™˜๊ฒฝ๋ณ€์ˆ˜:** ํ™˜๊ฒฝ ํŒŒ์ผ์„ ์ง์ ‘ ์ฐธ์กฐ. ๋ณ€์ˆ˜ ํ‚ค ์ด๋ฆ„์€ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ํ™•์ธ. + +## 7) ๋ผ์šฐํŒ… + +- GetX Named Routes ์‚ฌ์šฉ. +- ๋ผ์šฐํŠธ ์ด๋ฆ„: `GetRouterName` ์ƒ์ˆ˜ ํด๋ž˜์Šค์— ์ •์˜. +- ๋ผ์šฐํŠธ ๋ชฉ๋ก: `GetRouter.getPages`์— ๋“ฑ๋ก. ๊ฐ ๋ผ์šฐํŠธ์— Binding ์—ฐ๊ฒฐ. +- ๋„ค๋น„๊ฒŒ์ด์…˜: `Get.toNamed()`, `Get.offNamed()`, `Get.offAllNamed()`. + +## 8) ์ธ์ฆ ํ๋ฆ„ + +- Kakao(Android) / Apple(iOS) ์†Œ์…œ ๋กœ๊ทธ์ธ. +- JWT: AccessToken + RefreshToken โ†’ `flutter_secure_storage`์— ์ €์žฅ. +- 401 โ†’ DioInterceptor์—์„œ ์ž๋™ ํ† ํฐ ๊ฐฑ์‹  โ†’ ๊ฐฑ์‹  ์‹คํŒจ ์‹œ SecureStorage ์ดˆ๊ธฐํ™” ํ›„ ๋กœ๊ทธ์ธ ํ™”๋ฉด ์ด๋™. + +## 9) ์ฝ”๋“œ ์ƒ์„ฑ + +Freezed Entity, Retrofit DataSource, JsonSerializable Model ์ˆ˜์ • ํ›„ ๋ฐ˜๋“œ์‹œ ์‹คํ–‰: +```bash +flutter pub run build_runner build --delete-conflicting-outputs +``` +์ƒ์„ฑ ํŒŒ์ผ: `*.freezed.dart`, `*.g.dart` โ€” ์ด ํŒŒ์ผ๋“ค์€ ์ง์ ‘ ์ˆ˜์ •ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. + +## 10) ๊ธˆ์ง€ ์‚ฌํ•ญ + +- `print()` / `debugPrint()` ์‚ฌ์šฉ ๊ธˆ์ง€. +- ํ•˜๋“œ์ฝ”๋”ฉ๋œ ์ƒ‰์ƒ/ํฐํŠธ/๊ฐ„๊ฒฉ ์‚ฌ์šฉ ๊ธˆ์ง€ โ†’ `DeColors`, `DeFonts`, `DeGaps`, `DeDimensions` ์‚ฌ์šฉ. +- ViewModel์—์„œ ์ง์ ‘ UI ์œ„์ ฏ(BuildContext) ์ฐธ์กฐ ๊ธˆ์ง€. +- Data ๋ ˆ์ด์–ด์—์„œ Domain ๋ ˆ์ด์–ด ๊ตฌํ˜„์ฒด ์ฐธ์กฐ ๊ธˆ์ง€ (์˜์กด์„ฑ ์—ญ์ „ ์›์น™). +- `Get.put()` ๋‚จ์šฉ ๊ธˆ์ง€ โ†’ `Get.lazyPut()` ์šฐ์„  ์‚ฌ์šฉ. +- `!` (bang operator) ์‚ฌ์šฉ ๊ธˆ์ง€ โ†’ `?.`, `??` ์‚ฌ์šฉ. +- ์ƒˆ๋กœ์šด ํŒจํ‚ค์ง€ ์ž„์˜ ์ถ”๊ฐ€ ๊ธˆ์ง€. diff --git a/lib/features/auth/presentation/view_models/auth_view_model.dart b/lib/features/auth/presentation/view_models/auth_view_model.dart index c2e3984e..db42c24b 100644 --- a/lib/features/auth/presentation/view_models/auth_view_model.dart +++ b/lib/features/auth/presentation/view_models/auth_view_model.dart @@ -62,10 +62,10 @@ class AuthViewModel extends GetxController { return UiState.success(loginStatus); } catch (e, stack) { log.d('์นด์นด์˜ค ๋กœ๊ทธ์ธ ์‹คํŒจ\n $e \n $stack'); - print('================= ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์—๋Ÿฌ ์‹œ์ž‘ ================='); - print('์—๋Ÿฌ ๋‚ด์šฉ: $e'); - print('์Šคํƒ ํŠธ๋ ˆ์ด์Šค: $stack'); - print('================= ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์—๋Ÿฌ ๋ ================='); + log.e('================= ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์—๋Ÿฌ ์‹œ์ž‘ ================='); + log.e('์—๋Ÿฌ ๋‚ด์šฉ: $e'); + log.e('์Šคํƒ ํŠธ๋ ˆ์ด์Šค: $stack'); + log.e('================= ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์—๋Ÿฌ ๋ ================='); return UiState.failure('์นด์นด์˜ค ๋กœ๊ทธ์ธ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.'); } } diff --git a/lib/main.dart b/lib/main.dart index 03c20050..ea1906fd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,6 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:get/get.dart'; +import 'dart:io'; import 'core/constants/de_colors.dart'; import 'core/routers/get_router.dart'; @@ -20,7 +21,8 @@ void main() async { final prefsService = SharedPreferencesService(); await prefsService.init(); if (kDebugMode) { - await dotenv.load(fileName: '.env.dev'); + final envFile = Platform.isAndroid ? '.env.dev.android' : '.env.dev.ios'; + await dotenv.load(fileName: envFile); } else { await dotenv.load(fileName: '.env.prod'); AmplitudeUtil.init(); diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index b474c835..534df932 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,7 +7,9 @@ import Foundation import amplitude_flutter import connectivity_plus +import device_info_plus import firebase_core +import firebase_messaging import flutter_inappwebview_macos import flutter_secure_storage_macos import package_info_plus @@ -21,7 +23,9 @@ import webview_flutter_wkwebview func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AmplitudeFlutterPlugin.register(with: registry.registrar(forPlugin: "AmplitudeFlutterPlugin")) ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) diff --git a/pubspec.yaml b/pubspec.yaml index 5a520ab8..4e677d95 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,8 @@ dependencies: youtube_player_flutter: ^9.1.1 # Login firebase_core: ^3.10.0 + firebase_messaging: ^15.0.0 + device_info_plus: ^11.0.0 kakao_flutter_sdk_user: ^1.9.7+3 sign_in_with_apple: ^6.1.4 # ETC.. @@ -88,7 +90,8 @@ flutter: uses-material-design: true assets: - - .env.dev + - .env.dev.android + - .env.dev.ios - .env.prod - assets/fonts/ - assets/icons/