count_limit 規則
count_limit 對一個 live-row bucket 設定上限。它是伺服器端 quota primitive,可表達「每個專案最多三個 active tasks」、「每位醫師最多兩筆預約」,或「對應預約 bucket 已滿時不可加入候補」等契約。
本表 bucket
省略 table_id 時,會計算規則所屬表格內的資料列。where 選出 bucket,而 $row.<column> 值會使用候選列的 post-image 進行分區:
{
"type": "count_limit",
"name": "每個專案最多三個進行中工作",
"max": 3,
"where": [
{ "column": "專案代碼", "op": "eq", "value": "$row.專案代碼" },
{ "column": "狀態", "op": "eq", "value": "進行中" }
]
}此例中,進行中的工作會加入自己專案代碼的 bucket;草稿不符合 literal 狀態 = 進行中,因此不會被 veto。沒有 table_id 時不能使用 match;本表計數請以 $row predicate 分區。
明確目標 bucket
提供 table_id 時,規則會重用一跳式 exists matching model,計算該目標表中的資料列:
{
"type": "count_limit",
"name": "醫師已有上限數量的有效預約",
"max": 5,
"table_id": "33333333-3333-4333-8333-333333333333",
"match": {
"醫師": "醫師"
},
"where": [
{ "column": "狀態", "op": "eq", "value": "有效" }
]
}match 包含一至兩組「目標表 link → 本表 link」配對;每組兩側都必須 link 到同一張底層表。顯示名稱相同時可使用 "$same"。目標表必須位於同一個可到達的 scope chain;where 篩選目標表的 stored scalar,並可與相容的 $row.<本表欄位> 值或 scalar literal 比較。
明確 table_id 也可以指向本表。當 link anchor 比 scalar where 更能表達 bucket 時,這種形式很有用;例如以 "match": {"醫師": "$same"} 限制每位醫師最多兩列。
執行語意
max必填,而且必須是至少 1 的整數。- 只計算 live rows。刪除一列會釋放容量;還原時會重新檢查上限。
- 本表形式只有在候選 post-image 符合 bucket predicates 時才可能 veto。移入已滿 bucket 的 update 會被拒絕;移出則會通過,即使舊 bucket 已經超額。
- 若資料列已在額滿的本表 bucket 中,只修改其他欄位時,probe 會排除該列本身,不會把同一列重複計算。
$row分區值缺少或為 null,或明確目標形式缺少 link anchor 時,該候選列豁免。Anchor 必須存在時,請另外設定 presence contract。- Bulk write 與 approval replay 都會重新執行規則;先前暫存或刪除的列不會永久占用容量。
where 使用 stored-scalar predicate typing,最多接受 10 條 predicates。可選的 when 會縮小規則本身的套用條件;它與用來定義被計數資料列的 where 是兩件事。
安全發布
先用 rules.preview 驗證候選規則 shape。它的 sampled impact pass 只處理 SCP/invariant,不會計算一般 count_limit bucket,因此既有 bucket 數量必須另以針對性的 record query 稽核。Preview 永遠不會保留名額;真正具權威的判斷是實際寫入回應,它會依當下 bucket 以 transaction 評估。
透過 rules.set 發布時,請記住該端點會取代完整規則清單;保留既有 rule ID 與其他不相關規則。