Skip to content

Commit 39852c2

Browse files
authored
Merge pull request #130 from team-haribo/feature/#129-refactor-cleanup
🔀 :: (#129) - 다이얼로그 중복, 위젯 로컬 상태, pass-through 계층 정리와 CI·문서 정비
2 parents 0844e3b + 3bd0b9c commit 39852c2

20 files changed

Lines changed: 183 additions & 532 deletions

‎.github/workflows/flutter-ci.yaml‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,8 @@ jobs:
3838
- name: Install dependencies
3939
run: flutter pub get
4040

41-
- name: Generate code
42-
run: dart run build_runner build --delete-conflicting-outputs
43-
4441
- name: Analyze project source
45-
run: flutter analyze --no-fatal-warnings --no-fatal-infos
42+
run: flutter analyze
4643

4744
- name: Run tests
4845
run: flutter test

‎docs/naming-conventions.md‎

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,30 @@
2626
### 금지/비권장 이름
2727
- `pages` 사용 금지
2828
- 기존 `pages`는 점진적으로 `screens`로 이동한다.
29-
- `viewmodels` 사용 금지
30-
- Riverpod `Notifier`, `AsyncNotifier`, `Provider`는 모두 `providers` 아래에 둔다.
31-
- `states` 디렉터리 사용 금지
32-
- UI 상태 타입은 `models` 아래에 둔다.
29+
- 신규 코드는 `providers` / `models`를 쓴다.
30+
- 기존 `viewmodels` / `states` 디렉터리는 그대로 두고, 그 안의 코드를 수정할 때
31+
한 파일씩 옮긴다. 이름만 바꾸는 일괄 리네임은 하지 않는다.
32+
33+
## 상태를 어디에 둘까
34+
35+
디렉터리 이름보다 이 질문이 먼저다. Riverpod의 `Notifier`가 곧 ViewModel이므로
36+
"MVVM을 쓸까"가 아니라 **"이 상태가 위젯보다 오래 사는가"**로 판단한다.
37+
38+
### 1. Provider(= ViewModel)에 둔다
39+
- 화면을 벗어나도 유지돼야 하거나, 둘 이상이 읽는 상태
40+
- 서버 호출·비동기 로딩·에러·폼 검증이 붙는 상태
41+
- 예: `authProvider`, `signupProvider`, `mapScreenProvider`, `settingsProvider`
42+
43+
### 2. `setState`로 둔다
44+
- 위젯 하나만 읽고 쓰고, 위젯이 사라지면 같이 사라지는 상태
45+
- 바텀시트 안의 선택값, 토글 진행 중 플래그, 펼침/접힘 같은 것
46+
- provider로 올리면 `autoDispose.family` + 식별용 키가 따라붙는다.
47+
그건 `setState`를 어렵게 재구현한 것이다.
48+
- 부모가 새 값을 내려줄 때 따라가야 하면 `didUpdateWidget`에서 명시적으로 반영한다.
49+
50+
### 3. 만들지 않는다
51+
- 다른 provider의 메서드를 그대로 호출만 하는 ViewModel은 두지 않는다.
52+
- 위젯에서 `ref.read(대상provider.notifier)`를 직접 부른다.
3353

3454
## 파일 규칙
3555

@@ -103,6 +123,62 @@ feature/
103123
- `provider`로 통일한다. `viewmodel`은 더 이상 추가하지 않는다.
104124
- `model`로 통일한다. `state` 전용 디렉터리는 더 이상 추가하지 않는다.
105125
- pass-through `usecase`는 더 이상 기본값이 아니다.
126+
- 저장소/서비스도 마찬가지다. 인터페이스와 구현이 1:1이고 구현이 전달만 하면
127+
중간 계층 없이 `datasource` 또는 유틸을 직접 쓴다.
128+
플랫폼 API를 감싸 테스트에서 갈아끼워야 하는 경우(`PermissionService`)만 예외다.
129+
130+
## 정리 대상 (2026-08-19 기준)
131+
132+
규칙에 맞지 않지만 아직 옮기지 않은 것들. 수정이 닿을 때 함께 정리한다.
133+
134+
| 위치 | 내용 |
135+
| --- | --- |
136+
| `features/*/presentation/viewmodels/` | 디렉터리 11개. 안의 provider 이름은 이미 대부분 `xxxProvider`라 파일 위치만 남았다. |
137+
| `features/auth/verification/presentation/states/` | `models/`로 이동 |
138+
| `features/map/shared/presentation/widgets/` | 15개. 실제로 공용인 것만 남기고 나머지는 소유 하위 feature로 |
139+
| `features/map/routes/` | 다른 feature와 맞춰 `presentation/routes/`로 |
140+
| `features/home/domain/enums/student_role_enum.dart` | `home`의 유일한 파일인데 실사용처는 `member`/`outing`. `core/enums/`로 |
141+
| `features/auth/email_verification/data/models/request/email_verification/` | 경로에 feature 이름이 두 번 들어간다 |
142+
143+
## Git 네이밍
144+
145+
### 브랜치
146+
`<타입>/#<이슈번호>-<영문 설명>`
147+
148+
| 타입 | 용도 |
149+
| --- | --- |
150+
| `feature` | 기능 추가 |
151+
| `fix` | 버그 수정 |
152+
| `refactor` | 동작 변경 없는 구조 정리 |
153+
| `perf` | 성능 개선 |
154+
| `release` | 배포 준비 (`release/v1.4.2` 처럼 이슈번호 없이) |
155+
156+
- 타입은 브랜치가 하는 일에 맞춘다. 리팩터링에 `feature`를 붙이지 않는다.
157+
- 설명은 영문 kebab-case. 예: `refactor/#108-dead-code-cleanup`
158+
159+
### 커밋
160+
`:gitmoji: :: <한글 설명>`
161+
162+
- gitmoji는 콜론 형식(`:sparkles:`)으로 쓴다. 유니코드 이모지(`✨`)를 섞지 않는다.
163+
- 이슈 참조가 필요하면 설명 끝에 `(#126)`.
164+
165+
| gitmoji | 용도 |
166+
| --- | --- |
167+
| `:sparkles:` | 기능 추가 |
168+
| `:bug:` | 버그 수정 |
169+
| `:recycle:` | 리팩터링 |
170+
| `:zap:` | 성능 개선 |
171+
| `:memo:` | 문서 |
172+
| `:green_heart:` | CI |
173+
| `:bookmark:` | 버전업 |
174+
175+
### PR 제목
176+
`🔀 :: (#<이슈번호>) - <한글 설명>`
177+
178+
- PR 제목의 이모지는 변경 성격과 무관하게 항상 `🔀`다. 커밋과 달리 유니코드 이모지를 쓴다.
179+
- 배포 PR만 이슈번호 대신 버전을 쓴다. 예: `🔀 :: v1.4.4 - 핫플레이스 조회 기준 기간 1일로 변경`
180+
- base는 `develop`. `main`으로 직접 열지 않는다.
181+
- 본문은 `.github/PULL_REQUEST_TEMPLATE.md`를 채우고, 관련 이슈에 `Closes #N`을 남긴다.
106182

107183
## 예외
108184
- 외부 라이브러리/코드 생성기 제약이 있는 경우

‎lib/core/data/services_impl/settings_service_impl.dart‎

Lines changed: 0 additions & 33 deletions
This file was deleted.

‎lib/core/domain/services/settings_service.dart‎

Lines changed: 0 additions & 28 deletions
This file was deleted.

‎lib/core/providers/service_providers.dart‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import 'package:flutter_riverpod/flutter_riverpod.dart';
22
import 'package:goms/core/domain/services/permission_service.dart';
3-
import 'package:goms/core/domain/services/settings_service.dart';
43
import 'package:goms/core/domain/services/notification_service.dart';
54
import 'package:goms/core/data/services_impl/permission_service_impl.dart';
6-
import 'package:goms/core/data/services_impl/settings_service_impl.dart';
75
import 'package:goms/core/data/services_impl/notification_service_impl.dart';
86
import 'package:goms/features/notification/data/datasources/notification_api.dart';
97
import 'package:goms/core/network/dio_providers.dart';
@@ -13,11 +11,6 @@ final permissionServiceProvider = Provider<PermissionService>((ref) {
1311
return PermissionServiceImpl();
1412
});
1513

16-
/// Settings Service 제공자
17-
final settingsServiceProvider = Provider<SettingsService>((ref) {
18-
return SettingsServiceImpl();
19-
});
20-
2114
/// Notification Service 제공자
2215
final notificationServiceProvider = Provider<NotificationService>((ref) {
2316
final notificationApi = NotificationApi(ref.watch(dioProvider));

‎lib/core/widgets/dialogs/banned_outing_dialog.dart‎

Lines changed: 0 additions & 60 deletions
This file was deleted.

‎lib/core/widgets/dialogs/banned_outing_release_dialog.dart‎

Lines changed: 0 additions & 60 deletions
This file was deleted.

‎lib/core/widgets/dialogs/forced_outing_release_dialog.dart‎

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)