Skip to content

Latest commit

ย 

History

History
97 lines (79 loc) ยท 6.6 KB

technology-stack.md

File metadata and controls

97 lines (79 loc) ยท 6.6 KB

Technology stack

์„ ํƒ

์˜์—ญ ์„ ํƒ ๊ธฐ์ค€
์•ฑ ๋Ÿฐํƒ€์ž„ Expo SDK 56 CLEVER Routes์™€ ๊ฐ™์€ ๊ฒ€์ฆ ๊ฒฝ๋กœ ์‚ฌ์šฉ
๋ชจ๋ฐ”์ผ ํ”„๋ ˆ์ž„์›Œํฌ React Native 0.85 iOS์™€ Android ๋‹จ์ผ ์ฝ”๋“œ๋ฒ ์ด์Šค
UI ๋Ÿฐํƒ€์ž„ React 19 Expo 56 ์ •๋ ฌ ๋ฒ„์ „
์–ธ์–ด TypeScript 6 strict ๊ณ„์•ฝ๊ณผ ์ƒํƒœ ์ „์ด์˜ ์ •์  ๊ฒ€์ฆ
ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ npm lockfile ๊ธฐ์กด ์•ฑ๊ณผ ๊ฐ™์€ ์„ค์น˜ยทCI ํ๋ฆ„
Node.js 20.19.4 ์ด์ƒ ๊ธฐ์กด ์•ฑ ์—”์ง„ ๊ธฐ์ค€
๋ฏผ๊ฐ์ •๋ณด ์ €์žฅ Expo SecureStore ์ถ”ํ›„ ์Šน์ธ๋œ ์ธ์ฆ ํ† ํฐ ์ €์žฅ
๋ฐฐ์†ก ์ฆ๋น™ ์„ ํƒ Expo ImagePicker ์นด๋ฉ”๋ผ ์ดฌ์˜๊ณผ ์•จ๋ฒ” ์‚ฌ์ง„ ์„ ํƒ์„ Expo SDK์— ๋งž๊ฒŒ ์ฒ˜๋ฆฌ
๋ฐฐ์†ก ์ฆ๋น™ ์—…๋กœ๋“œ Expo FileSystem + Expo Fetch ๋กœ์ปฌ ์‚ฌ์ง„ URI๋ฅผ File๋กœ ๋ณ€ํ™˜ํ•ด ํ‘œ์ค€ ๋ฉ€ํ‹ฐํŒŒํŠธ ํŒŒ์ผ๋กœ ์ „์†ก
์ „ํ™”๋ฒˆํ˜ธ ์ฒ˜๋ฆฌ libphonenumber-js ๊ตญ๊ฐ€๋ฒˆํ˜ธ์™€ E.164 ์ •๊ทœํ™”
ํ…Œ์ŠคํŠธ Node test runner + tsx ๋„๋ฉ”์ธ ํ…Œ์ŠคํŠธ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๋Ÿฐํƒ€์ž„๊ณผ ๋ถ„๋ฆฌ
์ •์  ๊ฒ€์‚ฌ Expo ESLint + tsc --noEmit ๊ธฐ์กด ๊ฒ€์ฆ ๋ช…๋ น ์œ ์ง€
์ง€๋„ MapLibre React Native 11.3.4 CLEVER Routes์™€ ๊ฐ™์€ ๋„ค์ดํ‹ฐ๋ธŒ ์ง€๋„ ๊ฒฝ๋กœ ์‚ฌ์šฉ
์ง€๋„ ์Šคํƒ€์ผ OpenFreeMap Liberty Routes์˜ ๊ธฐ๋ณธ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์Šคํƒ€์ผ๊ณผ ์ •๋ ฌ
์ œ์Šค์ฒ˜ React Native Gesture Handler ๋“œ๋ž˜๊ทธ ์ž…๋ ฅ์„ ๋„ค์ดํ‹ฐ๋ธŒ UI ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌ
์• ๋‹ˆ๋ฉ”์ด์…˜ React Native Reanimated + Worklets React ์žฌ๋ Œ๋” ์—†์ด ์ฃผ๋ฌธ ์œ„์น˜๋ฅผ UI ์Šค๋ ˆ๋“œ์—์„œ ์ „ํ™˜
Android ๋ฐฐํฌ ๊ณ ์ • Google Drive APK + EAS Google Play AAB ์ง์ ‘ ์„ค์น˜ ์ฑ„๋„๊ณผ Play internal/production ์Šน๊ฒฉ์„ ๋ถ„๋ฆฌ
iOS ๋ฐฐํฌ EAS production + TestFlight + Unlisted App Store ํŒŒ์ผ๋Ÿฟ๊ณผ ์ •์‹ ๋น„๊ณต๊ฐœ ๋งํฌ ๋ฐฐํฌ๋ฅผ ๋ถ„๋ฆฌ

ํ˜„์žฌ ์ œ์™ธ

  • ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ: ์‹ค์ œ ๊ณต์œ  ์ƒํƒœ์™€ ์žฌ์‚ฌ์šฉ ์š”๊ตฌ๊ฐ€ ์—†๋‹ค.
  • API ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ: ํ˜„์žฌ ์Šน์ธ๋œ ์ธ์ฆ ํ˜ธ์ถœ์€ ํ‘œ์ค€ fetch๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค.
  • ๋‚ด๋น„๊ฒŒ์ด์…˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ: ์Šน์ธ๋œ ๋‘ ํ™”๋ฉด์€ ์ตœ์ƒ์œ„ ์ƒํƒœ ์ „ํ™˜์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค.
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์œ„์น˜ ์ถ”์ , ๊ฒฝ๋กœ ๊ณ„์‚ฐ, ์•Œ๋ฆผ: ํ˜„์žฌ ๋ฒ”์œ„์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ์›น์•ฑ๊ณผ PWA: ๋„ค์ดํ‹ฐ๋ธŒ ๊ถŒํ•œยท์ง€๋„ยท์ฆ๋น™ ๊ธฐ๋Šฅ์˜ ๋ฐฐํฌ ๋Œ€์•ˆ์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.
  • iOS Ad Hoc ์ •์‹ ๋ฐฐํฌ์™€ Enterprise ๋ฐฐํฌ: ๋‚ด๋ถ€ QA๊ฐ€ ์•„๋‹Œ ๋ฐฐ์†ก์› ์šด์˜ ๊ฒฝ๋กœ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ง€๋„ ๊ฒฝ๊ณ„

์ง€๋„ ํ™”๋ฉด์€ @maplibre/maplibre-react-native 11.3.4์™€ https://tiles.openfreemap.org/styles/liberty๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์•ฑ์€ ๋ฐฐ์†ก์ง€ ์ขŒํ‘œ๋กœ ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐยท๋ณด๊ฐ„ํ•˜๊ฑฐ๋‚˜ ์ง์„  ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ฒฝ๋กœ ์„ ์€ DSV ์„œ๋ฒ„๊ฐ€ OSRM/VWorld๋กœ ์ƒ์„ฑํ•ด ์‘๋‹ตํ•œ GeoJSON LineString geometry๋งŒ ์ˆ˜์ • ์—†์ด MapLibre source์— ์ „๋‹ฌํ•œ๋‹ค. geometry๊ฐ€ ์—†์œผ๋ฉด ๋ฐฐ์†ก์ง€ ํ‘œ์‹๋งŒ ํ‘œ์‹œํ•œ๋‹ค. GPS ์ „์ฒด ์ง€๋„ ํ™”๋ฉด์—์„œ๋งŒ ์‚ฌ์šฉ ์ค‘ ์œ„์น˜ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๊ณ  MapLibre UserLocation์˜ ๊ธฐ๋ณธ ์œ„์น˜์ , ์ •ํ™•๋„ ์›๊ณผ ๋ฐฉํ–ฅ ํ‘œ์‹œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ˆœ์„œ ํŽธ์ง‘์˜ ์ง€๋„ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์—์„œ๋Š” ์œ„์น˜๋ฅผ ์š”์ฒญํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์œ„์น˜ ๊ถŒํ•œ๊ณผ ์ถ”์ ์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ˆœ์„œ ํŽธ์ง‘ ๊ฒฝ๊ณ„

๊ฐ™์€ ๋ฐฐ์†ก์ง€ ID์˜ ์ฃผ๋ฌธ์€ ์ˆœ์„œ ํŽธ์ง‘์—์„œ ํ•œ ํ–‰์œผ๋กœ ๋ฌถ๋Š”๋‹ค. ๋ฐฐ์†ก์ง€ ๋“œ๋ž˜๊ทธ ์ค‘์—๋Š” React ์ฃผ๋ฌธ ๋ฐฐ์—ด์ด๋‚˜ MapLibre source๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. Gesture Handler๊ฐ€ ์ž…๋ ฅ์„ ๋ฐ›๊ณ  Reanimated shared value๊ฐ€ ํ™”๋ฉด์ƒ ๋ฐฐ์†ก์ง€ ์œ„์น˜๋งŒ ๋ณ€๊ฒฝํ•œ๋‹ค. ์†์„ ๋†“์€ ๋’ค ๋ฐฐ์†ก์ง€ ์ „์ฒด ์ฃผ๋ฌธ์˜ ์ตœ์ข… ์œ„์น˜๋ฅผ ์ฃผ๋ฌธ ๋ฐฐ์—ด์— ํ•œ ๋ฒˆ ๋ฐ˜์˜ํ•˜๋ฉฐ, ์ง€๋„ ๋งˆ์ปค๋„ ๊ทธ ํ™•์ •๋œ ๋ฐฐ์—ด๋กœ ํ•œ ๋ฒˆ ๊ฐฑ์‹ ํ•œ๋‹ค. ์ด ๊ทœ์น™์€ ๋“œ๋ž˜๊ทธ ์ค‘ JS ์žฌ๋ Œ๋”์™€ ์ง€๋„ native source ๊ฐฑ์‹ ์ด ํ”„๋ ˆ์ž„ ์—ฐ์†์„ฑ์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.

์ธ์ฆ ๊ฒฝ๊ณ„

๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฒ€์ฆ, ๊ณ„์ • ์ƒ์„ฑ, ๋กœ๊ทธ์ธ ์„ธ์…˜๊ณผ DSV ๋ฐฐ์†ก์› ์—ฐ๊ฒฐ์€ ์„œ๋ฒ„๊ฐ€ ์†Œ์œ ํ•œ๋‹ค. ์•ฑ์€ ์Šน์ธ๋œ DSV ์ธ์ฆ API ๊ณ„์•ฝ์— ๋”ฐ๋ผ ๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ์ „์†กํ•˜๊ณ , ์‘๋‹ต access token๊ณผ ๊ณ„์ • ์ •๋ณด๋Š” ํ™”๋ฉด ๋ฉ”๋ชจ๋ฆฌ์—๋งŒ ๋‘๊ณ , 30์ผ refresh token๊ณผ ๋งŒ๋ฃŒ ์‹œ๊ฐ๋งŒ Expo SecureStore์— ๋ณด๊ด€ํ•œ๋‹ค. ๊ธฐ๋ณธ API ์ฃผ์†Œ๋Š” https://clever-route-api.cleversystem.ai์ด๋ฉฐ EXPO_PUBLIC_DSV_API_BASE_URL๋กœ ์žฌ์ •์˜ํ•  ๋•Œ๋Š” localhost ๋˜๋Š” 127.0.0.1 ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์ œ์™ธํ•˜๊ณ  HTTPS์—ฌ์•ผ ํ•œ๋‹ค. ํ† ํฐ ์•ฑ ์‹œ์ž‘ ์‹œ refresh token์œผ๋กœ DSV ์„ธ์…˜์„ ๋ณต์›ํ•˜๊ณ  access token ๋งŒ๋ฃŒ 1๋ถ„ ์ „ ์ž๋™ ๊ฐฑ์‹ ํ•œ๋‹ค. ๋กœ๊ทธ์•„์›ƒ๊ณผ ๋งŒ๋ฃŒ ์„ธ์…˜์€ SecureStore์—์„œ ์‚ญ์ œํ•˜๋ฉฐ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ access token์€ ์˜๊ตฌ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ •์€ ๊ด€๋ฆฌ์ž๊ฐ€ ๋ฐœ๊ธ‰ํ•œ 30๋ถ„ ์œ ํšจ ์ผํšŒ์šฉ HTTPS ๋งํฌ๋ฅผ DSV ์›น์—์„œ ์—ฌ๋Š” ๋ฐฉ์‹์ด๋‹ค. ์•ฑ์€ ๋กœ๊ทธ์ธ ํ™”๋ฉด์—์„œ ์ด ๋ฐœ๊ธ‰ ๊ฒฝ๋กœ๋งŒ ์•ˆ๋‚ดํ•˜๋ฉฐ SMS ์ธ์ฆ, ์ดˆ๊ธฐํ™” ํ† ํฐ ์ˆ˜์‹ , ์žฌ์„ค์ • API ํ˜ธ์ถœ์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์žฌ์„ค์ • ์™„๋ฃŒ๋กœ ๊ธฐ์กด refresh session์ด ๋งŒ๋ฃŒ๋˜๋ฉด ๊ธฐ์กด ์„ธ์…˜ ๋งŒ๋ฃŒ ์ฒ˜๋ฆฌ์™€ ๋™์ผํ•˜๊ฒŒ SecureStore์˜ refresh token์„ ์‚ญ์ œํ•œ๋‹ค.

ํšŒ์›๊ฐ€์ž…์€ ๋กœ๊ทธ์ธ ํ™”๋ฉด์˜ ๋ฒ„ํŠผ์œผ๋กœ ์ง„์ž…ํ•œ๋‹ค. ์•ฑ์€ ์ด๋ฆ„๊ณผ ํœด๋Œ€์ „ํ™” ๋ฒˆํ˜ธ๋ฅผ ์„œ๋ฒ„์— ๋ณด๋‚ด๊ณ , ์„œ๋ฒ„๊ฐ€ ๊ฐ™์€ ์ด๋ฆ„๊ณผ ์ •๊ทœํ™”๋œ ์ „ํ™”๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง„ ํ™œ์„ฑยท๋ฏธ์—ฐ๊ฒฐ DSV ๋ฐฐ์†ก์›๋งŒ ์›์ž์ ์œผ๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค. ๊ฐ€์ž… ์š”์ฒญ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋กœ๊ทธ์ธ ์•„์ด๋”” ๋˜๋Š” ์ด๋ฉ”์ผ ์ฃผ์†Œ์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ•จ๊ป˜ ์ „์†กํ•˜๋ฉฐ, ๋ณ„๋„ ๊ฐ€์ž… ํ† ํฐ์ด๋‚˜ ์ฃผ๋ฏผ๋“ฑ๋ก์ •๋ณด๋Š” ์ˆ˜์ง‘ํ•˜๊ฑฐ๋‚˜ ์ „์†กํ•˜์ง€ ์•Š๋Š”๋‹ค.

ํ™•์žฅ ๊ธฐ์ค€

์ƒˆ ํŒจํ‚ค์ง€๋Š” ๋‹ค์Œ ์„ธ ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋งŒ์กฑํ•  ๋•Œ๋งŒ ์ถ”๊ฐ€ํ•œ๋‹ค.

  1. ์Šน์ธ๋œ ์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ์— ์ง์ ‘ ํ•„์š”ํ•˜๋‹ค.
  2. Expo 56๊ณผ์˜ ๋ฒ„์ „ ์ •ํ•ฉ์„ฑ์ด ํ™•์ธ๋œ๋‹ค.
  3. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ํ˜„์žฌ ์˜์กด์„ฑ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๋‹ค.

Android ์šด์˜ ์•Œ๋ฆผ๊ณผ ์†Œํ˜• ๋ช…๋ น

๊ธฐ์กด Expo Notifications์˜ ์ง์ ‘ FCM ํ† ํฐ๊ณผ route-updates ์ฑ„๋„์„ ์žฌ์‚ฌ์šฉํ•œ๋‹ค. ํ† ํฐ ๋“ฑ๋ก์˜ ์„œ๋ฒ„ tokenId์™€ ๋™์ผํ•œ deviceId๋กœ schema-v1 capability๋ฅผ ๋“ฑ๋กํ•œ๋‹ค. ์ธ์ฆ resolver๊ฐ€ ํ˜„์žฌ ๋ชฉ์ ์ง€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ํด๋ฆญ ๋ณต๊ตฌ์—๋Š” ์•Œ๋ฆผ ID์™€ ๊ณ„์ • ๋ฐ”์ธ๋”ฉ๋งŒ ์ €์žฅํ•œ๋‹ค.

AsyncStorage๋Š” ๋ฏธ๋ฐฐ์†ก ์ž…๋ ฅ ์ดˆ์•ˆ๊ณผ ์†Œํ˜• ์‹œ์ž‘ยท๋ณด๊ณ  ๋ช…๋ น์˜ ID, ๋ฐœ์ƒ ์‹œ๊ฐ, ๋ณธ๋ฌธ๊ณผ ์‹ ยท๊ตฌ fence๋ฅผ ์ €์žฅํ•œ๋‹ค. ์žฌ์‹œ๋„๋Š” ํ˜„์žฌ ๊ณ„์ •๊ณผ ์„œ๋ฒ„ context๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•œ๋‹ค. ์„œ๋ฒ„ ์Šน์ธ ์ „์—๋Š” ์„ฑ๊ณต์œผ๋กœ ํ‘œ์‹œํ•˜์ง€ ์•Š๋Š”๋‹ค. access token๊ณผ ๋ชฉ์ ์ง€ ์ƒ์„ธ๋Š” ์˜๊ตฌ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ์‚ฌ์ง„ ์˜คํ”„๋ผ์ธ ํ๋Š” ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค. ์œ„์น˜ ํŒ์ •๊ณผ 5๋ถ„ ๋ฐ˜๋ณต ์•Œ๋ฆผ ์˜ˆ์•ฝ์€ ์„œ๋ฒ„ ์ฑ…์ž„์ด๋‹ค. ์ƒˆ ๋„ค์ดํ‹ฐ๋ธŒ ์œ„์น˜ ๊ธฐ๋Šฅ์ด๋‚˜ ๋กœ์ปฌ ์•Œ๋ฆผ ํƒ€์ด๋จธ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ƒˆ API ์‚ฌ์šฉ ์กฐ๊ฑด์€ ์šด์˜ ์•Œ๋ฆผ ๋ฌธ์„œ๋ฅผ ๋”ฐ๋ฅธ๋‹ค.