Skip to Content
核心概念規則same_dimension_reference

same_dimension_reference

same_dimension_reference 讓原生 link 不會跨越邊界。連結到上層任務的任務必須屬於同一個專案;連結到價格的發票明細必須使用同一家公司的價格。這條規則指定三個 cardinality one 的 link:這一列選取的參照、這一列所屬的維度,以及被選取紀錄的維度。每一列都必須剛好連結一個目標,兩邊都必須剛好連結一個維度紀錄,而且兩個維度紀錄必須是同一筆 live 列。

Payload

{ "type": "same_dimension_reference", "name": "上層任務必須在同一專案", "reference_column": "上層任務", "source_dimension": "專案", "target_dimension": "專案" }
欄位契約
reference_column本表的 cardinality one link 欄位,用來選取目標紀錄。
source_dimension本表的 cardinality one link 欄位,指向這一列的維度紀錄。
target_dimensionreference_column 所連結資料表上的 cardinality one link 欄位,必須與 source_dimension 連到同一張維度表。

參照可以用顯示名稱或內部鍵。when 只能是 null 或 [],未知的鍵也會被拒絕;兩者都是 422 request 驗證錯誤。id 必須符合 rule_<8–32 hex>,name 最多 128 字。這條規則計入 10 條規則的上限,不計入 unique 上限。GET 會以顯示名稱回傳 reference_column 與 source_dimension;target_dimension 屬於目標表,會維持其內部 col_<hex> 鍵。

設定錯誤是 400,detail 為純字串:

detail原因
Reference fields must be native cardinality-one links三個欄位之一不是 link、沒有 link 定義,或 cardinality 是 many
Reference target table is not accessible被參照的資料表不存在、在垃圾桶或不在同一公司
Both dimensions must link to the same dimension tablesource_dimension 與 target_dimension 指向不同的資料表
Dimension table is not accessible維度表不存在、在垃圾桶或不在同一公司

來源 → 目標、來源 → 維度與目標 → 維度這三組也都適用一般的 link 範圍規則(相同範圍,或同一公司內較廣的範圍)。

伺服器強制執行的內容

對來源表的每一筆 live 列:

  • reference_column 剛好有一個目標,且該目標是 live 資料表中的 live 列;
  • source_dimension 剛好有一筆 live 的維度列;
  • 目標的 target_dimension 剛好有一筆,而且就是同一筆 live 維度列。

沒有 null 豁免:沒有參照或沒有維度的列會被拒絕。沒有維度的目標列可以存在,直到有來源列選取它為止。檢查不看 principal(會穿過所有 ACL 與 room 篩選),並在所有相關資料表的排序鎖之下進行,因此不會被競態繞過。

被拒絕的寫入回傳不含值的 409:

{ "detail": { "error": "same_dimension_reference_violation", "message": "Reference must share a live required dimension." } }

這條規則同時守護三張表,而不只是來源表:

寫入何時被拒絕
建立、更新、還原(revert)或復原(restore)來源列它的參照或維度違反不變條件
刪除來源列永遠不會(這只是移除一項義務)
修改目標列的 target_dimension,或刪除被參照的目標列仍有 live 來源列依賴它
刪除維度列仍有 live 來源列直接或透過其選取的目標依賴它
把目標表或維度表丟到垃圾桶仍有 live 來源列依賴它
復原來源表它的目標表或維度表在垃圾桶中

規則 closure 內的每一次寫入——來源、目標與維度表,加上透過其他 same_dimension_reference 規則與它們相連的任何資料表——都會重新驗證該 closure 中每個 binding 的 live 來源列。公司內的每一次資料列寫入也都會讀取該公司的參照 binding,所以公司內任何一個結構已損壞的 binding(規則的 link 不再是指向同一張維度表的 cardinality one link)都會讓資料列寫入以同樣的 409 fail closed,直到移除該規則為止;下方的欄位與 purge 保護就是為了避免這種情況。

啟用規則

PUT 在儲存前會檢查每一筆既有的 live 來源列:只要有一列違反不變條件,整份清單就以同樣的 409 拒絕,不會儲存任何東西。與其他所有規則型別不同,rules.preview 也會執行這個既有列檢查(在交易範圍的 guard 下進行,之後回滾),並回相同的 409——發布新的 binding 前請先預覽。

相關欄位與資料表的保護

操作回應
刪除或變更型別:reference_column/source_dimension(來源表)或 target_dimension(目標表)409 衝突 {"type": "dependent_rule", "field": "<欄位鍵>", "code": "same_dimension_reference_dependency", "message": "Remove the dependent reference rule before changing this link column."}
永久清除目標表或維度表Purge 預覽的 blocker {"code": "same_dimension_reference_dependency", "table_id": "<來源表>", "message": "Remove the dependent reference rule before purging its target or dimension table."};仍然執行到的 purge 會回 409 {"error": "same_dimension_reference_dependency"}

其他寫入路徑

  • 核准:套用已核准的變更時會重新檢查這條規則;違反時該變更以 apply_failed 結束,原因為 refused at apply (same_dimension_reference_violation): Reference must share a live required dimension.
  • Bulk 與匯入:不會逐列預檢這條規則,而是在寫入資料列時失敗。非同步 bulk ticket 會在該 chunk 提交時失敗(先前的 chunk 仍保留),同步 bulk 請求或 publish 提交則整批回滾。
  • 指令:碰到 binding 中任何一張表的指令,會把整個 closure 納入其 dependency contract,所以修改這條規則會讓那些指令變成 stale(見指令)。

請把規則放進完整的 rules 清單,透過 rules.set 發布。

Last updated on