Skip to content

feat: add template constraint validation (#86)#92

Merged
e7217 merged 1 commit into
mainfrom
feat/86-structural-data-validation
May 19, 2026
Merged

feat: add template constraint validation (#86)#92
e7217 merged 1 commit into
mainfrom
feat/86-structural-data-validation

Conversation

@e7217

@e7217 e7217 commented May 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • extend templates with relationship constraints
  • add constraint evaluator, violation events, and catalog check subject/CLI
  • enforce or warn on relation-create violations with rollback in enforce mode
  • document template constraints and add example constraints

Test

  • go test ./...
  • go vet ./...
  • go run ./cmd/core --check-constraints --config deploy/configs/core/config.dev.yaml

Copilot AI review requested due to automatic review settings May 19, 2026 18:21
@codecov

codecov Bot commented May 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.72340% with 97 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.61%. Comparing base (23ebf93) to head (c99c1b8).
⚠️ Report is 34 commits behind head on main.

Files with missing lines Patch % Lines
internal/core/constraints.go 62.31% 34 Missing and 18 partials ⚠️
cmd/core/main.go 0.00% 23 Missing ⚠️
internal/core/meta_handler.go 67.74% 11 Missing and 9 partials ⚠️
internal/core/config.go 77.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main      #92       +/-   ##
===========================================
+ Coverage   46.76%   63.61%   +16.85%     
===========================================
  Files           5       15       +10     
  Lines         355     2053     +1698     
===========================================
+ Hits          166     1306     +1140     
- Misses        168      537      +369     
- Partials       21      210      +189     
Files with missing lines Coverage Δ
internal/core/events.go 84.84% <100.00%> (ø)
internal/core/loader.go 72.22% <100.00%> (+1.38%) ⬆️
internal/core/config.go 68.58% <77.77%> (ø)
internal/core/meta_handler.go 45.27% <67.74%> (+40.72%) ⬆️
cmd/core/main.go 5.42% <0.00%> (+5.42%) ⬆️
internal/core/constraints.go 62.31% <62.31%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@e7217 e7217 merged commit 50ceec0 into main May 19, 2026
5 of 6 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class “template constraints” to the metadata model and core runtime so relationship cardinality rules can be validated, reported, and (optionally) enforced during relation creation and via a catalog-wide check.

Changes:

  • Extend asset templates with constraints (required/forbidden relations) and validate constraints during template directory load.
  • Add constraint evaluation/reporting, a NATS check subject, violation event publishing, and enforcement modes (warn/enforce/disabled) wired through core config and CLI.
  • Update example templates, docs, and tests to cover constraint parsing, evaluation, and enforcement behaviors.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
templates/vibration-sensor.yaml Adds required partOf relation constraint targeting equipment.
templates/temp-sensor.yaml Adds required partOf relation constraint targeting equipment.
templates/equipment.yaml Introduces an equipment template used as a constraint target.
internal/core/testdata/valid_template.yaml Updates test template to include a sample constraint section.
internal/core/metadata.go Extends AssetTemplate with TemplateConstraints/RelationConstraint definitions.
internal/core/meta_handler.go Adds constraints check subject and enforces/warns on relation-create violations with rollback.
internal/core/loader.go Validates template constraints after directory load.
internal/core/loader_test.go Adds assertions for loaded constraints and a negative test for unknown target_template.
internal/core/events.go Adds constraint-violation event subject and publisher method.
internal/core/constraints.go New evaluator/reporting logic plus template-constraint validation and error formatting.
internal/core/constraints_test.go Tests evaluator behavior, enforce-mode rollback, warn-mode publishing, and catalog check.
internal/core/config.go Adds constraints.enforcement config with defaults and validation.
internal/core/config_test.go Tests constraints config defaults, YAML loading, and invalid value rejection.
docs/USER_GUIDE.md Documents template constraints, enforcement modes, subjects, and CLI usage.
deploy/configs/core/config.staging.yaml Sets constraints.enforcement: warn.
deploy/configs/core/config.prod.yaml Sets constraints.enforcement: warn.
deploy/configs/core/config.dev.yaml Sets constraints.enforcement: warn.
cmd/core/main.go Adds --check-constraints CLI and wires config enforcement into MetaHandler.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +566 to +570
_ = h.store.DeleteRelation(relation.ID)
h.reply(msg, Response{Success: false, Error: err.Error()})
return
} else if !h.allowConstraintViolations(violations) {
_ = h.store.DeleteRelation(relation.ID)
Comment thread internal/core/loader.go
Comment on lines 42 to 49
path := filepath.Join(dir, entry.Name())
if err := l.LoadFromFile(path); err != nil {
return fmt.Errorf("failed to load template (%s): %w", path, err)
}
}

return nil
return validateTemplateConstraints(l)
}
Comment on lines +100 to +112
if count > 0 {
zero := 0
violations = append(violations, newConstraintViolation(
asset,
ConstraintForbiddenRelation,
constraint,
count,
nil,
&zero,
fmt.Sprintf("asset %s forbids %s relation(s) to template %s, found %d",
asset.ID, constraint.Type, constraint.TargetTemplate, count),
))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants