Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CardinalityConstraint ¶
type CardinalityConstraint struct {
NodeLabel string // Label to apply constraint to
EdgeType string // Type of edge (empty = any type)
Direction Direction // Direction of edges to count
Min int // Minimum number of edges (0 = optional)
Max int // Maximum number of edges (0 = unlimited)
}
CardinalityConstraint validates the number of edges a node has
func (*CardinalityConstraint) Name ¶
func (cc *CardinalityConstraint) Name() string
Name returns the constraint name
func (*CardinalityConstraint) Validate ¶
func (cc *CardinalityConstraint) Validate(graph GraphReader) ([]Violation, error)
Validate checks the cardinality constraint against all nodes with the target label
type Constraint ¶
type Constraint interface {
// Validate checks the constraint against the graph
// Returns a list of violations (empty if valid)
Validate(graph GraphReader) ([]Violation, error)
// Name returns a human-readable name for the constraint
Name() string
}
Constraint is the interface that all constraint types must implement. It uses the GraphReader interface for dependency injection, enabling easier testing and looser coupling to the storage implementation.
type GraphReader ¶
type GraphReader interface {
// Node operations
GetNode(nodeID uint64) (*storage.Node, error)
// GetAllNodesAcrossTenants returns every node from every tenant.
// Constraint validation currently runs across all tenants — for
// uniqueness/cardinality constraints, this means a violation in one
// tenant fires even when the duplicate lives in a different tenant.
// Per-tenant constraint validation is a separate follow-up; the
// audit-A3b rename surfaces the cross-tenant semantic at the call
// site so the limitation is visible in code review.
GetAllNodesAcrossTenants() []*storage.Node
FindNodesByLabelAcrossTenants(label string) ([]*storage.Node, error)
GetAllLabels() []string
// Edge operations
GetEdge(edgeID uint64) (*storage.Edge, error)
FindEdgesByTypeAcrossTenants(edgeType string) ([]*storage.Edge, error)
GetOutgoingEdges(nodeID uint64) ([]*storage.Edge, error)
GetIncomingEdges(nodeID uint64) ([]*storage.Edge, error)
}
GraphReader defines the read-only operations needed for constraint validation. This interface enables dependency injection and makes constraints testable without requiring a full GraphStorage implementation.
type PropertyConstraint ¶
type PropertyConstraint struct {
NodeLabel string // Label to apply constraint to
PropertyName string // Name of the property
Type storage.ValueType // Expected type (0 = any type)
Required bool // Whether property must exist
Min *storage.Value // Minimum value (for int/float)
Max *storage.Value // Maximum value (for int/float)
}
PropertyConstraint validates node properties
func (*PropertyConstraint) Name ¶
func (pc *PropertyConstraint) Name() string
Name returns the constraint name
func (*PropertyConstraint) Validate ¶
func (pc *PropertyConstraint) Validate(graph GraphReader) ([]Violation, error)
Validate checks the property constraint against all nodes with the target label
type UniqueEdgeConstraint ¶
type UniqueEdgeConstraint struct {
// EdgeType is the edge type to check for uniqueness
EdgeType string
// SourceLabel optionally restricts to edges from nodes with this label
SourceLabel string
// TargetLabel optionally restricts to edges to nodes with this label
TargetLabel string
}
UniqueEdgeConstraint ensures only one edge of a specific type exists between two nodes. This is useful for preventing duplicate relationships.
func (*UniqueEdgeConstraint) Name ¶
func (c *UniqueEdgeConstraint) Name() string
Name returns a human-readable name for this constraint
func (*UniqueEdgeConstraint) Validate ¶
func (c *UniqueEdgeConstraint) Validate(graph GraphReader) ([]Violation, error)
Validate checks that no duplicate edges exist between node pairs
type UniquePropertyConstraint ¶
type UniquePropertyConstraint struct {
// PropertyKey is the property that must be unique
PropertyKey string
// NodeLabel optionally restricts the constraint to nodes with this label.
// If empty and Scope is ScopeLabel, the constraint validates per-label uniqueness.
// If set and Scope is ScopeLabel, only nodes with this label are checked.
NodeLabel string
// Scope determines whether uniqueness is global or per-label
Scope UniqueScope
}
UniquePropertyConstraint ensures a property value is unique across nodes. This is useful for enforcing uniqueness on external IDs, emails, slugs, etc.
func (*UniquePropertyConstraint) Name ¶
func (c *UniquePropertyConstraint) Name() string
Name returns a human-readable name for this constraint
func (*UniquePropertyConstraint) Validate ¶
func (c *UniquePropertyConstraint) Validate(graph GraphReader) ([]Violation, error)
Validate checks that the property is unique according to the constraint scope
type UniqueScope ¶
type UniqueScope int
UniqueScope defines the scope of uniqueness checking
const ( // ScopeGlobal means the property must be unique across all nodes ScopeGlobal UniqueScope = iota // ScopeLabel means the property must be unique within nodes of the same label ScopeLabel )
func (UniqueScope) String ¶
func (s UniqueScope) String() string
type ValidationResult ¶
type ValidationResult struct {
Valid bool // True if no violations found
Violations []Violation // List of all violations
CheckedAt time.Time // When validation was performed
}
ValidationResult contains the results of validating a graph against constraints
func (*ValidationResult) GetViolationsBySeverity ¶
func (vr *ValidationResult) GetViolationsBySeverity(severity Severity) []Violation
GetViolationsBySeverity returns violations filtered by severity level
func (*ValidationResult) GetViolationsByType ¶
func (vr *ValidationResult) GetViolationsByType(violationType ViolationType) []Violation
GetViolationsByType returns violations filtered by type
type Validator ¶
type Validator struct {
// contains filtered or unexported fields
}
Validator manages a set of constraints and validates graphs against them
func (*Validator) AddConstraint ¶
func (v *Validator) AddConstraint(constraint Constraint)
AddConstraint adds a constraint to the validator
func (*Validator) AddConstraints ¶
func (v *Validator) AddConstraints(constraints []Constraint)
AddConstraints adds multiple constraints to the validator
func (*Validator) ClearConstraints ¶
func (v *Validator) ClearConstraints()
ClearConstraints removes all constraints from the validator
func (*Validator) GetConstraints ¶
func (v *Validator) GetConstraints() []Constraint
GetConstraints returns all constraints in the validator
func (*Validator) Validate ¶
func (v *Validator) Validate(graph GraphReader) (*ValidationResult, error)
Validate runs all constraints against the graph and returns the results
type Violation ¶
type Violation struct {
Type ViolationType
Severity Severity
NodeID *uint64
EdgeID *uint64
Constraint string
Message string
Details map[string]any
}
Violation represents a constraint violation
type ViolationType ¶
type ViolationType int
ViolationType categorizes the type of constraint violation
const ( MissingProperty ViolationType = iota InvalidType OutOfRange CardinalityViolation ForbiddenEdge InvalidStructure UniquenessViolation )
func (ViolationType) String ¶
func (vt ViolationType) String() string