smooth-app
전 세계 식품의 성분·영양·정보를 자유롭게 협업하고 공개하는 데이터베이스
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
紀錄貓咪每天的飲食(食物 g)、喝水(ml)、尿尿與便便次數、體重變化、除蟲藥的點藥週期提醒,以及到家累計天數的小網站。 用 Next.js + Supabase 打造,可部署到 Vercel。 畫面採用溫暖米色系、白色卡片 + 橘色重點色的風格,並支援上傳 Mocha 的頭像照片。除蟲藥點藥滿 3 個月、每週三量體重,都會透過瀏覽器推播通知提醒。 • Next.js 14(App Router + TypeScript) • Tailwind CSS • Supabase(Postgres 資料庫 + 前端直連的 REST API) • 部署:Vercel 主要資料表 entries,每一筆是一個事件(吃飯 / 喝水 / 尿尿 / 便便 / 點除蟲藥 / 量體重 / 活動 / 零食),可以一天記錄多次,畫面上會依日期加總顯示: 另外還有 push_subscriptions(瀏覽器推播訂閱資訊)、reminder_state(避免同一次到期重複推播)、settings(單一設定值,目前用來存到家日期、生日、飲水起始量、AI 分析快取結果)、food_brands(食物種類快捷選項,也存每種食物的卡路里設定)、activity_types(活動類型快捷選項)、snack_types(零食種類快捷選項)六張輔助表。完整定義見 supabase/schema.sql。README 전문 보기 ↗
紀錄貓咪每天的飲食(食物 g)、喝水(ml)、尿尿與便便次數、體重變化、除蟲藥的點藥週期提醒,以及到家累計天數的小網站。 用 Next.js + Supabase 打造,可部署到 Vercel。
畫面採用溫暖米色系、白色卡片 + 橘色重點色的風格,並支援上傳 Mocha 的頭像照片。除蟲藥點藥滿 3 個月、每週三量體重,都會透過瀏覽器推播通知提醒。
主要資料表 entries,每一筆是一個事件(吃飯 / 喝水 / 尿尿 / 便便 / 點除蟲藥 / 量體重 / 活動 / 零食),可以一天記錄多次,畫面上會依日期加總顯示:
| 欄位 | 說明 |
|---|---|
type | food / water / pee / poop / flea / weight / activity / snack |
amount | 數量(食物用 g、喝水用 ml、體重用 kg、尿尿/便便用次數,除蟲藥、活動、零食可留空) |
note | 備註,例如食物種類、便便軟硬程度、除蟲藥品名、活動類型、零食種類 |
occurred_at | 發生時間(尿尿/便便沒有精確時間,用上午/中午/下午/晚上換算成代表時間存入) |
updated_at | 最後修改時間,由資料庫 trigger 自動維護,新增時等於 created_at,之後每次被更新都會自動變成當下時間 |
另外還有 push_subscriptions(瀏覽器推播訂閱資訊)、reminder_state(避免同一次到期重複推播)、settings(單一設定值,目前用來存到家日期、生日、飲水起始量、AI 分析快取結果)、food_brands(食物種類快捷選項,也存每種食物的卡路里設定)、activity_types(活動類型快捷選項)、snack_types(零食種類快捷選項)六張輔助表。完整定義見 supabase/schema.sql。
Mocha 的頭像照片存在 Supabase Storage 的 avatars bucket 裡(固定檔名 mocha.*,上傳新照片會直接覆蓋舊的),設定見 supabase/storage.sql。
考慮到比較晚睡的情況,這個網站的「今天」是從凌晨 4 點算到隔天凌晨 3:59,不是一般的 0 點到 23:59。例如 10/13 凌晨 2:30 記的紀錄,會算進 10/12 那天,日期也會顯示 10/12,不會因為過了午夜就跳到隔天。「今日紀錄」卡片、「紀錄列表」、報表、AI 分析全部都是用這個分界,彼此一致。
用上方「←/→」切換到某一天之後,不管接下來按哪一種紀錄的「+」(食物、喝水、尿尿、便便、體重、除蟲藥、活動、零食都算),新增表單的時間預設都會是那一天,而不是永遠都是今天,方便補記錄之前忘記寫的紀錄。時間本身還是預設現在的時分,只有日期會跟著切換到的那一天走;表單裡都還是可以自己再改時間。(用起始/剩餘水量計算飲水量的功能例外,因為那個是量測當下水量的即時流程,跟切換到哪一天無關。)
「紀錄列表」裡的每一筆紀錄都可以點下去修改(例如打錯數量、選錯種類、時間不對),會打開跟新增時一樣的表單並帶入原本的內容,改完按「更新」就會儲存回原本那一筆紀錄(不會變成新的一筆)。點右邊的「✕」則維持原本刪除整筆紀錄的功能。
每筆紀錄都有 updated_at(最後修改時間),新增的當下跟 created_at 一樣,之後只要內容被改過(食物剩下多少、點進去編輯)就會自動更新。如果一筆紀錄曾經被改過,「紀錄列表」會在備註下面多顯示一行「最後修改:幾月幾號 幾點幾分」,方便之後想查某筆紀錄是什麼時候被誰改掉的。
push_subscriptions(這組訂閱同時涵蓋除蟲藥跟體重兩種提醒,只要開一次)。vercel.json):
/api/cron/flea-reminder:每天檢查一次,算出「上次點藥日期 + 3 個月」,到期且這次到期還沒推播過,就發送推播並清掉已經失效的訂閱。/api/cron/weight-reminder:只在每週三檢查,直接對所有訂閱裝置發送「該量體重了」的推播提醒。⚠️ iPhone 限制:iOS Safari 只有在把網站「加入主畫面」變成 App 之後,Web Push 才會生效,直接用瀏覽器分頁開啟是收不到通知的(Apple 的限制,不是這個網站的 bug)。Android/桌機瀏覽器(Chrome、Edge、Firefox)不需要額外設定。
Vercel Hobby(免費)方案的 Cron Job 上限是 2 個、且每個最多一天觸發一次,這個專案剛好用滿 2 個(除蟲藥每天檢查、體重每週三檢查),如果之後想加更多提醒,需要升級 Vercel Pro 方案。
網站有設定 app/icon.png(一般網站圖示)跟 app/apple-icon.png(iOS「加入主畫面」用的圖示,180×180),以及 public/manifest.json(讓加入主畫面後用全螢幕、沒有網址列的方式開啟,比較有 App 的感覺)。
目前的圖示是預設的貓臉圖案,如果想換成 Mocha 的真實照片,把照片傳給我,我直接把 app/apple-icon.png(建議至少 180×180)跟 app/icon.png 換掉重新部署即可。
⚠️ iOS 在「加入主畫面」的當下就會把圖示存起來,之後就算網站的圖示換了,桌面上已經加好的捷徑也不會自動更新,要重新加一次(先移除舊的捷徑,再重新「加入主畫面」)才會看到新圖示。
新增食物紀錄時,上方有快捷種類按鈕,預設是「皇家乾糧」、「皇家罐罐」,選一個會自動填入備註欄。按旁邊的「+」可以輸入新的種類名稱,存進 food_brands 資料表後,之後每次新增食物都會看到這個新種類。
到側邊選單「設定」→「食物卡路里設定」,可以幫每一種食物種類設定卡路里,兩種模式擇一:
每種食物還可以選填「含水量%」,給 AI 分析估算水分攝取用;留空的話系統會自動用常見比例估算(罐裝 78%、秤重 10%),不用一定要自己填。
卡路里設定是給「AI 分析」用的,沒有設定的食物種類不影響原本記錄食物的功能,只是那幾筆沒辦法算進卡路里/水分攝取量裡。
「紀錄列表」裡每一筆食物紀錄,份量下面都會顯示那一筆換算出來的卡路里(例如「114 kcal」);如果那筆的食物種類還沒設定卡路里,會顯示「未設定卡路里」,提醒你去設定頁補上。
「食物」卡片上除了橘色「+」,左邊還有一個灰色「−」,如果貓咪沒吃完:
「今日紀錄」顯示的總克數就是實際吃下去的量,不用另外靠加總負數紀錄來換算。如果吃的食物有設定卡路里,「食物」卡片上除了克數、次數,還會多顯示當天吃了多少卡路里(例如「95 g · 2 次 · 179 kcal」);如果當天有些紀錄的食物種類還沒設定卡路里,數字前面會加一個「約」,提醒這只是根據有資料的部分估算,不是當天真正的總量。
「喝水」卡片有兩個按鈕:
兩種方式記的都是同一種「喝水」紀錄,「今日紀錄」會把兩種方式加總顯示。
如果今天吃的食物有設定(或用預設值估算)含水量,「喝水」卡片下方會多顯示一行「估計共 X ml(含食物水分)」,把直接喝的水跟食物裡的水分加總估算,方便一眼看出大概攝取了多少水分,不用另外去看 AI 分析才知道。就算今天還沒有直接喝水的紀錄,只要吃過有水分的食物,這一行也會照樣顯示估算的水分攝取量,不會因為沒喝水紀錄就整個卡片都顯示「-」。
因為在旁邊看到貓咪尿尿/便便的當下很難精準記時間,這兩種紀錄改成:
「今日紀錄」卡片上顯示的是當天的加總次數(同一筆紀錄如果選了 3 次,就算 3 次)。
「紀錄列表」下方多一張「活動」卡片,用來記錄剪指甲、剃腳毛這類不定期的護理活動:
activity_types 資料表後,之後每次新增活動都會看到這個新類型(跟食物種類的邏輯一樣)「活動」卡片下方多一張「零食」卡片,記錄方式跟活動完全一樣:
snack_types 資料表後,之後每次新增零食都會看到這個新類型有兩種情境會讓畫面上的資料變舊,這個網站都處理了(lib/useVisibilityRefresh.ts):
不管哪種情況觸發更新,都不會跳回首頁或重設你正在看的日期、報表區間等狀態——資料是新的,但你還停在原本那一頁。
側邊選單「報表」可以看食物、喝水、便便、尿尿四項的趨勢,上方切換「1週」/「1個月」/「自訂期間」:
報表頁最下方有一張「AI 分析」卡片,把目前檢視期間的食物、飲水、體重、便便、尿尿、卡路里、水分攝取量數據整理起來,交給 Google Gemini(免費方案)生成一段繁體中文分析,說明這些數據之間可能有什麼關聯(例如食量增加是否對應體重上升、卡路里/水分攝取量是否超過或低於所需量、喝水量夠不夠),並提醒有沒有需要留意的地方。
settings 資料表,下次打開報表頁會直接顯示上次的分析結果(包含是什麼時候算的、算到哪一天),不會每次進頁面就重新呼叫一次 AIGEMINI_API_KEY 環境變數才能使用,申請方式見下方部署步驟supabase/schema.sql — 建立 entries、push_subscriptions、reminder_state、settings 資料表(如果你之前已經執行過舊版,重新整份貼上執行一次也沒關係,會自動升級)supabase/storage.sql — 建立存放頭像照片的 avatars storage bucketProject URLanon public key目前所有資料表跟
avatarsbucket 都開放給 anon key 讀寫(沒有登入機制),適合個人/家人使用的小工具。如果之後要公開分享或加上多人帳號管理,建議加上 Supabase Auth 並把 SQL 裡的 RLS policy 改成依auth.uid()過濾。
除蟲藥推播提醒需要一組 VAPID 金鑰(瀏覽器推播的憑證),本機執行:
npx web-push generate-vapid-keys
會得到一組 Public Key 和 Private Key,等一下本機開發跟 Vercel 都要用到。
報表頁的「AI 分析」功能需要一組 Google Gemini API Key:
Gemini 有免費方案(有次數限制,但這個 app 是個人/家人用量,需要按到「開始分析」才會呼叫一次,應該不會超過額度),不需要绑信用卡。如果不需要 AI 分析功能,可以跳過這步,
GEMINI_API_KEY留空即可,按「開始分析」時會顯示錯誤訊息但不影響其他功能。
npm install
cp .env.local.example .env.local
# 編輯 .env.local,填入 Supabase URL / anon key、VAPID 金鑰、自訂的 CRON_SECRET,以及上一步的 GEMINI_API_KEY
npm run dev
開啟 http://localhost:3000 即可使用。
Cron Job 只有部署到 Vercel 後才會自動排程執行,本機開發若要手動測試提醒邏輯,可以自己呼叫:
curl -H "Authorization: Bearer 你的CRON_SECRET" http://localhost:3000/api/cron/flea-remindercurl -H "Authorization: Bearer 你的CRON_SECRET" http://localhost:3000/api/cron/weight-reminder
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYNEXT_PUBLIC_VAPID_PUBLIC_KEYVAPID_PRIVATE_KEYCRON_SECRET(自己取一組隨機字串,Vercel 呼叫 Cron Job 時會自動帶上這個值驗證身分)GEMINI_API_KEY(上一步申請的 Gemini API Key,沒有的話 AI 分析功能會顯示錯誤,但不影響其他功能)之後每次 push 到部署分支,Vercel 都會自動重新部署;vercel.json 裡設定的兩個 Cron Job 也會跟著自動排程(除蟲藥每天、體重每週三,都是台灣時間早上 9 點檢查)。
app/ # Next.js App Router 頁面與 API 路由
app/settings # 設定頁(側邊選單點「設定」進入),推播開關、生日、食物卡路里設定
app/reports # 報表頁(側邊選單點「報表」進入),食物/便便/尿尿週或月比較
app/api/cron/flea-reminder # Vercel Cron 呼叫的除蟲藥提醒檢查(每天)
app/api/cron/weight-reminder # Vercel Cron 呼叫的體重提醒(每週三)
app/api/ai-analysis # 報表頁「AI 分析」呼叫的 API,整理數據(含卡路里)後轉發給 Gemini,並把結果存進 settings 當快取
components/ # 前端元件(側邊選單、寵物資訊卡、推播開關、體重卡、除蟲藥提醒卡、活動/零食卡、快捷選項按鈕、報表卡、AI 分析卡、生日設定、食物卡路里設定、今日紀錄格、新增/編輯紀錄彈窗、食物剩下多少彈窗、量水量彈窗、清單、日期切換)
lib/ # Supabase client、型別定義、日期工具、頭像上傳、推播訂閱、報表統計、飲水量起始值追蹤、食物/活動/零食類型快捷選項、貓咪生日與每日所需卡路里估算、AI 分析結果快取、App 恢復前景時自動刷新、共用的推播發送邏輯
public/sw.js # 接收推播通知的 Service Worker
supabase/schema.sql # entries / push_subscriptions / reminder_state / settings / food_brands 等資料表結構
supabase/storage.sql # 頭像照片 storage bucket 與權限
vercel.json # 除蟲藥、體重兩個提醒的 Cron Job 排程設定