Liking cljdoc? Tell your friends :D

wagoe.core.config.feature-flags

Feature flag management for gradual rollout of new functionality.

This namespace provides pure functions for checking feature flags based on environment variables and configuration.

The environment map is always a parameter. Each of these functions used to have a convenience arity that called (System/getenv) itself, in a namespace whose own docstring promised no side effects — so the promise and the code disagreed, and every caller of a 1-arity was reading ambient process state from the functional core (BOU-302). The convenience lives in wagoe.platform.shell.feature-flags, which is a shell namespace and may read the environment.

Design Principles:

  • Pure functions: No side effects, configuration passed as parameter
  • Explicit defaults: Clear behavior when flag not set
  • Type-safe: Boolean coercion with validation
  • Backward compatible: Defaults to false for new features
Feature flag management for gradual rollout of new functionality.

This namespace provides pure functions for checking feature flags based on
environment variables and configuration.

The environment map is always a parameter. Each of these functions used to
have a convenience arity that called `(System/getenv)` itself, in a
namespace whose own docstring promised no side effects — so the promise and
the code disagreed, and every caller of a 1-arity was reading ambient
process state from the functional core (BOU-302). The convenience lives in
`wagoe.platform.shell.feature-flags`, which is a shell namespace and may
read the environment.

Design Principles:
- Pure functions: No side effects, configuration passed as parameter
- Explicit defaults: Clear behavior when flag not set
- Type-safe: Boolean coercion with validation
- Backward compatible: Defaults to false for new features
raw docstring

wagoe.core.interceptor

Core interceptor pipeline execution engine.

Provides a lightweight interceptor chain pattern for handling cross-cutting concerns like logging, metrics, validation, and error handling in a declarative way.

Interceptors have three lifecycle functions:

  • :enter - executed in forward order during pipeline execution
  • :leave - executed in reverse order during successful completion
  • :error - executed in reverse order when an exception occurs

The context map is threaded through all interceptors and contains:

  • :request - original request data
  • :op - operation identifier (keyword)
  • :system - dependency injection map
  • :correlation-id - request correlation ID
  • :halt? - flag to short-circuit pipeline execution
  • other keys added by interceptors during execution
Core interceptor pipeline execution engine.

Provides a lightweight interceptor chain pattern for handling cross-cutting
concerns like logging, metrics, validation, and error handling in a
declarative way.

Interceptors have three lifecycle functions:
- :enter - executed in forward order during pipeline execution
- :leave - executed in reverse order during successful completion
- :error - executed in reverse order when an exception occurs

The context map is threaded through all interceptors and contains:
- :request - original request data
- :op - operation identifier (keyword)
- :system - dependency injection map
- :correlation-id - request correlation ID
- :halt? - flag to short-circuit pipeline execution
- other keys added by interceptors during execution
raw docstring

wagoe.core.interceptor-context

Context schema and validation for interceptor pipelines.

Defines the structure and validation rules for the context map that flows through interceptor pipelines, ensuring consistent data flow and preventing common runtime errors.

Context schema and validation for interceptor pipelines.

Defines the structure and validation rules for the context map that flows
through interceptor pipelines, ensuring consistent data flow and preventing
common runtime errors.
raw docstring

wagoe.core.schema

Canonical schemas for the core library's primary domain shapes.

Documents the two central data structures used across the framework:

  1. Validation result — returned by all core validation functions
  2. Interceptor context — the map that flows through interceptor pipelines

These schemas are provided as documentation references. Runtime validation of these shapes lives in wagoe.core.interceptor-context and wagoe.core.validation.result respectively.

Canonical schemas for the core library's primary domain shapes.

Documents the two central data structures used across the framework:

1. Validation result — returned by all core validation functions
2. Interceptor context — the map that flows through interceptor pipelines

These schemas are provided as documentation references. Runtime validation
of these shapes lives in wagoe.core.interceptor-context and
wagoe.core.validation.result respectively.
raw docstring

wagoe.core.utils.case-conversion

Generic case conversion utilities for API and data transformations.

This namespace provides reusable case conversion utilities that handle transformations between different naming conventions commonly used in APIs:

  • camelCase (JavaScript/JSON APIs)
  • kebab-case (Clojure idioms)
  • snake_case (Database/SQL)

These functions are designed to be nil-safe and handle nested data structures where appropriate.

Usage: (:require [wagoe.core.utils.case-conversion :as case-conversion])

(case-conversion/camel-case->kebab-case-map {:userId "123" :tenantId "456"}) ;; => {:user-id "123" :tenant-id "456"}

Generic case conversion utilities for API and data transformations.

This namespace provides reusable case conversion utilities that handle
transformations between different naming conventions commonly used in APIs:
- camelCase (JavaScript/JSON APIs)
- kebab-case (Clojure idioms)
- snake_case (Database/SQL)

These functions are designed to be nil-safe and handle nested data structures
where appropriate.

Usage:
(:require [wagoe.core.utils.case-conversion :as case-conversion])

(case-conversion/camel-case->kebab-case-map {:userId "123" :tenantId "456"})
;; => {:user-id "123" :tenant-id "456"}
raw docstring

wagoe.core.utils.pii-redaction

Shared PII redaction utilities used by error reporting adapters.

Shared PII redaction utilities used by error reporting adapters.
raw docstring

wagoe.core.utils.validation

Value predicates the CLI layer validates arguments with.

It also held a second implementation of validate-with-transform, validate-cli-args, validate-request and the result accessors — the same names wagoe.core.validation defined, with a different implementation and no compiled-schema cache. Nothing outside its own tests called them (BOU-323).

Schema validation goes through wagoe.core.validation, whose validators are compiled once and cached; result shapes live in wagoe.core.validation.result.

Value predicates the CLI layer validates arguments with.

It also held a second implementation of validate-with-transform,
validate-cli-args, validate-request and the result accessors — the same
names wagoe.core.validation defined, with a different implementation and no
compiled-schema cache. Nothing outside its own tests called them (BOU-323).

Schema validation goes through wagoe.core.validation, whose validators are
compiled once and cached; result shapes live in
wagoe.core.validation.result.
raw docstring

wagoe.core.validation

Compiled Malli validators, explainers and decoders, cached.

This is all this namespace does. It used to also carry a second copy of the validation-result API — validate-with-transform, validation-passed?, get-validation-errors, success-result, failure-result, error-map — wrapping wagoe.core.validation.result, and a third copy lived in wagoe.core.utils.validation with a different implementation of the same name. Two answers to one question, neither of them called by anything outside their own tests (BOU-323).

Worse, validate-with-transform chose its return shape at runtime from the :devex-validation feature flag: {:valid? true :data …} with the flag off, a structured success-result with it on. A function whose result shape depends on an environment variable cannot be typed, tested or documented — which is what ADR-036 §2 settles, and why the fork is gone rather than ported.

Result shapes live in wagoe.core.validation.result; rule helpers in wagoe.core.validation.registry; error codes in wagoe.core.validation.codes.

Compiled Malli validators, explainers and decoders, cached.

This is all this namespace does. It used to also carry a second copy of the
validation-result API — validate-with-transform, validation-passed?,
get-validation-errors, success-result, failure-result, error-map — wrapping
wagoe.core.validation.result, and a third copy lived in
wagoe.core.utils.validation with a different implementation of the same
name. Two answers to one question, neither of them called by anything
outside their own tests (BOU-323).

Worse, validate-with-transform chose its *return shape* at runtime from the
:devex-validation feature flag: {:valid? true :data …} with the flag off,
a structured success-result with it on. A function whose result shape
depends on an environment variable cannot be typed, tested or documented —
which is what ADR-036 §2 settles, and why the fork is gone rather than
ported.

Result shapes live in wagoe.core.validation.result; rule helpers in
wagoe.core.validation.registry; error codes in wagoe.core.validation.codes.
raw docstring

wagoe.core.validation.behavior

Behavior Specification DSL for validation testing.

Data-first DSL for declarative validation testing with reusable scenarios. All core functions are pure; only test expansion emits side-effectful deftest forms.

Example usage:

;; Define a scenario (def email-required-scenario {:name "email-required-missing" :description "User email is required" :module :user :schema-key :User :base {:name "Test User" :email "test@example.com"} :mutations [(remove-field :email)] :action validate-user-fn :assertions [{:expect :failure :codes #{:user.email/required} :snapshot? true}]})

;; Compile to test functions (compile-scenarios [email-required-scenario] {}) ;; => [["email-required-missing" (fn [] ...)]]

;; Or use macro for deftest generation (defbehavior-suite user-validation-tests [email-required-scenario email-format-scenario])

Behavior Specification DSL for validation testing.

Data-first DSL for declarative validation testing with reusable scenarios.
All core functions are pure; only test expansion emits side-effectful deftest forms.

Example usage:

  ;; Define a scenario
  (def email-required-scenario
    {:name "email-required-missing"
     :description "User email is required"
     :module :user
     :schema-key :User
     :base {:name "Test User" :email "test@example.com"}
     :mutations [(remove-field :email)]
     :action validate-user-fn
     :assertions [{:expect :failure
                  :codes #{:user.email/required}
                  :snapshot? true}]})

  ;; Compile to test functions
  (compile-scenarios [email-required-scenario] {})
  ;; => [["email-required-missing" (fn [] ...)]]

  ;; Or use macro for deftest generation
  (defbehavior-suite user-validation-tests
    [email-required-scenario
     email-format-scenario])
raw docstring

wagoe.core.validation.codes

Error code catalog and definitions.

This namespace defines standardized error codes used across all validation operations, ensuring consistency in error reporting and enabling i18n support.

Error Code Format: :domain.field/error-type

Examples: :user.email/required :user.email/invalid-format :user.role/invalid-value :billing.amount/out-of-range

Categories:

  • :required - Missing required field
  • :invalid-format - Format validation failure
  • :invalid-value - Value doesn't match allowed values
  • :out-of-range - Numeric/date value outside allowed range
  • :too-short - String/collection below minimum length
  • :too-long - String/collection above maximum length
  • :duplicate - Uniqueness constraint violation
  • :not-found - Referenced entity doesn't exist
  • :forbidden - Operation not allowed by business rules
  • :dependency - Depends on another field/condition

Design Principles:

  • Codes are keywords for easy matching
  • Hierarchical naming for discoverability
  • Module-specific prefixes for isolation
  • Generic suffixes for cross-module consistency
Error code catalog and definitions.

This namespace defines standardized error codes used across all validation
operations, ensuring consistency in error reporting and enabling i18n support.

Error Code Format:
  :domain.field/error-type

Examples:
  :user.email/required
  :user.email/invalid-format
  :user.role/invalid-value
  :billing.amount/out-of-range

Categories:
  - :required         - Missing required field
  - :invalid-format   - Format validation failure
  - :invalid-value    - Value doesn't match allowed values
  - :out-of-range     - Numeric/date value outside allowed range
  - :too-short        - String/collection below minimum length
  - :too-long         - String/collection above maximum length
  - :duplicate        - Uniqueness constraint violation
  - :not-found        - Referenced entity doesn't exist
  - :forbidden        - Operation not allowed by business rules
  - :dependency       - Depends on another field/condition

Design Principles:
  - Codes are keywords for easy matching
  - Hierarchical naming for discoverability
  - Module-specific prefixes for isolation
  - Generic suffixes for cross-module consistency
raw docstring

wagoe.core.validation.context

Contextual message rendering and example payload generation.

This namespace extends the message templating system to support:

  • Operation-aware messages (create, update, delete)
  • Role-based messaging
  • Multi-tenant context
  • Example payload generation using Malli

Design Principles:

  • Opt-in: Example generation requires explicit flag
  • Deterministic: Uses fixed seeds for reproducible examples
  • Redacted: Sensitive fields are replaced with placeholders
  • Minimal: Examples include only required + relevant fields
Contextual message rendering and example payload generation.

This namespace extends the message templating system to support:
- Operation-aware messages (create, update, delete)
- Role-based messaging
- Multi-tenant context
- Example payload generation using Malli

Design Principles:
- Opt-in: Example generation requires explicit flag
- Deterministic: Uses fixed seeds for reproducible examples
- Redacted: Sensitive fields are replaced with placeholders
- Minimal: Examples include only required + relevant fields
raw docstring

wagoe.core.validation.coverage

Pure coverage computation and reporting for validation rules.

All functions are pure with no side effects. Data is injected via function parameters. File I/O belongs in test helpers or Kaocha plugins.

Example usage:

;; Compute coverage (def result (compute {:registered #{:user.email/required :user.name/required} :executed #{:user.email/required} :by-module {:user #{:user.email/required :user.name/required}}})) ;; => {:total 2 :executed 1 :pct 50.0 :per-module {...} :missing #{:user.name/required}}

;; Generate human-readable report (human-report result) ;; => "Coverage: 50.0% (1/2) Module: user - 50.0% (1/2) Missing: :user.name/required"

;; Generate EDN report for file export (edn-report result) ;; => {:coverage 50.0 :total 2 :executed 1 :timestamp "..." ...}

Pure coverage computation and reporting for validation rules.

All functions are pure with no side effects. Data is injected via function parameters.
File I/O belongs in test helpers or Kaocha plugins.

Example usage:

  ;; Compute coverage
  (def result (compute {:registered #{:user.email/required :user.name/required}
                       :executed #{:user.email/required}
                       :by-module {:user #{:user.email/required :user.name/required}}}))
  ;; => {:total 2 :executed 1 :pct 50.0 :per-module {...} :missing #{:user.name/required}}

  ;; Generate human-readable report
  (human-report result)
  ;; => "Coverage: 50.0% (1/2)
Module: user - 50.0% (1/2)
Missing: :user.name/required"

  ;; Generate EDN report for file export
  (edn-report result)
  ;; => {:coverage 50.0 :total 2 :executed 1 :timestamp "..." ...}
raw docstring

wagoe.core.validation.generators

Property-based test data generators for validation testing.

This namespace provides pure functions for generating test data from Malli schemas, supporting both valid and invalid data generation with deterministic seeding.

Key Features:

  • Valid data generation conforming to schemas
  • Invalid data generation with specific violation types
  • Wagoe case generation (min/max values, edge cases)
  • Rule-aware generation for targeted testing
  • Deterministic seeding for reproducible tests

Design Principles:

  • Pure functions only (no side effects, no I/O)
  • Schema lookup via injected functions (no direct registry access)
  • Deterministic with explicit seeds
  • FC/IS compliant (all generators are functional core)

Usage: ;; Generate valid data (gen-valid-one User {:seed 42}) => {:id #uuid "..." :email "user@example.com" ...}

;; Generate invalid data (gen-invalid-one User :missing-required {:seed 42 :field :email}) => {:id #uuid "..." :name "John" ...} ; missing :email

;; Generate boundary cases (gen-boundaries User {:seed 42}) => [{:name "" ...} {:name "a" ...} {:name "aaa..." ...}]

Property-based test data generators for validation testing.

This namespace provides pure functions for generating test data from Malli schemas,
supporting both valid and invalid data generation with deterministic seeding.

Key Features:
- Valid data generation conforming to schemas
- Invalid data generation with specific violation types
- Wagoe case generation (min/max values, edge cases)
- Rule-aware generation for targeted testing
- Deterministic seeding for reproducible tests

Design Principles:
- Pure functions only (no side effects, no I/O)
- Schema lookup via injected functions (no direct registry access)
- Deterministic with explicit seeds
- FC/IS compliant (all generators are functional core)

Usage:
  ;; Generate valid data
  (gen-valid-one User {:seed 42})
  => {:id #uuid "..." :email "user@example.com" ...}
  
  ;; Generate invalid data
  (gen-invalid-one User :missing-required {:seed 42 :field :email})
  => {:id #uuid "..." :name "John" ...} ; missing :email
  
  ;; Generate boundary cases
  (gen-boundaries User {:seed 42})
  => [{:name "" ...} {:name "a" ...} {:name "aaa..." ...}]
raw docstring

wagoe.core.validation.messages

Error message templating and suggestion engine.

This namespace provides message template resolution, parameter interpolation, and intelligent suggestion generation for validation errors.

Key Features:

  • Template resolution with fallback chain (domain → shared → default)
  • Safe parameter interpolation with sanitization
  • 'Did you mean?' suggestion engine using Damerau-Levenshtein distance
  • Expected value, range, and regex hints
  • Dependency and resolution step formatting

Design Principles:

  • Non-breaking: Falls back to legacy messages if template missing
  • i18n-ready: All templates support parameter interpolation
  • Pure functions: No side effects, deterministic output
  • Sanitized: PII and sensitive data are filtered
Error message templating and suggestion engine.

This namespace provides message template resolution, parameter interpolation,
and intelligent suggestion generation for validation errors.

Key Features:
- Template resolution with fallback chain (domain → shared → default)
- Safe parameter interpolation with sanitization
- 'Did you mean?' suggestion engine using Damerau-Levenshtein distance
- Expected value, range, and regex hints
- Dependency and resolution step formatting

Design Principles:
- Non-breaking: Falls back to legacy messages if template missing
- i18n-ready: All templates support parameter interpolation
- Pure functions: No side effects, deterministic output
- Sanitized: PII and sensitive data are filtered
raw docstring

wagoe.core.validation.registry

Pure helpers for validation rule definitions.

Rule Format: {:rule-id keyword ; Unique identifier (e.g., :user.email/required) :description string ; Human-readable description :category keyword ; :schema | :business | :cross-field | :context :module keyword ; Module name (e.g., :user, :billing) :fields [keyword] ; Affected fields :error-code keyword ; Default error code :validator-fn (fn [data] ...) ; Actual validation function :dependencies [rule-id] ; Required rules (optional) :metadata map} ; Additional metadata (optional)

This namespace holds only pure rule-shape validation (no mutable state). The stateful in-process rule registry — registration, lookup, and execution tracking — lives in the shell at wagoe.platform.shell.validation-registry, so the functional core stays free of process state (FC/IS).

Pure helpers for validation rule definitions.

Rule Format:
  {:rule-id        keyword           ; Unique identifier (e.g., :user.email/required)
   :description    string            ; Human-readable description
   :category       keyword           ; :schema | :business | :cross-field | :context
   :module         keyword           ; Module name (e.g., :user, :billing)
   :fields         [keyword]         ; Affected fields
   :error-code     keyword           ; Default error code
   :validator-fn   (fn [data] ...)   ; Actual validation function
   :dependencies   [rule-id]         ; Required rules (optional)
   :metadata       map}              ; Additional metadata (optional)

This namespace holds only pure rule-shape validation (no mutable state). The
stateful in-process rule registry — registration, lookup, and execution
tracking — lives in the shell at wagoe.platform.shell.validation-registry,
so the functional core stays free of process state (FC/IS).
raw docstring

wagoe.core.validation.result

Standard validation result format and utilities.

This namespace defines the canonical result format for all validation operations in the Wagoe framework, supporting both schema validation and business rule validation with structured errors and warnings.

Result Format: {:valid? boolean ; Overall validation status :data map ; Validated/transformed data (if valid) :errors vector-of-error-maps ; Validation errors (if invalid) :warnings vector-of-warning-maps} ; Non-blocking warnings (optional)

Error/Warning Map Format: {:field keyword ; Field identifier :code keyword ; Error/warning code :message string ; Human-readable message :params map ; Template parameters :path vector ; Path to error location :rule-id keyword} ; Optional: validation rule ID

Design Principles:

  • Forward compatibility: new keys can be added without breaking existing code
  • I18n-ready: :code + :params enable future message translation
  • FC/IS compliant: pure data structures, no side effects

One shape, not two. This namespace used to expose devex-validation-enabled?, and wagoe.core.validation branched on it to decide whether to return {:valid? true :data …} or a structured result — a function whose return shape depended on an environment variable. ADR-036 §2 settles the shape, so the fork and this namespace's devex-validation-enabled? are gone. Nothing in src reads the flag now; the snapshot-test helper in libs/core/test still reads the env var directly (BOU-323).

Standard validation result format and utilities.

This namespace defines the canonical result format for all validation
operations in the Wagoe framework, supporting both schema validation
and business rule validation with structured errors and warnings.

Result Format:
  {:valid?   boolean                    ; Overall validation status
   :data     map                        ; Validated/transformed data (if valid)
   :errors   vector-of-error-maps       ; Validation errors (if invalid)
   :warnings vector-of-warning-maps}    ; Non-blocking warnings (optional)

Error/Warning Map Format:
  {:field   keyword                     ; Field identifier
   :code    keyword                     ; Error/warning code
   :message string                      ; Human-readable message
   :params  map                         ; Template parameters
   :path    vector                      ; Path to error location
   :rule-id keyword}                    ; Optional: validation rule ID

Design Principles:
- Forward compatibility: new keys can be added without breaking existing code
- I18n-ready: :code + :params enable future message translation
- FC/IS compliant: pure data structures, no side effects

One shape, not two. This namespace used to expose
`devex-validation-enabled?`, and wagoe.core.validation branched on it to
decide whether to return {:valid? true :data …} or a structured result — a
function whose return shape depended on an environment variable. ADR-036 §2
settles the shape, so the fork and this namespace's `devex-validation-enabled?`
are gone. Nothing in `src` reads the flag now; the snapshot-test helper in
`libs/core/test` still reads the env var directly (BOU-323).
raw docstring

wagoe.core.validation.snapshot

Pure snapshot capture, comparison, and serialization for validation testing.

This namespace provides data-only operations for snapshot testing:

  • capture: Create snapshot maps with metadata
  • stable-serialize: Deterministic EDN serialization
  • path-for: Compute snapshot file paths from test metadata
  • compare-snapshots: Deep comparison with detailed diffs

All functions are pure with no I/O. File operations belong in test helpers.

Example usage:

;; Capture a validation result (def snap (capture {:status :failure :errors [...]} {:schema-version "1.0" :seed 42 :meta {:test "user-email"}}))

;; Serialize deterministically (stable-serialize snap) ;; => "{:meta {:schema-version "1.0" :seed 42 ...} :result {...}}"_in

;; Compute file path (path-for {:ns 'wagoe.user.validation-test :test 'email-required :case 'missing}) ;; => "test/snapshots/validation/wagoe/user/validation_test/email_required__missing.edn"

;; Compare snapshots (compare-snapshots expected actual) ;; => {:equal? true :diff [nil nil nil]}

Snapshot format: {:meta {:schema-version "1.0" :seed 42 :test-ns 'wagoe.user.validation-test :test-name 'email-required :case-name 'missing :captured-at "2025-01-04"} :result <validation-result>}

Pure snapshot capture, comparison, and serialization for validation testing.

This namespace provides data-only operations for snapshot testing:
- capture: Create snapshot maps with metadata
- stable-serialize: Deterministic EDN serialization
- path-for: Compute snapshot file paths from test metadata
- compare-snapshots: Deep comparison with detailed diffs

All functions are pure with no I/O. File operations belong in test helpers.

Example usage:

  ;; Capture a validation result
  (def snap (capture {:status :failure :errors [...]} 
                    {:schema-version "1.0" :seed 42 :meta {:test "user-email"}}))

  ;; Serialize deterministically
  (stable-serialize snap)
  ;; => "{:meta {:schema-version \"1.0\" :seed 42 ...} :result {...}}"_in

  ;; Compute file path
  (path-for {:ns 'wagoe.user.validation-test :test 'email-required :case 'missing})
  ;; => "test/snapshots/validation/wagoe/user/validation_test/email_required__missing.edn"

  ;; Compare snapshots
  (compare-snapshots expected actual)
  ;; => {:equal? true :diff [nil nil nil]}

Snapshot format:
{:meta {:schema-version "1.0" 
        :seed 42 
        :test-ns 'wagoe.user.validation-test
        :test-name 'email-required
        :case-name 'missing
        :captured-at "2025-01-04"}
 :result <validation-result>}
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close