CPN Schema Reference
Overview
This document provides a complete reference for the CPN (Customer Part Number) Schema YAML specification. The schema defines the structure and constraints for CPN generation schemes in the Duro PLM system.
Schema Information
Schema Version: 1.0
JSON Schema:
https://json-schema.org/draft-07/schema#
Type: Object
Root Level Properties
version
string
Yes
Version of the CPN schema. Must match pattern ^\d+\.\d+$
schema_type
string
Yes
Must be "id_generation_scheme"
settings
object
Yes
Global settings for CPN generation
elements
array
Yes
Array of element definitions
examples
array
Yes
Array of example CPNs that follow the scheme
Settings Object
The settings
object contains global configuration options for CPN generation.
settings:
allow_override: boolean # Default: false
allow_freeform: boolean # Default: false
override_elements: [string] # Default: null (all elements)
freeform_validation: # Optional, only used when allow_freeform is true
pattern: string # Regex pattern for validation
max_length: integer # Maximum character length
description: string # Human-readable format description
allow_override
boolean
No
false
Whether manual CPN override is allowed. If false
, the user must always accept the system-generated CPN. If true
, the user may enter another CPN (see allow_freeform
for rules).
allow_freeform
boolean
No
false
Defines how overrides behave. If false
, overrides must still conform to the YAML scheme's format and validation rules. If true
, overrides may be any unique valid string.
override_elements
array
No
null
Array of element names that can be overridden individually. Only applies when allow_override
is true
. See "Element-Level Override Control" section below for details.
freeform_validation
object
No
-
Custom validation rules for freeform overrides. Only applies when allow_freeform
is true
. If not provided, defaults to alphanumeric characters, hyphens, and underscores with 50 character limit.
Freeform Validation Object
When allow_freeform
is true
, you can optionally specify custom validation rules:
pattern
string
No
Regex pattern that freeform CPNs must match. If not specified, uses default pattern ^[a-zA-Z0-9\-_]+$
max_length
integer
No
Maximum length for freeform CPNs. If not specified or ≤ 0, defaults to 50 characters
description
string
No
Human-readable description of the format requirements shown to users
Freeform Validation Examples
Basic freeform with default validation:
settings:
allow_override: true
allow_freeform: true
# Uses default pattern ^[a-zA-Z0-9\-_]+$ with 50 character limit
Custom pattern for company naming convention:
settings:
allow_override: true
allow_freeform: true
freeform_validation:
pattern: "^[A-Z]{2,4}-\\d{4,6}$"
max_length: 20
description: "Format: 2-4 letters, hyphen, 4-6 digits"
Flexible pattern with length limit:
settings:
allow_override: true
allow_freeform: true
freeform_validation:
pattern: "^[A-Z][A-Z0-9\\-_]*$" # Must start with uppercase letter
max_length: 25
description: "Must start with uppercase letter, followed by letters, numbers, hyphens, or underscores"
Element-Level Override Control
The override_elements
setting provides granular control over which specific elements in your CPN scheme can be overridden by users. This is useful when you want to allow customization of only certain parts of the CPN while keeping others fixed.
Override Elements Behavior
null
(default)
All elements are overrideable when allow_override
is true
["element1", "element2"]
Only the specified elements can be overridden
Override Elements Examples
Allow override of specific elements only:
settings:
allow_override: true
allow_freeform: false
override_elements: ["variant"] # Only variant can be overridden
elements:
- type: "list"
name: "category"
# ... category element (NOT overrideable)
- type: "numeric_counter"
name: "sequence"
# ... sequence element (NOT overrideable)
- type: "list"
name: "variant"
values: ["A", "B", "C"]
# This variant element CAN be overridden
Allow all elements to be overridden (default behavior):
settings:
allow_override: true
# override_elements not specified = all elements overrideable
Behavior Matrix
false
false
ignored
User must accept the system-generated CPN. No manual input allowed.
false
true
ignored
Same as above — allow_freeform
has no effect when allow_override
is false
.
true
false
null
(default)
User may override entire CPN or individual elements, but values must conform to YAML scheme rules.
true
false
["element1"]
User may override only specified elements. Values must conform to each element's validation rules.
true
true
null
(default)
User may override with freeform text OR override individual elements. Freeform validates against global freeform_validation
.
true
true
["element1"]
User may override with freeform text OR override specified elements with their element-level rules.
Elements
The elements
array contains definitions for each component of the CPN. Each element must be one of the following types:
list
— selects a value from a predefined list or referenceconstant
— inserts a fixed value such as a delimiter or prefixnumeric_counter
— generates sequential numeric integer values within a rangehex_counter
— generates sequential hexadecimal values within a rangefree
— allows user‑entered free‑form text validated by a regex and max lengthgroup
— bundles multiple elements into a single logical unit
Common Element Properties
All elements include these base properties:
type
string
Yes
Element type identifier (e.g., list
, constant
, numeric_counter
, etc.).
name
string
Yes
Unique name for the element.
required
boolean
No
Whether the element must appear in every generated CPN. Defaults to false
.
allow_freeform
boolean
No
Whether this element accepts freeform values beyond its defined constraints when overridden. Defaults to false
. Only applies when the element is listed in override_elements
.
freeform_validation
object
No
Custom validation rules for element-level freeform overrides. Only applies when allow_freeform
is true
for this element.
attachedTo
array
No
Names of one or more elements that this element is scoped to. Ensures values are unique within the context of the attached element(s).
About type
type
Specifies what kind of element is being defined. Must be one of: list
, constant
, numeric_counter
, hex_counter
, free
, or group
. This property determines how the element behaves in generation.
About name
name
A unique identifier for the element. This is used internally to reference the element (e.g., in attachedTo
) and must be unique within the scheme. Names should be descriptive (e.g., prefix
, sequence
, variant
) and not include spaces.
About required
required
Indicates whether the element must be present in every generated CPN.
If
true
, the element is always included.If
false
, the element may be omitted (e.g., optional group for free‑form suffixes).
Defaults to false
if not specified.
About allow_freeform
(Element-Level)
allow_freeform
(Element-Level)When an element has allow_freeform: true
and is listed in the override_elements
array, users can provide custom values that go beyond the element's normal constraints. For example, a list element with values ["A", "B", "C"]
could accept "Z"
as an override if allow_freeform: true
.
If
true
, the element accepts freeform values when overridden (validated againstfreeform_validation
if provided)If
false
or omitted, the element only accepts values that conform to its type-specific rulesOnly applies when the element is included in
settings.override_elements
About freeform_validation
(Element-Level)
freeform_validation
(Element-Level)Provides custom validation rules for individual element freeform overrides, following the same structure as global freeform_validation
:
freeform_validation:
pattern: "^[A-Z]{1,3}$" # Regex pattern
max_length: 10 # Maximum character length
description: "1-3 uppercase letters" # User-friendly description
If not provided, defaults to the same pattern as global freeform validation (alphanumeric, hyphens, underscores, 50 character limit).
About attachedTo
attachedTo
The attachedTo
property is commonly used with counters and variants to ensure that their values remain unique within the context of one or more parent elements. For example, a sequence counter attached to a prefix
will generate independent sequences for each prefix value. This prevents conflicts across different contexts without forcing a single global sequence. Multiple attachments are supported (e.g., ['prefix', 'sequence']
), allowing values to be scoped by combinations of elements when needed.
Example
- type: "numeric_counter"
name: "sequence"
required: true
attachedTo: ['prefix']
format:
min_value: 1
max_value: 9999
List Element
A list element allows selection from a predefined set of values. It’s typically used for intelligent schemes where the CPN prefix or another segment is determined by categories, part families, or other fixed options.
Values can be defined inline as strings, as objects with metadata, or pulled dynamically using template references. Optionally, a regex validation pattern can be applied for additional checks.
- type: "list"
name: string
required: boolean
allow_freeform: boolean
freeform_validation:
pattern: string
max_length: integer
description: string
use: string
values: (string[] | object[] | template_string)
validation:
pattern: string
values
array|string
Yes
Array of values or template reference
allow_freeform
boolean
No
Whether to accept freeform values beyond the list when overridden
freeform_validation
object
No
Custom validation for element-level freeform values
validation.pattern
string
No
Regex pattern for additional validation of list values
Values need to be one of:
Array of strings
Array of objects with
id
,name
, and optionaldescription
Template reference in format
${{namespace.field}}
List Element Examples
- type: "list"
name: "category"
required: true
values:
# Simple string array
- "410"
- "591"
- "423"
# OR object array with metadata
use: "id" # Optional: use when values have id/name pairs
values:
- id: "410"
name: "Screws"
description: "Mechanical fasteners"
- id: "591"
name: "Resistors"
description: "Electronic components"
# OR reference to system values
values: ${{ duro.categories }}
validation:
pattern: "^\\d{3}$" # Optional regex pattern
# Element-level freeform override example
- type: "list"
name: "variant"
required: true
values: ["A", "B", "C"]
allow_freeform: true
freeform_validation:
pattern: "^[A-Z]{1,3}$"
max_length: 3
description: "1-3 uppercase letters"
# Users can select A, B, C OR enter custom values like "Z", "XY", "ABC"
Constant Element
Constants are fixed values that are injected into every generated CPN. They can be used for delimiters (such as -
or .
), prefixes, or any string that should always appear in the same position. A constant can be any string length.
- type: "constant"
name: string
required: boolean
value: string
value
string
Yes
The constant value
Constant Element Example
- type: "constant"
name: "separator"
required: true
value: "-"
This inserts a dash (-) as a separator between other CPN elements.
- type: "constant"
name: "prefix"
required: true
value: "TMP-"
This ensures every CPN begins with the prefix TMP-
, e.g., TMP-10001
.
Numeric Counter
A numeric counter generates sequential numbers within the specified range. It is always fixed length, determined by the number of digits in format.max_value
, and the system automatically prepends leading zeros to match that length.
- type: "numeric_counter"
name: string
required: boolean
attachedTo: string[]
format:
min_value: integer
max_value: integer
attachedTo
array
No
Names of elements this counter is attached to
format.min_value
integer
Yes
Minimum value (must be ≥ 0)
format.max_value
integer
Yes
Maximum value
Numeric Counter Example
- type: "numeric_counter"
name: "sequence"
required: true
attachedTo: [category]
format:
min_value: 1
max_value: 99999
This numeric counter generates a 5‑digit sequence ranging from 00001
to 99999
. The length is determined by the number of digits in max_value
(here, 5 digits). Leading zeros are automatically prepended so that every value is fixed length.
Because in this example the counter is attached to the prefix
element, its sequence is tracked separately for each prefix value. This ensures uniqueness within the context of the prefix, rather than across all CPNs.
For example:
First three CPNs for prefix
100
:100-00001
100-00002
100-00003
Then the first CPN for prefix
101
:101-00001
Returning to prefix
100
, the next generated CPN continues from its own sequence:100-00004
Hex Counter
A hex counter generates sequential values in hexadecimal within the specified range. It is always fixed length, determined by the number of digits in format.max_value
, and the system automatically prepends leading zeros to match that length.
type: "hex_counter"
name: string
required: boolean
attachedTo: string[]
format:
min_value: string
max_value: string
attachedTo
array
No
Names of elements this counter is attached to
format.min_value
string
Yes
Minimum value in hex (pattern: ^[0-9A-F]+$
)
format.max_value
string
Yes
Maximum value in hex (pattern: ^[0-9A-F]+$
)
Hex Counter Example
2‑Digit Hex Sequence
- type: "hex_counter"
name: "sequence"
required: true
attachedTo: [category]
format:
min_value: "0"
max_value: "FF"
Generates values like 00, 01, … FE, FF. Always fixed at 2 hex digits with zero padding.
Group Element
Groups allow you to combine multiple elements into a single logical unit. They are especially useful for creating more complex structures and, when used with attachedTo
, can make the scoping of values clearer and less error‑prone.
A common pattern is grouping a prefix and a sequence into a base_cpn
group, so that a variant can attach to the group instead of attaching separately to both prefix and sequence. This ensures that the variant’s values are tracked in the context of the complete base number, improving clarity and reducing ambiguity in the YAML configuration.
type: "group"
name: string
required: boolean
elements: array
elements
array
Yes
Array of nested element definitions
Group elements can contain any other element type, including:
List elements
Constant elements
Free text elements (only available within groups)
Numeric counters
Hex counters
Group Element Examples
Example 1
- type: "group"
name: "variant group"
required: false
elements:
- type: "constant"
name: "separator"
value: "."
- type: "free"
name: "variant"
validation:
pattern: "^\\w{1,10}$"
This group defines an optional variant section for the CPN. It always inserts a period (.) as a separator, followed by a free‑form variant field. The variant allows any word character (A–Z, a–z, 0–9, _) with a length between 1 and 10.
Example CPNs:
123-4567.A
123-4567.TEST1
Example 2
- type: "group"
name: "base_cpn"
required: true
elements:
- type: "list"
name: "prefix"
required: true
values:
- id: "Category100"
value: "100"
validation:
pattern: "^[1-9][0-9]{2}$"
- type: "constant"
name: "delimiter_1"
value: "-"
- type: "numeric_counter"
name: "sequence"
required: true
attachedTo: ['prefix']
format:
min_value: 1
max_value: 99999
validation:
pattern: "^[1-9][0-9]{4}$"
- type: "constant"
name: "delimiter_2"
value: "-"
- type: "list"
name: "variant"
required: true
attachedTo: ['base_cpn']
values:
- id: "A"
value: "A"
- id: "B"
value: "B"
validation:
pattern: "^[A-Z]{1}$"
In this example:
The group
base_cpn
combinesprefix
andsequence
into a single logical unit.The
variant
is attached tobase_cpn
, so its values are tracked in the context of the complete base number rather than being tied individually to bothprefix
andsequence
.This approach makes the YAML more readable and unambiguous compared to listing multiple
attachedTo
references separately.
Free Text Element
The free
element allows users to provide custom input that isn’t generated automatically. Validations ensure that free‑form values follow defined rules, such as a regex pattern and maximum length. This is commonly used for suffixes, variant labels, or other optional identifiers that can be user‑entered.
Note: allow_override
must be true for free
to be available for user entry.
- type: "free"
name: string
validation:
pattern: string
max_length: integer
validation.pattern
string
Yes
Regex pattern for validation
validation.max_length
integer
Yes
Maximum length of the text
Examples Array
The examples
array must contain at least one example CPN that follows the defined scheme.
examples:
- "410-0001"
- "ELEC-591-0042.variant"
Template References
Template references allow dynamic value lists to be pulled from the system:
values: "${{ namespace.field }}"
Template references must match the pattern: ^\$\{\{\s*[\w\.]+\s*\}\}$
. Currently, the only supported namespace is duro
. and the only supported fields are categories
and families
.
Complete Schema Examples
Example 1: Basic Schema with Element-Level Overrides
$schema: "https://json-schema.org/draft-07/schema#"
version: "1.0"
schema_type: "id_generation_scheme"
settings:
allow_override: true
allow_freeform: true
override_elements: ["variant"] # Only variant can be overridden individually
freeform_validation:
pattern: "^[A-Z]{2,4}-\\d{4,6}$"
max_length: 20
description: "Format: 2-4 letters, hyphen, 4-6 digits"
elements:
- type: list
name: category
required: true
use: id
values:
- id: "410"
name: Screws
description: Mechanical fasteners
validation:
pattern: "^\\d{3}$"
- type: constant
name: separator
required: true
value: "-"
- type: numeric_counter
name: sequence
required: true
attachedTo: [category]
format:
min_value: 1
max_value: 9999
- type: list
name: variant
required: true
attachedTo: [category, sequence]
values: ["A", "B", "C"]
allow_freeform: true
freeform_validation:
pattern: "^[A-Z]{1,3}$"
max_length: 3
description: "1-3 uppercase letters"
examples:
- "410-0001-A"
- "410-0001-Z" # Custom variant override
Example 2: Mixed Override Control
version: "1.0"
schema_type: "id_generation_scheme"
settings:
allow_override: true
allow_freeform: false
override_elements: ["category", "variant"] # Multiple elements can be overridden
elements:
- type: list
name: category
required: true
values: ["ELEC", "MECH", "SOFT"]
# allow_freeform not specified = false (must pick from list)
- type: constant
name: delimiter1
value: "-"
- type: numeric_counter
name: sequence
required: true
attachedTo: [category]
format:
min_value: 1
max_value: 999
# This element is NOT in override_elements, so cannot be overridden
- type: constant
name: delimiter2
value: "-"
- type: list
name: variant
required: true
values: ["STD", "ALT"]
allow_freeform: true
freeform_validation:
pattern: "^[A-Z]{2,5}$"
max_length: 5
description: "2-5 uppercase letters"
# Users can pick STD/ALT OR enter custom variants like "PROTO"
examples:
- "ELEC-001-STD"
- "ELEC-001-PROTO" # Custom variant
- "CHEM-001-STD" # Custom category override
Validation Rules
Version must match pattern
^\d+\.\d+$
Schema type must be exactly
"id_generation_scheme"
All referenced element names must be unique within their scope
Counter ranges must be valid (min ≤ max) and min must be ≥ 0
Hex counter values must be valid hexadecimal strings
Template references must match the specified pattern
At least one example CPN must be provided
Group elements must contain at least one element
All elements must be valid and referenced correctly
Groups can be optional even if they contain required elements
Best Practices
Structure
Place required elements before optional ones
Group related elements together
Use consistent naming conventions
Validation
Always include regex patterns for list values
Set appropriate counter ranges for your volume
Consider case sensitivity implications
Documentation
Include descriptions for all list values
Provide diverse examples
Comment complex regex patterns
Maintenance
Use template references for shared value sets
Keep counter ranges generous for future growth
Consider versioning implications
Last updated