# Complete Data Contract Template
# Combines schema, coercion rules, validation rules, and metadata.
#
# Usage:
#   from pycharter import parse_contract, validate_with_contract
#
#   contract = parse_contract(contract_dict)  # or parse_contract_file("contract.yaml")
#   result = validate_with_contract(contract_dict, data)
#
# When registering with the store (DB or API), the data contract record has:
#   name, version, status, description (see seed contracts.yaml).
# You can set them at the top level below so the same file documents the contract identity.

# Data contract identity (used when registering with store; optional for parse_contract)
name: my_contract
version: "1.0.0"
status: active
description: User data contract with schema, coercion, validation, and metadata

schema:
  type: object
  title: User
  version: "1.0.0"

  properties:
    user_id:
      type: string
      description: Unique user identifier
      minLength: 1
      # PyCharter extension: coercion
      coercion: coerce_to_string
      # PyCharter extension: validations
      validations:
        non_empty_string: null

    name:
      type: string
      description: User's full name
      minLength: 1
      maxLength: 100
      coercion: coerce_to_stripped_string
      validations:
        non_empty_string: null
        max_length:
          threshold: 100

    email:
      type: string
      format: email
      description: User email address
      coercion: coerce_to_lowercase
      validations:
        is_email: null

    age:
      type: integer
      description: User age
      minimum: 0
      maximum: 150
      coercion: coerce_to_integer
      validations:
        greater_than_or_equal_to:
          threshold: 0
        less_than_or_equal_to:
          threshold: 150

    status:
      type: string
      description: Account status
      enum: [active, inactive, pending]
      coercion: coerce_to_lowercase
      validations:
        only_allow:
          allowed_values: [active, inactive, pending]

    created_at:
      type: string
      format: date-time
      description: Account creation timestamp
      coercion: coerce_to_datetime

    # Nullable field example
    notes:
      anyOf:
        - type: string
          maxLength: 500
        - type: "null"
      default: null
      description: Optional notes
      coercion: coerce_to_nullable_string
      validations:
        max_length:
          threshold: 500

  required:
    - user_id
    - name
    - email
    - status
    - created_at

# Optional: top-level coercion rules (same as template_coercion_rules.yaml structure)
# When present, parse_contract returns them; use with create-mixed or store for separate artifacts.
coercion_rules:
  version: "1.0.0"
  rules:
    user_id: coerce_to_string
    name: coerce_to_stripped_string
    email: coerce_to_lowercase
    age: coerce_to_integer
    status: coerce_to_lowercase
    created_at: coerce_to_datetime
    notes: coerce_to_nullable_string

# Optional: top-level validation rules (same as template_validation_rules.yaml structure)
validation_rules:
  version: "1.0.0"
  rules:
    user_id:
      non_empty_string: null
    name:
      non_empty_string: null
      max_length:
        threshold: 100
    email:
      is_email: null
    age:
      greater_than_or_equal_to:
        threshold: 0
      less_than_or_equal_to:
        threshold: 150
    status:
      only_allow:
        allowed_values: [active, inactive, pending]
    notes:
      max_length:
        threshold: 500

# Contract metadata (ownership, governance, and optional lifecycle nested inside)
metadata:
  version: "1.0.0"
  description: User data contract
  status: active
  created_at: "2025-01-01T00:00:00Z"
  created_by: data-team

  # Ownership information (nested in metadata)
  ownership:
    owner: data-team
    team: engineering

  # Optional: FSM lifecycle binding (for domain entities; e.g. PyStator machine name and field mapping)
  # lifecycle:
  #   state_machine_name: order_lifecycle
  #   machine_version: "1.0.0"
  #   state_field: status
  #   entity_id_field: order_id

  # Governance rules (nested in metadata)
  governance_rules:
    data_retention:
      days: 365
      reason: Standard user data retention
    pii_fields:
      fields: [email, name]
    sensitivity: confidential
    access_control:
      read: [analytics-team, data-team]
      write: [data-team]

# Optional: ontology (semantic field annotations; version + fields with concept, definition, relationships)
# ontology:
#   version: "1.0.0"
#   fields:
#     email:
#       concept: Email Address
#       broader: Contact Identifier
#       definition: Primary email address for the user.

# Version tracking (optional - for build_contract_from_store)
versions:
  schema: "1.0.0"
  coercion_rules: "1.0.0"
  validation_rules: "1.0.0"
  metadata: "1.0.0"
  # ontology: "1.0.0"   # when ontology section is present
