id: lead.prepare
version: 2
kind: action
sideEffect: none
title:
  de: Anfrage prüfen
  en: Preview a lead
description:
  de: "Prüft eine Kontaktanfrage (Name, E-Mail, Nachricht) ohne sie abzusenden — liefert eine draftId, die als Idempotency-Key eines späteren lead.submit dient. Nebenwirkungsfrei: es wird nichts zugestellt."
  en: "Validates a contact request (name, email, message) without submitting it — returns a draftId usable as the Idempotency-Key of a later lead.submit. Side-effect-free: nothing is dispatched."
input:
  type: object
  required: [name, email, message]
  additionalProperties: false
  properties:
    name:
      type: string
      minLength: 1
      maxLength: 200
    email:
      type: string
      format: email
      maxLength: 254
    message:
      type: string
      minLength: 1
      maxLength: 5000
output:
  type: object
  # RFC-1169: only `ready` is unconditionally required — the closed subset cannot
  # express conditional presence; the contract check enforces the rest.
  required: [ready]
  additionalProperties: false
  properties:
    ready:
      type: boolean
      description: true when the input validated and the preview draft is usable; false when fields are missing or invalid — never a 422 on this path
    draftId:
      type: string
      minLength: 71
      maxLength: 71
      description: "Present when ready — deterministic canonical hash of the validated input, usable as the Idempotency-Key of a later lead.submit"
    missing:
      type: array
      items:
        type: string
      description: Present when ready is false — names of absent required input fields
    problems:
      type: array
      items:
        type: object
        properties:
          field:
            type: string
          code:
            type: string
          detail:
            type: string
        required: [field, code, detail]
        additionalProperties: false
      description: "Present when ready is false — non-missing-field violations (format, length) with a closed code vocabulary"
    summary:
      type: object
      additionalProperties: true
      description: "Present when ready — the validated input echoed back so the caller can show the user what would be sent. Contains the caller's own PII — do not log beyond request scope"
    nextAction:
      type: string
      description: Present when ready — the submit-sibling capability id to call once the user confirms
    sideEffect:
      type: string
      description: "Present when ready — human+model readable consequence of nextAction"
nextAction:
  capability: lead.submit
  sideEffect: >
    Creates a project inquiry and dispatches it to the site owner.
requires:
  entitlements: [agent.actions]
  sections: [send-message]
limits:
  perMinutePerIp: 10
  maxPayloadBytes: 10240
