① 登入與主導航

flowchart LR A(["🌐 開啟系統\nlocalhost:3000"]) --> B{"已登入?"} B -- 否 --> C["🔐 login.html\n輸入 PIN"] C --> D{{"PIN 正確?"}} D -- 否 --> C D -- 是 --> E B -- 是 --> E E(["📋 訂單管理\norders.html\n(主頁)"]) E --> N1["禮服管理\ndresses.html"] E --> N2["財務報表\nfinance.html"] E --> N3["行事曆\ncalendar.html"] style A fill:#1a1a1a,color:#fff,stroke:#1a1a1a style E fill:#1a1a1a,color:#fff,stroke:#1a1a1a style C fill:#fef3c7,stroke:#d97706,color:#92400e style D fill:#fef3c7,stroke:#d97706,color:#92400e

② 預約參觀流程(每一位詢問的客人都從這裡開始)

flowchart TD Q(["📞 客人詢問\nIG私訊 / FB訊息 / LINE / 電話 / 現場走進來"]) --> A["+ 新增預約\ninquiries.html\n登記:怎麼得知我們+聯絡平台+需求類型\n⚠ 不管有沒有約成,每一筆詢問都要登記"] A --> B["約到參觀\n填預約日期+時間\n→ 自動出現在行事曆「參觀」"] A -. "約不到/已讀不回" .-> L["標記流失\n填流失原因\n⚠ 不要刪除紀錄"] B --> C["客人到店\n按「✓ 已到店」"] B -. "沒來(no-show)" .-> B2["改約日期\n或標記流失"] C --> D["成交 →「轉為訂單」\n姓名/電話/業務/客源自動帶入新訂單\n訂單建立成功才自動標記已轉訂單"] C -. "回去考慮" .-> E["持續跟進\n之後成交再轉訂單\n或標記流失"] S["📊 本月統計列(頁面上方)\n詢問 → 約參觀 → 已到店 → 成交\n以本月建立的詢問為分母"] style Q fill:#1a1a1a,color:#fff,stroke:#1a1a1a style A fill:#dbeafe,stroke:#93c5fd,color:#1e3a8a style D fill:#d1fae5,stroke:#6ee7b7,color:#064e3b style L fill:#fee2e2,stroke:#fca5a5,color:#991b1b style B2 fill:#fef3c7,stroke:#fcd34d,color:#78350f style S fill:#f5f5f4,stroke:#a8a29e,color:#57534e

③ 訂單管理流程

flowchart TD A0(["預約參觀成交\n→ 轉為訂單(資料自動帶入)"]) --> B A["📋 訂單列表\norders.html\n搜尋 / 篩選狀態 / 篩選業務"] --> B["+ 新增訂單\nadd-order.html"] A --> C["點擊訂單列\norder.html"] B --> B1["填寫資料\n新娘新郎 / 電話 / LINE\n服務方案 / 業務人員 / 客源"] B1 --> B2["重要日期\n預約來店 / 拍攝\n宴客 / 訂婚 / 歸寧"] B2 --> B5["建立訂單 →\norder.html\n⚡ 挑衣量身/取衣/還衣等禮服時程\n伺服器自動依拍攝/宴客日推算預設值"] C --> D["工作流程推進(依服務方案而異)\n訂單起點=已下定(詢問階段在預約參觀頁)\n⬇ 之後分兩條各跑各的\n📷 拍攝:確認檔期→通知挑衣→挑衣量身→修改完成\n→取衣 💰收尾款 →拍攝完成→還衣→選片→精修→送廠→拍攝結案\n🎊 宴客:確認檔期→通知宴客→挑衣量身\n→宴客取衣→宴客日→還衣→宴客結案\n(單租禮服:取衣後直接還衣→結案,跳過選片/精修/送廠)"] C --> E["收款紀錄\n+ 定金 / 尾款 / 加購款\n刪除紀錄"] C --> F["加購項目\n+ 名稱 / 數量 / 單價"] C --> G["指定禮服 →\n搜尋空閒禮服\n設定借出歸還日期"] C --> G2["禮服時程\n挑衣量身/取衣/還衣(拍攝+宴客各自)\n日期+時間,人工確認前為淺灰色\n確認後轉黑色、可能出現在行事曆"] C --> H["編輯基本資料\nadd-order.html?edit=ID"] C --> I["✕ 刪除整筆訂單\n連同付款/加購/禮服預約一併刪除\n二次確認"] style A fill:#f5f5f4,stroke:#a8a29e style D fill:#d1fae5,stroke:#6ee7b7,color:#064e3b style E fill:#fef3c7,stroke:#fcd34d,color:#78350f style G fill:#ede9fe,stroke:#c4b5fd,color:#4c1d95 style G2 fill:#ede9fe,stroke:#c4b5fd,color:#4c1d95 style I fill:#fee2e2,stroke:#fca5a5,color:#991b1b

④ 禮服管理流程

flowchart LR A["👗 禮服列表\ndresses.html\n搜尋 / 類型 / 狀態"] --> B["+ 新增禮服\nadd-dress.html"] A --> C["點擊禮服\ndress.html/:qr_code"] B --> B1["填寫\n名稱 / 類型 / 位置\n租借費用 / 備註"] B1 --> B2["儲存 → 產生 QR Code\n列印貼於吊牌"] QR(["📱 手機掃描 QR"]) --> C C --> C1{{"已登入?"}} C1 -- 否 --> C2["唯讀模式\n查看禮服資訊\n查看預約紀錄"] C1 -- 是 --> C3["完整功能\n+ 新增預約\n設定借出/歸還日期\n連結訂單(自動帶入姓名)"] A --> A1["✕ 刪除禮服\n無借用/預約紀錄才能刪除\n有紀錄則請改為「停用」"] style A fill:#f5f5f4,stroke:#a8a29e style QR fill:#1a1a1a,color:#fff,stroke:#1a1a1a style C2 fill:#f5f5f4,stroke:#d6d3d1,color:#78716c style C3 fill:#dbeafe,stroke:#93c5fd,color:#1e3a8a style A1 fill:#fee2e2,stroke:#fca5a5,color:#991b1b

⑤ 財務報表流程(四分頁)

flowchart LR A["💰 財務報表\nfinance.html"] --> R["📥 收入\n警示區/總覽\n全年預估收款/當月訂金\n未收款清單/業務業績"] A --> X["📤 支出\n本月拆帳卡(自動)\n新增帳務/帳務流水+合計列\n匯出 CSV 給記帳士"] A --> P["📆 付款排程\n⚠ 資金缺口預警\n每月固定項目自動生成\n付款打勾=自動記帳"] A --> L["🏦 貸款\n公司 7 筆/股東名義 3 筆\n剩餘本金・每月本息\n🔴 優先清償紅底標記"] R --> R1["點未收款列 →\norder.html 直接收款"] X --> X1["新增支出可選\n成本歸屬:本月/上月的帳"] P --> P1["下月已排應付 vs 下月預估收款\n缺口提前 30 天現形"] L --> L1["點 ✎ 編輯\n連動未付排程項"] style A fill:#f5f5f4,stroke:#a8a29e style P fill:#fef3c7,stroke:#fcd34d,color:#78350f style L fill:#fee2e2,stroke:#fca5a5,color:#991b1b style R1 fill:#d1fae5,stroke:#6ee7b7,color:#064e3b

⑥ 會計自動化(打勾一次,系統做完剩下的)

flowchart TD A["📆 付款排程\n付款打勾 ✓"] --> B{"項目類型?"} B -- "一般費用\n(有品牌+分類)" --> C["自動記一筆支出\n進帳務流水與損益"] B -- "月結/薪資類\n(↩歸上月標記)" --> D["自動記支出\n+成本歸屬上個月\n流水掛「歸X月」標籤"] B -- "公司貸款" --> E["利息 → 記利息支出(進損益)\n本金 → 剩餘本金遞減(不進損益)\n下期本息按銀行公式自動重算"] B -- "股東名義貸款\n/純提醒" --> F["只完成排程\n不記帳"] C --> G["取消打勾=全部復原\n(支出刪除・本金加回)"] D --> G E --> G H["📷 拍攝完成\n(訂單狀態)"] --> I["自動拆帳\nH→G 攝影費 18,000\nH→T 造型費 6,000"] I --> J["外包造型費\n下月 5 號自動加總成月結排程"] K["🧮 損益表(會計頁籤・CEO)\n支出按「歸屬月份」認列\n7月付的6月帳 → 算進6月成本"] style A fill:#1a1a1a,color:#fff,stroke:#1a1a1a style E fill:#fee2e2,stroke:#fca5a5,color:#991b1b style D fill:#fef3c7,stroke:#fcd34d,color:#78350f style I fill:#ede9fe,stroke:#c4b5fd,color:#4c1d95 style K fill:#d1fae5,stroke:#6ee7b7,color:#064e3b

⑦ 行事曆流程

flowchart LR A["📅 行事曆\ncalendar.html\n月份切換 ← →\n月曆/列表 兩種檢視"] --> B["🔵 預約參觀\n預約參觀的日期+時間\n(訂單的預約來店不上行事曆)"] A --> C["🟣 拍攝挑衣\n訂單 fitting_date\n★需人工確認才顯示"] A --> C2["🩷 宴客挑衣\n訂單 event_fitting_date(宴客前60天)\n★需人工確認才顯示"] A --> D["🟢 拍攝\n訂單 shoot_date"] A --> D2["🟣 拍攝取衣\n訂單 pickup_date(拍攝前1天)\n★需人工確認才顯示"] A --> E["🟡 宴客(含訂婚、歸寧)\n訂單 event_date / engagement_date / return_date"] A --> E2["🟡 宴客取衣\n訂單 event_pickup_date(宴客前1天)\n★需人工確認才顯示"] A --> G["⬜ 禮服歸還\n拍攝還衣+1天/宴客還衣+1天/禮服預約 end_date\n三種來源合併顯示同一標籤\n★即使未確認也顯示,但走過還衣步驟後自動消失"] B --> H2["點擊 →\ninquiry.html\n(該筆預約參觀)"] C --> H["點擊 →\norder.html"] C2 --> H D --> H D2 --> H E --> H E2 --> H G --> I["點擊 →\norder.html/dress.html"] A --> J["同一天事件過多\n→ 展開 Popup 顯示全部"] A --> K["🔘 圖例可點擊切換顯示/隱藏\n+全選按鈕\n篩選設定存在瀏覽器本機"] style A fill:#f5f5f4,stroke:#a8a29e style B fill:#dbeafe,stroke:#93c5fd,color:#1e3a8a style C fill:#ede9fe,stroke:#c4b5fd,color:#4c1d95 style C2 fill:#fce7f3,stroke:#f9a8d4,color:#831843 style D fill:#d1fae5,stroke:#6ee7b7,color:#064e3b style D2 fill:#ede9fe,stroke:#c4b5fd,color:#4c1d95 style E fill:#fef3c7,stroke:#fcd34d,color:#78350f style E2 fill:#fef3c7,stroke:#fcd34d,color:#78350f style G fill:#f3f4f6,stroke:#d1d5db,color:#374151

⑧ 訂單工作流程狀態(下定後,各場次各跑各的)

客人下定之後最多分成四條各自獨立的流程:📷 拍攝、💍 訂婚、🎊 宴客、🏠 歸寧。
每條線有自己的「確認檔期」與挑衣/取衣/還衣時程,各自推進、互不等待,也各自結案; 訂婚/歸寧純粹是用衣事件(不掛收款),流程與宴客相同(下圖以宴客為代表)。
沒填日期的場次整條收起來,填了日期自動出現。禮服預約用途四選一(拍攝/訂婚/宴客/歸寧),各鎖各的檔期。

flowchart LR S0(["由預約參觀成交轉入\n(或直接開單)\n詢問/約參觀階段都在預約參觀頁"]) --> S3 S3["已下定\n💰 收訂金"] S3 ==> P0 S3 ==> E0 subgraph P ["📷 拍攝流程"] direction LR P0["確認檔期"] --> P1["📢 通知挑衣\n(拍攝前 30 天)"] P1 --> P2["挑衣量身"] P2 --> P3["修改完成"] P3 --> P4["取衣\n💰 收尾款"] P4 --> P5["拍攝完成"] P5 --> P6["還衣"] P6 --> P7["挑片日\n(還衣後 30 天)"] P7 --> P8["精修中\n(挑片日後 30 天完成)"] P8 --> P9["送廠製作\n(送廠後 14 天完成)"] P9 --> P9b["📦 取件\n(送廠製作完成後 21 天)"] P9b --> P10["✅ 拍攝結案"] P4 -. "單租禮服\n(無後製)" .-> PR["還衣"] PR --> P10 end subgraph E ["🎊 宴客流程"] direction LR E0["確認檔期"] --> E1["📢 通知宴客\n(宴客前 60 天)"] E1 --> E2["挑衣量身"] E2 --> E4["宴客取衣\n💰 單租禮服:收尾款"] E4 --> E5["🎊 宴客當天"] E5 --> E6["還衣(隔天)"] E6 --> E7["✅ 宴客結案"] end S3 -.-> X["❌ 取消"] style S3 fill:#fef3c7,stroke:#fcd34d,color:#78350f style P0 fill:#1a1a1a,color:#fff,stroke:#1a1a1a style E0 fill:#1a1a1a,color:#fff,stroke:#1a1a1a style P1 fill:#ffedd5,stroke:#fb923c,color:#7c2d12 style E1 fill:#ffedd5,stroke:#fb923c,color:#7c2d12 style P4 fill:#fef3c7,stroke:#fcd34d,color:#78350f style E4 fill:#fef3c7,stroke:#fcd34d,color:#78350f style P5 fill:#d1fae5,stroke:#6ee7b7,color:#064e3b style E5 fill:#fce7f3,stroke:#f9a8d4,color:#831843 style PR fill:#e0e7ff,stroke:#a5b4fc,color:#3730a3 style P10 fill:#d1fae5,stroke:#6ee7b7,color:#064e3b style E7 fill:#d1fae5,stroke:#6ee7b7,color:#064e3b style X fill:#fee2e2,stroke:#fca5a5,color:#991b1b

— 系統架構參考 · System Architecture Reference —

以下三張是給開發/維運看的架構圖,跟上面同事日常操作的流程圖是不同性質的內容

A. 資料表關係圖 Database Schema

SQLite,共 35 張表,依業務領域分組;箭頭是實際存在的關聯。

flowchart TB subgraph ORD["訂單核心"] orders["orders
訂單主表:四線日期/狀態/方案"] order_addons["order_addons"] order_dresses["order_dresses(未使用的舊表)"] order_staff["order_staff"] order_photos["order_photos"] order_logs["order_logs"] other_visits["other_visits"] alteration_forms["alteration_forms"] orders --> order_addons orders --> order_dresses orders --> order_staff orders --> order_photos orders --> order_logs orders --> other_visits orders --> alteration_forms end subgraph LEAD["客源/LINE"] inquiries["inquiries"] inquiry_logs["inquiry_logs"] line_threads["line_threads"] line_messages["line_messages"] inquiry_drafts["inquiry_drafts"] inquiries --> inquiry_logs line_threads --> line_messages line_threads --> inquiry_drafts end subgraph DRESS["禮服"] dresses["dresses"] dress_bookings["dress_bookings(真正的預約禮服表)"] dress_deposits["dress_deposits"] cost_package_dresses["cost_package_dresses"] dresses --> dress_bookings end subgraph STAFF["人員/權限"] staff["staff"] staff_leaves["staff_leaves"] staff_page_access["staff_page_access"] staff_permissions["staff_permissions"] role_page_access["role_page_access"] role_permissions["role_permissions"] staff --> staff_leaves staff --> staff_page_access staff --> staff_permissions end subgraph MONEY["財務/會計"] payments["payments"] acct_entries["acct_entries"] acct_accounts["acct_accounts"] acct_categories["acct_categories"] acct_split_rules["acct_split_rules"] acct_history_pl["acct_history_pl"] payable_templates["payable_templates(含貸款欄位)"] payable_items["payable_items"] cost_common_items["cost_common_items"] cost_labor_pools["cost_labor_pools"] cost_params["cost_params"] monthly_targets["monthly_targets"] payable_templates --> payable_items end subgraph OTHER["選片/方案設定"] photo_selections["photo_selections"] packages["packages"] rental_prices["rental_prices"] end orders --> payments orders -.event_pickup/shoot_date.-> dress_bookings orders --> photo_selections orders -. order_id .-> acct_entries orders -. order_id .-> dress_deposits inquiries -. converted_order_id .-> orders packages -.-> cost_package_dresses classDef grp fill:transparent,stroke:#00000000; class ORD,LEAD,DRESS,STAFF,MONEY,OTHER grp;

· orders 是樞紐,四條獨立工作線(拍攝/訂婚/宴客/歸寧)各自有挑衣/取衣/還衣日期
· inquiries → orders 是靠 converted_order_id 這個欄位對應,不是資料庫外鍵約束
· order_dresses 這張表存在但整個系統都沒在用,真正的禮服預約記在 dress_bookings

B. 系統架構圖 System Architecture

Node.js(Bun 執行)+ Express 5,session-based 登入。單一 SQLite 檔案,前端是多頁 vanilla JS,外部只接 Google Gemini 與 LINE Messaging API。

flowchart LR subgraph CLIENT["瀏覽器/PWA"] pages["21 個 public/*.html
+ common.js 共用邏輯"] end subgraph SRV["server.js(Express, session auth)"] routes["routes/api/*.js
21 個路由檔,依領域拆分"] end subgraph DB["SQLite(goodluck.db)"] rw["db/database.js
可讀寫連線"] ro["db/readonly.js
唯讀連線・只給 Agent 用"] end subgraph AI["Google Gemini API"] flash["gemini-3.6-flash
全站小助理"] imagegen["gemini-3-pro-image
AI Studio(JOHNNY)"] vision["gemini-pro-latest
合約辨識/LINE 草稿判讀"] end subgraph LINEP["LINE Messaging API"] oa["三品牌官方帳號
GOODLUCK/HERMOSA/TAUXI"] end ngrok["ngrok 通道(本機開發環境對外)"] pages <-->|"fetch / session cookie"| routes routes --> rw routes -->|"僅 agent.js"| ro routes -->|"/api/agent/*"| flash routes -->|"/api/agent/studio"| imagegen routes -->|"contract.js/line-core.js"| vision oa -->|"webhook"| ngrok --> routes routes -->|"reply / push"| oa classDef ext fill:transparent,stroke-dasharray:3 3; class AI,LINEP,ngrok ext;

· 唯讀原則:agent.js 是全系統唯一走 db/readonly.js 的路由,SQLite 連線層級擋死寫入語句
· 資料庫下載防護:server.js 在 express.static 之前擋掉任何 .db/.sqlite 副檔名的請求(含 URL 編碼繞過)

C. Agent 架構圖 Agent Architecture

系統裡有四組會呼叫 Gemini 的代理流程。核心原則:工具化查詢、不用 NL2SQL;任何會寫入真實業務資料的動作都卡一道人工確認。

flowchart TB U1["同事在任一頁面
點浮動小助理"] --> A1 U2["JOHNNY 點小標籤"] --> A2 L1["LINE 客人傳訊息"] --> A3 U3["新增訂單頁
拍照上傳合約"] --> A4 subgraph A1["全站小助理 /api/agent/ask"] direction TB a1m["gemini-3.6-flash
+ Google 搜尋接地"] a1t["13 支唯讀工具"] a1g["每支工具掛 canAccess(page)"] a1m --- a1t --- a1g end subgraph A2["AI Studio /api/agent/studio"] direction TB a2m["gemini-3-pro-image
(無搜尋)"] a2t["同 13 支工具 + run_sql_query
(僅 JOHNNY)"] a2o["文字/生圖/改圖/讀圖
同一輪自動判斷"] a2m --- a2t --- a2o end subgraph A3["LINE 自動建單 line-core.js"] direction TB a3m["gemini-3.6-flash"] a3d["判讀訊息 → 草稿欄位"] a3h["寫入 inquiry_drafts
(待人工確認)"] a3m --> a3d --> a3h end subgraph A4["合約辨識 contract.js"] direction TB a4m["gemini-pro-latest(vision)"] a4d["結構化欄位抽取"] a4m --> a4d end a1g -->|"僅讀取,不落地"| END1(( )) a2o -->|"僅讀取/生成,不落地"| END2(( )) a3h -->|"人工確認才寫進 inquiries"| CONFIRM1["👤 人工確認"] a4d -->|"帶回 add-order.html 人工核對"| CONFIRM2["👤 人工確認"] style END1 fill:transparent,stroke:transparent style END2 fill:transparent,stroke:transparent

· 成本/拆帳(get_cost_and_split)與 run_sql_query 都標記 ceoOnly,只有 JOHNNY 能用
· 13 支共用工具依 tool.page 對照 staff_page_access,跟同事看到的頁面權限是同一套矩陣