Write to Jolly, feel jolly
์ค๋์ ์ด์ผ๊ธฐ๋ฅผ ์์ด ํธ์ง๋ก ๋จ๊ธฐ๊ณ ,
์กธ๋ฆฌ์ ๊ต์ ํผ๋๋ฐฑ๊ณผ ์ฐํ๋ก ๋๋ง์ ๊ธฐ๋ก์ ์์๊ฐ๋ ๋ชจ๋ฐ์ผ ์๋น์ค
์๋น์ค ์๊ฐ ยท ์ฃผ์ ํ๋ฉด ยท ์ํคํ ์ฒ ยท ๊ธฐ์ ์คํ ยท Contributors
Dear Jolly๋ ์ผ์์ ์์ด ๊ธ์ฐ๊ธฐ๋ฅผ ํธ์ง๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๊ฒฝํ์ผ๋ก ํ์ด๋ธ ์๋น์ค์ ๋๋ค. ํ๋ฃจ์ ์์ ์ฌ๊ฑด์ด๋ ๋ง์์ ๋จ์ ์ด์ผ๊ธฐ๋ฅผ ์กธ๋ฆฌ์๊ฒ ๊ฑด๋ค๊ณ , ์ด์ํ ๋ฌธ๋ฒ๊ณผ ํํ์ ๋์๋ณด๋ฉฐ ๋ค์ ํธ์ง๋ฅผ ์ด์ด๊ฐ๋๋ค.
| Write | Feedback | Stamp |
|---|---|---|
| ์์ด๋ก ์ค๋์ ์ด์ผ๊ธฐ๋ฅผ ์์ฑํด์. | ์๋ฌธ๊ณผ ๊ต์ ํํ, ํ์ต ํ์ ํจ๊ป ํ์ธํด์. | ํธ์ง์ ์ฐ๊ฒฐ๋ ์ฐํ์ ๊ธฐ๋ก์ ๋ชจ์๋ด์. |
์์ด๋ณด๋ฆฌ ํธ์ง์ง, ๋ฒ๊ฑด๋ ํฌ์ธํธ, ์ฐํ์ ๋ดํฌ ์ผ๋ฌ์คํธ๋ก ํธ์ง๋ฅผ ์ฐ๋ ๋ถ์๊ธฐ๋ฅผ ๋ด์์ต๋๋ค. ์ด ์ ์ฅ์๋ Flutter ๋ชจ๋ฐ์ผ ํด๋ผ์ด์ธํธ๋ฅผ ๋ค๋ฃจ๋ฉฐ, ํธ์งยทํผ๋๋ฐฑยท์ฐํ ๋ฐ์ดํฐ๋ ์๋ฒ API์ ์ฐ๋ํฉ๋๋ค.
![]() |
![]() |
![]() |
| 01 ยท ํธ์ง ์์ฑ ์กธ๋ฆฌ์๊ฒ ์ ํ๋ ์ค๋์ ์์ด ์ผ๊ธฐ |
02 ยท ํผ๋๋ฐฑ ๊ณ ์น ํํ๊ณผ ์ด์ ๋ฅผ ํ๋์ |
03 ยท ํธ์งํจ๊ณผ ์ฐํ ์์ด๋ ๊ธฐ๋ก์ ๋ค์ ์ฝ๋ ์ฆ๊ฑฐ์ |
์ ์ด๋ฏธ์ง๋ Figma์ ์ฑ์คํ ์ด ์๊ฐ ์์์ ๋๋ค. ์์ ๋ฌธ๊ตฌยท๋ ์งยท์ฐํ ์ยท๋ฐฐ์น๋ ์คํ ํ๋ฉด๊ณผ ๋ค๋ฅผ ์ ์์ผ๋ฉฐ, ์๋ ๊ธฐ๋ฅ ์ค๋ช ์ ํ์ฌ ์ฝ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ฑํ์ต๋๋ค. ์ด๋ฏธ์ง ์ถ์ฒ
flowchart LR
A["๋ก๊ทธ์ธ"] --> B["์ฝ๊ด ๋์ ยท ๋๋ค์ ๋ฑ๋ก"]
B --> C["ํ ยท ํธ์งํจ"]
C --> D["์์ด ํธ์ง ์์ฑ"]
D --> E["์ ๋ฌ ์๋ฃ ยท ํผ๋๋ฐฑ ๋๊ธฐ"]
E --> C
C --> F["๊ต์ ํผ๋๋ฐฑ ยท ํ์ต ํ"]
C --> G["์ค์ ยท ๊ณ์ ๊ด๋ฆฌ"]
style C fill:#F5EDE0,stroke:#7F011F,color:#262626
style D fill:#F5EDE0,stroke:#7F011F,color:#262626
style F fill:#CCF1E4,stroke:#007D58,color:#262626
| ๋จ๊ณ | ๊ตฌํ๋ ๊ฒฝํ |
|---|---|
| ์์ ยท ๋ก๊ทธ์ธ | ์ฑ ๋ฒ์ ๊ณผ ์ธ์ฆ ์ํ ํ์ธ ํ ์ง์ ํ๋ฉด ๊ฒฐ์ . ์นด์นด์ค ๋ก๊ทธ์ธ๊ณผ iOS์ Apple ๋ก๊ทธ์ธ ์ ๊ณต |
| ์จ๋ณด๋ฉ | ์ฝ๊ด ๋์ โ ๋๋ค์ ๋ฑ๋ก โ ํ์ ํ๋ฉด. ์๋ฃ ์ฌ๋ถ์ ๋ฐ๋ผ ํ์ํ ๋จ๊ณ๋ก ์ด๋ |
| ํธ์งํจ | ์ฐํ ์, ํธ์ง ๋ชฉ๋ก, ์ต์ ์ยท์ค๋๋ ์ ์ ๋ ฌ, ํ์ด์ง ์ด๋, ์ ํผ๋๋ฐฑ ๋ฐ ๋๊ธฐ ์ํ ํ์ |
| ํธ์ง ์์ฑ | ์๋ฌธยท์ซ์ยท๊ธฐ๋ณธ ๊ธฐํธ ์ค์ฌ ์ ๋ ฅ, ์ต๋ 500์, ์ ๋ฌ ์ ํ์ธ, ์ ์ถ ์คํจ ์๋ด์ ์ฌ์๋ |
| ๊ต์ ํ์ธ | ์์ ์ ํํ์ ์ทจ์์ , ๊ต์ ํํ์ ์ด๋ก์ ๊ฐ์กฐ. ์๋ฒ์์ ๋ฐ์ ํ์ต ํ ํ์ |
| ์ค์ | ๋๋ค์ ๋ณ๊ฒฝ, ์ฝ๊ดยท๊ฐ์ธ์ ๋ณด ์ฒ๋ฆฌ๋ฐฉ์นจ ํ์ธ, ๋ฌธ์, ๋ก๊ทธ์์, ํ์ ํํด |
๊ธฐ๋ฅ๋ณ ํ๋ฉด์ features์ ๋ชจ์ผ๊ณ , ๋๋ฉ์ธ ๊ท์น๊ณผ ๋ฐ์ดํฐ ์ ๊ทผ์ ๋ถ๋ฆฌํ์ต๋๋ค. Riverpod Provider๊ฐ ๋ฐ์ดํฐ ์์คยท์ ์ฅ์ยท์ ์ค์ผ์ด์ค๋ฅผ ์ฐ๊ฒฐํ๊ณ , ํ๋ฉด์ ์ ์ค์ผ์ด์ค๋ฅผ ํตํด ์์
์ ์์ฒญํฉ๋๋ค.
lib/
โโโ main.dart # ProviderScope์ ์ฑ ์์์
โโโ app/ # ์ฑ ๊ตฌ์ฑ, GoRouter ๋ผ์ฐํ
๊ณผ ์ ๊ทผ ์ ์ด
โโโ core/
โ โโโ config/ # API ๋ฐ ์๋น์ค ์ค์
โ โโโ di/ # Riverpod ์์กด์ฑ ์ฐ๊ฒฐ
โ โโโ network/ # Dio, ์ธ์ฆ ์ธํฐ์
ํฐ, API ์์ธ
โ โโโ platform/ # ์ฑ ์ ๋ณด, ๊ธฐ๊ธฐ ์๊ฐ๋ ๋ฑ ํ๋ซํผ ๊ธฐ๋ฅ
โ โโโ storage/ # ์ธ์ฆ ์ ๋ณด ๋ณด๊ด
โ โโโ theme/ # ์์ยทํ์ดํฌ๊ทธ๋ํผยทํ
๋ง
โ โโโ utils/ # ๋๋ค์ ๊ฒ์ฆ ๋ฑ ๊ณตํต ๋๊ตฌ
โ โโโ widgets/ # ๋ฒํผยทํธ์ง ์นด๋ยท๋ค์ด์ผ๋ก๊ทธ ๋ฑ ๊ณตํต UI
โโโ features/
โ โโโ splash/ # ์ด๊ธฐ ๋ฒ์ ยท์ธ์
ํ์ธ
โ โโโ login/ # ์์
๋ก๊ทธ์ธ๊ณผ ์ฝ๋ฐฑ
โ โโโ onboarding/ # ์ฝ๊ดยท๋๋ค์ยทํ์ ํ๋ฉด
โ โโโ home/ # ํธ์ง ๋ชฉ๋กยท์ ๋ ฌยทํผ๋๋ฐฑ ์ํ ๊ฐฑ์
โ โโโ write/ # ํธ์ง ์์ฑยท์ ์ถยท์๋ฃ
โ โโโ review/ # ๊ต์ ๊ฒฐ๊ณผ์ ํ์ต ํ
โ โโโ settings/ # ์ค์ ๊ณผ ๊ณ์ ๊ด๋ฆฌ
โ โโโ update/ # ๊ฐ์ ์
๋ฐ์ดํธ ์๋ด
โโโ domain/
โ โโโ entity/ # User, Letter, LetterReview ๋ฑ
โ โโโ model/ # Result: Success / Failure
โ โโโ repository/ # ๋ฐ์ดํฐ ์ ๊ทผ ์ธํฐํ์ด์ค
โ โโโ usecase/ # auth / letter / version ์์
โโโ data/
โโโ auth/ # ์ธ์ฆ APIยทDTOยท์ ์ฅ์ ๊ตฌํ
โโโ letter/ # ํธ์ง APIยทDTOยท์ ์ฅ์ ๊ตฌํ
โโโ version/ # ๋ฒ์ APIยทDTOยท์ ์ฅ์ ๊ตฌํ
assets/ # ์ด๋ฏธ์งยทSVG ์์ด์ฝยทLottieยทPretendard
test/ # ๋จ์ยท์์ ฏ ํ
์คํธ
android/ ยท ios/ # ๋ชจ๋ฐ์ผ ํ๋ซํผ ์ค์
flowchart LR
UI["features ยท ํ๋ฉด / ์ํ"] --> UC["domain ยท UseCase"]
UC --> RI["domain ยท Repository ์ธํฐํ์ด์ค"]
IM["data ยท RepositoryImpl"] -.->|"๊ตฌํ"| RI
IM --> DS["data ยท RemoteDataSource / DTO"]
DS --> NET["core ยท Dio / ์ธ์ฆ ์ธํฐ์
ํฐ"]
NET --> API["์๋ฒ API"]
IM --> STORE["core ยท SecureStorage (์ธ์ฆ)"]
style UC fill:#F5EDE0,stroke:#7F011F,color:#262626
style RI fill:#F5EDE0,stroke:#7F011F,color:#262626
์์กด์ฑ ๊ตฌ์ฑ์ providers.dart, ๋ผ์ฐํ
์ routes.dart์์ ํ์ธํ ์ ์์ต๋๋ค. API ์๋ต์ DTO์์ Entity๋ก ๋ณํํ๊ณ , ์ ์ฅ์ ๊ตฌํ์ ์ฑ๊ณตยท์คํจ๋ฅผ Result๋ก ์ ๋ฌํฉ๋๋ค.
์ํ ๊ด๋ฆฌ๋ ํ๋ฉด๋ณ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค. Riverpod์ ํตํ ์์กด์ฑ ์ฃผ์
๊ณผ ํธ์ง ์ ์ถ์ AsyncNotifier, ์คํ๋์์ ChangeNotifier ๊ธฐ๋ฐ ViewModel, ํยท๋ฆฌ๋ทฐ ๋ฑ์ ConsumerStatefulWidget ๋ด๋ถ ์ํ๋ฅผ ํจ๊ป ์ฌ์ฉํฉ๋๋ค.
๋ฒ์ ์ pubspec.yaml์ ์ ์ธ ๋ฒ์์ด๋ฉฐ, ํด์๋ ์์กด์ฑ ๋ฒ์ ์ pubspec.lock์ ๊ธฐ๋ก๋ฉ๋๋ค.
| ์์ญ | ์ฌ์ฉ ๊ธฐ์ | ์ ์ฉ ๋ด์ฉ |
|---|---|---|
| ์ฑ ยท ์ธ์ด | Flutter ยท Dart ^3.10.1 |
iOSยทAndroid ๋ชจ๋ฐ์ผ UI์ ์ฑ ๋ก์ง |
| ์ํ ยท ์์กด์ฑ ์ฃผ์ | flutter_riverpod ^3.3.2 |
Provider ๊ตฌ์ฑ, ์ ์ค์ผ์ด์ค ์ฃผ์ , ํธ์ง ์ ์ถ ์ํ |
| ๋ผ์ฐํ | go_router ^15.1.2 |
ํ๋ฉด ์ด๋, ๋ก๊ทธ์ธยท์จ๋ณด๋ฉ ์ํ์ ๋ฐ๋ฅธ ๋ฆฌ๋ค์ด๋ ํธ |
| ๋คํธ์ํฌ | dio ^5.7.0 |
REST API ํต์ , ์ธ์ฆ ํค๋, ํ ํฐ ๊ฐฑ์ |
| ์ธ์ฆ ์ ๋ณด ์ ์ฅ | flutter_secure_storage ^9.2.4 |
์ก์ธ์คยท๋ฆฌํ๋ ์ ํ ํฐ๊ณผ ์จ๋ณด๋ฉ ์ํ ๋ณด๊ด |
| ๋ก๊ทธ์ธ ยท ์ธ๋ถ ์ฐ๊ฒฐ | app_links ^7.0.0 ยท url_launcher ^6.3.2 |
์์ ๋ก๊ทธ์ธ ์ฝ๋ฐฑ ์์ , ์ธ๋ถ URL ์ด๊ธฐ |
| ํ๋ซํผ ์ ๋ณด | package_info_plus ^9.0.1 ยท flutter_timezone ^5.1.0 |
์ฑ ๋ฒ์ ํ์ธ, ํธ์ง ์์ฑ ์ ๊ธฐ๊ธฐ ์๊ฐ๋ ์ ๋ฌ |
| ๊ทธ๋ํฝ ยท ๋ชจ์ | flutter_svg ^2.3.0 ยท lottie ^3.3.3 |
SVG ์์ด์ฝยท์ผ๋ฌ์คํธ, ๋ก๋ฉ ์ ๋๋ฉ์ด์ |
| ํ์ดํฌ๊ทธ๋ํผ | Pretendard | Regular ยท Medium ยท SemiBold ยท Bold ํฐํธ |
| ํ์ง ํ์ธ | flutter_test ยท flutter_lints ^6.0.0 |
๋จ์ยท์์ ฏ ํ ์คํธ์ ์ ์ ๋ถ์ ๊ท์น |
๋ก๊ทธ์ธ ์ฝ๋ฐฑ์ผ๋ก ๋ฐ์ ์ธ์ ์ ์ ์ฅํ๊ณ , ํ ํฐยท์ฝ๊ด ๋์ยท๋๋ค์ ๋ฑ๋ก ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋ฉด ์ ๊ทผ์ ์ ์ดํฉ๋๋ค. ์ฑ ์์ ์ ์๋ฒ ๋ฒ์ ์ ์ฑ ์ ํ์ธํด ๊ฐ์ ์ ๋ฐ์ดํธ ํ๋ฉด์ผ๋ก ์ฐ๊ฒฐํ๋ ํ๋ฆ๋ ๊ตฌ์ฑํ์ต๋๋ค.
AuthInterceptor๋ 401 ์๋ต์ ๋ํด ํ ํฐ์ ๊ฐฑ์ ํ๊ณ ์๋ ์์ฒญ์ ์ฌ์๋ํฉ๋๋ค. ์งํ ์ค์ธ ๊ฐฑ์ Future๋ฅผ ๊ณต์ ํด ์ค๋ณต ๊ฐฑ์ ์ ์ค์ด๊ณ , ์ฌ์๋ ํ์๋ก ๊ฐ์ ์์ฒญ์ด ๋ฐ๋ณต ๊ฐฑ์ ๋์ง ์๋๋ก ์ฒ๋ฆฌํฉ๋๋ค.
ํ ํ๋ฉด์ ์ ์ถยท๊ฒํ ์คยท์๋ฃยท์คํจ ์ํ๋ฅผ ๊ตฌ๋ถํฉ๋๋ค. ๋๊ธฐ ํธ์ง๊ฐ ์์ ๋ 10์ด ๊ฐ๊ฒฉ์ผ๋ก ์ํ๋ฅผ ํ์ธํ๊ณ , ์ฑ์ด ๋นํ์ฑ ์ํ์ด๊ฑฐ๋ ๋๊ธฐ ๋์์ด ์์ผ๋ฉด ํด๋ง์ ๋ฉ์ถฅ๋๋ค. ์์ฒญ ์ ํ ์ค๋ฅ์๋ 1๋ถ ๋๊ธฐ๋ฅผ ์ ์ฉํฉ๋๋ค. ์นด์ดํธ๋ค์ด ํ์์ ์๋ฒ์ ์ค์ ์๋ฃ ์ํ๋ฅผ ๋ณ๋๋ก ๋ค๋ฃน๋๋ค.
๋ฆฌ๋ทฐ DTO์์ ๊ต์ ๊ตฌ๊ฐ์ ์์๋๋ก ์ ๋ฆฌํ๊ณ , ๋ฆฌ๋ทฐ ํ๋ฉด์์ ์๋ฌธ ์ทจ์์ ๊ณผ ๊ต์ ๊ฐ์กฐ๋ฅผ ์กฐํฉํฉ๋๋ค. ํผ๋๋ฐฑ์ด ์๊ฑฐ๋ ์์ฑ์ ์คํจํ ๊ฒฝ์ฐ์ ํ๋ฉด๋ ๊ตฌ๋ถํฉ๋๋ค.
ํ ๋ง์ ๊ณตํต ์์ ฏ์ผ๋ก ์์, ๊ธ๊ผด, ๋ฒํผ, ํธ์ง ํค๋, ์ฐํ ์นด๋์ ๋ค์ด์ผ๋ก๊ทธ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ๊ฐ๋ณ ํ๋ฉด์์๋ ๊ฐ์ ํธ์ง ์๋น์ค์ ์ธ์์ด ์ด์ด์ง๋๋ก ๊ตฌ์ฑํ์ต๋๋ค.
|
YeonJeen @yeonjeen |
Dart ^3.10.1 ์กฐ๊ฑด์ ๋ง์กฑํ๋ Flutter SDK์ Android ๋๋ iOS ๊ฐ๋ฐ ํ๊ฒฝ์ด ํ์ํฉ๋๋ค. iOS ์คํ์๋ macOS์ Xcode๊ฐ ํ์ํฉ๋๋ค.
flutter pub get
flutter run --dart-define=JOLLY_API_BASE_URL=https://YOUR_API_HOST/api/v1YOUR_API_HOST๋ ์ฌ์ฉํ ๋ฐฑ์๋ ์ฃผ์๋ก ๋ฐ๊ฟ์ฃผ์ธ์. ๋ก๊ทธ์ธ๊ณผ ํธ์ง ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ฉด ํด๋น ์๋ฒ ๋ฐ ์์
๋ก๊ทธ์ธ ์ฝ๋ฐฑ ์ค์ ์ด ์ฐ๊ฒฐ๋์ด ์์ด์ผ ํฉ๋๋ค.
ํ๊ฒฝ ์ค์ ๊ณผ ๊ฒ์ฆ ๋ช ๋ น
ApiConfig์ ์ค์ ์ --dart-define์ผ๋ก ์ ๋ฌํ ์ ์์ต๋๋ค.
| ์ค์ | ์ฉ๋ |
|---|---|
JOLLY_API_BASE_URL |
๋ฐฑ์๋ API ๊ธฐ๋ณธ ์ฃผ์ |
JOLLY_AUTH_SCHEME |
๋ก๊ทธ์ธ ์ฝ๋ฐฑ ์คํด, ๊ธฐ๋ณธ๊ฐ dearjolly. ๋ค์ดํฐ๋ธ ์ฑ ์ค์ ๊ณผ๋ ์ผ์นํด์ผ ํจ |
JOLLY_APP_VERSION |
ํ๋ซํผ์์ ์ฑ ๋ฒ์ ์ ์ฝ์ง ๋ชปํ์ ๋์ ๋์ฒด๊ฐ |
JOLLY_IOS_STORE_URL ยท JOLLY_AOS_STORE_URL |
์ ๋ฐ์ดํธ ์๋ด์์ ์ด ์คํ ์ด ์ฃผ์ |
JOLLY_TIME_ZONE |
๊ธฐ๊ธฐ ์๊ฐ๋ ์กฐํ ์คํจ ์ ๋์ฒด๊ฐ, ๊ธฐ๋ณธ๊ฐ Asia/Seoul |
flutter analyze
flutter testํ ์คํธ ์ฝ๋๋ test/์์ ํ์ธํ ์ ์์ต๋๋ค.
์ค๋์ ํ ๋ฌธ์ฅ์ด, ๋ด์ผ์ ์กฐ๊ธ ๋ ์์ฐ์ค๋ฌ์ด ์์ด๊ฐ ๋๋๋ก.
Write to Jolly, feel jolly โ๏ธ


