goalu 寫入權矩陣(階段 1 硬門檻)

一句話:198 張活表中 47 張有兩個以上應用程式在寫,其中 hcusthcust_trd 各有 7 個 writer; david@%tom@% 目前是 GRANT ALL PRIVILEGES ON *.*(全域超權,不限 goalu), 只有 salary_app 已收斂成最小權限。這份矩陣是階段 1 帳號拆分與階段 2 CI 攔檢的共同依據。

產生日期:2026-08-18 · 資料來源:真實 DB(information_schema)+ 全站靜態掃描 · 重生指令見文末〈可重跑〉一節(矩陣必須可重生,不可手改後漂移


1. 摘要

指標數量
goalu 表總數579 張(+25 views)
活表(近 90 天有寫入,本矩陣範圍)198
冷表(90 天無寫入,另案處理)381 張
🔴 兩個以上 app writer47
🟢 單一 app writer103 張
⚪ 無 app writer(DB 內部寫或待確認)48 張(其中 14 張由 SP/EVENT/TRIGGER 寫)
DB 內部寫入層68 個 PROCEDURE 有寫入、20 個 EVENT(全 ENABLED)、8 個 TRIGGER

2. 站台 × DB 帳號現況

站台目錄DB 帳號目前權限狀態
ERP(kngoatmilk)/var/www/kngoatmilk/prod/htmldavidALL ON *.*🔴 待拆
html/salary/var/www/html/salarydavid(明碼寫在 include/cndb.phpALL ON *.*🔴 待拆
html/report/var/www/html/reportdavid(明碼 include/cndb.phpALL ON *.*🔴 待拆
html/sales/var/www/html/salesdavid(明碼 include/cndb.phpALL ON *.*🔴 待拆
html/sony/var/www/html/sonydavid(明碼 admin/_inc/config.phpALL ON *.*🔴 待拆
kng.tw/var/www/kng.tw/public_htmldavid(明碼 api/db.phpALL ON *.*🔴 待拆
www.kngoatmilk.com/var/www/www.kngoatmilk.comdavid(env DB_ERP_USER)ALL ON *.*🔴 待拆
forms/var/www/forms.kngoatmilk.comdavidALL ON *.*🔴 待拆
line/var/www/line.kngoatmilk.comdavidALL ON *.*🔴 待拆
invoice/var/www/invoicedavidALL ON *.*🔴 待拆
delivery/var/www/delivery.kngoatmilk.comdavidALL ON *.*🔴 待拆
pbx/var/www/pbx.kngoatmilk.comdavidALL ON *.*🔴 待拆
pbx-laravel12/var/www/pbx-laravel12davidALL ON *.*🔴 待拆
inventory/var/www/inventory.kng.twtomALL ON *.*🔴 待拆
story/var/www/story.kng.twtomALL ON *.*🔴 待拆
salary(new)/var/www/salarysalary_app9 條表級最小權限✅ 已完成(範本)
salary 測試/var/www/salary (phpunit)salary_test_roSELECT ON goalu.*✅ 已完成
(唯讀工具)dbview / MCPdbview_ro、mcp_roSELECT ON goalu.*✅ 唯讀

🔴 david@%tom@%ALL ON *.*——不只 goalu,整台 MariaDB 全庫可寫(含 callhub、muxue、lk、shop…)。 拆帳號時第一步是把 *.* 收成 goalu.*,再逐站收到表級。

3. 核心表矩陣

欄位說明:W=寫入者(Insert/Update/Delete/Replace/Truncate);R=讀取者; DB 內部=SP/EVENT/TRIGGER 寫入(這些繞過應用層,拆帳號時 DEFINER 要一併確認)。

站台縮寫:sal=html/salary ERP=kngoatmilk rpt=html/report sls=html/sales sony=html/sony

家戶客戶/訂單/帳務 (42 張,其中 19 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
hcustsal:DIU ERP:DIU sls:IU www:DIU forms:IU dlv:IU invt:Urpt kng line inv pbx pbx12SP×6 / ⚡本表有 trigger×6🔴 多 writer
hcust_trdsal:IU ERP:DIU sls:DIU www:DIU forms:IU inv:IU invt:DIrpt pbx pbx12TG:update_addr_log@hcust,update_area_log@hcust,update_comp_idno_log@hcust,update_lv_tp_log@hcust,update_rv_tp_log@hcust / SP×13🔴 多 writer
hcust_dorderERP:DIU sls:IU www:DIU forms:IUsal rpt invSP×3 / ⚡本表有 trigger×1🔴 多 writer
paymentsal:DIU sls:IU www:IU line:IUformsSP×1🔴 多 writer
address_book_indexessal:DU ERP:DU line:Irpt www inv dlv🔴 多 writer
customerssal:DU ERP:DIU line:IUrpt www inv dlv pbx pbx12🔴 多 writer
hcust_tokensal:D www:DIU line:DIUERP rpt🔴 多 writer
tradessal:DIU ERP:DIU www:IUrpt line invSP×4🔴 多 writer
address_bookssal:DU ERP:DIrpt www line🔴 多 writer
apart_salessal:IU inv:IUrpt sls forms🔴 多 writer
change_resourcessal:I ERP:Irpt🔴 多 writer
contactssal:D ERP:DIU🔴 多 writer
cub_rcvsal:IU ERP:Iwww line🔴 多 writer
cub_recordsal:I ERP:I🔴 多 writer
customer_evenssal:D ERP:DIU🔴 多 writer
customer_price_detailssal:I ERP:IUinv🔴 多 writer
customer_pricessal:I ERP:IUinv🔴 多 writer
hcust_antERP:I inv:Usal rpt sls www lineEV:dvm_bill_auto_post / SP×7🔴 多 writer
order_recordssal:D ERP:Irpt🔴 多 writer
apart_compinv:IUsal rpt sls forms🟢 單一
cub_estimatesal:I🟢 單一
customer_phone_indexsal:DIT🟢 單一
customer_pmsERP:DIsal invSP×2🟢 單一
customer_pre_jobsERP:I🟢 單一
customer_price_templatesERP:IU🟢 單一
customers_gpssal:IU🟢 單一
hcust_amt_preERP:IUsal www invSP×8🟢 單一
hcust_amt_rcvERP:DIUsal line invEV:dvm_bill_auto_post / SP×7🟢 單一
hcust_ant_mkERP:IU🟢 單一
hcust_dvERP:Isal rpt sls www lineSP×2🟢 單一
hcust_evenERP:DIU🟢 單一
hcust_qtyfERP:Isal sls www line invEV:qtyf_credit / SP×10🟢 單一
hcust_token_archivesal:I🟢 單一
hcust_trd_delERP:I🟢 單一
hcust_trd_rtERP:I🟢 單一
payment_attemptssal:I🟢 單一
payment_callback_failuressal:ISP×1🟢 單一
customer_gssal ERP rpt inv❓ 待確認
customer_hssal ERP❓ 待確認
hcust_closeERP❓ 待確認
hcust_dorder_rtrpt slsTG:rt_order@hcust_dorder,rt_order_copy1_copy1@hcust_dorder_oat_origin⚙️ DB 內部
hcust_sales_per❓ 待確認

團體客戶 (17 張,其中 4 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
gcust_antsal:U ERP:I inv:U🔴 多 writer
gcustsal:U ERP:DIUrpt www invSP×1🔴 多 writer
gcust_clssal:DIU ERP:DIUwwwSP×1🔴 多 writer
gcust_mlERP:DIU invt:Usal🔴 多 writer
gcust_ant_singlesal:IU🟢 單一
gcust_atm_postedsal:I🟢 單一
gcust_dorderERP:DIUsal www🟢 單一
gcust_dvERP:Isal rpt inv🟢 單一
gcust_evenERP:DIUSP×1🟢 單一
gcust_muERP:DIUsal🟢 單一
gcust_narea_antERP:I🟢 單一
gcust_narea_idnosal:I🟢 單一
gcust_priceERP:DIUinv🟢 單一
gcust_price_classesERP:DIU🟢 單一
gcust_trdERP:DIUsalSP×1🟢 單一
gcust_closeERP❓ 待確認
gcust_ml_itemssal ERP invt❓ 待確認

配送/估奶 (22 張,其中 5 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
daily_orderssal:D ERP:DIUrpt www line inv invt🔴 多 writer
dv_orderssal:D ERP:IUinv🔴 多 writer
mareasal:U ERP:DIUrpt www forms line inv dlv invtSP×1🔴 多 writer
rt10_listsal:U forms:UrptSP×1🔴 多 writer
weekly_orderssal:DU ERP:Irpt line🔴 多 writer
daily_dvsERP:Irpt invtEV:inventory_update_dv,inventory_update_dv2 / SP×2🟢 單一
daily_gprod_jobsERP:I🟢 單一
daily_gprodsERP:DI🟢 單一
delivery_listdlv:IUsal🟢 單一
dv_coversERP:Isal dlv🟢 單一
dv_dvmsERP:Isal🟢 單一
marea_coversERP:I🟢 單一
sales_hcust_qtyERP:I🟢 單一
weekly_order_itemssal:DERP rpt line🟢 單一
daily_orders_shadowERP❓ 待確認
daily_salesrptEV:daily_sales / SP×1⚙️ DB 內部
dv_orders_shadowERP❓ 待確認
dv_unit_pricesal ERPEV:new_dv_unit_price / SP×1⚙️ DB 內部
i_dv_record_copy3sal rptEV:insert_dv_record_copy3,insert_dv_record_copy3_daily⚙️ DB 內部
marea_cover_detailsERP❓ 待確認
sales_dvm_productsERP❓ 待確認
sales_dvmsERP rpt❓ 待確認

庫存 (4 張,其中 0 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
inventory_detailsinvt:DIUsalEV:inventory_update_dv,inventory_update_dv2 / SP×4🟢 單一
inventory_itemsinvt:DIUsalEV:inventory_update_dv,inventory_update_dv2 / SP×4🟢 單一
inventory_maininvt:IUsalSP×2🟢 單一
inventory_side_productsinvt:IU🟢 單一

發票/請款 (14 張,其中 7 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
i_formsal:DIU www:DIU kng:U forms:IU line:DIUSP×1🔴 多 writer
invoicessal:I ERP:DI inv:DIUlineSP×4🔴 多 writer
i_deadlineERP:DIU inv:IUsal rpt sls www forms line🔴 多 writer
i_form_trackwww:I forms:IUsal kng🔴 多 writer
i_visit_datasal:DIU sls:DIUrpt🔴 多 writer
i_visit_groupsal:IU sls:IUrpt🔴 多 writer
invoice_detailssal:I inv:DIERP lineSP×5🔴 多 writer
i_prod_no_dvsERP:DI🟢 單一
i_day_qtyERP rptEV:i_day_qty⚙️ DB 內部
i_lbt❓ 待確認
i_prodsal ERP rpt www forms line inv invt❓ 待確認
i_rv_tp_areasal ERP www❓ 待確認
i_sales_carinv❓ 待確認
i_sales_dailyinv❓ 待確認

電訪/通聯 (9 張,其中 2 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
pbx_call_recordsal:I pbx:IU pbx12:IUrpt inv story🔴 多 writer
call_emptysal:DI inv:I🔴 多 writer
call_datasal:Urpt invEV:retain_data_05T1_cust,retain_data_event,topup_call_data_daily,update_daily_stats / TG:delete_calldata_after_star@hcust / SP×7🟢 單一
call_empty_autosal:IU🟢 單一
pbx_call_transcriptsal:Urpt🟢 單一
call_05T1_custEV:retain_data_05T1_cust,retain_data_event / SP×2⚙️ DB 內部
call_listsal rpt invEV:refill_call_list_daily,retain_data_event,topup_call_data_daily / SP×3⚙️ DB 內部
pbx_call_transcript_breeze❓ 待確認
pbx_tokenpbx pbx12❓ 待確認

訊息/LINE (15 張,其中 6 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
SMS_logsal:I www:IU forms:I inv:IUERP🔴 多 writer
line_chatsal:IU www:I line:IUERP rpt🔴 多 writer
line_group_linksal:DIU line:IUERP🔴 多 writer
message_logssal:DIU www:UERP🔴 多 writer
sony_line_chatsal:IU sony:IU🔴 多 writer
sony_line_usersal:IU sony:IU🔴 多 writer
line_chat_auto_reply_logsal:I🟢 單一
line_chat_summarysal:IU🟢 單一
line_cs_quality_casessal:DI🟢 單一
line_cs_quality_jobssal:IU🟢 單一
line_menu_clicksline:Isal🟢 單一
line_noticesal:DI🟢 單一
line_unfollowline:IUsal🟢 單一
line_unlogin_assignline:DIsal🟢 單一
line_unlogin_listsal:ITline🟢 單一

人資/薪資 (14 張,其中 1 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
humsal:U inv:IUERP rpt invt salN🔴 多 writer
hum_coninv:IUsal🟢 單一
hum_nrddinv:IUsal🟢 單一
hum_relinv:DIU🟢 單一
hum_related_custsal:DI🟢 單一
hum_sarsalN:D🟢 單一
hum_sardsalN:DU🟢 單一
hum_wktimesal:Iinv🟢 單一
salary_export_auditssalN:I🟢 單一
sys_uempinv:IUsal ERP rpt sls line dlv invt salN🟢 單一
hum_dvm❓ 待確認
hum_msarsal salNSP×3⚙️ DB 內部
hum_msardsalNSP×3⚙️ DB 內部
hum_special_offinvEV:insert_special_off_day / SP×2⚙️ DB 內部

系統/排程/稽核 (17 張,其中 3 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
bug_reportssal:IU line:U🔴 多 writer
cron_alertssal:IU ERP:I🔴 多 writer
sys_salesrpt:U inv:IUsal ERP sls forms dlv🔴 多 writer
cron_job_logssal:IU🟢 單一
cron_jobssal:IU🟢 單一
cron_permission_snapshotssal:IU🟢 單一
sys_pmERP:IUsal inv🟢 單一
sys_sidebar_menusal:DITU🟢 單一
auditsERP❓ 待確認
jobsERP❓ 待確認
personal_access_tokens❓ 待確認
posting_logERP line❓ 待確認
procedure_performance_logsinvtEV:inventory_update_dv,inventory_update_dv2,refill_call_list_daily,topup_call_data_daily / SP×4⚙️ DB 內部
sys_cpu❓ 待確認
sys_log❓ 待確認
sys_rpt_list❓ 待確認
task_resultsERP❓ 待確認

AI/其他 (4 張,其中 0 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
ai_assetssal❓ 待確認
ai_jobssal❓ 待確認
ai_module_health❓ 待確認
gpu_jobssalEV:gpu_jobs_retention⚙️ DB 內部

未分類 (40 張,其中 0 張多 writer)

W(寫入者)R(讀取者)DB 內部寫入判定
birthday_card_donesal:DI🟢 單一
date_tagsinvt:DI🟢 單一
element_eventsERP:I🟢 單一
estimate_runsERP:I🟢 單一
fax_print_logsal:I🟢 單一
fax_rotationsal:I🟢 單一
gprodERP:IUsal sls www forms line inv🟢 單一
i_credit_qtyfERP:IEV:qtyf_credit / SP×1🟢 單一
i_dvm_ynERP:DIUsal🟢 單一
i_send_msgsal:DR🟢 單一
i_steambox_possal:RERP🟢 單一
ibadtrdcountrpt:DIU🟢 單一
iexpenseinv:IUrpt🟢 單一
net_perf_ad_spendsal:I🟢 單一
net_perf_configsal:U🟢 單一
net_perf_settlementsal:I🟢 單一
notessal:DIU🟢 單一
oldprice40_review_notessal:DI🟢 單一
orders_form_othersal:I🟢 單一
page_daily_accesssal:I🟢 單一
page_infosal:IU🟢 單一
price_templatesERP:DIU🟢 單一
punch_hum_anyipsal:DI🟢 單一
renewal_sms_logsal:DIU🟢 單一
salary2txt_logsal:I🟢 單一
sales_dept_performance_targetsERP:IU🟢 單一
sony_admin_usersony:U🟢 單一
sor_configsal:I🟢 單一
sor_extrasal:DI🟢 單一
sor_maintain_schoolsal:DI🟢 單一
sor_pricesal:U🟢 單一
tasksERP:IU🟢 單一
toy_stocksinvt:DI🟢 單一
youtube_summariessal:DIU🟢 單一
julaug40_review_cache❓ 待確認
newold_review_cache❓ 待確認
oldprice40_charged_cachesal❓ 待確認
oldprice40_review_cache❓ 待確認
rpt_delivery_achievementsal rptEV:evt_daily_delivery_update / SP×1⚙️ DB 內部
sales_reportrpt slsEV:sales_report / SP×1⚙️ DB 內部

2.1 🔴 非 web 直連者:Windows 桌面 client(原盤點漏掉的第 17 個 writer)

這是 david@% 那個 %(允許任意 host)的存在理由,也是「停用 david」的最大阻擋。

指標近 90 天
操作筆數214
來源電腦8 台(DESKTOP-URBL6KGMAY-PCDESKTOP-F0ROLQ6…)
使用者16 人
最近一次2026-08-17

用到的功能(sys_log.prg_id,即桌面程式的表單名):

表單對應業務筆數人數影響的表
frmhcust客戶維護17213hcust(+6 個 trigger 連鎖)
frmdept_work0 / frmdept_work部門工作102hum_*
frmhum / frmhum_msar / frmhum_rpt10/13/20人資與薪資133humhum_msar
frmhcust_ant_err / frmgcust_ant_edit應收帳款調整92hcust_antgcust_ant
frmsales_hcust_qty業務業績31sales_hcust_qty
frmhcust_mulist2 / frmhcust_mdqty / frmhcust_close_chk / frmvend客戶名單/數量/結清/廠商7家戶相關

🔴 兩個直接後果: 1. hum_msar(薪資)不是只有新薪資站在碰——桌面 frmhum_msar 也在改。 C2 薪資站的 9 月驗收要把這件事納入:新站不是唯一入口。 2. david@% 不能在桌面 client 退場前停用。階段 1 的「david 連續 7 天零新連線」 出口條件,必須先確認這 8 台電腦已停用或改走新帳號,否則會直接打斷 16 個人的日常作業。

追蹤方式:sys_log 就是它的存取日誌(musercomp_nameprg_idlog_time), 停用前先用它確認歸零,比看 processlist 可靠。

4. DB 內部寫入層(繞過應用層)

這一層是矩陣最容易被忽略的部分:拆完應用帳號,這些照樣會寫。 SP/EVENT/TRIGGER 都以 DEFINER 身分執行——目前多為 david@%, 所以「把 david 停用」之前必須先把這些 DEFINER 換掉,否則排程與觸發器會全數失效。

4.1 EVENT(20 個,全部 ENABLED)

EVENT呼叫的 SP寫入表
daily_salesdaily_salesdaily_sales
dvm_bill_auto_postdvm_bill_auto_posthcust_amt_rcv, hcust_ant
evt_daily_delivery_updatesp_daily_delivery_updaterpt_delivery_achievement
gpu_jobs_retentiongpu_jobs
i_day_qtyi_day_qty
insert_dv_pointinsert_dv_point⚠️ 查無寫入表(多為寫冷表或僅讀,待確認)
insert_dv_record_copy3i_dv_record_copy3
insert_dv_record_copy3_dailyi_dv_record_copy3
insert_special_off_dayinsert_special_off_dayhum_special_off
inventory_update_dvinventory_update_dvdaily_dvs, inventory_details, inventory_items, procedure_performance_logs
inventory_update_dv2inventory_update_dvdaily_dvs, inventory_details, inventory_items, procedure_performance_logs
new_dv_unit_pricenew_dv_unit_pricedv_unit_price
new_dv_unit_price_pointnew_dv_unit_price_point⚠️ 查無寫入表(多為寫冷表或僅讀,待確認)
qtyf_creditqtyf_credithcust_qtyf, i_credit_qtyf
refill_call_list_dailyrefill_call_list_recentcall_list, procedure_performance_logs
retain_data_05T1_custretain_data_05T1_custcall_05T1_cust, call_data
retain_data_eventretain_data_eventcall_05T1_cust, call_data, call_list
sales_reportsales_reportsales_report
topup_call_data_dailytopup_call_data_05T1call_data, call_list, procedure_performance_logs
update_daily_statsupdate_daily_statscall_data

4.2 TRIGGER(8 個)

TRIGGER掛在時機連帶寫入
delete_calldata_after_starhcustAFTER UPDATEcall_data
rt_orderhcust_dorderAFTER UPDATEhcust_dorder_rt
rt_order_copy1_copy1hcust_dorder_oat_originAFTER UPDATEhcust_dorder_rt
update_addr_loghcustAFTER UPDATEhcust_trd
update_area_loghcustAFTER UPDATEhcust_trd
update_comp_idno_loghcustAFTER UPDATEhcust_trd
update_lv_tp_loghcustAFTER UPDATEhcust_trd
update_rv_tp_loghcustAFTER UPDATEhcust_trd

🔴 hcust 上掛了 6 個 AFTER UPDATE trigger——任何一個站 UPDATE hcust, 都會連帶寫 hcust_trd(異動記錄)與 call_data。這是「7 個 writer」真正的殺傷力所在: 不是 7 個地方改客戶資料,是 7 個地方各自觸發一整串連鎖寫入

4.3 PROCEDURE

178 個 PROCEDURE 中 68 個有寫入。寫入表數最多的前 15 個:

PROCEDURE寫入表數寫入表(節選)
payment_post8hcust_amt_pre, hcust_amt_rcv, hcust_ant, hcust_qtyf, hcust_trd, payment, payment_callback_failures, trades
double_amt_post6hcust_amt_pre, hcust_amt_rcv, hcust_ant, hcust_qtyf, hcust_trd, trades
hcust_pre_post6hcust_amt_pre, hcust_amt_rcv, hcust_ant, hcust_qtyf, hcust_trd, trades
inventory_update_dv4daily_dvs, inventory_details, inventory_items, procedure_performance_logs
pre_over7_post4hcust_amt_pre, hcust_amt_rcv, hcust_ant, hcust_trd
inventory_create3inventory_details, inventory_items, inventory_main
write_hcust_addr3hcust, hcust_dorder, hcust_trd
inventory_transfer3inventory_details, inventory_items, inventory_main
rcv_ant_undo3hcust_amt_pre, hcust_ant, hcust_qtyf
retain_data_event3call_05T1_cust, call_data, call_list
topup_call_data_05T13call_data, call_list, procedure_performance_logs
create_invoices_hcust_v22invoice_details, invoices
delete_amt_pre2customer_pms, hcust_amt_pre
inventory_update2inventory_details, inventory_items
create_invoices_gcust2invoice_details, invoices

5. 表對表的同步/衍生關係(同步方向)

來源目的機制現況
hcust_dorderweekly_ordersERP SyncOld job 雙寫🔄 並行中——salary 等舊站仍讀舊表,故雙寫不能停;ERP 重心是收斂雙寫,不是刪死碼
hcust_dorderhcust_dorder_rtTRIGGER rt_order (AFTER UPDATE)🔄 生效中
hcusthcust_trdTRIGGER update_addr/area/rv_tp/lv_tp/comp_idno_log🔄 生效中(5 個 trigger 都寫異動記錄)
hcustcall_dataTRIGGER delete_calldata_after_star🔄 客戶改名為 * 開頭時停掉電訪名單
daily_ordersdaily_orders_shadowshadow 估奶驗證⏸️ 已停用goalu.tasks id 45/46 status→0,2026-08-17);影子表凍結觀察一個月結後清
dv_ordersdv_orders_shadow同上⏸️ 已停用
(多表)i_dv_record_copy3EVENT insert_dv_record_copy3 / _daily🔄 每日寫入,526 萬列
call_datacall_list / call_05T1_custEVENT retain_data_eventrefill_call_list_dailytopup_call_data_daily🔄 每日輪替電訪名單
dorder / dorderd / hcust_trdh(無)🧊 真凍結——2025-03-14 同日停寫,可列入冷表退場

6. 三方一致抽查(checklist 硬門檻驗證)

checklist 要求「抽查 3 張表,矩陣記載與呼叫關係、實際 GRANT 三方一致」。 ⚠️ 說明:codebase-memory 不索引 SQL 字面值(表名寫在字串裡), 故第二方改用掃描器輸出的實際寫入點(檔:行),比符號圖更硬。

hum_msar

程式碼實證(掃描器記錄的寫入檔,取樣附行號):

hcust

程式碼實證(掃描器記錄的寫入檔,取樣附行號):

trades

程式碼實證(掃描器記錄的寫入檔,取樣附行號):

三方比對結論

矩陣程式碼實證實際 GRANT一致?
hum_msarweb app writer、SP×3新薪資站零寫入呼叫(僅 CALL);但桌面 frmhum_msar 在寫(見 2.1)salary_appSELECT,INSERT,UPDATE,DELETE⚠️ 矩陣需補「桌面 client」欄;salary_app GRANT 過寬——見第 7 節
hcust7 個 app writer+6 trigger7 站皆有實際寫入點全部走 davidALL ON *.*✅ 一致(但現況本身就是問題)
trades3 個 app writer+SP×4api/messaging.php:1660credit_callback.php:298、ERP TradeService同上✅ 一致

7. 立即可收窄的權限(矩陣的第一個實際成果)

目前 GRANT程式實際用到建議
hum_sarSELECT,INSERT,UPDATE,DELETESELECT+DELETE(Livewire/Sar/Sars.php撤 INSERT,UPDATE(新增/修改走 SP)
hum_sardSELECT,INSERT,UPDATE,DELETESELECT+UPDATE+DELETE(Livewire/Sard/*撤 INSERT
hum_msarSELECT,INSERT,UPDATE,DELETE只有 SELECT(寫入由 SP salarysalary_dv 代勞)撤 INSERT,UPDATE,DELETE
hum_msardSELECT,INSERT,UPDATE,DELETE只有 SELECT(同上)撤 INSERT,UPDATE,DELETE
salary_export_auditsSELECT,INSERTSELECT+INSERT(ExportController✅ 剛好

⚠️ 先別直接 REVOKE:SP 以 DEFINER=david@% 代跑,撤掉表級權限不影響 CALL, 但 9 月算薪驗收(docs/decision-c2-mount-20260817.md)還沒跑完, 建議驗收通過後再收,並在收完後跑 composer testdatabase/gm/verify.sh 複驗。

8. 收斂路線(對應戰線 B「寫入權集中」)

8.1 優先序:先動 writer 最多的

順位writer 數為什麼先動
1hcust7客戶主檔+6 個 trigger 連鎖寫入,事故半徑最大
2hcust_trd7業務異動核(trades 三方寫入之一),帳務與配送都靠它
3i_form5表單收單入口,對外站與 LINE 都在寫
4hcust_dorder4訂單主檔,且正與 weekly_orders 雙寫並行
5payment4金流紀錄,4 個 writer 分散在對外站與 LINE
6SMS_log4訊息稽核,收斂進 kng/notify 後應只剩一個 writer
7address_book_indexes3PK 是保留字 index,多方寫入易出錯
8customers3新世代客戶表,ERP 應為唯一 writer
9gcust_ant3團戶應收,與 invoice 站重疊
10hcust_token3對外票券,www 與 line 各寫各的

8.2 階段 1 待辦(本矩陣直接衍生)

  1. david@%tom@%ALL ON *.* 收成 goalu.*——這一步不改任何程式碼, 卻立刻消除「一個帳號打穿全機 MariaDB(callhub/muxue/lk/shop…)」的風險。先做這個。
  2. 逐站建專屬帳號,照本矩陣的 W/R 欄授權;順序建議由讀多寫少的站開始: html/report(2 張表寫入)→ html/sony(3)→ kng.tw(1)→ forms(3)→ inventory(7)→ line(4)→ invoice(3)→ html/sales(6)→ www(11)→ ERP(最後,它應該是唯一 writer)
  3. html/salary 是最大宗(87 張表寫入)——它同時是「總務室」問題本體, 不建議一次拆,應隨階段 5 對內站歸併逐模組搬遷。
  4. 🔴 桌面 client 先處理david@% 不能在 8 台 Windows 電腦(16 人)退場前停用。 先用 sys_log 確認實際使用者與功能,決定「搬到 web」或「配一個專屬帳號 legacy_desktop」。 這是階段 1 出口條件(david 零連線)的真正阻擋點。
  5. DEFINER 換人:停用 david 之前,先把 68 個 SP/20 個 EVENT/8 個 TRIGGER 的 DEFINER 換成專用的 goalu_scheduler 帳號,否則排程全掛。
  6. 明碼密碼html/salaryhtml/reporthtml/saleshtml/sonykng.tw 五站 把 david/密碼寫死在 PHP 裡,拆帳號時一併改成讀 env。

8.3 刻意不做

誰只能讀。實際收斂是階段 2~5 的事,階段 1 只要矩陣正確且帳號照它授權。

9. 可重跑(矩陣不可手改後漂移)

掃描器在 tools/db-matrix/,重生指令:

cd /var/www/html/salary/tools/db-matrix
./rebuild.sh          # 重跑全部掃描並覆寫 ../../erp_docs/write-permission-matrix.md

內部流程:

  1. active_tables.txtinformation_schema.TABLES(90 天內 UPDATE_TIME
  2. scan_writers.py ← raw SQL(INSERTUPDATEDELETEREPLACETRUNCATECALL)+ DB::table()->write
  3. scan_eloquent.py ← Eloquent Model → table,再找靜態寫入呼叫
  4. scan_erp_repo.py ← ERP 專用:RepositoryEntity → table(ERP 走 Repository 統一寫入層)
  5. scan_readers.pyFROMJOINDB::table()/Model 存在即算 reader
  6. db_chain.py ← EVENT →(遞迴)CALL SP → 寫入表;TRIGGER 同理
  7. gen_matrix.pyfinalize.py ← 合併輸出本文件

掃描器的已知限制(讀矩陣前先知道)

限制影響緩解
靜態掃描抓不到動態表名($table 變數拼接)可能漏 writer48 張「無 app writer」已逐張人工複查,見第 10 節
Eloquent 關聯寫入($parent->items()->create())未涵蓋可能漏 writerERP 走 Repository,已另掃;其餘站關聯寫入少
.sql 檔(SP 定義/dump)已排除避免把 SP 備份誤算成應用寫入SP 寫入改由 DB 端 information_schema 取得,更準
UPDATE_TIME 對 InnoDB 非精確值活表/冷表邊界可能±數張邊界表以業務判斷為準,不以 90 天硬切

10. 無 app writer 的 48 張表

10.1 由 DB 內部寫入(14 張)——正常

寫入者
call_05T1_custEVENT retain_data_05T1_cust, retain_data_event / SP×2(retain_data_05T1_cust, retain_data_event
call_listEVENT refill_call_list_daily, retain_data_event, topup_call_data_daily / SP×3(refill_call_list_recent, retain_data_event, topup_call_data_05T1
daily_salesEVENT daily_sales / SP×1(daily_sales
dv_unit_priceEVENT new_dv_unit_price / SP×1(new_dv_unit_price
gpu_jobsEVENT gpu_jobs_retention
hcust_dorder_rtTRIGGER rt_order@hcust_dorder, rt_order_copy1_copy1@hcust_dorder_oat_origin
hum_msarSP×3(salary, salary_add_up, salary_dv
hum_msardSP×3(salary, salary_add_up, salary_dv
hum_special_offEVENT insert_special_off_day / SP×2(insert_special_off, insert_special_off_day
i_day_qtyEVENT i_day_qty
i_dv_record_copy3EVENT insert_dv_record_copy3, insert_dv_record_copy3_daily
procedure_performance_logsEVENT inventory_update_dv, inventory_update_dv2, refill_call_list_daily, topup_call_data_daily / SP×4(inventory_update_dv, refill_call_list_recent, retain_data_05T1_list, topup_call_data_05T1
rpt_delivery_achievementEVENT evt_daily_delivery_update / SP×1(sp_daily_delivery_update
sales_reportEVENT sales_report / SP×1(sales_report

10.2 查無任何 writer(34 張)——待人工確認

這些表近 90 天有寫入時間戳,卻掃不到 writer。可能原因:外部腳本(bash/python cron)、 動態表名、其他主機寫入、或 UPDATE_TIME 因 optimize 而變動(實際已停寫)。

有引用的站(非寫入)研判
ai_assetshtml/salary待查
ai_jobshtml/salary待查
ai_module_healthaigen 能力控制台,疑走 bash/python
auditsERP(kngoatmilk)ERP auditing 套件寫(vendor)
customer_gsERP(kngoatmilk), html/report, html/salary, invoice待查
customer_hsERP(kngoatmilk), html/salary待查
daily_orders_shadowERP(kngoatmilk)待查
dv_orders_shadowERP(kngoatmilk)待查
gcust_closeERP(kngoatmilk)待查
gcust_ml_itemsERP(kngoatmilk), html/salary, inventory待查
hcust_closeERP(kngoatmilk)待查
hcust_sales_per疑由 SP 動態寫
hum_dvm疑由 SP 動態寫
i_lbt疑已停寫(UPDATE_TIME 誤差)
i_prodERP(kngoatmilk), forms, html/report, html/salary, inventory, invoice, line, www.kngoatmilk.com待查
i_rv_tp_areaERP(kngoatmilk), html/salary, www.kngoatmilk.com待查
i_sales_carinvoice待查
i_sales_dailyinvoice待查
jobsERP(kngoatmilk)Laravel queue 內建表,框架寫(vendor 已排除掃描)
julaug40_review_cache待查
marea_cover_detailsERP(kngoatmilk)疑已停寫
newold_review_cache待查
oldprice40_charged_cachehtml/salary待查
oldprice40_review_cache待查
pbx_call_transcript_breeze夜批通話轉錄(daily_run.sh)寫,非 PHP
pbx_tokenpbx, pbx-laravel12待查
personal_access_tokensSanctum 發 token 時寫(vendor)
posting_logERP(kngoatmilk), line待查
sales_dvmsERP(kngoatmilk), html/report待查
sales_dvm_productsERP(kngoatmilk)待查
sys_cpu疑為主機監控腳本寫(非 PHP)
sys_log已查明:Windows 桌面 client 的存取日誌(見 2.1),不是 web 站寫的
sys_rpt_list已查明:桌面 client 的報表列印記錄(SALES_HCUST_QTY 等)
task_resultsERP(kngoatmilk)疑為排程結果表,ERP TaskRepository 動態寫

相關文件: 整合規劃 v5 · 執行路線圖 · 七階段檢核清單 · 網域規劃 · 薪資站帳號範本 /var/www/salary/docs/db-account-matrix.md