花錢的當下拍張收據或截圖,Booky 幫你把商務與個人支出分好——報稅只需幾個點擊,不必毀掉整個週末。
拍張收據,它就自動歸好類。30 秒帶你看完。
不需要信用卡,沒有垃圾訊息,只是上線時通知你。
開發日誌
把一支 Python script 變成 SaaS 過程中的真實 commit — 有轉向、有 revert,還有 Jill 第三次重寫整個 codebase。最新的在最上面。
Booky 大半輩子,後端都相信「App 說誰登入就是誰」— 沒事的時候沒事,出事就出大事。這一章把這個縫從頭補到尾。現在每一次請求都帶著一張簽過名的身分,Booky 碰任何一筆資料之前先驗它一次;App 不能再「說自己是你」就算數。你的收據圖、上傳的檔案,全部收緊成一人一戶 — 有人拿到連結也拉不走、跑不了辨識、刪不掉。幕後那些本來就不該對外的機關全數封起來,金額一樣、幣別不同的轉帳也不會再自己悄悄配成一對。這些你一眼都看不到;它們改的是「誰有資格看到」。這是最不起眼的一種工,也正是這種工,讓你可以不用再去想它。
某天晚上,收據辨識底下的模型被抽掉,掃描當場黑掉。補法不是換一顆 — 是一條三層備援鏈:主力讀不到就悄悄退到第二層,再退到裝置本地那層,真的要跟你說「這張讀不了」之前,先自己過完三關。
這段開始的時候,預算還是個相當死板的東西 — 選好你的 50/30/20,乖乖畫在線內,畫出去就被念。六個禮拜把它變成一個有主張的東西。你現在可以切出自己的支出群組,不必再住在三個固定的桶子裡;Booky 會讀你過去幾個月,提一份「看起來像你的人生」的預算,而不是一張白紙;訂閱會先從頭上悄悄預留起來,不再冷不防伏擊你。最後,那些硬天花板拆掉了:目標比例變成一條你可以拿自己去對照的參考線,群組變成你拿來歸類的資料夾、而不是一頭撞上去的牆。預算不再嘮叨,開始給建議。
有好幾個禮拜,手機上的 Booky 就是「桌面版縮小」。這一章把它重蓋成一支你會窩在沙發上、單手就想點開的東西。清單像原生 App 那樣做到滿版;帳戶變成一疊可以左右滑的卡;整張卡都能點,不用再找那個小小的連結;底部導航長在你拇指本來就在的地方。Budget 頁 — 整個產品裡最擠的一頁 — 在手機上做到跟桌面同級,不再把你踢回瀏覽器。還有一直在手機上壞掉的 dark mode,終於看起來像有人是「故意設計成這樣」的。Booky 從沒上過任何商店,但就在這個禮拜裡的某一刻,它開始有了「已經上架」的手感。
大多數記帳 App 用一個安安靜靜的數字結束一個月。Booky 長出了一個會看氣氛的月結回顧:你這個月守住了,它跟你一起慶祝;超支了,它不罵你 — 它坐在你旁邊,指指下個月值得看一眼的地方。現在 dashboard 上整個月都掛著一顆小小的健康徽章,讓「這個月到底如何」不會是 30 號才突然砸下來的驚嚇。這是 Booky 第一個其實跟錢無關的東西 — 它在意的是你離開這些數字時,心裡是什麼感覺。
花費的甜甜圈以前是一張你看著的圖。現在它是一個你可以挖進去的東西 — 點那塊模模糊糊的「Others」或「未分類」,它就攤開成底下那一堆真實交易;父分類展開成子分類的 chip,讓你一個一個剝掉。
訂閱從一張平鋪的清單,變成一條你可以往前讀的時間軸 — 什麼時候扣、下一筆什麼時候來。Dashboard 上那張「即將到期」的卡也變成一扇門:點下去,直接落在那個訂閱住的地方。
以前收據對上銀行那筆,是一次性的猜。現在你編輯一筆交易,它背後的配對會重跑一遍 — 收據日期辨錯了,改回來,配對自己安安靜靜地重新結算。還有一類「確認合併會把綁定的轉帳吃掉」的 bug,這次徹底補死。
5/10 Budget 長出 50/30/20 的脊椎之後一個月,這頁回答你的那一側還是一張平鋪的數字清單 — 有用,但不是你會在禮拜天晚上多看幾眼的東西。連著兩個禮拜的 #582 把這件事補上。多了一層子分類的診斷,可以看到每組 Needs / Wants / Savings 到底是怎麼花掉的;超支的分類用比較穩的顏色標出來,不再用警報紅;多了一條 pacing bar,告訴你「這個月走到這時間點,你應該花到哪、實際走到哪」;多了一張 burn-up 圖,把累積花費跟「應該按比例走」那條線畫在一起,趨勢自己會講話;新加的 stacked macro 趨勢圖把三個月的 Needs / Wants / Savings 疊在一起;Top Categories 卡從同心圓環(瞄一眼看不清楚)換成乾淨的橫條排行榜 infographic;budget 詳細頁的圓環收編、字體一路靜悄悄地全升級。這頁從一張工作清單,變成一段關於你這個月的故事。
整層圖表從一套繪圖庫換到另一套,螢幕上不准有任何一張圖抖一下 — 同樣的圖,換了地基,肉眼零回歸。
連著九天的 design-system 翻新 — token SSOT、約莫 100 處字體統一收進一小組角色、圓角 / 陰影 / 動畫時長 / z-index 各自的 token 家族、顏色引擎換成 oklch + zinc,可重用的元件(EmptyState、PageHeader、StatusPill、StatValue、FieldLabel、Logo、圖表圖例、下拉選單)各自收進一個 SSOT。功能一個都沒動,但這張臉不再像「三次重寫的產物」。
blog 的 post 卡片以前 Booky 那格都是個 placeholder。這個 commit 補上一顆從零畫出來的 B icon(之前根本沒有現成的 asset)— Booky 的文章從這天起遠遠一眼就認得出來。
Booky 前六個禮拜過得很單純 — 你把收據丟進去、Booky 把帳變出來,整個過程裡沒有半毛錢被收掉。這個 commit 把它的第一批方案攤給世界看:跟 Meander 的擺在同一張價格卡上,共用月費 / 年費 toggle、共用 14 天試用。卡片本身長出能同時擺兩家方案的骨架 — 一張 UI、兩個服務。在這之前,家裡唯一掛訂閱按鈕的只有 Meander;從這天起,Booky 也有自己的一顆 — Jill 第三次重寫的這份 codebase,從這天起不再只是個免費的實驗。
把 Booky 配對腦袋之前默默自己決定的那些角落,這天一次都調緊。重複偵測不再硬擋,先問你;反向配對救回來 — pending 撞上 settled 可以合,恢復成壞掉之前的做法;拆過的子交易孤兒被收回給原本的父,不再像鬼一樣飄;金額輸入欄全站收進同一個 SSOT。表面上看不到 — 這就是重點。
這個 commit 之後,這頁變成兩個用法:直接點是方案頁,帶 ?tab=topup 進來就直接落在點數包選單。同一張介面,兩條路。
為了方案要上線,Booky 的升級頁這天被仔細修了一輪:Meander 那邊「誠實補差價」的對話框直接搬過來、Free 方案不再裝得能按、那條「回 Booky」的連結在同一個下午被搬了四次,最後落到該在的地方。
沒有任何單一大功能,就是把你最常碰的那幾塊地方一次擦亮:方案名統一成 Basic / Pro / Premium,再給一個共用的「是不是付費版」helper;以前那個謎一樣的「Keywords」介面改叫 Automations(因為它做的就是這件事);帳戶欄位不再寫「Type」「Account」,改成「Starting Balance」「Paid from」「Bank Account」。順手把分類視窗修圓潤、shadcn Tabs 也接上去。
Booky 後台的那些小判斷 — 抓重複、串轉帳、配對等中的收據、猜分類 — 以前只活在網頁裡。這禮拜搬出來放到 Booky 自己身上,未來的 Android 版(跟之後任何新入口)都會用同一顆腦袋回答你。同一天順手放了 207 項自動檢查下去,確保搬家途中沒哪裡偷偷出包。
Budget 以前是個平鋪清單,回答的是「這個花了多少」 — 有用,但不會改變你怎麼花錢。這禮拜它長出形狀:頂部釘一個月薪,每個分類落進 Needs / Wants / Savings(經典的 50/30/20),整頁開始問該問的問題 — 你照你講好的比例在花嗎?
Booky 跟上跨產品的法務頁更新,自己的服務條款跟隱私政策也上線了。
連著幾天沒大動作,但很多小地方不再粗糙:背景變柔、border 變淺、警告平靜下來(原本的 amber 換成新的 Ghost Orange)、Analysis 圖表多了縮放,幾個小毛刺也順手清掉。Booky 開始整套呼吸同一口氣。
在網頁上用 Google 登入、其實要回 Android?網頁現在會把你連登入狀態一起送回去,不再把你卡在瀏覽器裡。Android 版的第一根水管。
在這個 commit 之前,Booky 內部所有日期都用 UTC 在想事情。對住在澳洲、比 UTC 早十一小時的 Jill 跟 Beer 來說,這代表午夜過後買的咖啡永遠被算進「昨天」的帳,訂閱續費按 UTC 的鐘跳,永遠不是你的鐘。這個 commit 把這條縫補起來,而且不只補給澳洲使用者 — 是補給所有人。第一次打開 Booky,它會自動偵測你人在哪,時區自己對上去,連對應這個地區的幣別也一起到位(兩個都還能在合併後的「Region & Currency」面板裡手動換)。四個 phase 同一天落地讓這件事在哪裡都成立 — Booky 裡的日期跟你眼前的月曆,從這天起再也沒有誤差,無論那塊月曆掛在哪面牆上。
Analysis 頁上方的 All / Income / Expense 切換,現在會同時帶動圖表跟現金流數字 — 之前只動下面的清單,圖表還是顯示全部。
底部導覽抽成單一來源,四個主頁一致;Profile 頁從頭重寫成分區設定列;子頁加返回鍵;History 頁用滑上來的 filter 抽屜取代原本桌面那條 sidebar。在手機上用 Booky 這件事,從「桌面版的縮小版」變成「真的是手機 app」。
在這個 commit 之前,拍完收據照片直接送進 OCR。如果你拍歪了,model 不是直接卡住,就是悄悄把數字看錯,你要等交易跑出來才會發現。這個 commit 之後,每一個 OCR 入口都會先過一道預覽:照片送到你面前、橫的自動轉正、你還能手動再轉,再決定要不要按下去讓 model 讀。OCR 從「一次性猜中」變成「先確認過再下手」 — Booky 動手之前會先問你一句:這張,是你要的嗎?
支援一次丟一疊收據。之前一次只能掃一張,現在整疊丟下去 Booky 一起處理。
在這之前,Booky 活在自己的瀏覽器分頁裡。你登入、掃收據、看交易紀錄,全都在同一個地方。這個 commit 之後,Booky 會講話了。Android client 有路可以進來。Mate 也有路可以進來。第一張照片走過 Mate、回來變成一筆放在對的帳戶、掛對的分類的真實交易 — 那一刻 loop 閉上了:Booky 不再只是跟家族其他人共用同一套登入,而是變成可以被叫得到的,跟 Moltfi、Meander 一樣。從這天起真的算加入生態系。
同一個 commit 裡塞了兩件大事。第三次架構重寫 — Jill 又一次把 pattern 整乾淨、container 跟 presentation 拆開、type 收緊。然後同一份 diff 裡面藏著:收據 OCR。拍一張照片,回來一筆結構化的交易。值得停下來講 OCR 這一邊。Jill 本業是網頁設計師,不是工程師。以前做 OCR 是工程師的活。她自己做出來,AI 把她不會的部分補起來。我們都有點不敢相信,OCR 跟一次重寫架構居然在同一個禮拜五推出去。
Booky 第一次擁有一個網址,任何人打開都看得到。在這之前它就跑在 Jill 的筆電跟我們自己的 dev server 上,沒了。第一次 deploy 並不順 — 第一次 build 因為一個 dependency 衝突沒過,後來又補了一輪才弄綠。隔天再一個小 commit,把 git author 改對重觸發一次 deploy。Deploy 都是這個樣子。重點是:有網址了,網址打得開了,網站活在網路上了。
多幣別的故事終於對上。每天自動抓匯率,跨幣別的總額才有意義。
第一個正經的資料生命週期 feature。代表「敢 undo」,不是只敢刪。
Booky 不再是只有 Jill 能登入的東西。這個 commit 之後,每一筆資料都知道自己是誰的、每一個動作都知道自己在替誰跑,前門會去 everydays.tools 確認你訂閱沒、再決定要不要放你進來。第一天是單人 prototype;這一天變成多人 SaaS。同一個產品,底下換了個形狀。
帳單不會自己繳,人會忘。把它存成資料,不存在腦袋。
同一天兩個大動作。一個塞滿所有東西的後端怪物 — 早期所有 code 都堆在那一支 — 被拆成「每個關注點一個檔案」:accounts、categories、budgets,等等。然後一直擺在旁邊當第二個後端的 Python 服務,當天一次砍光。這個 commit 之後,Booky 從兩個後端變成一個,從兩種語言變成一種。多語言時期就此結束。
react-virtuoso,revert 掉,改成 batch mutations同一個下午三個 commit:先 WIP 加 react-virtuoso,再 revert 並寫上 "unstable",最後用 useTransition + optimistic UI 解掉同一個列表卡頓問題。漂亮的函式庫輸了,React 內建的 primitive 贏了,沒多塞 dep。
把銀行 CSV 匯進來時,有些交易你可能已經手動輸過。Reconcile 比對金額 / 日期 / 描述,問你:是同一筆嗎?要合併還是跳過?沒這個功能,每次匯入都會產生重複資料;有了它,手動跟自動輸入終於能共存。
下注的時刻:這是一個真的產品,不是 notebook。該選一套正經的前端 stack。
上層一個簡單的記帳介面,底下一支小小的 Python 把 PDF 對帳單裡的交易撈出來。對 PDF 解析的執念在最一開始就有。這個執念到今天還是產品的骨架 — 我們這邊大部分銀行不給 Jill 乾淨的匯出檔,只給她對帳單。Booky 就是為了處理這件事誕生的。