Dev

開發日誌

軟刪除這件小事,背後的細節卻不小

軟刪除這件小事,背後的細節卻不小 原本只想補一個產品刪除 API。硬刪除直覺又乾脆,但總會有人手滑、客服就會來敲門。最後還是加了 deletedAt 欄位,用軟刪除留個回頭路。 一做下去才發現沒那麼單純:所有產品查詢都要顧到「未刪除」的狀態,沒有 WHERE deletedAt IS NULL 就會漏風。服務層邏輯跟 API 文件也都得跟著調,免得前端看到回傳數量不對又一臉問號。 刪除做完,回頭補分類查詢。前一晚還在想:「分類過濾真的有人用嗎?」如果首頁只放「最近分析的產品」,確實沒什麼意思。乾脆把首頁改成分類區塊,產品頁也補上分類過濾。React 端只是狀態篩選,沒太多問題;後端就麻煩了。 一開始用判斷 categoryId 的單層過濾,寫到一半才想到還有子分類。只好改成遞迴,把子分類的產品一併撈進來,測試也補齊,避免邊界情境漏掉。 今天接前端馬上踩坑:原本只有一層下拉,後端已經支援子分類,前端卻還是平面結構。
YI

為體驗與準確性重構一切

圖片輪播的坑,比我想的深得多。昨天把 .gitignore 的怪事整理完,今天回到產品開發,把待辦清單裡的圖片輪播放進度。原本估半小時的小元件,結果一做就發現邊界狀況一堆。 先是圖片 URL 的檢查,避免破圖。寫到載入狀態才真正頭痛——使用者網路慢,圖片還沒載好,輪播就先動,那體驗直接崩。我改成所有圖片載完再開始輪播,空檔用 placeholder 撐住。以為穩了,接著又遇到載入失敗要怎麼處理?最後還是每張都加 onError,統一顯示 fallback 圖。不浪漫,但必要。因為破圖看起來不只像 bug,更像品牌管理失敗。 前端收尾後回到 API。產品分類查詢本來是簡單的 CRUD,結果分頁+子分類一上場,原本的產品資料模型就不夠用了,查詢邏輯整個打結。只好重構模型,補上子分類結構,連產品分析服務的主要功能也一起調整,讓「產品質地描述」的提取跟新架構對齊。這種調整就是牽一髮動全身,漏一角,
YI

中文用語統一大作戰:從小細節到底層穩定,這週我修了哪些坑

本來計畫把時間放在核心功能的優化,結果一打開產品分析服務的介面,先被一堆不一致的中文用詞刺了一下。看似微小的「上傳」「提交」「新增」差異,對品牌商用戶的專業感和信任度卻是很實在的扣分。想到我們的客群特別在乎質感,我還是把今天的重心從新功能挪開,展開一場用語清掃。 原本只想改幾個明顯錯誤,一搜 repo 才發現同一概念居然有十幾種搭配方式。最後我從使用情境與用戶習慣出發,整理了一份用語表,將「提交資料」「新增商品」一律統一為「上傳產品」。順手檢查之前的 log,也驚覺開發初期為了快,留下了 test.log、debug.log、temp.log 等臨時檔,甚至沒被 .gitignore 排除。這些東西被 commit 進 repo,真的不行。於是我把怪異的日誌檔案全數加入忽略規則,清乾淨殘留檔案,整個專案視覺與結構都清爽許多。 如果說這天的成果看起來不炫炮,那這週整體就是一場「挖坑與填坑」的連續劇:AI
YI

AI 分類越做越複雜,是在挖坑還是填坑?

AI 分類越做越複雜,是在挖坑還是填坑? 這幾天把重心放在兩件事:產品分類的 AI 自動化,以及安全檢查服務的重構。原本以為只是把 API 接上、模型升級一下,結果一路從資料結構、路由、日誌,到架構設計全被牽出來重整。 先說分類。起初的做法很直接:把產品名稱與描述丟給模型,拿回分類結果就寫進資料庫。實際跑了才發現,回傳格式不穩定,JSON 有時多空格或斷行,parse 會炸。我先補了 try-catch、把原始回應與錯誤一併記錄,至少 debug 不再摸黑。更大的問題是分類的邏輯本身:現實裡很多產品會對應多個類別(保濕、防曬、抗老化),單一分類不合理。最後把產品與分類改成多對多關係,資料庫 schema 重構、API 路由也重排,分類功能的 URL 更直覺。趁勢把產品 ID 改成
YI

FindSkin:從命名到體驗,把混亂收回來

這兩天都在跟「膚質分析」這件事纏鬥。原本系統裡有「膚質檢測」、「肌膚分析」、「問卷調查」三種叫法,越看越不順,乾脆全部統一成 FindSkin。結果一改名才發現,牽一髮動全身:API 路徑、資料表、前端組件、token 邏輯都得一起動。commit 的時候我一直在念自己:「當初命名到底在趕什麼?怎麼會放著這麼不一致的東西不管。」還好順手把 API token 的處理重構掉,意外抓到一個埋在 URL 裡的空格,難怪之前測試總有股不對勁。 回頭看問卷流程,沒有進度條這件事說不過去。現在誰還做問卷不給進度?所以加了狀態管理跟進度顯示,提交後自動跳結果頁。前端則把標語做成堆疊,抓重點字句,層次清楚很多。這段時間確實花在 CSS 和排版上不算少,我也不免自問:「是不是又過度設計了?用戶真的在意透明度 0.6 跟 0.7
YI

訪客帳號到底該怎麼設計?我有點後悔了 🤔

今天原本只是想「順手」把訪客帳號做起來,結果整個上午都被 AuthProvider 綁住。昨天還天真以為用 localStorage 放個暱稱就好,實作下去才知道麻煩在細節:訪客要不要能轉正式帳號、名稱怎麼同步、初始化狀態怎麼顯示,這些都不是一兩行就能搞定。 名稱同步最卡。一開始打算在 ProfilePage 處理,但切頁時會閃一下,整個很不專業。最後把邏輯拉回 AuthProvider,用 isInitialized 管初始化,至少不會再出現奇怪的名稱閃爍。只希望不要再冒出什麼邊界情況,真的拜託。 下午切到產品評論功能。訪客能不能留言這題,暫時定案:訪客不能直接留言,但會有「訪客資訊提示框」引導註冊,保留互動性,又不怕被 spam 灌爆。一起做了 @ 提及功能,本來 API 只存使用者名稱,後來想到改名就會爆,改成存使用者 ID,資料一致性才算穩。 晚上塞進去一直想做的膚質檢測。通知用了
YI

重構永遠不是「只是改一下」的事

今天原本只打算把產品頁改成 client-side component,改善 SSR 時卡卡的效能與 UX。結果一動到 loading 與 error 處理,才發現 API 壓根沒把這些場景算進去,只好整包重整。有人會問:「真的有必要碰 API?用戶會在意嗎?」我很清楚,這種邊角不處理乾淨,之後一定回來咬人。 另外,之前為了避快取加的 timestamp 參數也被我拆了。看似能解快取問題,實際上讓圖片 URL 每次都不同,反而破壞瀏覽器快取。最後改成在上傳或刪除頭像時主動重置預覽 URL,用戶看到更新更即時、更順。順手把顏色生成函式也修了一下,避免測到那種詭異的橘綠色組合。 下午做產品評分與評論時,又卡在「要不要開放訪客留言」。直覺是開放,互動會增加;但想到 spam 防治與認證成本,最後先保守,暫時只給登入會員評論,之後再看情況調整。這種決定難免自我懷疑,
YI