Post

[Capstone-Start] Flutter MVP Day โ€” Initial Commit

[Capstone-Start] Flutter MVP Day โ€” Initial Commit

๐Ÿ“… ์ผ์‹œ: 2026. 05. 23

๐Ÿ’ฌ ๋‚ด์šฉ: ์ผ์ฃผ์ผ์น˜ ๋กœ์ปฌ ๊ฐœ๋ฐœ์„ ํ•œ ๋ฒˆ์— push โ€” Stage 4 ~ Stage 9 + ์šด๋™ ํƒญ ์™„์„ฑ


ํ† ์š”์ผ ์•„์นจ๊นŒ์ง€ ์ผ์ฃผ์ผ์น˜ ์ž‘์—…์ด ์ „๋ถ€ ๋กœ์ปฌ ๋ธŒ๋žœ์น˜์—๋งŒ ์Œ“์—ฌ ์žˆ์—ˆ๋‹ค. PLAN ๋ฌธ์„œ, ๋ถ€ํŠธ์ŠคํŠธ๋žฉ, ์ฝ”์–ด ์ธํ”„๋ผ, ๋””์ž์ธ ์‹œ์Šคํ…œ๊นŒ์ง€ โ€” ๋งค์ผ ๋‹จ๊ณ„๋ณ„๋กœ ์ง„์ฒ™์ด ์žˆ์—ˆ์ง€๋งŒ GitHub ๋ ˆํฌ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ• ์ง€๊ฐ€ ์•„์ง ์ •ํ•ด์ง€์ง€ ์•Š์•„ push๋ฅผ ๋ฏธ๋ค˜๋‹ค. ์˜ค๋Š˜ Initial commit์„ ํ‘ธ์‹œํ–ˆ๋‹ค. ์ด ์‹œ์ ๋ถ€ํ„ฐ PLAN์˜ Stageร—Phase ๋‹จ์œ„๋กœ ์ปค๋ฐ‹์„ ๋Š์œผ๋ฉด์„œ, ๋™์‹œ์— ํ† ์š”์ผ์ด ๋๋‚˜๊ธฐ ์ „์— ๊ฐ€๋Šฅํ•œ ๋‹จ๊ณ„๊นŒ์ง€ ๋ฐ€์–ด๋ถ™์ด๋Š” ๊ฒŒ ์˜ค๋Š˜ ๋ชฉํ‘œ์˜€๋‹ค.

์›๊ฒฉ์— ํ‘ธ์‹œํ•œ ์ปค๋ฐ‹๋งŒ 70๊ฐœ๊ฐ€ ๋„˜๋Š”๋‹ค. ๋‹จ๊ณ„๋ณ„๋กœ ํšŒ๊ณ ๋ฅผ ์ •๋ฆฌํ•œ๋‹ค.

1. Stage 0 โ€” Discovery & Decisions (docs:)

PLAN.md (367์ค„), STRUCTURE.md (246์ค„), DESIGN_TOKENS.md, CONTRIBUTING_NOTES.md๋ฅผ ํ•œ ๋ฒˆ์— ์ปค๋ฐ‹ํ–ˆ๋‹ค. PLAN ยง9 ๊ฒฐ์ • ์ด๋ ฅ์— Q1~Q12 ๋ชจ๋‘๋ฅผ ๋ฐ•์•˜๊ณ , Co-Authored-By: Claude โ€ฆ trailer ๊ธˆ์ง€ ๊ทœ์น™์„ CONTRIBUTING_NOTES์— ๋ช…์‹œํ–ˆ๋‹ค.

2. Stage 1 โ€” Bootstrap (feat(bootstrap):, ci(...), chore:)

  • chore: bootstrap flutter project (phase 1.1)
  • chore: add lib/ skeleton & assets dirs (phase 1.2)
  • chore(deps): add core dependencies (phase 1.3) โ€” Riverpod, go_router, dio, drift, fl_chart ๋“ฑ ํ•œ ๋ฒˆ์—.
  • chore: harden analyzer & lint rules (phase 1.4) โ€” flutter_lints + riverpod_lint(custom_lint).
  • feat(bootstrap): wire AppConfig, single main + dart-define (phase 1.5)
  • ci: add format/analyze/test workflow (phase 1.6)
  • ci(web): deploy to GitHub Pages on main push (phase 1.7)
  • ci(web): auto-provision GitHub Pages site on first run (stage 1 hotfix) โ€” actions/configure-pages@v5๋กœ ์ฒซ ์‹คํ–‰ ์‹œ Pages ์‚ฌ์ดํŠธ๊ฐ€ ์ž๋™ ํ™œ์„ฑํ™”๋˜๋„๋ก ๋ฐ•์•„ ๋‘ .

3. Stage 2 โ€” Core Infrastructure (PR #3, 7 phases)

feature/fe-flutter-bootstrap ๋ธŒ๋žœ์น˜๋ฅผ ๋จธ์ง€ํ•˜์ž๋งˆ์ž feature/fe-flutter-core-infra ๋ธŒ๋žœ์น˜๋ฅผ ์—ด๊ณ  7๊ฐœ phase๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ์Œ“์•˜๋‹ค.

  • 2.1 feat(router): StatefulShellRoute + BottomNav ์…ธ.
  • 2.2 feat(riverpod): ProviderObserver + Logger DI.
  • 2.3 feat(theme): tokenized colors/typo/spacing/radius + AppTheme.
  • 2.4 feat(network): dio + ์ธํ„ฐ์…‰ํ„ฐ 3์ข…(logging / auth / mock).
  • 2.5 feat(storage): drift + secure_storage + prefs.
  • 2.6 feat(errors): AppError sealed + Result + ErrorView/EmptyState.
  • 2.7 feat(l10n): ko + en ARB ๊ณจ๊ฒฉ.

4. Stage 3 โ€” Design System (PR #4, 5 phases)

  • 3.1 feat(catalog): /dev/ui-catalog (dev-only).
  • 3.2 feat(design): atom 5์ข… โ€” Button/Card/Input/Badge/Avatar.
  • 3.3 feat(design): molecule 3์ข… โ€” MetricCard/ChartCard/SectionHeader.
  • 3.4 feat(responsive): breakpoints + ResponsiveBuilder.
  • 3.5 feat(charts): fl_chart ๋ž˜ํผ โ€” line/bar/donut.

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์–ด์ œ๊นŒ์ง€ ๋กœ์ปฌ์—์„œ ์ง„ํ–‰ํ–ˆ๋˜ ๋ถ„๋Ÿ‰์ด๋‹ค. PR #4๊ฐ€ ๋จธ์ง€๋˜๋ฉด์„œ ์ง„์งœ ๋ณธ๊ฒฉ์ ์ธ ์˜ค๋Š˜์˜ ์ž‘์—…์ด ์‹œ์ž‘๋๋‹ค.

5. Stage 4 โ€” Feature MVPs (PR #5)

8๊ฐœ ํ”ผ์ฒ˜๋ฅผ mock ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๋ฒˆ์— ์ฐ์–ด๋ƒˆ๋‹ค. ๊ฐ ํ”ผ์ฒ˜๋Š” ๋™์ผ ํŒจํ„ด โ€” mock ์‹œ๋“œ โ†’ repository โ†’ controller(Riverpod) โ†’ page/widget.

  • 4.1 feat(dashboard): real summary content with mock repository.
  • 4.2 feat(diet): diet record MVP with mock 3-meal day.
  • 4.3 feat(exercise): weekly exercise MVP.
  • 4.4 feat(my_health): vitals MVP with mock 7-day history.
  • 4.5 feat(ai_coach): mock suggestions MVP.
  • 4.6 feat(notification): in-app panel + simulated push.
  • 4.7 feat(place): nearby places MVP w/ Maps placeholder.
  • 4.8 feat(auth): mock social sign-in MVP.

์—ฌ๊ธฐ์„œ ํ•œ ๊ฐ€์ง€ ๊ฒฐ์ •์ด ๋˜ ๊ฐˆ๋ ธ๋‹ค. AI Coach ์‘๋‹ต์„ ์ง„์งœ ์™ธ๋ถ€ API๋กœ ๋ถ™์ผ์ง€ mock์œผ๋กœ ๊ฐˆ์ง€. PLAN Q7 ๊ฒฐ์ •๋Œ€๋กœ mock์œผ๋กœ ๊ฐ”๋‹ค โ€” features/ai_coach/data/์— 5~6๊ฐœ ์‹œ๋‚˜๋ฆฌ์˜ค JSON์„ ์‹œ๋“œํ•ด ๋‘๊ณ , ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋”ฐ๋ผ ํ‚ค์›Œ๋“œ ๋งค์นญ์œผ๋กœ ์‹œ๋‚˜๋ฆฌ์˜ค ํ•˜๋‚˜๋ฅผ ๊ณจ๋ผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‹จ์ˆœํ•œ ๋กœ์ง. ์บก์Šคํ†ค ์ผ์ • ์•ˆ์—์„œ prompt engineering๊นŒ์ง€ ๋“ค์–ด๊ฐ€๋ฉด ์‹œ๊ฐ„์ด ์•ˆ ๋งž๋Š”๋‹ค๊ณ  ๋ดค๋‹ค.

์•Œ๋ฆผ(notification)์€ ํ‘ธ์‹œ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์ด ๊นŒ๋‹ค๋กœ์› ๋‹ค. FCM์„ ์“ฐ์ง€ ์•Š๊ธฐ๋กœ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—(Q9), NotificationCenter ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ 30์ดˆ ํƒ€์ด๋จธ๋กœ mock ์•Œ๋ฆผ์„ ํ์—์„œ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด in-app panel์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค.

Place ํ™”๋ฉด์˜ ์ง€๋„(google_maps_flutter)๋Š” Stage 4์—์„œ๋Š” placeholder๋งŒ ๋‘๊ณ , ์‹ค์ œ ์ง€๋„ ์ž„๋ฒ ๋“œ๋Š” ์‹œ์—ฐ ์ง์ „์— API ํ‚ค์™€ ํ•จ๊ป˜ ํ™œ์„ฑํ™”ํ•˜๋Š” ์ชฝ์œผ๋กœ ๋ฏธ๋ค˜๋‹ค. ์นด๋“œ ๋ฆฌ์ŠคํŠธ๋Š” mock 6๊ฐœ๋กœ ํ‘œ์‹œ.

6. Stage 5 โ€” Integration & Polish (PR #6)

  • 5.1 feat(nav): LoggerNavigatorObserver + flutter import ์ •๋ฆฌ.
  • 5.2 feat(dashboard): staggered fade + slide on summary cards (flutter_animate).
  • 5.3 feat(a11y): MetricCard exposes a single Semantics label โ€” TalkBack/VoiceOver๊ฐ€ ์นด๋“œ๋ฅผ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ์ฝ๋„๋ก.
  • 5.4 feat(responsive): two-column dashboard for tablet/desktop.
  • 5.5 feat(i18n): externalise dashboard copy โ€” ๋ชจ๋“  ๋ฌธ์ž์—ด์„ ARB๋กœ ์ด๋™.

5.3 a11y์—์„œ ํ•œ ๋ฒˆ ๋ง‰ํ˜”๋‹ค. MetricCard๋Š” child๊ฐ€ ์—ฌ๋Ÿฌ Text ์œ„์ ฏ์„ ๊ฐ–๋Š”๋ฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์Šคํฌ๋ฆฐ๋ฆฌ๋”๋Š” ๊ฐ๊ฐ์„ ๋”ฐ๋กœ ์ฝ๋Š”๋‹ค. โ€œ์˜ค๋Š˜ ์นผ๋กœ๋ฆฌ 350kcal 1800 ์ค‘โ€์ด ๋ณ„๊ฐœ๋กœ 3๋ฒˆ ์ฝํ˜€์„œ ์ •์‹  ์‚ฌ๋‚ฉ๋‹ค. Semantics(container: true, label: '...') ํ•œ ๋ฒˆ์— ๋ฌถ๊ณ , child Text๋“ค์„ ExcludeSemantics๋กœ ๊ฐ€๋ฆฌ๋‹ˆ๊นŒ ํ•œ ์ค„๋กœ ๊น”๋”ํžˆ ์ฝํžŒ๋‹ค.

7. Stage 6 โ€” Quality (PR #7)

ํ…Œ์ŠคํŠธ ์นดํ…Œ๊ณ ๋ฆฌ 4์ข…์„ ํ•œ ๋ฒˆ์— ์ฑ„์› ๋‹ค.

  • 6.1 test: model invariants / edge cases โ€” DietDay, ExerciseWeek, VitalLog ๊ฐ™์€ ๋ชจ๋ธ์˜ ์ž˜๋ชป๋œ ์ธ์ž ๊ฑฐ๋ถ€ ์ผ€์ด์Šค.
  • 6.2 test(dashboard): page-level widget tests for data & error paths โ€” happy path 1๊ฐœ + ์—๋Ÿฌ/๋กœ๋”ฉ ์ƒํƒœ 2๊ฐœ.
  • 6.3 test(golden): infra + AppButton variants snapshot โ€” golden_toolkit์œผ๋กœ atom์˜ ์‹œ๊ฐ ํšŒ๊ท€ ๊ฐ€๋“œ.
  • 6.4 test(integration): app smoke โ€” integration_test/์— 4ํƒญ ์ „ํ™˜ ์‹œ๋‚˜๋ฆฌ์˜ค 1๊ฐœ.

flutter test๊ฐ€ ๊ทธ๋ฆฐ์ด๊ณ , golden์€ ์ฒ˜์Œ ํ•œ ๋ฒˆ ์ƒ์„ฑ ํ›„ ๋ณ€๊ฒฝ ์—†์Œ์„ ํ™•์ธํ–ˆ๋‹ค. ์ปค๋ฒ„๋ฆฌ์ง€๋Š” 70%+๋ฅผ ๋ชฉํ‘œ๋กœ ํ–ˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” 63%์„ . Stage 8 ์ดํ›„๋กœ ํ•œ ๋ฒˆ ๋” ์ฑ„์›Œ ๋„ฃ์„ ๊ฑฐ๋‹ค.

8. Stage 7 โ€” Release Scaffolding (PR #8)

  • chore(release): RELEASE.md + CHANGELOG.md โ€” v0.1.0+1 ์ดˆ์•ˆ.
  • ๋ฒ„์ „ ์ •์ฑ…: --build-name/--build-number๋กœ ๋นŒ๋“œ ์‹œ ์ฃผ์ž…. pubspec.yaml์˜ version:์€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ๋งŒ ๋‘ .

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ 14์‹œ 30๋ถ„์ฏค. ์‹œ๊ฐ„์ด ๋‚จ์•„์„œ Stage 8(UX alignment)๊นŒ์ง€ ๊ฐ™์€ ๋‚  ๋ฐ€์–ด๋ถ™์ด๊ธฐ๋กœ ํ–ˆ๋‹ค.

9. Stage 8 โ€” UX Alignment with React Original (PR #9)

์›๋ณธ React ํ”„๋กœํ† ํƒ€์ž…๊ณผ ํ”ฝ์…€ ๋‹จ์œ„๋กœ ์ •๋ ฌํ•˜๋Š” ๋‹จ๊ณ„. ์ด๋•Œ๋ถ€ํ„ฐ ๋””์ž์ธ ๊ฒฐ์ •์˜ ์‚ฌ์†Œํ•œ ์–ด๊ธ‹๋‚จ์ด ํ•œ ๋ฒˆ์— ์Ÿ์•„์ ธ ๋‚˜์™”๋‹ค.

  • 8.1 refactor(theme): align tokens with original default_shadcn_theme.css โ€” primary, muted, border ์ƒ‰์„ React ์›๋ณธ ์ •ํ™•ํžˆ ์˜ฎ๊น€.
  • 8.2 feat(shell): align BottomNav with React original + OncareHeader.
  • 8.3 feat(dashboard): five-card home layout matching the React original โ€” ์ŠคํŠธ๋ฆญ / ์˜ค๋Š˜์˜ ๊ฑด๊ฐ• / ์ผ์ • / ์ฃผ๊ฐ„ ์ ์ˆ˜ / AI ์ฝ”์น˜ 5์žฅ.
  • 8.4 feat(diet): nutrition summary + AI coach card + meal list.
  • 8.5 feat(exercise): four stat cards + chart + AI coach + history.
  • 8.6 feat(my_health): profile + risk + indicators + points + settings.
  • 8.7 feat(modals): Calendar sheet + QuickInput + AddEvent dialogs.
  • 8.8 feat(panels): right-slide Notification + AI Coach overlays.

์—ฌ๊ธฐ์„œ ์ž์ž˜ํ•œ fixup ์ปค๋ฐ‹์ด ๋‹ค์„ฏ ๊ฐœ์ฏค ๋“ค์–ด๊ฐ”๋‹ค โ€” DietDay ์ƒ์„ฑ์ž ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๋ฐ”๋€Œ๋ฉด์„œ unit test๊ฐ€ ๊นจ์กŒ๊ณ , MealCard pill ์ƒ‰์ƒ์ด ์–ด๊ธ‹๋‚ฌ๊ณ , nav-switching widget test๊ฐ€ ๋” ์ด์ƒ AppBar์— ์˜์กดํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋๊ณ . ๋‹ค ์ฆ‰์‹œ ์žก์•˜๋‹ค.

์Šคํƒ€์ผ ์ฐจ์›์˜ ์ •๋ˆ๋„ ๊ฐ™์ด โ€” style: drop deprecated activeColor + use Dart 3 wildcards, style(my_health): drop unnecessary braces in '$rank์œ„ ๋žญํ‚น'. Dart 3์˜ (_, _) wildcard ํŒจํ„ด์€ separatorBuilder ๊ฐ™์€ ์ฝœ๋ฐฑ์—์„œ ๋ฏธ์‚ฌ์šฉ ์ธ์ž๋ฅผ ๊ฐ•์ œ๋กœ ๋ช…์‹œํ•  ๋•Œ ๊น”๋”ํ•˜๋‹ค.

CHANGELOG์™€ ๋ฒ„์ „์„ v0.2.0+2๋กœ ์˜ฌ๋ฆผ.

10. Stage 9 โ€” Local Backend via drift + LocalApiInterceptor (PR #10)

์ด๊ฒŒ ์˜ค๋Š˜ ๊ฐ€์žฅ ๋งŒ์กฑ์Šค๋Ÿฌ์› ๋˜ ๋ถ€๋ถ„์ด๋‹ค. ๋ฐฑ์—”๋“œ ํŒ€์ด ์•„์ง API๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ํ”„๋ก ํŠธ์—”๋“œ๋งŒ์œผ๋กœ ํ’€์Šคํƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋Š” ํŠธ๋ฆญ์ด๋‹ค.

๊ธฐ๋ณธ ์•„์ด๋””์–ด๋Š” ์ด๊ฑฐ๋‹ค โ€” dio ์ธํ„ฐ์…‰ํ„ฐ๋กœ request๋ฅผ ๊ฐ€๋กœ์ฑ„์„œ drift DB์—์„œ ์ง์ ‘ ์‘๋‹ต์„ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”๋“œ๋Š” ํ‰์ƒ์‹œ์ฒ˜๋Ÿผ GET /diet/days/today๋ฅผ ๋ถ€๋ฅด๊ณ , network ๋ ˆ์ด์–ด์—์„œ ์ง„์งœ API์ธ ์ฒ™ drift๊ฐ€ ์‘๋‹ตํ•œ๋‹ค. ๋ฐฑ์—”๋“œ๊ฐ€ ๋ถ™์œผ๋ฉด ์ธํ„ฐ์…‰ํ„ฐ๋งŒ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†์ด ๊ทธ๋Œ€๋กœ ์ „ํ™˜๋œ๋‹ค.

  • 9.1 feat(storage): drift schema v2 โ€” diet_days, meal_entries, exercise_sessions, vital_logs, schedule_events 5๊ฐœ ํ…Œ์ด๋ธ” ์ถ”๊ฐ€.
  • 9.2 feat(storage): seed React mock data into drift on first run โ€” seeded_v1 ํ”Œ๋ž˜๊ทธ๋กœ ํ•œ ๋ฒˆ๋งŒ.
  • 9.3 feat(network): LocalApiInterceptor skeleton + snake_case mapper โ€” ๋ฐฑ์—”๋“œ ์ปจ๋ฒค์…˜์— ๋งž์ถฐ ์‘๋‹ต์„ snake_case๋กœ ํ˜๋ฆผ.
  • 9.4 feat(diet): GET /diet/days/today via LocalApiInterceptor + DioDietRepository.
  • 9.5 feat(vitals): POST /vitals/{kind} + GET .../latest with QuickInput wiring โ€” ๋Œ€์‹œ๋ณด๋“œ QuickInput ๋ชจ๋‹ฌ์—์„œ ์ฒด์ค‘์„ ์ž…๋ ฅํ•˜๋ฉด drift์— ์ €์žฅ๋˜๊ณ , ๋‹ค์Œ fetch์—์„œ ์žกํžŒ๋‹ค.
  • 9.6 feat(exercise): GET /exercise/weeks/current with weekly aggregation โ€” drift ์ฟผ๋ฆฌ์—์„œ weekday๋ณ„ GROUP BY.
  • 9.7 feat(schedule+noti): /schedule/events and /notifications.
  • 9.8 feat(dashboard): GET /dashboard/summary aggregating diet+exercise+vital+schedule โ€” ๊ฐ€์žฅ ๋ณต์žกํ•œ ์—”๋“œํฌ์ธํŠธ. 4๊ฐœ ๋„๋ฉ”์ธ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ๋ฌถ์–ด ์‘๋‹ต.
  • 9.9 feat(misc): AI Coach / users.me / MyHealth / Places.
  • 9.10 docs(plan): Stage 9 decision log + e2e smoke test.

์ถ”๊ฐ€ docs๋„ ๊ฐ™์ด โ€” docs(backend): API_CATALOG + DUMMY_BACKEND options, docs: link API_CATALOG + DUMMY_BACKEND from README. API_CATALOG.md์— prefix์™€ path ๊ทœ์•ฝ, request/response ํŽ˜์ด๋กœ๋“œ ์Šคํ‚ค๋งˆ๋ฅผ ๋ฐฑ์—”๋“œ์™€ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ ์—ˆ๋‹ค. ๋ฐฑ์—”๋“œ ํŒ€์ด ์‹ค์ œ API๋ฅผ ์งค ๋•Œ ์ด ์นดํƒˆ๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ํ”„๋ก ํŠธ๋Š” ๊ทธ๋Œ€๋กœ ๋™์ž‘ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ํ•œ ๋ฒˆ ํฌ๊ฒŒ ๋ง‰ํ˜”๋‹ค. Web ๋นŒ๋“œ๊ฐ€ drift WASM ์—†์ด ๋ถ€ํŒ…์ด ์•ˆ ๋จ.

1
2
fix(web): bundle drift WASM (sqlite3.wasm + drift_worker.js)
fix(web): pair sqlite3.wasm with the resolved sqlite3 dart package + 4xx/5xx as DioException

drift๋Š” web์—์„œ SQLite๋ฅผ WASM์œผ๋กœ ๋Œ๋ฆฌ๋Š”๋ฐ, sqlite3.wasm๊ณผ drift_worker.js๋ฅผ ๋นŒ๋“œ ์‚ฐ์ถœ๋ฌผ์— ๊ฐ™์ด ๋„ฃ์–ด์ค˜์•ผ ํ•œ๋‹ค. ์ฒ˜์Œ์—๋Š” web/ ๋””๋ ‰ํ† ๋ฆฌ์— ์ž„์˜ ๋ฒ„์ „์„ ๋ฐ•์•„ ๋‘๋‹ˆ๊นŒ sqlite3 Dart ํŒจํ‚ค์ง€์™€ SHA๊ฐ€ ์•ˆ ๋งž์•„ ๋ถ€ํŒ…์ด ๊นจ์กŒ๋‹ค. ์ •๋‹ต์€ pubspec lock์œผ๋กœ ๋ฌถ์ธ sqlite3 ํŒจํ‚ค์ง€์˜ ์ •ํ™•ํ•œ ๋ฒ„์ „๊ณผ ํŽ˜์–ด๋ฅผ ๋งž์ถฐ์„œ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ๊ฒƒ. tool/fetch_drift_wasm.sh ์Šคํฌ๋ฆฝํŠธ๋กœ ์ž๋™ํ™”ํ•ด ๋‘์—ˆ๋‹ค โ€” CI ๋ฐฐํฌ ์›Œํฌํ”Œ๋กœ์šฐ์—์„œ ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ถ€๋ฅด๋„๋ก ์ถ”ํ›„ ๋ฐ•์„ ๊ฑฐ๋‹ค(๋‚ด์ผ ์ž‘์—…).

๋˜ ํ•œ ๊ฐ€์ง€ ์งš์—ˆ๋˜ ๊ฒƒ โ€” dio๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ 4xx/5xx๋ฅผ ์ •์ƒ ์‘๋‹ต์œผ๋กœ ํ†ต๊ณผ์‹œํ‚ค๋Š” ์˜ต์…˜์ด ์žˆ๋Š”๋ฐ, LocalApiInterceptor๊ฐ€ ์—๋Ÿฌ ์‹œ DioException์„ ๋˜์ง€์ง€ ์•Š์œผ๋ฉด controller์—์„œ try/catch๊ฐ€ ์•ˆ ์žกํžŒ๋‹ค. validateStatus: (_) => true๋ฅผ ๋„๊ณ , ์ธํ„ฐ์…‰ํ„ฐ์—์„œ status code๋ณ„๋กœ DioException ์ •ํ™•ํžˆ throwํ•˜๋„๋ก ๋ณด๊ฐ•ํ–ˆ๋‹ค.

CHANGELOG์™€ ๋ฒ„์ „์„ v0.3.0+3์œผ๋กœ ์˜ฌ๋ฆผ. chore: end of stage 9 โ€” local backend via drift+LocalApiInterceptor.

11. ์šด๋™ ํƒญ โ€” Stage 9 ์ดํ›„์˜ ๋ณด๋„ˆ์Šค (PR #11)

PR #10 ๋จธ์ง€ ํ›„์—๋„ ์‹œ๊ฐ„์ด ์ข€ ๋‚จ์•˜๋‹ค. ์šด๋™ ํŽ˜์ด์ง€์— ํ—ฌ์Šค์žฅ(Place) ํƒญ ์ง„์ž…์ ๊ณผ ์šด๋™ ๊ธฐ๋ก ์ถ”๊ฐ€ FAB์„ ๋ถ™์˜€๋‹ค.

  • feat(exercise): tab-based ์šด๋™ page with ํ—ฌ์Šค์žฅ view + ์šด๋™ ๊ธฐ๋ก ์ถ”๊ฐ€ FAB.
  • feat(exercise): seed multi-type sessions per day for stacked WeeklyActivity chart โ€” ์œ ์‚ฐ์†Œ / ๊ทผ๋ ฅ / ์ŠคํŠธ๋ ˆ์นญ 3์ข…์ด ํ•œ ๋ง‰๋Œ€ ์•ˆ์— ๋ˆ„์ ๋˜๋„๋ก stacked bar๋กœ ์ „ํ™˜. seeded_v1 โ†’ seeded_v2๋กœ ์‹œ๋“œ ๋ฒ„์ „์„ ์˜ฌ๋ ธ๊ณ , ์—…๊ทธ๋ ˆ์ด๋“œ ์‹œ ๋‹จ์ผ ํƒ€์ž… ๋ฐ์ดํ„ฐ๊ฐ€ ์ž๋™ ์ •๋ฆฌ๋˜๋„๋ก ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋กœ์ง ์ถ”๊ฐ€.
  • feat(chart): wider bars, always-on weekday labels, stacked tooltip โ€” fl_chart ๊ธฐ๋ณธ ํˆดํŒ์€ ํ•œ ๋ฒˆ์— 1๊ฐœ ์‹œ๋ฆฌ์ฆˆ๋งŒ ๋ณด์—ฌ์ค˜์„œ, ๋ˆ„์  ๋ง‰๋Œ€ ์œ„์—์„œ ์„ธ ์‹œ๋ฆฌ์ฆˆ๋ฅผ ํ•œ ๋ฒˆ์— ๋ณด์—ฌ์ฃผ๋Š” ์ปค์Šคํ…€ ํˆดํŒ์œผ๋กœ ๊ต์ฒด.

ExerciseWeek.workoutCount๊ฐ€ ํ•œ ๊ฐ€์ง€ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋ถ€๋ถ„์ด์—ˆ๋‹ค โ€” ๊ฐ™์€ ๋‚ ์— ์œ ์‚ฐ์†Œ 30๋ถ„ + ๊ทผ๋ ฅ 30๋ถ„์ด ์žˆ์œผ๋ฉด โ€œ์šด๋™ 2ํšŒโ€์ธ์ง€ โ€œ์šด๋™ 1ํšŒ(2์ข…)โ€์ธ์ง€. ์›๋ณธ React์—์„œ๋Š” โ€œ์šด๋™ํ•œ ๋‚  ์ˆ˜โ€์˜€๊ธฐ ๋•Œ๋ฌธ์— collapse ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ด์„œ ๊ฐ™์€ ๋‚  ์—ฌ๋Ÿฌ ํ–‰์„ 1๋กœ ๋ฌถ์—ˆ๋‹ค.

12. ์˜ค๋Š˜์˜ ํšŒ๊ณ ์™€ ๋‚ด์ผ ํ•  ์ผ

  • ๊ณ ๋ฏผํ–ˆ๋˜ ๊ฒƒ:
    • Stage 9 โ€” ๋ฐฑ์—”๋“œ๊ฐ€ ์—†๋Š”๋ฐ ๋ฐฑ์—”๋“œ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๊ฒŒ ๊ณผํ•œ ์—”์ง€๋‹ˆ์–ด๋ง ์•„๋‹Œ๊ฐ€? ๊ฒฐ๊ตญ ๋ฐฑ์—”๋“œ์™€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฏธ๋ฆฌ ํ•ฉ์˜ํ•ด ๋‘˜ ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฒฐ๋ก . API_CATALOG.md๊ฐ€ ๊ทธ ํ•ฉ์˜์˜ ์‚ฐ๋ฌผ์ด๋ผ ํ—›๋ˆ ๊ฒŒ ์•„๋‹ˆ๋‹ค.
    • drift WASM ํŽ˜์–ด๋ง โ€” sqlite3 ํŒจํ‚ค์ง€ lock ๋ฒ„์ „๊ณผ wasm ํŒŒ์ผ์ด ์„œ๋กœ SHA๊ฐ€ ๋งž์•„์•ผ ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊นจ๋‹ซ๋Š” ๋ฐ ํ•œ์ฐธ ๊ฑธ๋ ธ๋‹ค.
  • ๊ฒฐ์ •ํ•œ ๊ฒƒ: ์ผ์ฃผ์ผ์น˜ ๋กœ์ปฌ ์ž‘์—…์„ ์›๊ฒฉ์— ๋ชจ๋‘ ํ‘ธ์‹œ ์™„๋ฃŒ. Stage 0~Stage 9 + ์šด๋™ ํƒญ. v0.3.0+3 ํƒœ๊น….
  • ๋‚จ์€ ๋ฌธ์ œ:
    • CI ๋ฐฐํฌ ์›Œํฌํ”Œ๋กœ์šฐ์—์„œ drift WASM ์ž๋™ ๋‹ค์šด๋กœ๋“œ โ€” ์ง€๊ธˆ์€ ๋กœ์ปฌ ๋นŒ๋“œ์—์„œ๋งŒ ๋™์ž‘. ๋‚ด์ผ tool/fetch_drift_wasm.sh๋ฅผ ์›Œํฌํ”Œ๋กœ์šฐ์— ๋ผ์šธ ์˜ˆ์ •.
    • README์™€ ๋‹ค์ด์–ด๊ทธ๋žจ โ€” ์ง€๊ธˆ์€ ASCII art๋ฟ. ์บก์Šคํ†ค ๋ฐœํ‘œ ์ž๋ฃŒ๋กœ ์“ฐ๋ ค๋ฉด SVG๋กœ ์˜ฎ๊ฒจ์•ผ ํ•œ๋‹ค.
    • UI ๋””ํ…Œ์ผ โ€” ์นด๋“œ ๋ณด๋”, AI ์ฝ”์น˜ ์นด๋“œ ์•„์ด์ฝ˜, ์‹๋‹จ/์šด๋™์˜ ๋‚ ์งœ ํ—ค๋” ๋“ฑ ์ž์ž˜ํ•˜๊ฒŒ React ์›๋ณธ๊ณผ ๋‹ค๋ฅธ ๋ถ€๋ถ„์ด 5~6๊ฐœ ๋‚จ์•„ ์žˆ๋‹ค.
    • ์‹œ์—ฐ ํ™˜๊ฒฝ base-href โ€” ์ปค์Šคํ…€ ๋„๋ฉ”์ธ์„ ๋ถ™์ผ ๊ฒฝ์šฐ /oncare-flutter/ โ†’ /๋กœ ๋ฐ”๊ฟ”์•ผ ํ•จ.

๋‚ด์ผ์€ PR ๋‹จ์œ„๋กœ ์ž‘๊ฒŒ ๋Š์œผ๋ฉด์„œ (1) README/๋‹ค์ด์–ด๊ทธ๋žจ ์ •๋ฆฌ, (2) UI ๋””ํ…Œ์ผ ์ •๋ ฌ์„ ์ง„ํ–‰ํ•  ์˜ˆ์ •์ด๋‹ค. ์‹œ์—ฐ D-day๊ฐ€ ๋‹ค๊ฐ€์˜ค๊ธฐ ๋•Œ๋ฌธ์— ํฐ ๊ธฐ๋Šฅ ์ถ”๊ฐ€๋ณด๋‹ค๋Š” ๋งŒ๋“ค์–ด์ง„ ํ™”๋ฉด์„ ๊น”๋”ํ•˜๊ฒŒ ๋‹ค๋“ฌ๋Š” ์ชฝ์œผ๋กœ ๊ฐ€๋Š” ๊ฒŒ ๋งž๋‹ค.


๐Ÿ“Œ ์š”์•ฝ

์˜ค๋Š˜์€ ์ผ์ฃผ์ผ์น˜ ๋กœ์ปฌ ์ž‘์—…์„ ์›๊ฒฉ์— ํ•œ๊บผ๋ฒˆ์— ํ‘ธ์‹œํ•œ ๋‚ ์ด๋‹ค. PR #2~#11๊นŒ์ง€ 10๊ฐœ PR์„ ๋จธ์ง€ํ•˜๋ฉด์„œ Stage 0(Discovery) โ†’ Stage 9(Local backend via drift+LocalApiInterceptor) + ์šด๋™ ํƒญ stacked chart๊นŒ์ง€ ์™„์„ฑ.

This post is licensed under CC BY 4.0 by the author.