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

Property
Type
Required
Description

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
Property
Type
Required
Default
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:

Property
Type
Required
Description

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

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

allow_override
allow_freeform
override_elements
Behavior

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 reference

  • constant — inserts a fixed value such as a delimiter or prefix

  • numeric_counter — generates sequential numeric integer values within a range

  • hex_counter — generates sequential hexadecimal values within a range

  • free — allows user‑entered free‑form text validated by a regex and max length

  • group — bundles multiple elements into a single logical unit

Common Element Properties

All elements include these base properties:

Property
Type
Required
Description

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

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

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

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)

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 against freeform_validation if provided)

  • If false or omitted, the element only accepts values that conform to its type-specific rules

  • Only applies when the element is included in settings.override_elements

About 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

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
Property
Type
Required
Description

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:

  1. Array of strings

  2. Array of objects with id, name, and optional description

  3. 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
Property
Type
Required
Description

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
Property
Type
Required
Description

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
Property
Type
Required
Description

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
Property
Type
Required
Description

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 combines prefix and sequence into a single logical unit.

  • The variant is attached to base_cpn, so its values are tracked in the context of the complete base number rather than being tied individually to both prefix and sequence.

  • 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
Property
Type
Required
Description

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

  1. Version must match pattern ^\d+\.\d+$

  2. Schema type must be exactly "id_generation_scheme"

  3. All referenced element names must be unique within their scope

  4. Counter ranges must be valid (min ≤ max) and min must be ≥ 0

  5. Hex counter values must be valid hexadecimal strings

  6. Template references must match the specified pattern

  7. At least one example CPN must be provided

  8. Group elements must contain at least one element

  9. All elements must be valid and referenced correctly

  10. 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