๋๋ค ๊ธฐ๋ฐ ๋ฐ๋ ค๋๋ฌผ ์ฐ์ฑ
ยท๋๋ด ๋งค์นญ & ์ปค๋ฎค๋ํฐ ์ฑ (Flutter ยท iOS/Android)
GPS ๋๋ค ์ธ์ฆ์ ๊ธฐ๋ฐ์ผ๋ก ์ด์๊ณผ ๋ฐ๋ ค๋๋ฌผ ์ฐ์ฑ
๋ฉ์ดํธ๋ฅผ ์ฐพ๊ณ , ๋๋ดยท๋ถ์ยท์
์์ ๋งค์นญํ๋ฉฐ,
์ฃผ๋ณ ๋ฐ๋ ค๋๋ฌผ ์์ค์ ์ง๋์์ ์ฐพ์ ํ๊ธฐ๋ฅผ ๋๋๋ ํ์ดํผ๋ก์ปฌ ์๋น์ค์
๋๋ค.
์ปค๋ฎค๋ํฐ ํผ๋
๊ฒ์๊ธ ์์ฑ (WYSIWYG)
์ฝ์ ์บ๋ฆฐ๋
์์ค ์ง๋
์์ค ์์ธ (์ธ์ฆ ์
์ฒด)
์ฑํ
๋ด ์ ๋ณด (ํซ ํ์ด๋ก)
์
์ฒด ๋ชจ๋ (๋ ์ผ๊ตด)
AI ์ ์ ์ธ์ฆ
์์ญ
๋ด์ฉ
๐๏ธ ๋๋ค ์ธ์ฆ
GPS + ํ์ ๋ ์ญ์ง์ค์ฝ๋ฉ ๊ธฐ๋ฐ ์ง์ญ ์ธ์ฆ(30์ผ ์ฃผ๊ธฐ ์ฌ์ธ์ฆ) โ ๋ชจ๋ ๊ฒ์๊ธยทํผ๋๊ฐ ์ธ์ฆ ๋๋ค ๊ธฐ์ค
๐ ๋งค์นญ
๋๋ฐ์ฐ์ฑ
/ ๋๋ฆฌ์ฐ์ฑ
/ ๋๋ด / ๋ถ์ / ์
์ ๊ฒ์๊ธ โ ์ง์ โ ์๋ฝ โ ์ฝ์ โ ์ํธ ํ๊ธฐ
๐ธ AI ์ฌ์ง ์ธ์ฆ
๋ฐ๋ ค๋๋ฌผ ์ ์ ์ธ์ฆ(์์ ๋ฑ๋ก) + ๊ฒ์๊ธ ์ฌ์ง ์ค์กด ๊ฒ์ฆ(AI ๊ฐ์ฒด ๋์กฐยท์์น ๊ฒ์ฆ) โ ํ์ ๋งค๋ฌผ ์ฐจ๋จ
๐บ๏ธ ์์ค ์ง๋
๋ค์ด๋ฒ ์ง๋ ๊ธฐ๋ฐ ๋ฐ๋ ค๋๋ฌผ ์์ค(๋ณ์ยท์นดํ ๋ฑ) ํ์, ๋ฐฉ๋ฌธ ํ๊ธฐยท๋ณ์ ยทํ๊ธฐ ๋๊ธ
๐ช ์
์ฒด ๊ณ์
์ฌ์
์ ์ธ์ฆ(๊ตญ์ธ์ฒญ ์กฐํ + ๊ณต๊ณต๋ฐ์ดํฐ ๋์กฐ ์๋์น์ธ) โ ํ ๊ณ์ ์ ๊ฐ์ธ/์
์ฒด ๋ ์ผ๊ตด ๋ถ๋ฆฌ, ์
์ฒด ์์ ์นดํ
๊ณ ๋ฆฌ
๐ฌ ์ฑํ
1:1 ์ค์๊ฐ ์ฑํ
(Realtime), ์ฌ์ง ์ ์ก, ๋ฉ์์ง ์ญ์ (30์ผ ์ ์ ํ๊ธฐ), ์
์ฒด ๋ฌธ์ ๋ถ๋ฆฌ
๐ ์๋ฆผ
FCM ํธ์ + ์ธ์ฑ ์ค์๊ฐ ์๋ฆผ, ํญ ์ ํด๋น ํ๋ฉด ์งํ ๋ฅ๋งํฌ, ์ ํ๋ณ ์์ ์ค์
๐ฅ ์์
ํ๋ก์ฐ(Pawing/Pawmate โ ๊ฐ์ธยท์
์ฒด ์ผ๊ตด ๋
๋ฆฝ), ์ฌ์ฉ์ยท๋ฐ๋ ค๋๋ฌผยท์ํธ ๊ฒ์
flowchart LR
subgraph App["๐ฑ Flutter (this repo)"]
UI[Screens / Widgets] --> SVC[Services ยท Repository ๊ณ์ธต]
MOTION[motion/ ์คํ๋ง ๋ชจ์
์์คํ
] --> UI
end
subgraph Supabase["โ๏ธ Supabase (pmdb repo)"]
PG[(PostgreSQL<br/>RLS ยท ํธ๋ฆฌ๊ฑฐ ยท RPC)]
EF[Edge Functions<br/>Deno]
RT[Realtime]
ST[Storage]
end
SVC -- "PostgREST + ์ปค์คํ
JWT" --> PG
SVC -- "์ธ์ฆ/SMS/AI ๊ฒ์ฆ" --> EF
SVC -- "์ฑํ
ยท์๋ฆผ ๊ตฌ๋
" --> RT
SVC -- "์ด๋ฏธ์ง ์
๋ก๋" --> ST
EF --> EXT["๊ตญ์ธ์ฒญ ยท Solapi SMS ยท Gemini ยท<br/>juso.go.kr ยท ๋ค์ด๋ฒ ์ง์ญ๊ฒ์"]
PG -- "pg_cron + pg_net" --> FCM[FCM ํธ์]
Loading
์ธ์ฆ : ์ ํ๋ฒํธ OTP ๊ธฐ๋ฐ ์ปค์คํ
์ธ์ฆ(HS256 JWT + refresh ํ ํฐ). Supabase Auth ๋ฏธ์ฌ์ฉ โ
๋ชจ๋ RLS ๊ฐ app.uid()(JWT sub) ๊ธฐ์ค์ผ๋ก ๋์ํฉ๋๋ค.
๋ณด์ ์์น : ํด๋ผ์ด์ธํธ์๋ publishable ํค๋ง. ์ฐ๊ธฐ ๊ฒ์ฆ์ด ํ์ํ ์์
์
SECURITY DEFINER RPC / DB ํธ๋ฆฌ๊ฑฐ๊ฐ ์ต์ข
๊ฐ์ (ํด๋ผ์ด์ธํธ ๊ฒ์ฆ์ UX ์ฉ).
ํด๋ผ์ด์ธํธ ๊ณต๊ฐ ํคยท์๋ณ์๋ lib/env.dart ํ๊ณณ์ ๋ชจ์ฌ ์์ผ๋ฉฐ
--dart-define ์ผ๋ก ํ๊ฒฝ๋ณ ์ค๋ฒ๋ผ์ด๋ํ ์ ์๋ค(๋น๋ฐ ํค๋ ์๋ฒ ์ ์ฉ).
๋ชจ์
: lib/motion/ ์ ์คํ๋ง ํ๋ฆฌ๋ฏธํฐ๋ธ(PressableยทEntranceยทCollapseRoute ๋ฑ)๋ฅผ
์ ํ๋ฉด์ด ๊ณต์ โ ์นด๋ ํ์ฅ/์ถ์, ์ธ์ด๋ด๋ ค ๋ซ๊ธฐ ๋ฑ ์ผ๊ด๋ ์ ํ ์ธ์ด.
lib/
main.dart # ์ฑ ์ด๊ธฐํ ยท ํธ์/๋ฅ๋งํฌ ๋ผ์ฐํ
screen/ # ํ๋ฉด (tabs/ ๋ฉ์ธ 5ํญ, admin/ ๊ด๋ฆฌ์, auth/ ์ธ์ฆ)
services/ # Supabase ์ ๊ทผ ๋ฆฌํฌ์งํ ๋ฆฌ ยท ํธ์ ยท ์ค์๊ฐ ยท ์์น
models/ # ๋๋ฉ์ธ ๋ชจ๋ธ
widgets/ # ๊ณต์ฉ ์์ ฏ (ํผ๋ ์นด๋ ยท ํ์ผ ยท ์ํธ)
motion/ # ์คํ๋ง ๋ชจ์
์์คํ
(์ ํ ยท ์ด๊ฐ ํผ๋๋ฐฑ)
theme/ # ๋ผ์ดํธ/๋คํฌ ํ๋ ํธ ยท ํ
๋ง
test/ # ์์ ฏ ํ
์คํธ
์ ์ฅ์
๋ด์ฉ
pmdb
Supabase ๋ฐฑ์๋ โ DB ๋ง์ด๊ทธ๋ ์ด์
(์คํค๋งยทRLSยทํธ๋ฆฌ๊ฑฐยทRPC ์ ์ฒด ๋ ํผ๋ฐ์ค ๋ฌธ์ ํฌํจ) ยท Edge Functions
pmlegal
์๋น์ค ์ด์ฉ์ฝ๊ด ยท ๊ฐ์ธ์ ๋ณด์ฒ๋ฆฌ๋ฐฉ์นจ ยท ์์น๊ธฐ๋ฐ์๋น์ค ์ฝ๊ด (์ ๋ณธ)
# Flutter stable ์ฑ๋ (Dart SDK ^3.12)
flutter pub get
flutter run # ์ฐ๊ฒฐ๋ ๊ธฐ๊ธฐ/์๋ฎฌ๋ ์ดํฐ
# ๊ฒ์ฌ & ํ
์คํธ
flutter analyze
flutter test
์ง๋ยทSupabase ๋ฑ ํด๋ผ์ด์ธํธ ๊ณต๊ฐ ํค๋ lib/env.dart ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋์ํ๋ฉฐ,
--dart-define=SUPABASE_URL=... ๋ฑ์ผ๋ก ํ๊ฒฝ๋ณ ์ฌ์ ์ํ ์ ์์ต๋๋ค.
์ฃผ์๊ฒ์(ํ์๋ถ juso) ํค๋ ์ฟผํฐ ๋จ์ฉ ์ฌ์ง๊ฐ ์์ด ๊ธฐ๋ณธ๊ฐ ์์ด
--dart-define=JUSO_API_KEY=... ๋ก๋ง ์ฃผ์
ํฉ๋๋ค โ ๋ฏธ์ค์ ์ ์ฃผ์ ๊ฒ์๋ง
๋นํ์ฑํ๋๊ณ (์๋ ์
๋ ฅ ํด๋ฐฑ) ๋๋จธ์ง ๊ธฐ๋ฅ์ ์ ์ ๋์ํฉ๋๋ค.
ํธ์(FCM/APNs)๋ ์ค๊ธฐ๊ธฐ + ์๋ช
์ค์ ์ด ํ์ํฉ๋๋ค.