第五天,我整理了分錢系統的操作流程,也規劃了帳本首頁、帳本明細、結算,以及現金付款與找零四個主要畫面。今天接著思考另一個問題:畫面上的這些內容,背後到底需要保存哪些資料?
之前看原型時,我比較容易注意到按鈕、配色和金額顯示。但如果要繼續加入多帳本、資料保存與現金找零,就不能只靠畫面來思考。系統需要知道哪一筆支出屬於哪一本帳、誰先付款、哪些人參與分攤,以及每個人有哪些現金可以使用。
所以今天先不增加程式,也不急著建立資料庫,而是把資料結構與規則整理成一份設計。這份設計會成為後續修改原型的依據,並不代表相關功能今天已經實作完成。
我先把需要保存的內容分成帳本、成員、支出、分攤明細與現金資料。帳本用來區分不同聚餐或旅行,成員代表這本帳裡的人,支出記錄每次消費,分攤明細說明這筆錢由誰負擔,現金資料則記錄每個人這次願意拿來付款與找零的鈔票和硬幣。
整理成員資料時,我先決定把姓名與識別碼分開。姓名是給使用者看的,識別碼則是讓系統確認「這是同一個人」的依據。例如小明之後把名稱改成「小明同學」,他的成員識別碼仍然不變,原本的付款與分攤紀錄也就不需要跟著改成另一個人。
不過,有了識別碼,也不代表介面可以完全不管重名。如果畫面上出現兩個一模一樣的「小明」,使用者仍然可能選錯。因此,第一版先禁止同一本帳出現完全相同的顯示名稱,遇到同名的朋友時,可以加上暱稱區別。識別碼解決資料連接的問題,名稱規則則幫助使用者辨識。
每筆支出需要保存支出名稱、金額、所屬帳本、付款人,以及分攤方式。付款人使用成員識別碼連接,不直接用姓名判斷。參與分攤的人也必須是同一本帳裡的成員,避免不同帳本的資料混在一起。
付款人和分攤成員則是兩個不同的角色。有的人可能只是幫忙代墊,自己沒有參與消費,所以付款人不一定要出現在分攤名單裡。這個規則在畫面上看起來只是取消一個勾選,但資料設計也必須允許這種情況。
分攤方式目前分成平均分攤與自訂金額。平均分攤只需要保存參與者,再由系統根據總金額計算每人的負擔。自訂分攤則需要記錄每位參與者指定的金額,而且所有人的金額加起來,必須等於這筆支出的總額。
金額方面,第一版先固定使用新台幣整數元。支出金額必須大於零,自訂分攤可以填零,但不能出現負數。這樣能讓目前的計算規則保持明確,也避免在尚未需要小數金額時,增加不必要的複雜度。
平均分攤仍然會遇到零頭問題。例如 100 元由三個人分攤,不能每個人都填 33 元,因為這樣會少掉 1 元。因此,我決定在帳本中保存固定的成員順序,只從該筆支出的參與者裡,依順序分配剩下的零頭。
這個順序不能隨著姓名排序或勾選先後改變,否則使用者只是改了顯示方式,就可能連誰多付一元都變了。第一版先不提供任意調整成員順序的功能,讓相同資料能得到一致的分攤結果。
接著是現金資料。每位成員需要記錄這次可用的 1,000 元、500 元、100 元,以及 50 元、10 元、5 元和 1 元各有多少張或多少個。這些數量必須是非負整數,不能出現半張百元鈔,也不能填負的一個五十元。
第五天提到的「未填」與「零」,今天也需要落實到資料結構裡。我決定用 null 表示尚未確認,用 0 表示已確認沒有。例如某個人的百元鈔數量是 2,五十元數量是 null,代表他已經確認有兩張百元鈔,但還沒確認有沒有五十元,系統不能直接把它當成沒有。
第一版會等所有成員確認完這些面額後,再開始計算現金方案。收款人也包含在內,因為他手上的零錢可能是找零能否完成的關鍵。這裡保存的是本次可用的現金,不是要求使用者記錄自己全部的財產。
另一個重要決定,是把原始資料和計算結果分開。支出的金額、付款人與分攤名單,是使用者輸入的原始資料;每個人已經代墊多少、應該分攤多少,以及最後應收或應付多少,則是系統算出來的結果。
我不希望讓使用者同時修改原始支出和結算總額,因為兩邊可能對不起來。比較清楚的方式,是讓結算結果始終從支出重新計算。使用者修改一筆餐費後,相關分攤與最後的付款清單就一起更新。
現金找零方案也屬於計算結果,但它除了金額,還需要包含執行順序。系統必須說明誰把哪些面額交給誰,以及對方要找回哪些鈔票或硬幣。只確認最後的淨額正確還不夠,每一步執行時,也要確認那個人當下真的拿得出指定的現金。
例如某個人必須先收到一個五十元,才能在下一步拿它找零,這兩個步驟就不能任意交換。後續設計找零演算法時,也需要把這種現金流動的順序納入考慮,而不是只把每個人的最終金額湊平。
為了避免使用者照著過期的方案付款,我也規劃了帳目版本與現金版本。當支出或會影響計算的成員資料改變,就更新帳目版本;當現金數量改變,就更新現金版本。每次產生找零方案時,記下當時使用的版本,之後只要版本不同,就代表方案需要重新計算。
修改和刪除資料也需要規則。編輯支出時,先確認金額、付款人與分攤資料都有效,再取代原本的支出,避免只改了一半就影響結算。刪除支出後要重新計算;已經與支出產生關聯的成員,也不能直接移除,必須先處理相關帳目。
今天完成的是資料結構、欄位用途、範例與驗證規則,還沒有建立資料庫,也沒有把這份設計全部套進原型。目前先以適合前端使用的方式整理,等之後真的需要後端時,再決定哪些資料要拆成獨立資料表。
這次整理讓我發現,畫面上看起來簡單的一個名字、一個金額或一個勾選,背後其實都有資料關係。先把這些關係想清楚,之後和 AI 討論程式時,就能更具體地說明哪些資料可以改、哪些規則必須維持,以及修改之後需要重新計算什麼。
接下來會從最基本的單筆平均分攤開始,對照今天的資料設計,檢查現有原型的計算與操作。已經做過的部分就拿來理解、整理與驗證,不需要為了配合天數重新做一次。Day 7,就從一筆支出如何變成每個人的分攤結果開始。