๐ค ์ธ๊ณต์ง๋ฅ๊ณผ์ ํ์ ์ค์ ๊ฐ์ด๋ - devlink-community/gaesubang-app GitHub Wiki
์ด ํ๋ก์ ํธ์์์ AU ํ์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์ฝ์ด ๋ก์ง (๋ฐ์ดํฐ, ์ํ, ์ ์ค์ผ์ด์ค ๋ฑ)์ ChatGPT์ ํจ๊ป ๋น ๋ฅด๊ฒ ์ค๊ณํ๊ณ ์๋ํ
- ์ธ๊ฐ ๊ฐ๋ฐ์๋ค์ ๊ทธ๋งํผ UI/UX์ ์ง์ค
- ๊ฒฐ๊ณผ์ ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์ ๋ฌ๋๋ ํ๋ฉด์ ์์ฑ๋์ ์ฌ๋์ ๋ํ ์ผ์ ์์๋ถ๋ ๊ฒ
์ด ํ๋ก์ ํธ์์ ChatGPT๋ ๋จ์ ๋ฌธ์ ์์ฑ ๋ณด์กฐ๊ฐ ์๋
Dart ์ฝ์ด ๋ก์ง์ ์ค๊ณ ๋ฐ ๊ตฌํ ํํธ๋๋ก ํ์ฉ๋ฉ๋๋ค.
- AI๋
data/
,domain/
,usecase/
๊ณ์ธต์ ์ค๊ณ์ ๋ฆฌํฉํ ๋ง์ ์ฃผ๋ - ์ธ๊ฐ ๊ฐ๋ฐ์๋ UI ์์ ฏ ๊ตฌ์ฑ, ํ๋ฉด ํ๋ฆ, ์ฌ์ฉ์ ๊ฒฝํ์ ์ง์ค
-
.md
๊ฐ์ด๋๋ AI์๊ฒ ํ์ ๊ฐ๋ฐ ๊ธฐ์ค์ ์ ๋ฌํ๊ธฐ ์ํ ์ฐธ์กฐ ๋ฌธ์ ์ญํ ์ ํฉ๋๋ค.
ChatGPT์ โํ๋ก์ ํธโ๋ ๋จ์ ๋ํ ๊ธฐ๋ก ๊ธฐ๋ฅ์ด ์๋๋ผ,
AI๊ฐ ํ๋ก์ ํธ์ ๊ฐ๋ฐ ๊ตฌ์กฐ, ์ ๋ก๋ํ ํ์ผ, ์ง์นจ์ "๊ธฐ์ต"ํ๊ณ ์ฅ๊ธฐ์ ์ผ๋ก ํ์ฉํ ์ ์๋๋ก ํด์ฃผ๋ ๊ธฐ๋ฅ์ ๋๋ค.
Flutter ๊ฐ๋ฐ์์ ํนํ ๋ค์๊ณผ ๊ฐ์ ์ฉ๋๋ก ์ ์ฉํฉ๋๋ค:
- ํ๋ก์ ํธ ์ ์ฉ
lib/
,core/
,docs/
ํ์ผ ๊ตฌ์กฐ๋ฅผ ๊ทธ๋๋ก AI์๊ฒ ์ธ์์ํด - ๊ฐ ๊ณ์ธต๋ณ ํ์ผ(์:
result.dart
,login_use_case.dart
)์ ๋ถ์ํ์ฌ ๊ตฌ์กฐ๋ฅผ ๊ธฐ์ต - ๋ฌธ์ ๊ฐ์ด๋(
naming.md
,state_guide.md
)๋ฅผ ๊ธฐ์ค์ผ๋ก AI์๊ฒ ๊ธฐ์ค ์ ์
- ChatGPT ์ผ์ชฝ ๋ฉ๋ด โ "ํ๋ก์ ํธ" โ ์ ํ๋ก์ ํธ ์์ฑ
- ์:
SurvivorNet Flutter App
ํญ๋ชฉ | ์ค๋ช | ์์ |
---|---|---|
์ง์นจ ์ค์ | ํ๋ก์ ํธ์ ์ฌ์ฉํ ์ํคํ ์ฒ, ํด๋ ๊ตฌ์กฐ, ๋ค์ด๋ฐ ๊ท์น ๋ฑ | โFreezed ๊ธฐ๋ฐ MVI ๊ตฌ์กฐ, ๊ธฐ๋ฅ ๋จ์ ํด๋ ๋ถ๋ฆฌ, ๋ชจ๋ Action์ sealed classโ |
ํ์ผ ์ ๋ก๋ | ํต์ฌ .dart ํ์ผ, .md ๊ฐ์ด๋ ์
๋ก๋ |
result.dart , naming_guideline.md ๋ฑ |
๊ธฐ๋ณธ ๊ธฐ๋ฅ ์์ ๋ฑ๋ก | ํ ํ๋ฆฟ ํ์ผ์ ๋ฏธ๋ฆฌ ๋ฑ๋กํด์ ๊ธฐ์ค ์ ์ |
custom_button.dart , login_use_case.dart
|
์ ํ | ์ ๋ก๋ ๋์ |
---|---|
๊ณตํต ์ฝ์ด |
failure.dart , result.dart , ui_state.dart
|
๊ณตํต ์ปดํฌ๋ํธ |
custom_button.dart , input_field.dart
|
์ค๊ณ ๊ฐ์ด๋ ๋ฌธ์ |
naming_guidelines.md , state_structure.md
|
ํ ํ๋ฆฟ ํ์ผ |
base_view_model.dart , profile_view_model.dart
|
๐ ํ์ผ ์
๋ก๋ ํ:
"์ด ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ failure.dart, result.dart, ui_state.dart ๊ธฐ์ค์ ๋ณด๊ณ ,
login_use_case.dart๋ฅผ ์ค๊ณํด์ค. API๋ ์ด๋ฉ์ผ/๋น๋ฐ๋ฒํธ ๊ธฐ๋ฐ์ด์ผ."
โก๏ธ ChatGPT๋ ํ์ผ ๋ด ๊ธฐ์ค์ ์ฝ๊ณ , ๊ทธ์ ๋ง์ถ UseCase ํ
ํ๋ฆฟ์ ์ ์ํจ
๐ ๋ฌธ์ ๊ธฐ๋ฐ ์์ฒญ:
"์ด ๊ฐ์ด๋ ๋ฌธ์์ ๋ฐ๋ผ ViewModel์ ํ์ํ ์ํ ํ๋ ๊ตฌ์ฑํด์ค."
<state_guidelines.md ์ผ๋ถ ๋ณต๋ถ ๋๋ ๋ฑ๋ก>
์ ๋ต | ์ค๋ช |
---|---|
๐ ์ง์นจ ์ ๋ฐ์ดํธ ์์ฃผ ํ๊ธฐ | ๊ตฌ์กฐ ๋ณ๊ฒฝ, ๋ค์ด๋ฐ ์ปจ๋ฒค์ ๋ฐ๋๋ฉด ์ง์นจ๋ ์ ๋ฐ์ดํธ |
๐ ๋ฌธ์ ์ฐ์ ์ ๊ณต | ๊ธฐ์ค .md ๋ฌธ์๋ฅผ ์ฒจ๋ถํ๋ฉด ์ ํ๋ ์์น |
๐๏ธ ํ์ผ๋ช ๋ช ํํ ์ธ๊ธ | โlogin_use_case.dart ๊ธฐ์ค์ผ๋ก ๋ง๋ค์ด์คโ ์ฒ๋ผ ๋ช ํํ ์ง์๊ฐ ํจ๊ณผ์ |
๐งช ๋น๊ต ์์ฒญ ํ์ฉ | โA vs B ํ์ผ ์ค ์ด๋ค ๊ตฌ์กฐ๊ฐ ์ ์ง๋ณด์์ ์ ๋ฆฌํ๊ฐ?โ์ ๊ฐ์ ๋ถ์ ์์ฒญ ๊ฐ๋ฅ |
์ค๋ช | |
---|---|
์ธ๊ฐ ๊ฐ๋ฐ์ | UI ์ค๊ณ ๋ฐ ๊ตฌํ๋ฟ๋ง ์๋๋ผ, AI๊ฐ ์์ฑํ ๋ก์ง์ ์ค๊ณ ๊ฒํ , ๋ถ๋ถ ๋จ์ ํ ์คํธ, ๋๋ฉ์ธ ํ๋ฆ ์ดํด ๋ฐ ๊ตฌ์กฐ ๊ฐ์ ๊น์ง ํฌํจ |
ChatGPT | ๋น์ฆ๋์ค ๋ก์ง, ์ํ ๊ตฌ์กฐ, UseCase/Repository์ ์ด์ ์ค๊ณ ๋ฐ ์๋ํ ์์ฑ ์ง์ |
๊ฐ๋ฐ ๊ฐ์ด๋ ๋ฌธ์ | ํ์ ์ค๊ณ ๊ธฐ์ค์ ๋ช ํํ ์ ๋ฌํ๋ ์ฐธ์กฐ์ฉ ๋ฌธ์ |
ํ ํ๋ฆฟ ํ์ผ | ๊ตฌ์กฐ์ ์ค๊ณ ํ๋ฆ์ ์๋ ์์ฑ ๊ธฐ์ค (AI ์์ฑ ๊ฒฐ๊ณผ ํ์ง ํฅ์์ ๊ธฐ์ฌ) |
โ ๏ธ ์ฃผ์: AI๋ ๋ก์ง ์๋ํ์ ๋ณด์กฐ์์ด๋ฉฐ, ์ต์ข ์ฑ ์์ ์ธ๊ฐ ๊ฐ๋ฐ์์๊ฒ ์์ต๋๋ค.์์ฑ๋ ์ฝ๋์ ์๋ ํ์ , ์ค๊ณ ๊ฒ์ฆ, ๋ถ๋ถ ๋จ์ ํ ์คํธ, ๋๋ฉ์ธ ์ฐ๊ฒฐ์ฑ์ ๋ฐ๋์ ์ฌ๋์ด ์ง์ ๊ฒํ ํ๊ณ ๋ณด์ํด์ผ ํฉ๋๋ค.
ํนํ ์ํ ๋ถ๋ฆฌ, ์ ์ค์ผ์ด์ค ํ๋ฆ, ViewModel ๋ด ์ญํ ๊ตฌ๋ถ์ ํ์ ๊ธฐ์ค์ ๋ฐ๋ผ ๋ฐ๋ณต์ ์ผ๋ก ๊ฐ์ ๋์ด์ผ ํฉ๋๋ค.
AI์ ํ์ ํ ๋ ํต์ฌ์ โ๋ฌด์์ ์ด๋ป๊ฒ ์์ฒญํ๋๋โ ์ ๋๋ค.
๊ธฐ์ค ๋ฌธ์๋ ํ ํ๋ฆฟ์ด ์ ๊ฐ์ถฐ์ ธ ์์ด๋, ์์ฒญ ๋ฐฉ์์ด ๋ชจํธํ๋ฉด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ ์ด๋ ต์ต๋๋ค.
์ด ์น์ ์ ์ฐ๋ฆฌ ํ์ ์ํคํ ์ฒ์ ๊ฐ๋ฐ ๊ตฌ์กฐ์ ๋ง์ถฐ,
์ค์ ๋ก ํจ๊ณผ์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ ์ํ ์์ฒญ ์์ ํ ํ๋ฆฟ์ ์ ๋ฆฌํ ๊ฒ์ ๋๋ค.
์ด ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ base_view_model.dart์ ui_state.dart ๊ธฐ์ค์ผ๋ก,
saved_recipes_view_model.dart ์์ฑํด์ค.
์ํ๋ UiState<List<Recipe>> ํ๋๋ง ์ฌ์ฉํ๊ณ , ๋ถ๋งํฌ ์ถ๊ฐ/์ญ์ ๊ธฐ๋ฅ๋ ํฌํจ์์ผ.
์ด์ ๋ฒ์ ์ profile_state.dart์ ๋ด๊ฐ ์์ ํ ๋ฒ์ ๋น๊ตํด์
์ํ ํ๋ ์ค๊ณ๊ฐ ์ด๋ค ์ ์์ ๊ฐ์ ๋๋์ง ์ค๋ช
ํด์ค.
ํ์ ์๋ ์ค๋ณต์ด๋ ๋ถํ์ํ ์ํ๊ฐ ์์ผ๋ฉด ํจ๊ป ์ง์ ํด์ค.
๊ธ์ฐ๊ธฐ ํ๋ฉด์์ ๋ค์ ์ํ๊ฐ ํ์ํด:
- ์ ๋ชฉ ์
๋ ฅ
- ๋ณธ๋ฌธ ์
๋ ฅ
- ์ด๋ฏธ์ง ์
๋ก๋ ๋ฆฌ์คํธ
- ์์์ ์ฅ ์ฌ๋ถ
์ด ์ํ๋ค์ ๊ตฌ์กฐํํด์ freezed ๊ธฐ๋ฐ ProfilePostState๋ก ์ค๊ณํด์ค.
ํ์ํ๋ฉด ๊ฐ ๊ฐ์ฒด(ValueObject)๋ ์ ์ํด์ค.
login_use_case.dart ํ์ผ ๊ธฐ์ค์ผ๋ก,
fetch_saved_recipes_use_case.dart ์ค๊ณํด์ค.
๊ฒฐ๊ณผ๋ UiState๋ก ๋ฐํํ๊ณ , Repository๋ ์ด๋ฏธ ๊ตฌํ๋์ด ์๋ค๊ณ ๊ฐ์ ํด.
onTapFollow(int userId) ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ follow_view_model.dart๊ฐ ์์ด.
mock_follow_repository.dart๋ ์
๋ก๋ํด๋จ๊ณ ,
๋จ์ toggle ๊ตฌ์กฐ์ผ. ์ํ๊ฐ Success/Favorite โ UnFavorite๋ก ๋ฐ๋๋ ํ๋ฆ ํ
์คํธ ์ฝ๋๋ฅผ ๋ง๋ค์ด์ค.
์ด ๋ฒํผ์ custom_button.dart ํ
ํ๋ฆฟ์ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด์ค.
- ๋์ด๋ ๊ณ ์ ๊ฐ 48
- ์์ด์ฝ ์ ๋ฌด, isLoading, isDisabled ์์ฑ ํฌํจ
- ํญ์ ๋ถ๋ชจ ์์ ฏ์ maxWidth ๊ธฐ์ค์ผ๋ก responsiveํ๊ฒ
์ธ๋ถ ์คํ์ผ(AppTextStyles, ColorStyle ๋ฑ)๊น์ง ํฌํจํด์ ์ค๊ณํด์ค.
-
๊ธฐ์ค ํ์ผ๋ช ์ ๋ช ํํ๊ฒ ์ ์ํ ๊ฒ
(์: "login_use_case.dart ๊ธฐ์ค", "profile_state.dart ์ฐธ๊ณ ")
-
์๊ตฌ ํญ๋ชฉ์ ๋ช ์์ ์ผ๋ก ๋์ดํ ๊ฒ
(์: โ์ธ ๊ฐ์ง ์ํ๋ง ํฌํจํด์ฃผ์ธ์โ, โ๋ถํ์ํ ์ํ๋ ์ง์ ํด์ฃผ์ธ์โ)
-
๋ฌธ์/ํ์ผ ๊ธฐ๋ฐ ์์ฒญ ์
.md
๋๋.dart
์ผ๋ถ๋ฅผ ๋ถ์ฌ์ ์ ์(AI๊ฐ ๊ตฌ์กฐ๋ฅผ ๊ธฐ์ตํ๊ณ ๊ธฐ์ค์ ๋ฐ๋ผ ์๋ต ๊ฐ๋ฅ)
์ด ์น์ ์ ํฅํ ์ค์ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์ถ์ ๋๋ฉด ๋ ์ถ๊ฐํ๊ฑฐ๋ ๋ณด์๋ ์ ์์ต๋๋ค.
ํ์์ด ์ง์ ์คํํ ์ ํจํ ์์ฒญ ํ ํ๋ฆฟ์ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ณ ๋ฐ์ํด์ฃผ์ธ์.