[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"store-me":-1,"$f26mj3f5tazdwk":3},{"post":4,"surround":389},{"id":5,"title":6,"answer":7,"body":8,"cluster":356,"date":357,"description":358,"draft":359,"extension":360,"faq":361,"meta":377,"navigation":378,"path":379,"search":380,"seo":381,"stem":382,"tags":383,"updated":380,"__hash__":388},"blog\u002Fblog\u002Fvibe-coding-pet-booking-system.md","自己用 AI 做一套寵物預約系統，可行嗎？","可行，但要知道自己在賭什麼。預約系統大部分的嚴重錯誤都不會報錯——超賣、 取消的訂單繼續佔房、跨時區算錯營業日、別人改得動你的訂單，畫面上全部 看起來正常。AI 生成的程式能通過示範，不代表它在兩個人同時按下預訂時是對的。",{"type":9,"value":10,"toc":344},"minimark",[11,19,22,28,31,34,39,42,45,52,63,66,72,76,79,86,89,96,100,103,106,109,113,116,123,136,143,146,153,157,255,261,264,267,288,291,297,301,304,324,327,336],[12,13,14,15],"p",{},"先講結論：",[16,17,18],"strong",{},"可行，但要知道自己在賭什麼。",[12,20,21],{},"我寫程式第四年，現在在做的就是一套寵物住宿與美容的預約系統。這篇不是要說「外行不要碰」——我看過店家自己用 AI 做出來的東西真的在收單，也真的解決了他們原本用紙本和訊息對帳的痛苦。",[12,23,24,25],{},"我想講的是另一件事：",[16,26,27],{},"預約系統大部分的嚴重錯誤，都不會報錯。",[12,29,30],{},"這是它跟多數小工具最大的差別。一個算錯的報表，你打開就看到數字怪怪的。一個排版跑掉的頁面，你一眼就知道。但預約系統出事的時候，畫面上通常一切正常——直到客人帶著狗站在你櫃檯前。",[12,32,33],{},"下面四個是我在自己這套系統裡真的踩過、或是特地寫防護擋住的地方。",[35,36,38],"h2",{"id":37},"一超賣兩個人訂到同一間房","一、超賣：兩個人訂到同一間房",[12,40,41],{},"這是預約系統唯一真正致命的問題。",[12,43,44],{},"AI 生成的程式幾乎都長這樣：先查這間房那幾天有沒有空，有空就寫入訂單。讀起來完全合理，示範也一定會過。",[12,46,47,48,51],{},"問題在那兩個動作",[16,49,50],{},"中間有一段空隙","。兩個客人同時按下預訂，兩邊都查到「有空」，然後兩邊都寫入成功。那段空隙只有幾十毫秒，所以你自己測十次可能一次都撞不到——但一家生意好的店，週五晚上就是會有兩個人同時在看同一間房。",[12,53,54,55,58,59,62],{},"正確的做法是在",[16,56,57],{},"同一個資料庫交易裡","先鎖住「那一間房的那一天」，拿到鎖之後才計算。跨多天的訂單還要",[16,60,61],{},"依日期由小到大鎖","，不排序的話兩筆日期交錯的訂單會互相卡死。",[12,64,65],{},"這些都不是功能，是不變條件。你在功能表上看不到它，示範的時候也感覺不出差別，但它決定了這套系統能不能拿來做生意。",[12,67,68,71],{},[16,69,70],{},"怎麼自己測","：開兩個分頁，填好同一間房同一個日期，盡量同時按下送出。應該要一筆成功、一筆明確失敗。多試幾次。",[35,73,75],{"id":74},"二取消的訂單還佔著房間","二、取消的訂單還佔著房間",[12,77,78],{},"這個更陰，因為它連客訴都不會有。",[12,80,81,82,85],{},"查空房的時候要排除已取消、已逾時、被退回的訂單。漏掉任何一種，那間房就繼續被一筆早就不存在的訂單佔著——而",[16,83,84],{},"沒有任何錯誤訊息","。畫面正常、系統正常，只是那間房再也賣不出去。",[12,87,88],{},"店家會發現的症狀是「怎麼最近都沒人訂那間」。他會去檢查照片、檢查價格、檢查曝光，然後把問題歸給淡季。",[12,90,91,92,95],{},"我的處理方式是把「哪些狀態算佔位」定義成一份常數，所有查詢都用它，",[16,93,94],{},"禁止任何地方自己拼條件","。因為漏掉的那一次不會紅，只會安靜地少賣一間房。",[35,97,99],{"id":98},"三時區晚上八點以後下的訂單掉到隔天","三、時區：晚上八點以後下的訂單掉到隔天",[12,101,102],{},"台灣是 UTC+8。如果程式用世界標準時間去算「這是哪一天」，晚上八點之後下的訂單會被記到隔天——庫存就扣在錯的格子上。",[12,104,105],{},"這種錯有一半的時間是對的（早上到下午都正常），所以它會躲很久。而且它通常不是一個獨立的 bug，是散落在每一個碰到日期的地方：查空房、算幾晚、排提醒、報表分組。",[12,107,108],{},"AI 很會寫日期處理，但它不知道你的營業日是以哪個時區、幾點換日。這件事沒有人告訴它，它就會用預設值。",[35,110,112],{"id":111},"四權限改一個編號就看得到別人的資料","四、權限：改一個編號就看得到別人的資料",[12,114,115],{},"這是四項裡面唯一會變成法律問題的。",[12,117,118,119,122],{},"預約系統天生會存客人的姓名、電話，很多還存了毛孩的醫療備註與獸醫聯絡方式。而最常見的漏洞不是被駭客攻破，是",[16,120,121],{},"權限根本沒擋","：",[124,125,126,130,133],"ul",{},[127,128,129],"li",{},"網址上的訂單編號改一個字，就看得到別人的訂單",[127,131,132],{},"查詢參數帶上別家店的代號，就看得到別家店的客人名單",[127,134,135],{},"「這筆訂單屬於哪家店」是從前端送上來的，而前端送什麼是使用者決定的",[12,137,138,139,142],{},"第三點我自己踩過。改期那支功能一度沒有檢查店家範圍，任何登入的人都能改別家店的訂單，甚至把訂單搬進別家店的房間——那家店的日曆上會憑空多出一筆不屬於它的預約。修法是",[16,140,141],{},"店家身分一律從登入狀態決定，絕不從請求內容拿","。",[12,144,145],{},"還有幾個更細的：權限不足要回「找不到」而不是「沒有權限」（後者等於告訴對方「這個東西存在，你只是進不去」，可以拿來一筆一筆試）；沒有登入就能打的查詢要有次數上限，不然一支迴圈就能把你的資料庫或第三方額度耗光。",[12,147,148,149,152],{},"這些都不是「做完功能再加上去」的東西。它們要在每一支新端點寫出來的當下就在，而",[16,150,151],{},"靠人記得是行不通的","——我這邊是做成全站統一的攔截層，因為第 187 支端點不會有人記得。",[35,154,156],{"id":155},"那麼差在哪","那麼，差在哪？",[158,159,160,175],"table",{},[161,162,163],"thead",{},[164,165,166,169,172],"tr",{},[167,168],"th",{},[167,170,171],{},"自己用 AI 做",[167,173,174],{},"營運級系統",[176,177,178,189,200,211,222,233,244],"tbody",{},[164,179,180,184,187],{},[181,182,183],"td",{},"示範時",[181,185,186],{},"沒有差別",[181,188,186],{},[164,190,191,194,197],{},[181,192,193],{},"兩人同時下訂",[181,195,196],{},"多半兩筆都成立",[181,198,199],{},"一筆成功、一筆明確失敗",[164,201,202,205,208],{},[181,203,204],{},"取消之後",[181,206,207],{},"位子可能沒放回去，且不報錯",[181,209,210],{},"狀態判定集中在一處",[164,212,213,216,219],{},[181,214,215],{},"出錯時",[181,217,218],{},"通常沒有錯誤訊息",[181,220,221],{},"監控、健康檢查、失敗通知",[164,223,224,227,230],{},[181,225,226],{},"資料外流",[181,228,229],{},"權限多半靠前端藏起來",[181,231,232],{},"每支端點各自驗證身分與範圍",[164,234,235,238,241],{},[181,236,237],{},"改壞了",[181,239,240],{},"要靠人記得回頭檢查",[181,242,243],{},"自動測試擋住回頭路",[164,245,246,249,252],{},[181,247,248],{},"客人資料",[181,250,251],{},"在你自己的電腦或帳號裡",[181,253,254],{},"有備份、有匯出、有刪除流程",[12,256,257,260],{},[16,258,259],{},"最上面那一列是重點","：示範的時候兩者看不出差別。這就是為什麼「我用一個下午就做出來了」跟「這套可以拿來經營」之間的距離，比感覺上遠很多。",[35,262,263],{"id":263},"什麼時候自己做反而是對的",[12,265,266],{},"我不覺得所有東西都該買現成的。自己用 AI 做，在這三個條件同時成立的時候是很划算的：",[268,269,270,276,282],"ol",{},[127,271,272,275],{},[16,273,274],{},"只有自己人用"," —— 沒有外部使用者，就沒有權限與個資的問題",[127,277,278,281],{},[16,279,280],{},"不會有兩個人同時做同一件事"," —— 沒有併發，超賣那一整類問題就不存在",[127,283,284,287],{},[16,285,286],{},"算錯了當場改得掉"," —— 出錯的代價是重跑一次，不是得罪客人",[12,289,290],{},"符合的例子很多：員工排班表、月結報表、把 Excel 整理成另一種格式、貼文素材產生器。這些拿 AI 做又快又好，也不需要誰來審。",[12,292,293,296],{},[16,294,295],{},"預約系統剛好三個條件都相反","：對外開放、天生併發、算錯的代價是客人帶著狗到現場沒有房間。",[35,298,300],{"id":299},"給已經自己做了一套的店家三個問句","給已經自己做了一套的店家：三個問句",[12,302,303],{},"不用打掉重練，先問這三件事。有明確答案就繼續用，答不出來的那一項就是你接下來最可能出事的地方。",[268,305,306,312,318],{},[127,307,308,311],{},[16,309,310],{},"兩個人同時下訂會怎樣？"," ——「我試過，一筆成功一筆失敗」才算答案，「應該不會吧」不算",[127,313,314,317],{},[16,315,316],{},"取消之後那個位子有真的放回去嗎？"," —— 取消一筆，回去查那幾天的空房，數字要對得上",[127,319,320,323],{},[16,321,322],{},"改掉網址上的編號，看不看得到別人的資料？"," —— 自己試一次，三十秒就知道",[12,325,326],{},"這三個問題跟「你用什麼做的」無關。AI 做的、外包做的、買現成的，都該問得出來。",[12,328,329,330,335],{},"如果你正在比較現成的方案，",[331,332,334],"a",{"href":333},"\u002Fblog\u002Ffree-pet-booking-system-what-to-check","免費的寵物預約系統要看哪四件事","那篇講的是另一組問題——那四個問的是廠商的商業條件，這三個問的是系統的正確性，兩組不重疊。",[12,337,338,339,343],{},"想直接看一套已經在營運的系統長什麼樣，可以從",[331,340,342],{"href":341},"\u002Fpricing","方案與定價","那一頁進去。",{"title":345,"searchDepth":346,"depth":347,"links":348},"",2,3,[349,350,351,352,353,354,355],{"id":37,"depth":346,"text":38},{"id":74,"depth":346,"text":75},{"id":98,"depth":346,"text":99},{"id":111,"depth":346,"text":112},{"id":155,"depth":346,"text":156},{"id":263,"depth":346,"text":263},{"id":299,"depth":346,"text":300},"booking-system","2026-09-15","一位在職四年的軟體工程師，從超賣、時區、權限與快取四個實際會出事的地方，說明 AI 生成的預約系統跟營運級系統差在哪，以及什麼情況下自己做反而是對的。",false,"md",[362,365,368,371,374],{"q":363,"a":364},"AI 寫的預約系統會出現超賣嗎？","會，而且是最常見的一種。標準寫法是先查有沒有空房、再寫入訂單， 兩個動作之間有一段空隙，兩個人同時下訂就會兩筆都成立。 要避免必須在同一個資料庫交易裡鎖住那一間房的那一天再判斷， 而那不是「功能」，示範時也看不出來差別。",{"q":366,"a":367},"怎麼測試預約系統有沒有超賣問題？","開兩個瀏覽器分頁，填好同一間房、同一個日期，然後盡量同時按下送出。 正確的系統會有一筆成功、一筆明確失敗；有問題的會兩筆都成立。 多試幾次，因為那段空隙只有幾十毫秒，不是每次都撞得到。",{"q":369,"a":370},"自己做系統，客人的資料會有什麼風險？","最常見的不是被駭，是權限沒擋乾淨：網址上的編號改一個數字， 就看得到別家店或別位客人的姓名與電話。這種漏洞不會有錯誤訊息， 而且通常要等到有人發現才知道，那時資料已經外流一段時間了。",{"q":372,"a":373},"什麼情況下自己用 AI 做反而比較好？","只有自己人用、資料不外流、算錯了當場改得掉的東西——排班表、 內部報表、一次性的資料整理。這些場景沒有併發、沒有外部使用者、 出錯的代價是重跑一次。預約系統三個條件都相反。",{"q":375,"a":376},"已經自己做了一套，要怎麼判斷能不能繼續用？","問三件事：兩個人同時下訂會怎樣、取消的訂單有沒有真的把位子放回去、 別人改掉網址上的編號看不看得到別人的資料。三個都有明確答案就繼續用， 答不出來的那一項就是你接下來最可能出事的地方。",{},true,"\u002Fblog\u002Fvibe-coding-pet-booking-system",null,{"title":6,"description":358},"blog\u002Fvibe-coding-pet-booking-system",[384,385,386,387],"店家","預約系統","住宿","美容","C8kAdqr0j18FXNu2m72cdtHOz64kRVZXxLpUNGK-rpw",[380,390],{"title":391,"path":333,"stem":392,"description":393},"免費的寵物預約系統要看哪四件事？","blog\u002Ffree-pet-booking-system-what-to-check","免費方案的差別不在功能表長短，在碰到上限那天會發生什麼。用四個問句檢查免費的寵物旅館與美容預約系統，並看有我顧免費版實際包含與不包含的東西。"]