---
title: "Custom Fields"
description: "Define and use custom metadata fields for your artifacts"
---

# Custom Fields

Custom fields extend artifacts with domain-specific metadata. Define fields for risk levels, compliance tags, cost estimates, team assignments, or any other data your process requires.

## Defining Custom Fields

### In Configuration

```yaml
# .tracertm/config.yaml
metadata:
  fields:
    # Enum field with fixed values
    - name: risk_level
      type: enum
      values: [low, medium, high, critical]
      default: medium
      description: "Risk assessment level"

    # String field
    - name: business_owner
      type: string
      required: false
      description: "Business stakeholder"

    # Number field
    - name: estimated_hours
      type: number
      min: 0
      max: 1000
      description: "Estimated effort in hours"

    # Boolean field
    - name: security_reviewed
      type: boolean
      default: false
      description: "Has passed security review"

    # Date field
    - name: target_date
      type: date
      description: "Target completion date"

    # Multi-select
    - name: affected_systems
      type: array
      item_type: string
      description: "Systems impacted by this change"
```

### Per Artifact Type

```yaml
# Different fields for different artifact types
metadata:
  by_type:
    feature:
      fields:
        - name: story_points
          type: number
          min: 1
          max: 21
        - name: sprint
          type: string
        - name: epic
          type: reference
          target_type: epic

    bug:
      fields:
        - name: severity
          type: enum
          values: [critical, major, minor, trivial]
        - name: reproducible
          type: boolean
          default: true
        - name: environment
          type: enum
          values: [production, staging, development]

    test:
      fields:
        - name: test_type
          type: enum
          values: [unit, integration, e2e, performance, security]
        - name: automated
          type: boolean
          default: false
        - name: execution_time_ms
          type: number
```

## Field Types

### String

```yaml
- name: external_id
  type: string
  max_length: 100
  pattern: "^[A-Z]+-[0-9]+$"  # Regex validation
  description: "External system reference"
```

```python
client.create_item(
    title="Feature",
    item_type="feature",
    metadata={"external_id": "JIRA-123"}
)
```

### Number

```yaml
- name: story_points
  type: number
  min: 1
  max: 21
  integer_only: true
  description: "Fibonacci story points"

- name: completion_percentage
  type: number
  min: 0
  max: 100
  decimal_places: 1
```

```python
client.create_item(
    title="Feature",
    item_type="feature",
    metadata={
        "story_points": 8,
        "completion_percentage": 75.5
    }
)
```

### Enum

```yaml
- name: component
  type: enum
  values:
    - value: api
      label: "API Layer"
      color: "#4CAF50"
    - value: frontend
      label: "Frontend"
      color: "#2196F3"
    - value: backend
      label: "Backend"
      color: "#FF9800"
    - value: database
      label: "Database"
      color: "#9C27B0"
  required: true
```

```python
client.create_item(
    title="Feature",
    item_type="feature",
    metadata={"component": "api"}
)

# List valid values
values = client.get_field_values("component")
# ['api', 'frontend', 'backend', 'database']
```

### Boolean

```yaml
- name: security_sensitive
  type: boolean
  default: false
  description: "Contains security-sensitive functionality"
```

```python
client.create_item(
    title="Payment Processing",
    item_type="feature",
    metadata={"security_sensitive": True}
)

# Filter by boolean
sensitive = client.list_items(
    metadata={"security_sensitive": True}
)
```

### Date/DateTime

```yaml
- name: due_date
  type: date
  description: "Target completion date"

- name: reviewed_at
  type: datetime
  description: "When last reviewed"
```

```python
from datetime import date, datetime

client.create_item(
    title="Feature",
    item_type="feature",
    metadata={
        "due_date": "2024-12-31",
        "reviewed_at": datetime.now().isoformat()
    }
)
```

### Array

```yaml
- name: affected_teams
  type: array
  item_type: string
  min_items: 1
  unique: true
  description: "Teams that need to be notified"

- name: tags
  type: array
  item_type: string
  max_items: 10
```

```python
client.create_item(
    title="Feature",
    item_type="feature",
    metadata={
        "affected_teams": ["backend", "frontend", "qa"],
        "tags": ["security", "performance"]
    }
)
```

### Reference

```yaml
- name: parent_epic
  type: reference
  target_type: epic
  required: false
  description: "Parent epic for this feature"

- name: blocking_bugs
  type: array
  item_type: reference
  target_type: bug
```

```python
# Reference to another item
client.create_item(
    title="Feature",
    item_type="feature",
    metadata={"parent_epic": "EPIC-001"}
)

# Reference validated - must exist
# Raises error if EPIC-001 doesn't exist
```

### Object (Nested)

```yaml
- name: contact
  type: object
  schema:
    - name: name
      type: string
      required: true
    - name: email
      type: string
      pattern: "^[a-z@.]+$"
    - name: role
      type: enum
      values: [owner, stakeholder, contributor]
```

```python
client.create_item(
    title="Feature",
    item_type="feature",
    metadata={
        "contact": {
            "name": "John Smith",
            "email": "john@example.com",
            "role": "owner"
        }
    }
)
```

## Using Custom Fields

### Creating Items

```python
from tracertm import TraceRTMClient

client = TraceRTMClient()

# Create with custom metadata
feature = client.create_item(
    title="User Authentication",
    item_type="feature",
    description="OAuth2 authentication flow",
    metadata={
        "risk_level": "high",
        "component": "api",
        "story_points": 13,
        "security_reviewed": False,
        "affected_teams": ["security", "backend"],
        "due_date": "2024-12-31"
    }
)
```

### Updating Metadata

```python
# Update specific fields
client.update_item(
    "FEAT-001",
    metadata={
        "security_reviewed": True,
        "story_points": 8
    }
)

# Merge with existing metadata
item = client.get_item("FEAT-001")
item.metadata["completion_percentage"] = 50
client.update_item("FEAT-001", metadata=item.metadata)
```

### Reading Metadata

```python
# Access metadata
item = client.get_item("FEAT-001")

print(f"Risk: {item.metadata.get('risk_level')}")
print(f"Points: {item.metadata.get('story_points')}")
print(f"Teams: {item.metadata.get('affected_teams')}")

# Direct access
risk = item.metadata["risk_level"]
```

## CLI Usage

```bash
# Create with metadata
tracertm create feature "User Auth" \
  --metadata '{"risk_level": "high", "story_points": 13}'

# Update metadata
tracertm update FEAT-001 \
  --metadata '{"security_reviewed": true}'

# View metadata
tracertm get FEAT-001 --show-metadata

# Filter by metadata
tracertm list --type feature --metadata '{"risk_level": "high"}'
tracertm list --type feature --metadata '{"security_reviewed": false}'

# Search in metadata
tracertm search --metadata-field component --metadata-value api
```

## Field Configuration Options

### Required Fields

```yaml
- name: risk_level
  type: enum
  values: [low, medium, high]
  required: true
  required_message: "Risk level must be set before review"
```

### Default Values

```yaml
- name: priority
  type: enum
  values: [low, medium, high]
  default: medium

- name: automated
  type: boolean
  default: false

- name: story_points
  type: number
  default: 0
```

### Conditional Requirements

```yaml
- name: security_justification
  type: string
  required_when:
    field: security_sensitive
    equals: true
  message: "Security-sensitive items require justification"
```

### Computed Fields

```yaml
- name: risk_score
  type: number
  computed: true
  formula: "probability_value * impact_value"
  read_only: true
```

## Field Groups

Organize fields into logical groups:

```yaml
metadata:
  groups:
    - name: planning
      label: "Planning Information"
      fields:
        - story_points
        - sprint
        - due_date

    - name: risk
      label: "Risk Assessment"
      fields:
        - risk_level
        - security_sensitive
        - security_reviewed

    - name: ownership
      label: "Ownership"
      fields:
        - business_owner
        - affected_teams
```

## Inheritance

```yaml
metadata:
  inheritance:
    # Features inherit component from epic
    feature:
      inherit_from: parent_epic
      fields: [component, business_owner]

    # Stories inherit from feature
    story:
      inherit_from: parent_feature
      fields: [sprint, component]
```

```python
# Parent epic
epic = client.create_item(
    title="Auth Epic",
    item_type="epic",
    metadata={"component": "api", "business_owner": "pm@example.com"}
)

# Feature inherits component automatically
feature = client.create_item(
    title="Login Feature",
    item_type="feature",
    metadata={"parent_epic": epic.id}
)

print(feature.metadata["component"])  # "api" (inherited)
```

## Best Practices

### 1. Use Enums for Controlled Values

```yaml
# Good: Enum prevents invalid values
- name: component
  type: enum
  values: [api, frontend, backend]

# Avoid: Free-text leads to inconsistency
- name: component
  type: string
```

### 2. Provide Meaningful Defaults

```yaml
# Good: Sensible default
- name: risk_level
  type: enum
  values: [low, medium, high]
  default: medium

# Avoid: Required without default causes friction
- name: risk_level
  type: enum
  values: [low, medium, high]
  required: true  # Users must always specify
```

### 3. Document Fields

```yaml
- name: story_points
  type: number
  description: |
    Fibonacci estimate of effort.
    1-3: Small (< 1 day)
    5-8: Medium (1-3 days)
    13-21: Large (1-2 weeks)
  help_url: "https://wiki.example.com/estimation"
```

### 4. Version Control Field Schemas

```yaml
# Keep in .tracertm/config.yaml in version control
# Changes tracked and reviewed like code
```

## Related Topics

- [Standard Fields](/docs/wiki/concepts/metadata/standard-fields) - Built-in fields
- [Validation](/docs/wiki/concepts/metadata/validation) - Validation rules
- [Search and Filter](/docs/wiki/concepts/metadata/search) - Query metadata

