Umikora 開發環境設定
本文件是新成員從零到能跑起來的完整 onboarding 指南。v0.2 起 admin portal 與本地 Supabase 已加入;完整架構見 ARCHITECTURE.md,實作計畫見 IMPLEMENTATION_PLAN.md,部署環境見 INFRA.md。
目錄
1. 前置條件
1.1 必裝工具
| 工具 | 最低版本 | macOS 安裝 | Windows 安裝 |
|---|---|---|---|
| Node.js | 20+ | brew install node@20 或用 nvm / fnm |
nvm-windows 或 fnm |
| Docker Desktop | 最新 | brew install --cask docker |
從 docker.com 下載 |
| Supabase CLI | 2.x | brew install supabase/tap/supabase |
scoop install supabase 或 npm i -g supabase |
| Git | 2.x | 預裝 | winget install git.git |
| Expo Go(手機) | 最新 | App Store / Google Play 下載到手機 | 同左 |
Node 版本由根目錄
.nvmrc鎖定(目前20)。若用 nvm:nvm use。
1.2 確認工具就緒
node -v # 應為 v20.x
npm -v
git --version
supabase --version
docker --version
Docker Desktop 安裝後需手動啟動一次(macOS:從「應用程式」開啟 Docker.app;Windows:開始選單點 Docker Desktop)。確認 docker info 能跑代表 daemon 已就緒。
1.3 重要:不要把 repo 放在 iCloud 同步資料夾
⚠️ 不要把 repo clone 到 ~/Desktop 或 ~/Documents — macOS 預設會把這兩個資料夾同步到 iCloud Drive,當多台裝置或瀏覽器同時存取時,iCloud 會產生帶 2 後綴的衝突副本(例如 package 2.json、tsconfig 2.json),汙染工作目錄。
建議放在:~/Projects/UMIKORA(不在 iCloud 同步範圍)。
mkdir -p ~/Projects
2. 取得 repo
2.1 Clone
cd ~/Projects
git clone https://github.com/tuitone/UMIKORA.git
cd UMIKORA
預設會 checkout 到
main分支。
2.2 切換到 staging(開發分支)
日常開發在 staging 分支(feature 分支從 staging 開出):
git checkout staging
git pull origin staging # 確保是最新
分支策略
feature/* → PR → staging → 驗證 → PR → main
| 分支 | 用途 | 自動部署 |
|---|---|---|
feature/* |
個人開發 | 無 |
staging |
整合測試 | Supabase staging + Vercel preview |
main |
正式版 | Supabase production + Vercel production |
詳見 INFRA.md。
3. 安裝依賴
這是一個 npm workspaces monorepo,在根目錄執行一次即可安裝全部(apps/* + packages/*):
npm install
預期輸出約 1495 packages,耗時 15–30 秒。
若看到
npm warn deprecated警告(uuid、glob 等)可忽略,不影響使用。
4. 啟動本地 Supabase
4.1 確認 Docker 在跑
docker info >/dev/null 2>&1 && echo "Docker OK" || echo "Docker 未啟動"
若未啟動:
- macOS:
open -a Docker,等 10–30 秒 - Windows:開始選單 → Docker Desktop
4.2 啟動 Supabase
npm run supabase:start
# 等同 supabase start,會自動拉 Docker images(首次約 2–5 分鐘)
成功後會看到表格輸出,包含:
| 服務 | URL / 值 |
|---|---|
| Database | postgresql://postgres:postgres@127.0.0.1:54322/postgres |
| API URL | http://127.0.0.1:54321 |
| Studio URL | http://127.0.0.1:54323 |
| Publishable key | sb_publishable_... |
4.3 Supabase Studio(視覺化後台)
開啟 http://127.0.0.1:54323 可看到 Supabase Studio(類似雲端 Dashboard),能瀏覽 tables、跑 SQL、看 Edge Functions。
本地 Studio 無認證,僅限開發用。
4.4 首次需跑 migrations
supabase start 會自動套用 supabase/migrations/ 底下的所有 migration(包含 featured schema + content catalog)。若要重置:
npm run supabase:reset # drops + reruns all migrations + seed
5. 生成環境變數
npm run setup:local
此腳本(scripts/setup-local.mjs)會:
- 讀取
supabase status取得 API URL + anon key - 偵測本機 LAN IP(給手機連線用)
- 寫入三個
.env.local檔:
| 檔案 | 內容 |
|---|---|
apps/admin/.env.local |
NEXT_PUBLIC_SUPABASE_URL + NEXT_PUBLIC_SUPABASE_ANON_KEY |
apps/mobile/.env.local |
EXPO_PUBLIC_APP_ENV=local + EXPO_PUBLIC_SUPABASE_URL(LAN IP) + anon key |
.env.local(根目錄) |
同 mobile |
成功輸出範例:
✅ Local environment configured
API URL : http://127.0.0.1:54321
anon key : (hidden)
Admin portal → cd apps/admin && npm run dev
Mobile Expo → cd apps/mobile && npx expo start
Mobile LAN URL: http://192.168.0.119:54321
Phone Wi-Fi IP: 192.168.0.119
⚠️
.env.local都在.gitignore內,不會進版控。clone 新機器後必須重跑此步驟。⚠️ 若 LAN IP 偵測失敗(輸出「Could not detect LAN IP」),手動編輯
apps/mobile/.env.local把127.0.0.1改成你的 Wi-Fi IP。
6. 啟動 Admin Portal
另開一個終端:
cd ~/Projects/UMIKORA/apps/admin
npm run dev
預期看到:
▲ Next.js 16.x
- Local: http://localhost:3000
開啟 http://localhost:3000。
6.1 登入(Supabase Auth magic link)
v0.2 admin portal 使用 Supabase Auth magic link 登入:
- 在登入頁輸入你的 email
- 收到 Supabase 寄的 magic link email
- 點擊後自動導回 admin portal
本地 Supabase 預設不會真的寄信,但可在 Supabase Studio(
http://127.0.0.1:54323→ Authentication → Users)看到生成的 magic link,或在 Studio 的 Logs 查看。
6.2 設定角色
登入後預設是 anon 角色(無寫入權限)。要測試 CRUD 需在 Supabase Studio 把該 user 的 app_metadata.role 設為 editor / reviewer / admin:
- Studio → Authentication → Users → 選你的 user
- 編輯
app_metadataJSON:{ "role": "admin" } - 重新登入 admin portal(token 會帶新 role)
角色權限對照見 INFRA.md §Content catalog。
7. 啟動 Mobile App
另開一個終端:
cd ~/Projects/UMIKORA/apps/mobile
npx expo start
7.1 用 Expo Go 連線
- 手機安裝 Expo Go(App Store / Google Play)
- 手機與電腦連同一個 Wi-Fi
- 用 Expo Go 掃描終端顯示的 QR code
⚠️ Mobile app 因依賴
expo-sqlite,不支援 Web。用瀏覽器開會看到WebUnsupported畫面,這是正常的。
7.2 連不上時的檢查
| 現象 | 處理 |
|---|---|
| QR 掃了沒反應 | 確認手機 Wi-Fi 與電腦同網段 |
| App 載入後 Supabase 連線失敗 | 確認 apps/mobile/.env.local 的 URL 是 LAN IP(不是 127.0.0.1) |
| Tunnel 模式連不上 | 改用 npx expo start --tunnel(需裝 @ expo/ngrok)或直接 LAN |
7.3 首次啟動行為
首次開啟會走 onboarding 流程(選擇身份 / 語言),完成後進入主畫面。本地 SQLite 會從 content/packs/official-v1.json seed 內容(離線 fallback)。
8. 驗證 Checklist
跑完上述步驟後,依序確認:
8.1 Supabase
- [ ]
supabase status顯示 API URLhttp://127.0.0.1:54321 - [ ] Supabase Studio
http://127.0.0.1:54323能開 - [ ] Table Editor 看到
modules、chapters、cards、pathways、featured_items等表
8.2 Admin Portal
- [ ]
http://localhost:3000能開 - [ ] 能用 magic link 登入
- [ ] 設成
admin角色後能看到 Dashboard、Modules、Cards 等頁面
8.3 Mobile
- [ ] Expo Go 掃 QR 後 App 開啟
- [ ] Onboarding 流程跑完
- [ ] Home 顯示 due count、Stats 顯示 radar chart
- [ ] Explore tab 有 featured feed(若 Supabase 連不上會 fallback 到 mock)
8.4 共享邏輯測試
npm test # 跑 packages/shared 的 Vitest 單元測試
# 或
node scripts/verify-shared.mjs # 快速驗證 SM-2 邏輯
9. 日常操作
9.1 停止服務
# 停 Admin / Mobile:在各自終端按 Ctrl+C
# 停 Supabase
npm run supabase:stop
9.2 重啟 Supabase(保留資料)
npm run supabase:stop
npm run supabase:start
9.3 重置 Supabase(清空資料)
npm run supabase:reset # drops + reruns all migrations + seed
# 之後需重跑 npm run setup:local(anon key 會變)
9.4 重新生成 .env.local
當 Supabase 重啟後 anon key 改變時:
npm run setup:local
9.5 拉最新 staging
git checkout staging
git pull origin staging
npm install # 若 package.json 有變動
# 若 migration 有變動:
npm run supabase:reset # 或單獨 supabase db push
npm run setup:local # 重生成 env
10. 常見問題
10.1 failed to inspect container health: No such container
Supabase 容器不存在(首次或重置後)。執行:
npm run supabase:start
10.2 Cannot connect to the Docker daemon
Docker Desktop 沒啟動。
open -a Docker # macOS
# 等待 Docker 圖示變成運行中
10.3 Port 54321 被佔用
npm run supabase:stop
npm run supabase:start
若仍佔用,檢查是否有其他 Docker container 或本機 Postgres:
docker ps -a | grep 54321
lsof -i :54321 # macOS
10.4 工作目錄出現 2 結尾的檔案(package 2.json 等)
這是 iCloud Drive / Dropbox 等雲端同步產生的衝突副本。代表 repo 被放在同步資料夾內(如 ~/Desktop、~/Documents)。
解法:
- 把 repo 移到非同步步資料夾(如
~/Projects/) - 刪除所有帶
2的檔案:find . -name "* 2.*" -not -path "./node_modules/*" -delete - 若
.git/refs/heads/出現main 2之類的壞 ref,刪掉它:rm -f ".git/refs/heads/main 2"
10.5 git branch 出現 warning: ignoring ref with broken name
同 10.4,有帶空格的壞 ref。刪掉 .git/refs/heads/ 內檔名帶空格的檔案即可。
10.6 Expo Web 白屏 / WebUnsupported 畫面
正常。Mobile app 依賴 expo-sqlite,不支援 Web。請用 Expo Go(iOS / Android)或模擬器。
10.7 npm run setup:local 報 Could not extract Supabase API URL
Supabase 沒在跑。先 npm run supabase:start,再重跑 setup:local。
10.8 Admin portal 登入後看不到內容 / 無法編輯
角色權限問題。預設登入是 anon(唯讀)。到 Supabase Studio 把 user 的 app_metadata.role 設成 editor 或 admin,再重新登入。
10.9 只想驗證 SM-2 / radar 邏輯,不想跑全套
npm test # Vitest 單元測試
node scripts/verify-shared.mjs # 快速 SM-2 驗證
11. 部署環境對照
| Local | Staging | Production | |
|---|---|---|---|
| Git branch | feature/* |
staging |
main |
| Supabase | Docker(:54321) |
雲端 project | 雲端 project |
| Admin portal | npm run dev(:3000) |
Vercel preview | Vercel production |
| Mobile | Expo Go on LAN | staging APK | production APK |
| 取得 repo | 本機 | push staging 自動 |
push main 自動 |
Supabase cloud 部署透過 Supabase GitHub Integration(自動偵測 supabase/migrations/)。Admin portal 部署透過 Vercel。詳見 INFRA.md。
切換到 staging / production Supabase(本機測試用)
覆寫 apps/mobile/.env.local:
EXPO_PUBLIC_APP_ENV=staging
EXPO_PUBLIC_SUPABASE_URL=https://<staging-project>.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_<staging-key>
或用 EAS build profile(見 INFRA.md §EAS Build)。