Skip to content

Latest commit

ย 

History

History
74 lines (56 loc) ยท 11.3 KB

module-structure.md

File metadata and controls

74 lines (56 loc) ยท 11.3 KB
authority canonical
status active
last_verified 2026-10-30

๋ชจ๋“ˆ ๊ตฌ์กฐ

์‹ค์ œ ๋“ฑ๋ก ์—ฌ๋ถ€๋Š” settings.gradle.kts์—์„œ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์ธต ๊ฒฝ๊ณ„๋Š” ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

๋ชจ๋“ˆ ํŒจํ‚ค์ง€ ๊ธฐ์ค€ ํ˜„์žฌ ์ƒํƒœ ๋˜๋Š” ์ถ”๊ฐ€ ์‹œ์ 
:app com.yapp.plus ์•ฑ ์ง„์ž…์ ยท์„ธ์…˜ ๋ณต์›์— ๋”ฐ๋ฅธ ์‹œ์ž‘ ๋ชฉ์ ์ง€ยทGoogle ์ธ์ฆ ๊ฒฐ๊ณผ์™€ ๊ฐ€์ž… ์ด๋™ยท๋กœ๊ทธ์•„์›ƒ/ํ†ตํ•ฉ ํƒˆํ‡ด ์ƒํƒœ์™€ ๋‚ด๋น„๊ฒŒ์ด์…˜ยทYAPP Data ์กฐ๋ฆฝยทํ† ํฐ ์ €์žฅ/๊ฐฑ์‹ ยทํƒญ ๋‚ด๋น„๊ฒŒ์ด์…˜
:core:designsystem com.yapp.plus.core.designsystem ํ…Œ๋งˆยท๊ณตํ†ต ์ปดํฌ๋„ŒํŠธยท์ธ์ฆ ๊ณตํ†ต ํ‘œํ˜„ ๊ตฌํ˜„๋จ
:core:preview com.yapp.plus.core.preview debug ์ „์šฉ ๋ฒ”์šฉ Preview providerยท์ž…๋ ฅ fixture ๊ตฌํ˜„๋จ
:feature:main:home com.yapp.plus.feature.main.home YAPP ์ด๋ฒˆ ์ฃผ ์„ธ์…˜ยท์ถœ์„ ์ธ์ฆยท์‚ฌ์ „ ๋ณด๊ณ ยท์ฃผ๊ฐ„ ๊ณต์ง€ ์—ฐ๊ฒฐ; ์•Œ๋ฆผยท์ ์ˆ˜ ์ง„์ž… ์ˆจ๊น€
:feature:main:schedule com.yapp.plus.feature.main.schedule ํ˜„์žฌ ๊ธฐ์ˆ˜ ์ผ์ • API RouteยทViewModelยทUI ๋งคํ•‘ ๋ฐ ์ผ์ • ํ™”๋ฉดยท๋ชจ๋ธ ๊ตฌํ˜„๋จ; App์—์„œ ์—ฐ๊ฒฐ
:feature:main:board com.yapp.plus.feature.main.board ๊ณต์ง€ ๋ถ„๋ฅ˜ยท์ปค์„œ ๋ชฉ๋กยทMarkdown ์ƒ์„ธยท๊ณผ์ œยท์ฒจ๋ถ€ ์ด๋ฏธ์ง€ยท์ฝ์Œ ํ™•์ธ API ์—ฐ๊ฒฐ
:feature:main:my com.yapp.plus.feature.main.my Figma ์š”์•ฝยท๊ทœ์น™ยท๋ณ„๋„ ์ด๋ ฅ UI, ์ถœ์„ ์ ์ˆ˜ยท์ปค์„œ ์กฐํšŒ ViewModelยท์˜ค๋ฅ˜ ์žฌ์‹œ๋„; ์ธ์ฆ ์‘๋‹ต ์ด๋ฆ„ ํ‘œ์‹œ; ๋ฏธํ™•์ธ ๊ธฐ์ˆ˜ยท์—ญํ• ยท์ง๊ตฐยท๋ฉด์ œ๊ถŒยท๋ฌธ์˜ UI ์œ ์ง€
:feature:setting com.yapp.plus.feature.setting ์•ฝ๊ด€ยท์•Œ๋ฆผ UIยทFigma ๋กœ๊ทธ์•„์›ƒ/ํšŒ์› ํƒˆํ‡ด ํ™•์ธยท์ง„ํ–‰ยท์˜ค๋ฅ˜ ์žฌ์‹œ๋„ UI; ์•ฑ ๋ฒ„์ „ยทํ™•์žฅ ์•ˆ๋‚ด ์ œ๊ฑฐ; ์ธ์ฆ ์š”์ฒญ์€ App ์ฝœ๋ฐฑ ์‚ฌ์šฉ
:feature:login com.yapp.plus.feature.login Google Credential Manager ID ํ† ํฐยท์›๋ณธ nonce ํš๋“, nonce ํ•ด์‹œยท์ทจ์†Œยท์ค‘๋ณต ์š”์ฒญยท์ธ์ฆ ์˜ค๋ฅ˜ ์žฌ์‹œ๋„
:feature:signup com.yapp.plus.feature.signup ๊ฐ€์ž… ํ† ํฐ์„ ๋ฐ›์•„ ์ด๋ฆ„ยทํœด๋Œ€ํฐ ์ž…๋ ฅยท๊ฒ€์ฆยท์„œ๋ฒ„ ์ œ์ถœยท์™„๋ฃŒ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌ; ์ž…๋ ฅ์€ ๋ณต์›ํ•˜๊ณ  ํ† ํฐ์€ ๋ฉ”๋ชจ๋ฆฌ ์ „์šฉ
:domain com.yapp.plus.domain ์ˆœ์ˆ˜ Kotlin/JVM; ์ธ์ฆยท์„ธ์…˜ Repository ๊ณ„์•ฝ๊ณผ ์ธ์ฆ/์„ธ์…˜ ์ž‘์—… ๊ฒฐ๊ณผ, ์ผ์ •ยท์ถœ์„ ๊ณ„์•ฝยท๊ฐ€์ž… ์ž…๋ ฅ ๊ฐ’ ๊ฐ์ฒด; ์‚ฌ์šฉ์ž ์ถœ์„ ์กฐํšŒยท์ด๋ฆ„ยท๊ณต์ง€ยท์‚ฌ์ง„ยท๊ธฐ๊ธฐ Repository ๊ณ„์•ฝ๊ณผ Data ๊ตฌํ˜„ ์—ฐ๊ฒฐ
:data com.yapp.plus.data Google OIDC ์ธ์ฆยทํšŒ์›๊ฐ€์ž…ยท๋กœ๊ทธ์•„์›ƒยทํ†ตํ•ฉ ํƒˆํ‡ดยท์„ธ์…˜ ๊ฐฑ์‹  ๋ฐ YAPP ์ผ์ •ยท์ถœ์„ยท๊ณต์ง€ยทํŒ€ ์‚ฌ์ง„ยทํ‘ธ์‹œ ๊ธฐ๊ธฐ ์–ด๋Œ‘ํ„ฐ์™€ Repository, ์ด๋ฆ„ยทํ† ํฐ ์•”ํ˜ธํ™” ์ €์žฅ ์—ฐ๊ฒฐ
:core:network com.yapp.plus.core.network Ktor HTTP clientยทJSONยทํ™˜๊ฒฝ๋ณ„ base URLยทdebug ๋กœ๊ทธยทํ† ํฐ ๋ณต์›/๊ต์ฒด ์กฐ์œจยท401 ๊ฐฑ์‹  ๋ฐ ์ค‘๋ณต ๋ฐฉ์ง€ ๊ตฌํ˜„; API DTO๋Š” :data ์†Œ์œ 
build-logic Gradle convention plugins ๋ณ„๋„ included build; ์•ฑ ๋ชจ๋“ˆ์ด ์•„๋‹˜
:core:datastore com.yapp.plus.core.datastore DataStore ์„ธ์…˜ ๋ ˆ์ฝ”๋“œยทKeystore ์•”ํ˜ธํ™”ยท๋ฐฑ์—… ์ œ์™ธ ํŒŒ์ผ ์ €์žฅ ๊ตฌํ˜„๋จ; Data์—์„œ ์‚ฌ์šฉ

14๊ฐœ Gradle ๋ชจ๋“ˆ์˜ ๊ณตํ†ต ์„ค์ •์€ build-logic convention plugin์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. App์€ Hilt ์ง„์ž…์ ๊ณผ ๋„คํŠธ์›ŒํฌยทRepository ๊ฐ์ฒด ์กฐ๋ฆฝ์„ ๊ฐ–๊ณ , :core:network๋Š” Ktor Android client, JSON ์ง๋ ฌํ™”, ํ™˜๊ฒฝ๋ณ„ base URL๊ณผ ์ธ์ฆยท์„ธ์…˜ ๊ฐฑ์‹  ์กฐ์œจ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. :data๋Š” Network์˜ ์˜๊ตฌ ์ €์žฅ ๊ณ„์•ฝ์„ :core:datastore์— ์—ฐ๊ฒฐํ•˜๋ฉฐ App์ด singleton์œผ๋กœ ์กฐ๋ฆฝํ•ฉ๋‹ˆ๋‹ค. ์ €์žฅ๋œ ์ตœ์‹  ํ† ํฐ ์Œ์€ ์ฒซ ์ธ์ฆ ์š”์ฒญ ์ „์— ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค. ์„ธ์…˜ ์ผ์ • ์กฐํšŒ์˜ Domain ๊ณ„์•ฝ, :data์˜ DataSourceยทDTO ๋งคํ•‘ยทRepository ๊ตฌํ˜„, ํ™ˆยท์ผ์ • Feature์˜ ViewModelยทUI ๋ณ€ํ™˜์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Domain๊ณผ Data์˜ ๊ธฐ๋Šฅ๋ณ„ ๋ถ„๋ฆฌ๋Š” ๊ทœ๋ชจ์™€ ์˜์กด ๊ด€๊ณ„์— ๋”ฐ๋ผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ๋ฒ„์ „์€ YAPP ์„œ๋ฒ„์˜ Google ๋„ค์ดํ‹ฐ๋ธŒ ์ธ์ฆยทํšŒ์›๊ฐ€์ž…ยท๋กœ๊ทธ์•„์›ƒยทํ†ตํ•ฉ ํƒˆํ‡ดยท์ผ์ •ยท์ถœ์„ ์ธ์ฆยท๋ณด๊ณ  ์–ด๋Œ‘ํ„ฐ๋ฅผ App Hilt์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์— ํ™•์ธ๋œ ๊ณ„์•ฝ๋งŒ DataSourceยทDTO๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. My ์ถœ์„ ์ ์ˆ˜ยท์ด๋ ฅ ์กฐํšŒ๋ฅผ ์ธ์ฆ client์— ์—ฐ๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์ง€์™€ ์‚ฌ์ „ ๋ณด๊ณ  ํ™”๋ฉด ๋ฐ ์ธ์ฆ ์‘๋‹ต ์ด๋ฆ„์„ ์—ฐ๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ํŒ€ ์‚ฌ์ง„ ์—…๋กœ๋“œยท์ œ์ถœ๊ณผ ํ‘ธ์‹œ ๊ธฐ๊ธฐ ๋“ฑ๋กยทํ•ด์ œ๋Š” ์–ด๋Œ‘ํ„ฐยทHilt ์กฐ๋ฆฝ๊นŒ์ง€ ์™„๋ฃŒํ–ˆ๊ณ  ์‹ค์ œ ํŒ€์› ์„ ํƒยทFirebase ์—ฐ๊ฒฐ์€ ํ›„์†์ž…๋‹ˆ๋‹ค. My ๊ธฐ์ˆ˜ยท์—ญํ• ยท์ง๊ตฐยท์ง€๊ฐ ๋ฉด์ œ๊ถŒยท์•Œ๋ฆผยท๋ฌธ์˜๋Š” UI๋ฅผ ์œ ์ง€ํ•˜๊ณ  ๋ฏธํ™•์ธ ๊ณ„์•ฝ์˜ ์—ฐ๊ฒฐ๋งŒ ๋น„์›Œ ๋‘ก๋‹ˆ๋‹ค.

Login Feature๋Š” Google Credential Manager์˜ ID ํ† ํฐ๊ณผ nonce๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์˜ App ์ฝœ๋ฐฑ์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. App์€ YAPP ์ธ์ฆ ๊ฒฐ๊ณผ๋ฅผ ํ•ด์„ํ•ด ์„ธ์…˜์„ ์ €์žฅํ•˜๊ฑฐ๋‚˜ Signup Feature๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. Signup Feature๋Š” ๊ฐ€์ž… ํ† ํฐ์„ ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ์ด๋ฆ„ยทํœด๋Œ€ํฐ ์ž…๋ ฅ, E.164 ๊ฒ€์ฆ, ์„œ๋ฒ„ ์ œ์ถœยท์™„๋ฃŒ ์ „ํ™˜๊ณผ ๋‚ด๋ถ€ ๋’ค๋กœ ๊ฐ€๊ธฐยท์ž…๋ ฅ ๋ณต์›์„ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค. ์‹œ์ž‘ ์‹œ ์„ธ์…˜ ๋ณต์›์€ App์ด ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค.

App์€ ๋„ค ํƒญยท๊ณต์ง€ IDยท์„ค์ • ํ™”๋ฉด ์ด๋™์„ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค. ํ™ˆ๊ณผ ์ผ์ •์˜ ViewModel์€ Repository ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์˜ˆ์‹œ ๊ฐ’์€ src/debug Preview์—์„œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. My ViewModel์€ ์ถœ์„ ์ ์ˆ˜์™€ ์ด๋ ฅ API ์š”์ฒญยทํŽ˜์ด์ง€ยท์˜ค๋ฅ˜๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๋ณ„๋„ ์ด๋ ฅ ํ™”๋ฉด ์ด๋™์€ App์˜ ์ €์žฅ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ๋ณ„ ํ™”๋ฉด์€ Preview์™€ ํ…Œ์ŠคํŠธ์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ž„์‹œ ๋น„๊ณต๊ฐœ ํ…Œ์ŠคํŠธ ๊ตฌํ˜„์€ release/v1.0.1์— ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋žœ์น˜ ์šด์˜์€ CONTRIBUTING.md๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

ํŒŒ์ผ ๋ฐฐ์น˜

  • Android ๋ชจ๋“ˆ์˜ Kotlin ์†Œ์Šค๋Š” src/main/java/<ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ>/์— ๋‘ก๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ Kotlin/JVM Domain ์†Œ์Šค๋Š” domain/src/main/kotlin/<ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ>/์— ๋‘ก๋‹ˆ๋‹ค.
  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” src/test/, ๊ธฐ๊ธฐ ํ…Œ์ŠคํŠธ๋Š” src/androidTest/์˜ ํ•ด๋‹น ํŒจํ‚ค์ง€์— ๋‘ก๋‹ˆ๋‹ค.
  • App์—๋Š” Android ์ง„์ž…์ ยท์ „์ฒด ๋‚ด๋น„๊ฒŒ์ด์…˜ยท๊ฐ์ฒด ์กฐ๋ฆฝ์„, Feature์—๋Š” ํ™”๋ฉดยทViewModelยทUiState์™€ ๊ธฐ๋Šฅ๋ณ„ UI ๋ณ€ํ™˜์„ ๋‘ก๋‹ˆ๋‹ค.
  • Domain์—๋Š” ๋ชจ๋ธยท์ •์ฑ…ยทRepository ๊ณ„์•ฝยทํ•„์š”ํ•œ UseCase๋ฅผ, Data์—๋Š” Repository ๊ตฌํ˜„ยทDataSourceยทDTOยทDomain ๋ณ€ํ™˜์„ ๋‘ก๋‹ˆ๋‹ค.
  • ๊ฐ Android ๋ชจ๋“ˆ์˜ Hilt ์˜์กด์„ฑ ์ฃผ์ž… ํŒŒ์ผ(@Module, @Binds, @Provides ์„ ์–ธ ๋“ฑ)์€ ๋ชจ๋“ˆ ๋ฃจํŠธ์˜ di/ ํŒจํ‚ค์ง€์— ๋‘ก๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด App์€ com.yapp.plus.di, ๋กœ๊ทธ์ธ Feature๋Š” com.yapp.plus.feature.login.di๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋…๋ฆฝ UI ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„์€ ๋ชจ๋“ˆ ๋ฃจํŠธ์˜ components/ ํŒจํ‚ค์ง€์— ๋‘ก๋‹ˆ๋‹ค. ํ•„์š”ํ•˜๋ฉด components/auth/, components/button/์ฒ˜๋Ÿผ ํ•˜์œ„ ํŒจํ‚ค์ง€๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. RouteยทScreen๊ณผ ํ™”๋ฉด ์ƒํƒœ ๋ณ€ํ™˜์€ Feature์˜ ๊ธฐ๋Šฅ ํŒจํ‚ค์ง€์— ๋‘๊ณ  components/์™€ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • Designsystem์˜ ํ…Œ๋งˆ๋Š” core/designsystem/src/main/java/com/yapp/plus/core/designsystem/theme/์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋„ ์ด ๋ชจ๋“ˆ์˜ components/์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ธ์ฆ์˜ ๊ณตํ†ต ํ‘œํ˜„์€ Designsystem์˜ components/auth/์— ๋‘ก๋‹ˆ๋‹ค. ํ‘œ์‹œ๊ฐ’๊ณผ ์ฝœ๋ฐฑ๋งŒ ๋ฐ›๊ณ  Feature ์ƒํƒœยท๋ชฉ์ ์ง€ยท์ธ์ฆ ์ •์ฑ…์„ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ๋ณ„ ๋ฌธ๊ตฌยท๋กœ๊ทธ์ธ ๊ณต๊ธ‰์ž ๋กœ๊ณ ยท์ƒํƒœ ๋ณ€ํ™˜์€ Feature๊ฐ€ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค.
  • Preview ์ „์šฉ ์†Œ์Šคยท๋ฆฌ์†Œ์Šค๋Š” ๊ฐ ๋ชจ๋“ˆ์˜ src/debug/์— ๋‘ก๋‹ˆ๋‹ค. Preview ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ๋Š” ๋Œ€์‘ํ•˜๋Š” components/ ํ•˜์œ„ ๊ฒฝ๋กœ์™€ ๋งž์ถฅ๋‹ˆ๋‹ค. :core:preview๋„ debug ์†Œ์Šค์—๋งŒ providerยทfixture๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ DesignsystemยทFeatureยทDomainยทDataยทNavigation์— ์˜์กดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์†Œ๋น„ ๋ชจ๋“ˆ์€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ debugImplementation(project(":core:preview"))์œผ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. src/main์€ debug ํƒ€์ž…์„ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ณ  ์•ฑ release ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„์— Preview ๋ชจ๋“ˆ์„ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž ๋ฌธ๊ตฌ๋Š” ํ•ด๋‹น Android ๋ชจ๋“ˆ์˜ src/main/res/values/strings.xml์— ๋‘ก๋‹ˆ๋‹ค.
  • ๋ฒ”์šฉ ํŒŒ์ผยท๋ชจ๋“ˆ์„ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ฒ˜์˜ ์‹ค์ œ ๊ณตํ†ต ์ฑ…์ž„์ด ํ™•์ธ๋˜๋ฉด ๊ณตํ†ตํ™”ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“ˆ ๋ณ€๊ฒฝ ์ ˆ์ฐจ

๋ชจ๋“ˆ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์˜ฎ๊ธธ ๋•Œ ์‹ค์ œ ์ฑ…์ž„ยท์‚ฌ์šฉ์ฒ˜ยท๊ณ„์•ฝยทํ˜ธ์ถœ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผยทํŒจํ‚ค์ง€๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  settings.gradle.kts์— ๋“ฑ๋กํ•œ ๋’ค ์•„ํ‚คํ…์ฒ˜์˜ ์˜์กด์„ฑ ๋ฐฉํ–ฅ๊ณผ App์˜ ๊ฐ์ฒด ์กฐ๋ฆฝ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉํ•  Fakeยทํ…Œ์ŠคํŠธ ๋„๊ตฌ๋Š” ํ•„์š”ํ•  ๋•Œ ํ…Œ์ŠคํŠธ ์˜์กด์„ฑ์œผ๋กœ๋งŒ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์˜ํ–ฅ๋ฐ›๋Š” ๋ชจ๋“ˆ๊ณผ ํ˜ธ์ถœ๋ถ€๋ฅผ ๊ฒ€์ฆํ•˜๊ณ  ์ด ๋ฌธ์„œ, AGENTS.md, README.md์˜ ์ƒํƒœ๋ฅผ ํ•จ๊ป˜ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค. ์—†๋Š” ๋ชจ๋“ˆ์ด๋‚˜ ๊ฒ€์‚ฌ ๋„๊ตฌ์˜ ๋ช…๋ น์„ ์‹คํ–‰ํ–ˆ๋‹ค๊ณ  ๋ณด๊ณ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ธ์ฆ ์„ธ์…˜ ์ž๋™ ๊ฒ€์ฆ

  • App ๋‚ด๋น„๊ฒŒ์ด์…˜ UI ํ…Œ์ŠคํŠธ๋Š” debug ์ „์šฉ Hilt ์ง„์ž…์  NavigationTestActivity๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ComponentActivity๋Š” Hilt ViewModel์„ ์ƒ์„ฑํ•˜์ง€ ๋ชปํ•˜๋ฉฐ ์ด ํ…Œ์ŠคํŠธ Activity๋Š” release ์†Œ์Šค์— ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • App์˜ AppAuthViewModelTest๋Š” Fake Repository๋กœ ์„ฑ๊ณต ์ „ ์„ธ์…˜ ๋ณด์กด, ์‹คํŒจยท์žฌ์‹œ๋„, ์ค‘๋ณตยท๊ต์ฐจ ์š”์ฒญ ๋ฐฉ์ง€์™€ ์ทจ์†Œ ํ›„ ๋กœ๋”ฉ ํ•ด์ œ๋ฅผ ๊ฒ€์ฆํ•˜๋ฉฐ 8๊ฑด์„ ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค.

  • App์˜ AccountDeletionUiTest 4๊ฑด์€ ์ฃผ์ž…ํ•œ ์ฝœ๋ฐฑ์œผ๋กœ ํšŒ์› ํƒˆํ‡ด ํ™•์ธยท๋ณต์›ยท์ง„ํ–‰ยท์˜ค๋ฅ˜ ์žฌ์‹œ๋„๋ฅผ, SessionOperationNavigationUiTest 3๊ฑด์€ ์„ฑ๊ณต ์ฝœ๋ฐฑ ํ›„ ๋กœ๊ทธ์ธ ๋ณต๊ท€ยทMain back stack ์ œ๊ฑฐ์™€ My ์ด๋ ฅ ํ™”๋ฉด์˜ ์ƒํƒœ ๋ณต์›ยท์‹œ์Šคํ…œ ๋’ค๋กœ ๊ฐ€๊ธฐ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. API 35 ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ 7๊ฑด์„ ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ API ์—ฐ๊ฒฐ์€ ๊ตฌํ˜„๋์ง€๋งŒ ์ด UI ํ…Œ์ŠคํŠธ๋Š” ๋ชจ์˜ ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์„œ๋ฒ„ E2E ๊ฒ€์ฆ์œผ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • MyPageUiTest, ConnectedApisUiTest, UnconnectedFeaturesUiTest, ์œ„ ๋‘ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์™€ ReleaseDesignUiTest.settingsActionsRemainReachableOnCompactScreen์„ ํ•จ๊ป˜ ์‹คํ–‰ํ•ด API 35์—์„œ UI ํ…Œ์ŠคํŠธ 18๊ฑด์„ ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์ง€์˜ ๋ช…์‹œ์  ์ฝ์Œ ํ™•์ธ, ๋ณด๊ณ  ์„ ํƒยท์‚ฌ์œ , ์ด๋ฆ„ ํ‘œ์‹œ์™€ ๋ฏธํ™•์ธ ํšŒ์› ํ•„๋“œ, My ๋‚ด์—ญยท๊ทœ์น™ยท๋นˆ ํ™”๋ฉดยท์žฌ์‹œ๋„๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ํ™”๋ฉด ๋ฐ์ดํ„ฐ์™€ ์ œ์ถœ ์ฝœ๋ฐฑ์€ ํ…Œ์ŠคํŠธ ๋Œ€์—ญ์ž…๋‹ˆ๋‹ค.

  • Network์˜ TokenStorePersistenceTest์™€ RestoredSessionAuthenticationTest๋Š” ์ €์žฅ์†Œ ์žฌ์ƒ์„ฑ ํ›„ ๋ณต์›, ์ฒซ ์š”์ฒญ์˜ ๋ณต์› ๋Œ€๊ธฐ, 401 ๊ฐฑ์‹ ยท์žฌ์‹œ๋„, ๋™์‹œ 20๊ฐœ ์š”์ฒญ์˜ ๊ฐฑ์‹  1ํšŒ ๊ณต์œ , ์ €์žฅ ์‹คํŒจยท์ทจ์†Œ์™€ ์„ธ์…˜ ๊ต์ฒด ๊ฒฝ๊ณ„๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. SessionAuthenticationTest๋Š” ์›๋ž˜ ์š”์ฒญ์˜ methodยทbodyยทqueryยทheaders ๋ณด์กด๊ณผ ๊ธฐ์กด ์ธ์ฆ ๊ฒฝ๊ณ„๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

  • Data์˜ SessionRestartInstrumentedTest๋Š” ์‹ค์ œ SessionTokenLocalDataSourceยทDataStoreยทAndroid Keystore๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ APK์—์„œ ํ† ํฐ ํšŒ์ „ ์ €์žฅ โ†’ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ ํ›„ ๋ณต์›ยท์‚ญ์ œ โ†’ ๋‹ค์‹œ ์ข…๋ฃŒ ํ›„ ๋นˆ ์„ธ์…˜ ๋ณต์›์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ํ† ํฐ์€ ๊ฐ€์งœ ๊ฐ’์ด๊ณ  ์ผ๋ฐ˜ ์•ฑ์˜ ์„ธ์…˜ ํŒŒ์ผ์ด๋‚˜ ์‹ค์ œ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ํ”„๋กœ์„ธ์Šค ๊ฒ€์ฆ์€ ์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์„ธ ๋‹จ๊ณ„๋ฅผ ๊ฐ๊ฐ ๋ณ„๋„ instrumentation ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰ํ•˜๊ณ  PID๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์ธ ๋‹จ๊ณ„ ์ธ์ž๊ฐ€ ์—†๋Š” ์ผ๋ฐ˜ instrumentation ์‹คํ–‰์—์„œ๋Š” ํ•ด๋‹น ์„ธ ๋‹จ๊ณ„๊ฐ€ ์ƒ๋žต๋ฉ๋‹ˆ๋‹ค. adb๊ฐ€ PATH์— ์—†์œผ๋ฉด ์Šคํฌ๋ฆฝํŠธ์˜ --adb ์˜ต์…˜์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

./gradlew :core:network:testDebugUnitTest :data:testDebugUnitTest :data:installDebugAndroidTest
python3 scripts/verify_session_restart.py --serial emulator-5554

๊ธฐ๊ธฐ serial์€ ์‹คํ–‰ ์ค‘์ธ ๊ธฐ๊ธฐ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. ์‹ค์ œ YAPP ์„œ๋ฒ„์˜ ์ดˆ๊ธฐ ์„ธ์…˜ยทํ† ํฐ ํšŒ์ „ ๊ฒ€์ฆ์—๋Š” ๋ณ„๋„์˜ ์œ ํšจํ•œ ํ…Œ์ŠคํŠธ ํ† ํฐ ์Œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.