<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Southern Light</title><description>Notes on systems, tools, and side projects.</description><link>https://southern-light.dev/</link><item><title>當了一日 Android 工程師，結果兇手是 Supabase 後台的兩個星號</title><link>https://southern-light.dev/blog/android-supabase/</link><guid isPermaLink="true">https://southern-light.dev/blog/android-supabase/</guid><description>你有沒有過那種，code 一行都沒錯、測試全綠、release 也發了，結果功能照樣炸——而真正的兇手躺在一個你三天沒打開的後台設定頁裡？</description><pubDate>Sun, 31 May 2026 00:00:00 GMT</pubDate></item><item><title>我在 prod 加密了 PII，然後用了錯的 key</title><link>https://southern-light.dev/blog/pii-wrong-key-backfill/</link><guid isPermaLink="true">https://southern-light.dev/blog/pii-wrong-key-backfill/</guid><description>你有沒有過那種，覺得自己做了一件很負責任的事——替 prod 資料庫裡的敏感資料全部加密——然後過了一段時間，才發現你加密得很用力，但是用了錯的 key？</description><pubDate>Sun, 31 May 2026 00:00:00 GMT</pubDate></item><item><title>三個晚上不到，我用 Gemini 3.1 Preview 燒掉了 600 美</title><link>https://southern-light.dev/blog/gemini-3-1-preview-burned-600usd/</link><guid isPermaLink="true">https://southern-light.dev/blog/gemini-3-1-preview-burned-600usd/</guid><description>你有沒有過那種，覺得自己抓到一個超猛的工作流、興奮到連續三個晚上不睡覺，結果隔天早上被一封「您的用量已達 100%」的信打回現實的經驗？我這禮拜剛經歷過——而且不是貴 50 美 100 美那種剛剛好的痛，是三個晚上、$608 USD、一封 GCP 用量警示信那種痛。</description><pubDate>Fri, 29 May 2026 00:00:00 GMT</pubDate></item><item><title>讀完 Harness Engineering 那篇我才發現——軟體工程沒被淘汰，只是搬家了</title><link>https://southern-light.dev/blog/blog-2026-05-29-harness-engineering/</link><guid isPermaLink="true">https://southern-light.dev/blog/blog-2026-05-29-harness-engineering/</guid><description>你有沒有過那種，看完一篇技術文章之後，整個下午看自己的 codebase 都覺得不對勁的經驗？我前幾天就是。起因是被人塞了一篇 HackMD——〈Harness Engineering 完全解析〉，本來想說又一個 AI buzzword，划個五分鐘交差，結果一路讀到底，讀完之後我第一件事是打開自己手上專案的根目錄…</description><pubDate>Fri, 29 May 2026 00:00:00 GMT</pubDate></item><item><title>把 Claude 當包工頭、Gemini 當小工，居然真的有用</title><link>https://southern-light.dev/blog/claude-gemini/</link><guid isPermaLink="true">https://southern-light.dev/blog/claude-gemini/</guid><description>你有沒有過那種，明明手上有一把刀，卻硬要拿榔頭去切牛排的時刻？</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate></item><item><title>我的 codebase 裡有 33 個寫死的 `#fff`、11 種隨手敲的 z-index，跟 39 個 `text-[10px]` 等級的魔術數字</title><link>https://southern-light.dev/blog/codebase-33-fff11-z-index-39-text-10px/</link><guid isPermaLink="true">https://southern-light.dev/blog/codebase-33-fff11-z-index-39-text-10px/</guid><description>說真的，我以前都假裝沒看到這些東西。一個白色字 、一個彈窗 、一個小標籤 ——每個單獨看都很合理，合在一起就是一鍋沒人敢動的湯。直到我想做 dark mode，發現要改前景色得手動 grep 33 個檔案，我才認清：這不是設計，這是技術債穿了件設計的外套。</description><pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate></item><item><title>我把 Gemini 偽裝成 Opus，然後被 Cloudflare 524 打趴在地——一個還沒驗收的地端模型實驗</title><link>https://southern-light.dev/blog/gemini-opus-cloudflare-524/</link><guid isPermaLink="true">https://southern-light.dev/blog/gemini-opus-cloudflare-524/</guid><description>你有沒有過那種，明明只是想「換一個便宜一點的引擎」，結果整個禮拜都在跟一堆中間人搏鬥的經驗？我這幾天就是。我沒在改產品、沒在修 bug，我在做一件聽起來很單純的事——讓我的 coding agent 不要每次都燒 Claude 的錢。然後我發現，難的從來不是模型本身，是模型外面那一圈東西。</description><pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate></item><item><title>一個只有「對方」看得到的 bug，因為我永遠是那個 A</title><link>https://southern-light.dev/blog/bug-a/</link><guid isPermaLink="true">https://southern-light.dev/blog/bug-a/</guid><description>你有沒有寫過那種 bug——你自己用一百次都正常，因為你剛好站在它隱形的那一側？我這天抓到一隻，它在 prod 上活了不知道多久，而我完全沒發現，原因蠢到我想找個地洞鑽進去：因為我永遠是那個 member A。</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate></item><item><title>同一個 bug 我修了三次，前兩次都在打空氣</title><link>https://southern-light.dev/blog/bug/</link><guid isPermaLink="true">https://southern-light.dev/blog/bug/</guid><description>你有沒有過那種，明明已經「修好」了、還很有自信地寫了 commit message，結果隔了幾小時又回來修同一個地方的經驗？我這四天經歷了三次——同一個 bug，三張臉，前兩張我都打偏。</description><pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate></item><item><title>Wildcard 一直頂著 Vite 的預設 favicon 出門——直到我幫它長出一張壞笑臉</title><link>https://southern-light.dev/blog/wildcard-brand-smirk-favicon/</link><guid isPermaLink="true">https://southern-light.dev/blog/wildcard-brand-smirk-favicon/</guid><description>你有沒有過那種，一個東西做得滿認真的，但分享出去的連結預覽圖卻是別人的——那種尷尬？</description><pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate></item><item><title>保單可以掛在別人家的車上——直到我把那個洞補起來</title><link>https://southern-light.dev/blog/futari-insurance-ownership/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-insurance-ownership/</guid><description>你有沒有寫過那種 bug——你自己用一百次都正常，因為你剛好站在它隱形的那一側？</description><pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate></item><item><title>我開了四個 session 跑 over night，隔天醒來像在看別人的鬼屋</title><link>https://southern-light.dev/blog/session-over-night/</link><guid isPermaLink="true">https://southern-light.dev/blog/session-over-night/</guid><description>你有沒有過那種，睡前覺得自己是天才、醒來覺得自己是凶手的經驗？</description><pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate></item><item><title>Wildcard 終於不像「灰色 stone-100 盒子大集合」了——一場野地改造</title><link>https://southern-light.dev/blog/wildcard-stone-100/</link><guid isPermaLink="true">https://southern-light.dev/blog/wildcard-stone-100/</guid><description>說真的，Wildcard 野地對戰是個讓你出門撿石頭、撿樹枝、撿樹葉，拍照拿來打剪刀石頭布的遊戲——結果整個介面長得像一份報稅表單。到處都是 、，每張卡片都一個樣（灰、灰、還是灰）。一個叫你去野地探險的 app，UI 卻冷得像主機房——這就很尷尬啦。</description><pubDate>Fri, 22 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 的 dashboard 只會哭窮——直到我幫它加了一個「進帳」模式</title><link>https://southern-light.dev/blog/futari-dashboard/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-dashboard/</guid><description>說來好笑，我做了一個記帳 app，結果它只會記你「花了多少」。打開 Futari 的 dashboard，BalanceHero 上永遠是一個往下掉的數字——彷彿在提醒你「你又窮了一點」。但人不是只會花錢的（至少帳面上要假裝不是），薪水、轉帳、那筆久違的退款，總得有地方安放吧？所以這次我幫 dashboard 長…</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate></item><item><title>我為了消滅一個閃爍，掉進了 React hydration 的兔子洞</title><link>https://southern-light.dev/blog/react-hydration/</link><guid isPermaLink="true">https://southern-light.dev/blog/react-hydration/</guid><description>故事的起點是一個極其無辜的需求——「讓使用者收合的卡片，下次打開還是收合的」。BalanceHero 可以收起來、MonthlyStatsView 可以摺疊，使用者收好了，重新整理一下又全部展開——這很煩。我心想，這不就是一個  的事嗎？</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate></item><item><title>我寫了一篇文章警告大家別忘記 await——然後我忘了 await</title><link>https://southern-light.dev/blog/await-await/</link><guid isPermaLink="true">https://southern-light.dev/blog/await-await/</guid><description>前幾天我才寫了一篇短文，講「忘記  的 server action 會讓 balance 比真實資料早一步出去」——還煞有介事地下了個結論：「TypeScript 不會幫你抓忘記 await，丟掉 Promise 它覺得你是故意的。」結果這天  trip query——、、 三個 function 全部忘了 aw…</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate></item><item><title>一個用石頭打架的遊戲，卻用 emoji 當牌面——Wildcard 的「野地」長出來了</title><link>https://southern-light.dev/blog/emoji-wildcard/</link><guid isPermaLink="true">https://southern-light.dev/blog/emoji-wildcard/</guid><description>說真的，一個叫你出門撿石頭、撿樹枝、撿樹葉拍照對戰的遊戲，牌面卻是 🪨📄✂️ 這種系統內建 emoji，每台手機 render 出來還長得不一樣——這事我自己都看不下去。Wildcard 野地對戰的核心明明是「實物」，UI 卻像隨手 demo 出來的。所以我把整套畫面打掉，蓋了一個叫 fieldbook（野地…</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate></item><item><title>那天我終於受不了——把 Button 寫了第八次的那一天</title><link>https://southern-light.dev/blog/button/</link><guid isPermaLink="true">https://southern-light.dev/blog/button/</guid><description>——20 個 match。每一個都是某個 sheet / wizard / setting 裡某顆 button，每一個都有自己微妙不一樣的 padding、border-radius、hover state。我在 codebase 裡寫了八種 Button 而每一種都堅持自己才是「對的」。</description><pubDate>Tue, 19 May 2026 00:00:00 GMT</pubDate></item><item><title>保險忘了帶編輯筆、車色其實是字串騙局——Futari 那一輪小修小補</title><link>https://southern-light.dev/blog/futari/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari/</guid><description>說來尷尬——我自己在 Futari 上新增了一張保險，填完才發現「咦怎麼沒有編輯按鈕」。翻 code 才想起來，當初 scaffold 保險 detail page 時，TYPE_OPTIONS 還沒把它 expose 出來，所以連 edit pencil 都沒接上。後來 Phase 1 解鎖保險新增，這顆釘子就…</description><pubDate>Tue, 19 May 2026 00:00:00 GMT</pubDate></item><item><title>Agent 看不懂的 codebase，就是壞掉的 codebase——agentic 時代的易讀性筆記</title><link>https://southern-light.dev/blog/agent-codebase-codebaseagentic/</link><guid isPermaLink="true">https://southern-light.dev/blog/agent-codebase-codebaseagentic/</guid><description>前陣子我讓 Claude 在 Futari 的 codebase 裡加一個小功能——「在 trip detail 頁加一個 end trip 按鈕」。結果它跑去翻了 、然後翻了 、然後翻了 、然後翻了 、然後翻了 ——花了我大概 40k tokens 才開始動工。我看著 token meter 跳，心裡只有一個念…</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate></item><item><title>把 /battle 從「能跑」升級成「會挑兵」——順便給 Wildcard 寫了一本野外手冊</title><link>https://southern-light.dev/blog/battle-wildcard/</link><guid isPermaLink="true">https://southern-light.dev/blog/battle-wildcard/</guid><description>之前 Wildcard 的 /battle 流程，老實說是個直線：點開、拍照、出牌、結算。沒有「我手上有什麼牌」這件事——每場對戰都從零開始，像每天早上忘記昨晚自己存了什麼進冰箱（然後又買一次牛奶）。這次把 deck 接進來，順便發現一堆藏在 IndexedDB 角落裡的孤兒。</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate></item><item><title>那天我把 CWMoney 用戶從十年前的記帳 app 救出來</title><link>https://southern-light.dev/blog/cwmoney-app/</link><guid isPermaLink="true">https://southern-light.dev/blog/cwmoney-app/</guid><description>friend test 之後最常聽到的回饋是——「我用 CWMoney / Spendee / Honeydue 十年了，要我換 app？資料怎麼辦？」。然後我打開 CWMoney 的 export，看到一份 utf-16 編碼、欄位順序跟它 UI 完全不一樣、日期格式長得像  的 CSV——我懂了，這不是「換 …</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 1.0.0 上線了——順便聊聊我在 friend test 收尾那天幹了什麼</title><link>https://southern-light.dev/blog/futari-100-friend-test/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-100-friend-test/</guid><description>friend test 一開始我以為會是「拿到反饋、改幾個 bug、發版」這種純粹的事。結果反饋進來、自己再點一遍 app，發現問題不是 bug——是整個 sign-in 頁長得像一個 2019 年沒人維護的 side project。然後是 i18n 沒做完、RLS 有洞、prod log 飆紅、CDN 拿 1…</description><pubDate>Sun, 17 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 終於記得錢「進來」也是一筆 transaction：IncomeTransactions 上線</title><link>https://southern-light.dev/blog/futari-transactionincometransactions/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-transactionincometransactions/</guid><description>Futari 之前只記得錢「出去」——進帳？哦，那只是「balance 自己變大」這個結果</description><pubDate>Sun, 17 May 2026 00:00:00 GMT</pubDate></item><item><title>為什麼旅行不能用主帳本記？——一條 sub-ledger 在 7 版內長出來的全紀錄</title><link>https://southern-light.dev/blog/sub-ledger-7/</link><guid isPermaLink="true">https://southern-light.dev/blog/sub-ledger-7/</guid><description>老實說，「旅行」這題我一開始想當鴕鳥。Futari 是個記帳工具，旅行支出理論上就是普通 transaction、加個 tag 不就好了？兩週前我還這樣覺得。</description><pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate></item><item><title>從一張卡開始：Wildcard 的牌組系統，跟 jsdom 的 Blob 吵了一架</title><link>https://southern-light.dev/blog/wildcard-jsdom-blob/</link><guid isPermaLink="true">https://southern-light.dev/blog/wildcard-jsdom-blob/</guid><description>老實說，一個對戰遊戲沒有「自己的牌組」就只是個用相機拍石頭的玩具——這件事我其實心裡有數，只是一直假裝沒看到。直到  每次都得重新拍照才能出牌，我才認真坐下來把 deck system 補起來。</description><pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate></item><item><title>多幣別才上線 14 小時，就被我自己收回去——v0.17.2 / v0.17.3 的反向收斂日</title><link>https://southern-light.dev/blog/14-v0172-v0173/</link><guid isPermaLink="true">https://southern-light.dev/blog/14-v0172-v0173/</guid><description>&lt;p&gt;老實說——昨天凌晨 00:37 才 ship 完 v0.17.1、把 &lt;code&gt;CurrencySelector&lt;/code&gt; 接到 AddSheet 上、自己看著 &lt;code&gt;¥5,000 ≈ NT$1,110&lt;/code&gt; 即時 render 還很感動。&lt;strong&gt;結果今天中午自己 dogfood…</description><pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate></item><item><title>把「房子」這個 type 從佔位符變成會講話的人：Futari 第七種愛物落地</title><link>https://southern-light.dev/blog/type-futari/</link><guid isPermaLink="true">https://southern-light.dev/blog/type-futari/</guid><description>老實說——TypePicker 裡那塊「房子」tile 已經在那邊冷板凳坐了快兩個版本，按下去長一個跟車子幾乎一樣的 form，存下去之後 detail page 一片白——對，就是那種「功能是有，但你按了會懷疑自己是不是按錯」的 type。第七種愛物（物品）都先它一步落地了，房子還在當佔位符——這次決定把它從 …</description><pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 開發日誌 1：從零開始，到定期收入落地</title><link>https://southern-light.dev/blog/futari-1/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-1/</guid><description>五月二號，我坐下來開始動手。</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 開發日誌 2：從定期收入到加權分攤落地</title><link>https://southern-light.dev/blog/futari-2/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-2/</guid><description>v0.8.0 剛出，我沒有停下來。</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 開發日誌 3：離開也保留陪伴，守護成為自己的模組</title><link>https://southern-light.dev/blog/futari-3/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-3/</guid><description>v0.14.2 merge 進來那天，我停下來看了一眼 backlog。</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate></item><item><title>一天發四個版本、外加把多幣別跟旅行帳本一次寫穿——v0.16.2 到 v0.17.1 的長日</title><link>https://southern-light.dev/blog/v0162-v0171/</link><guid isPermaLink="true">https://southern-light.dev/blog/v0162-v0171/</guid><description>說真的，「Futari 不支援多幣別」這個事實一直讓我有點難解釋。我自己住台北、用台幣，邏輯上沒問題——可是兩個禮拜前測試使用者一句「我們下個月要去東京，所有 JPY 開銷怎麼記？」當場把我問住。寫成台幣 ÷ 4.5、心算成日圓？再認真的伴侶過兩個月都會放棄、回去用 Excel。Futari 一直定位是「兩個人的…</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate></item><item><title>在 wildcard 蓋一座牌組系統前，我先蓋了三把鏟子</title><link>https://southern-light.dev/blog/wildcard/</link><guid isPermaLink="true">https://southern-light.dev/blog/wildcard/</guid><description>牌組系統的 spec 寫到一半，我才意識到 wildcard 還是一個沒有任何測試的專案——所以這個 feature 的第一個 commit，不是 createCard，而是 。是的，在我打算讓使用者用相機把照片變成卡片之前，我得先說服 jsdom 接受 （它不接受，要 polyfill），還要哄 Indexed…</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate></item><item><title>把 1205 行的 ChatSessionView 拆成人類看得懂的形狀</title><link>https://southern-light.dev/blog/1205-chatsessionview/</link><guid isPermaLink="true">https://southern-light.dev/blog/1205-chatsessionview/</guid><description>VanishWhisper 的 ChatSessionView 不知不覺長到 1205 行——我那種「之後一定會重構」的之後，永遠是還沒到。每次想加一個小功能都要先深呼吸三次，怕碰錯一行就連帶吹掉貼圖面板、燈箱、刪除確認 banner 三個東西。</description><pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate></item><item><title>把保險從愛物裡搬走、再給愛物加上第七種——v0.16.0 的兩件事</title><link>https://southern-light.dev/blog/v0160/</link><guid isPermaLink="true">https://southern-light.dev/blog/v0160/</guid><description>&lt;p&gt;老實說——「保險是愛物嗎」這題我糾結很久。前面六種愛物：車、房、孩子、寵物、植物，再加保險，我們的 spec 本來都歸在同一張 &lt;code&gt;Assets&lt;/code&gt; 表底下。從 schema 看起來理直氣壯——一張 base table + 1:1 detail table per type，&lt;stron…</description><pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate></item><item><title>一個 1517 行的 AssetSheet、64 個 useState、跟一條走丟的章節線</title><link>https://southern-light.dev/blog/1517-assetsheet64-usestate/</link><guid isPermaLink="true">https://southern-light.dev/blog/1517-assetsheet64-usestate/</guid><description>說真的——昨天才剛 ship 、把「關係章節」這個概念寫進 schema，結果今天打開自己的  頁面，看到的不是完整的人生。 上線之後，從 X 邀請別人組 group 的角度看歷史是 ok 的：X 的過去章節、X 的現在章節，都在。但 Y 的角度——那個被留下後又拿到新 solo group 的人——看到的是空白頁。</description><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate></item><item><title>我自己刻了一個 numpad，然後一週後把它砍掉</title><link>https://southern-light.dev/blog/numpad/</link><guid isPermaLink="true">https://southern-light.dev/blog/numpad/</guid><description>Futari 的記帳 sheet 一開始長這樣：底部彈出一張卡，金額是大大的 NT$ hero，下面是我親手刻的九宮格 numpad——每顆按鈕都有 active state、有 haptic 感、還能長按連刪。我那時還挺得意的（畢竟 designer mode 全開）。</description><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate></item><item><title>「如果有一天你們分開了，這個 app 會怎樣？」——v0.15.0 把這題寫進 schema</title><link>https://southern-light.dev/blog/app-v0150-schema/</link><guid isPermaLink="true">https://southern-light.dev/blog/app-v0150-schema/</guid><description>老實說我以前刻意不去想這題。Futari 是給兩個人用的家計簿——伴侶、夫妻——可是伴侶會分開啊。我之前的設計裡，「離開群組」這個 action 根本不存在：你不能離開、不能把對方踢掉、不能換 partner。要嘛繼續用、要嘛兩個人各自把帳號棄掉。這對「兩個人的信任」這個 pitch 來說，是個很尷尬的盲點——你…</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate></item><item><title>當「樹葉、石頭、剪刀」變成多人戰場——一段 Firestore 跟 Vision API 的纏鬥</title><link>https://southern-light.dev/blog/firestore-vision-api/</link><guid isPermaLink="true">https://southern-light.dev/blog/firestore-vision-api/</guid><description>原本 wildcard 是個我自己玩開心的小東西——拍一張石頭、剪刀、或樹葉的照片（對，原本是雲朵，但你能想像在台北市區到底要去哪拍雲），丟給 Google Vision API 辨識類型，然後跟系統比一場猜拳。問題來了：朋友想加入。「給我一個 link 我也玩」——好啊，能多難。</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate></item><item><title>我把兩個 PR ship 出去又自己 revert 回來——v0.14.x 的長日</title><link>https://southern-light.dev/blog/pr-ship-revert-v014x/</link><guid isPermaLink="true">https://southern-light.dev/blog/pr-ship-revert-v014x/</guid><description>老實說這天的 git log 看起來像我發了 v0.14.1，半小時後又 reverted 兩個 feature，然後改成 release v0.14.2——對，就是這麼荒謬。如果你只看 tag history 大概會以為我在玩什麼版本號疊疊樂，但實情是：兩個明明測過會動的 feature，merge 進 mai…</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate></item><item><title>VanishWhisper 在 Threads 裡開，會把使用者的身分整個吃掉</title><link>https://southern-light.dev/blog/vanishwhisper-threads/</link><guid isPermaLink="true">https://southern-light.dev/blog/vanishwhisper-threads/</guid><description>原因是這樣：Threads / Instagram / Facebook / LINE / WeChat / TikTok / X 這些 app 都用自己的 sandboxed webview 開外部連結。在那個 webview 裡寫進 IndexedDB 的東西——你的 RSA private key、所有 s…</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 的餘額不再撒謊：把 balance 從「另存一欄」改成「每筆交易後重算」</title><link>https://southern-light.dev/blog/futari-balance/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-balance/</guid><description>寫情侶帳本最荒謬的事，就是你以為「兩人之間誰欠誰多少」是一個欄位——你 INSERT 一筆 transaction，順手 UPDATE 一下 group balance，搞定。然後某天你 soft-delete 一筆舊帳，UPDATE 漏掉了，畫面上的數字就開始撒謊——而最尷尬的是，撒謊對象是你另一半。</description><pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate></item><item><title>一個信任宣示頁，怎麼一路長成 v0.13.x 的雙向確認儀式</title><link>https://southern-light.dev/blog/v013x/</link><guid isPermaLink="true">https://southern-light.dev/blog/v013x/</guid><description>說起來其實有點不好意思——我之前在 Settings 裡面有一個叫「使用條款」的連結，點下去是 dead link。對，沒錯，一個記帳 app 的法律入口 404。要不是 doc-keeper 那輪 sweep 把這顆地雷翻出來，我可能還會繼續讓它躺在那裡，等某個認真的伴侶點下去然後決定把這個 app 從手機刪掉。</description><pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate></item><item><title>從 64 種暱稱卡到 900 種，順便偷學 vercel-labs 的 skills 規矩</title><link>https://southern-light.dev/blog/64-900-vercel-labs-skills/</link><guid isPermaLink="true">https://southern-light.dev/blog/64-900-vercel-labs-skills/</guid><description>說真的，我之前的 random nickname pool 只有 8×8 = 64 種組合，玩個幾局就會撞到一樣的「靜謐石頭」、「微涼樹枝」——不是說重複很糟啦，但 Wildcard 野地對戰本來就是「帶你的石頭來」這種 vibe，結果系統幫你取的名字比石頭還少，畫面有點微妙。</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate></item><item><title># 一天 72 個 commit 的後遺症：把 Futari 從 0.8.1 推到 0.11.3</title><link>https://southern-light.dev/blog/72-commit-futari-081-0113/</link><guid isPermaLink="true">https://southern-light.dev/blog/72-commit-futari-081-0113/</guid><description>說來有點荒謬——我寫了好幾個月的 Futari，結果連  都被自己的 middleware 一腳踢去 。對，整站 SEO 等於零。Google bot 來敲門，被我 307 redirect 到登入頁，看一眼就走了，連 sitemap 都沒機會吃到。一個對外行銷靠 organic 的 PWA，這真的不行。</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate></item><item><title>第五代程式語言 Fifth Genernation Language</title><link>https://southern-light.dev/blog/fifth-genernation-language/</link><guid isPermaLink="true">https://southern-light.dev/blog/fifth-genernation-language/</guid><description>每隔一段時間，我們寫程式的方式就會被重新定義一次。</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate></item><item><title>Futari 的地基：從 Drizzle migration 到 RLS，一天搭完的 infra 紀錄</title><link>https://southern-light.dev/blog/futari-drizzle-migration-rls-infra/</link><guid isPermaLink="true">https://southern-light.dev/blog/futari-drizzle-migration-rls-infra/</guid><description>說真的，「先把 auth 搞定再說」這句話我講了多少次，然後就跳過去——直到 Futari 真正要送出第一個 commit 的那天。</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate></item><item><title>從 `new Buffer()` 的陰影走出來：用 AES-256-GCM 保護家庭帳本的敏感欄位</title><link>https://southern-light.dev/blog/new-buffer-aes-256-gcm/</link><guid isPermaLink="true">https://southern-light.dev/blog/new-buffer-aes-256-gcm/</guid><description>一個記帳 app，不加密也沒人在乎——直到你意識到你把伴侶的消費明細明文存在資料庫裡，然後默默把那個念頭壓下去。</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate></item><item><title>從「我要用最先進的工具組」到「OK...，run first」</title><link>https://southern-light.dev/blog/okrun-first/</link><guid isPermaLink="true">https://southern-light.dev/blog/okrun-first/</guid><description>一個新 side project 的 initial commit 永遠是最令人興奮的——所有架構都還是完美的，還沒踩任何坑。然後第二個 commit 就把你拉回現實。</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate></item><item><title>帳本的靈魂不在 UI，在那三個純函式</title><link>https://southern-light.dev/blog/ui/</link><guid isPermaLink="true">https://southern-light.dev/blog/ui/</guid><description>一開始的問題很具體：兩個人共用帳本，誰欠誰多少錢？——聽起來很簡單，直到你開始寫 code，才發現「觀點」才是最麻煩的事。</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate></item><item><title>換了裝置，名字全消失了——VanishWhisper 的加密 label 搬家</title><link>https://southern-light.dev/blog/vanishwhisper-label/</link><guid isPermaLink="true">https://southern-light.dev/blog/vanishwhisper-label/</guid><description>以前換新手機之後，VanishWhisper 裡每個聊天都變回冷冰冰的 UID prefix——「你幫我取名叫 Alice 的那個人」變成 ，要你自己想起來那是誰。Sessions 搬過去了，名字沒有。這根本是在整自己。</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate></item><item><title>Wildcard 野地對戰：用石頭樹葉打架，Vision API 幫你出牌</title><link>https://southern-light.dev/blog/wildcard-vision-api/</link><guid isPermaLink="true">https://southern-light.dev/blog/wildcard-vision-api/</guid><description>一開始的 commit message 叫做「racing car 1」——沒有 1 之前的版本，沒有任何說明，只有一輛不知道要開去哪的車。這就是 Wildcard 野地對戰的誕生。</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate></item><item><title>從設計文件到 AES-256-GCM：Oikos 的第一批 commits 都在解決「信任問題」</title><link>https://southern-light.dev/blog/aes-256-gcmoikos-commits/</link><guid isPermaLink="true">https://southern-light.dev/blog/aes-256-gcmoikos-commits/</guid><description>說真的，大部分 side project 死在同一個地方：第一個 commit 之後的第三天。</description><pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate></item><item><title>VanishWhisper：兩年前的 Firebase 空殼，現在有了完整的 E2E 加密和消失訊息</title><link>https://southern-light.dev/blog/vanishwhisper-firebase-e2e/</link><guid isPermaLink="true">https://southern-light.dev/blog/vanishwhisper-firebase-e2e/</guid><description>兩年前我在 Firestore 建了個 repo，然後什麼都沒發生——直到最近。</description><pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate></item><item><title>我幾乎沒寫任何 code，但這個 side project 的每個架構決策都是我的</title><link>https://southern-light.dev/blog/code-side-project/</link><guid isPermaLink="true">https://southern-light.dev/blog/code-side-project/</guid><description>我是後端工程師，最近做了第一個前端 side project——VanishWhisper，一個端對端加密的閱後即焚聊天 app。整個開發過程我幾乎沒有親手打過任何 code，commit message 也是 Claude 寫的，測試也是，我頂多負責在手機上戳一戳看有沒有壞掉。</description><pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate></item><item><title>Hello, world</title><link>https://southern-light.dev/blog/hello-world/</link><guid isPermaLink="true">https://southern-light.dev/blog/hello-world/</guid><description>This is the first post on Southern Light. The site is built with Astro, served from GitHub Pages, and writes posts via labelled GitHub Issues.</description><pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate></item></channel></rss>