Skip to main content

nodedb_crdt/validator/
types.rs

1// SPDX-License-Identifier: BUSL-1.1
2
3//! Validator input/output types.
4
5use crate::dead_letter::CompensationHint;
6use loro::LoroValue;
7use nodedb_types::Surrogate;
8
9/// Outcome of validating a proposed change against constraints.
10#[derive(Debug)]
11pub enum ValidationOutcome {
12    /// All constraints satisfied — safe to commit.
13    Accepted,
14    /// One or more constraints violated — delta rejected.
15    Rejected(Vec<Violation>),
16}
17
18/// A single constraint violation.
19#[derive(Debug, Clone)]
20pub struct Violation {
21    /// The constraint that was violated.
22    pub constraint_name: String,
23    /// Human-readable reason.
24    pub reason: String,
25    /// Suggested fix.
26    pub hint: CompensationHint,
27}
28
29/// A proposed row change to validate.
30#[derive(Debug, Clone)]
31pub struct ProposedChange {
32    /// Target collection.
33    pub collection: String,
34    /// Row ID being inserted/updated.
35    pub row_id: String,
36    /// Stable cross-engine identity assigned at the boundary.
37    ///
38    /// `Surrogate::ZERO` is the in-test sentinel and is also accepted
39    /// for legacy callers that have not yet plumbed an assigner. UNIQUE
40    /// and FK checks key on this when non-zero, so cross-engine bitmap
41    /// joins reference the same row identity.
42    pub surrogate: Surrogate,
43    /// Field values being set.
44    ///
45    /// For bitemporal collections, the reserved columns `_ts_valid_from`
46    /// and `_ts_valid_until` appear in this vec alongside user fields;
47    /// constraint validation inspects them via
48    /// [`crate::validator::bitemporal`] helpers.
49    pub fields: Vec<(String, LoroValue)>,
50}