Facturas y recibos comparten la misma entrada. ¿Cómo evitar mezclar las dos estructuras?

Una interfaz recibe facturas y recibos, y es fácil escribir objetos grandes con "todos los campos opcionales". Un objeto así puede contener cualquier cosa, pero es difícil decir exactamente qué se recibe. Sería más claro mantener dos contratos separados y seleccionar uno de ellos con el campo de tipo explícito.

Las facturas y los recibos a menudo se colocan en la misma interfaz para su procesamiento, pero si solo se usa un objeto amplio con "todos los campos opcionales" para recibirlos, puede acomodar cualquier entrada, pero no puede decir qué tipo de documento se recibe. Este artículo está dirigido a desarrolladores y personal empresarial que necesitan diseñar una interfaz de recepción de documentos o mantener reglas de validación de esquemas JSON. Después de leer esto, aprenderá cómo mantener dos contratos independientes, seleccionar uno con un campo de tipo explícito y manejar conflictos de rama y tipos desconocidos.

Los ejemplos de este artículo utilizan muestras sintéticas para demostrar los métodos de procesamiento. El código se ha verificado con ejemplos en un entorno aislado, pero esto no es garantía de todos los archivos reales ni del rendimiento del producto. Antes de procesar documentos importantes, conserve los originales y revíselos de acuerdo con los límites y elementos de aceptación del texto.

¿Cómo afrontar la entrada compartida de facturas y recibos? Conclusión de una frase

Al recibir dos documentos del mismo portal, es más claro mantener dos contratos separados y usar el campo kind requerido para seleccionar uno de ellos, en lugar de usar un objeto amplio que pueda contener todo.

tu situaciónPrácticas recomendadasrazón
La misma interfaz necesita recibir facturas y recibos.Mantenga dos contratos separados, seleccionados con el campo de tipo requeridoUn objeto grande con todos los campos opcionales puede contener cualquier cosa, pero es difícil explicar lo que se recibe.
Organizar sucursales con oneOfCada rama usa const para arreglar el tipo.oneOf requiere que coincida exactamente una rama. La superposición de campos de rama hará que la entrada legal falle.
Tipo de entrada faltante o conflicto de campoDevuelve un mensaje de error claro que muestra campos y fuentes en conflictoMostrar únicamente "no coincide" no puede ayudar a localizar el problema
El clasificador no puede distinguir entre tipos de documentosConservar el estado desconocido e ingresar a la cola independiente para ser clasificadoElegir una sucursal al azar solo producirá un "éxito" falso
Verificación de estructura aprobadaNo significa que la clasificación sea correcta, ni tampoco que los documentos sean auténticos.La confianza en la clasificación, la verificación de la estructura y la autenticidad empresarial son tres niveles diferentes.

¿Por qué no puedes usar un objeto amplio?

Riesgo de hacer que todos los campos sean opcionales

Cuando una interfaz acepta facturas y recibos, es fácil escribir objetos grandes con "todos los campos opcionales". De hecho, un objeto de este tipo puede recibir una variedad de entradas, pero a costa de:

  • Es imposible saber por la estructura qué documento se recibe.
  • Los elementos obligatorios y opcionales de los dos documentos se mezclan entre sí y las reglas de verificación son cada vez más confusas.
  • Cuando ocurre un error, es difícil explicar exactamente dónde la entrada no es la esperada.

Sería más claro mantener dos contratos separados y seleccionar uno de ellos con un campo de tipo explícito.

oneOf no es uno cualquiera

La superposición de ramas hará que la entrada legal falle.

oneOf requiere que la entrada coincida exactamente con una rama. Si ambas ramas pasan al mismo tiempo, la verificación general fallará.

Si las ramas contienen sólo unos pocos campos opcionales, es probable que se superpongan significativamente. En este momento, los datos legales no pasan la verificación.

Utilice tipo y constante para eliminar la superposición

El uso del campo kind requerido más el valor fijo de const puede establecer límites claros entre ramas y eliminar dichas superposiciones de antemano.

Para obtener más detalles sobre las reglas de combinación, consulte Reglas de combinación de esquemas JSON.

Un protocolo de descarga ejecutable

from jsonschema import Draft202012Validator

def branch(kind, identity):
    return {
        "type": "object", "additionalProperties": False,
        "required": ["kind", identity],
        "properties": {"kind": {"const": kind},
                       identity: {"type": "string", "minLength": 1}}
    }

schema = {"oneOf": [branch("invoice", "invoice_number"),
                    branch("receipt", "receipt_number")]}
v = Draft202012Validator(schema)
valid = lambda x: not list(v.iter_errors(x))
assert valid({"kind": "invoice", "invoice_number": "I-1"})
assert valid({"kind": "receipt", "receipt_number": "R-1"})
assert not valid({"kind": "invoice", "receipt_number": "R-1"})
assert not valid({"kind": "receipt", "receipt_number": ""})
assert not valid({"kind": "invoice", "invoice_number": "I-1",
                  "receipt_number": "R-1"})
assert not valid({"kind": "unknown"})

Este es un registro de ejemplo simplificado y no es un modelo de campo completo de una factura real. El código demuestra la selección de ramas y el rechazo de campos redundantes. La tasa impositiva, el encabezado y el monto deben definirse por separado.

Si la empresa permite campos adicionales, los espacios de nombres para estos campos deben hacerse explícitos en lugar de cancelar silenciosamente todas las restricciones.

No muestres simplemente "no hay coincidencia" en el mensaje de error

Sólo se muestra "no coincide" y ni los usuarios ni los mantenedores saben dónde radica el problema. La siguiente tabla enumera varias características de entrada comunes y los métodos de retroalimentación correspondientes:

Características de entradaDudas realesSugiere comentarios
Una especie de deficienciaNo se puede elegir el acuerdoPor favor, proporcione el tipo de documento
Conflicto entre los campos de tipo y númeroLas dos estructuras se mezclanMostrar campos en conflicto y sus fuentes
Cadenas vacías numeradasLa clave existe pero no tiene valorMirando atrás al área numerada
Tipo desconocidoEl acuerdo actual no cubre estoEntra en la cola independiente para ser clasificado

Los tipos inciertos también necesitan una salida

Si el clasificador no puede distinguir entre facturas y recibos, el estado desconocido debe mantenerse en lugar de seleccionar aleatoriamente una sucursal para lograr un "éxito".

Aquí hay tres niveles diferentes que deben considerarse por separado:

  • Confianza en categorías: Qué confianza tiene el sistema al juzgar los tipos de documentos.
  • Verificación de estructura: Introduce si se cumple el contrato seleccionado.
  • Autenticidad empresarial: Si los documentos en sí son auténticos y válidos.

La verificación estructural no puede demostrarse a la inversa como correcta, ni puede demostrar que el documento sea genuino.

El tipo de documento también debe mantenerse en el proceso de traducción

El mismo campo puede requerir terminología diferente en distintos documentos. Al utilizar terminología OmniDoc y flujos de trabajo bilingües de revisiones, proporcionar tipos de documentos con listas de entrega ayuda a los revisores a entender el contexto del número y la cantidad.

No dejes que un objeto JSON amplio borre estas diferencias.

📊 Comparación de núcleos

Método¿Se puede definir claramente el tipo de documento?Manifestaciones cuando las ramas se solapanManejo de tipos desconocidos
Objetos amplios con todos los campos opcionalesEs difícil explicar qué se recibióNo aplicable; no existen límites de rama entre camposFácil de tragar por objetivos anchos y difícil de notar
Dos contratos independientes + tipo requeridoSelecciona claramente usando el campo kindUtiliza const para fijar valores y reducir la superposiciónDeja el estado desconocido y entra en la cola para ser ordenado

🎯 ¿Qué método te conviene?

Si necesitas recibir tanto facturas como recibos al mismo tiempo

Mantén dos contratos separados y establece kind como campo obligatorio.

Si tus campos de rama se solapan extensamente

Arregla kind con const en cada rama para evitar que la entrada legítima coincida con múltiples ramas simultáneamente.

Si tu sistema permite campos adicionales

Primero, aclarar el espacio de nombres del campo adicional y luego decidir cómo relajar las restricciones.

Si tu clasificador no está lo suficientemente seguro

Conserva el estado desconocido y envía documentos a la cola para que los ordenen; no selecciones sucursales a la fuerza.

❓ Preguntas frecuentes (FAQ)

1. ¿Por qué no usar simplemente un objeto donde todos los campos sean opcionales?

Una pareja así puede fingir cualquier cosa, pero es difícil saber exactamente qué recibe.

2. ¿Por qué OneOf causa un fallo válido de entrada?

oneOf requiere que empareje exactamente una rama. Si ambas ramas pasan simultáneamente, la comprobación general fallará. Esta situación es probable que ocurra cuando los campos de ramificación se solapan extensamente.

3. ¿A qué deberías prestar atención al permitir campos adicionales?

El espacio de nombres para el campo adicional debe estar claramente definido, en lugar de eliminar silenciosamente todas las restricciones.

4. ¿Qué pasa si el clasificador no puede determinar el tipo de documento?

Mantener el estado desconocido y entrar en una cola independiente para ser clasificada; no seleccione aleatoriamente una rama para ensamblar una rama exitosa.

5. ¿Aprobar la verificación estructural demuestra la autenticidad de los documentos?

No. La confianza en la clasificación, la verificación estructural y la autenticidad empresarial son tres niveles distintos; la verificación estructural no puede demostrar la autenticidad de los documentos.

📝 Resumen

Al colocar facturas y recibos en la misma entrada, guarda dos contratos separados y seleccionalos usando el campo kind requerido, haciendo que el tipo de documento introducido sea claramente visible. También deben diseñarse conjuntamente la verificación de ramas, la retroalimentación de errores y las exportaciones de tipos desconocidos.

Experiencia ahora: Sube tu documento para empezar a traducir, conservando el formato original

Actualizado 2026-11-15