Fatture e ricevute condividono lo stesso ingresso. Come evitare di mescolare le due strutture?
Un'unica interfaccia riceve sia fatture che ricevute ed è facile scrivere oggetti di grandi dimensioni con "tutti i campi opzionali". Un oggetto del genere può contenere qualsiasi cosa, ma è difficile dire cosa contenga esattamente. Sarebbe più chiaro mantenere due contratti distinti e selezionarne uno con il campo tipo esplicito.
Fatture e ricevute vengono spesso inserite nella stessa interfaccia per l'elaborazione, ma se per riceverle viene utilizzato solo un oggetto ampio con "tutti i campi facoltativi", può accogliere qualsiasi input, ma non può indicare quale tipo di documento viene ricevuto. Questo articolo è destinato agli sviluppatori e al personale aziendale che devono progettare un'interfaccia di ricezione di documenti o gestire le regole di convalida dello schema JSON. Dopo aver letto questo, imparerai come mantenere due contratti indipendenti, selezionarne uno con un campo di tipo esplicito e gestire i conflitti di ramo e i tipi sconosciuti.
Gli esempi in questo articolo utilizzano campioni sintetici per dimostrare i metodi di elaborazione. Il codice è stato controllato con esempi in un ambiente isolato, ma ciò non è una garanzia di tutti i file reali o delle prestazioni del prodotto. Prima di elaborare documenti importanti, conservare gli originali e rivederli rispettando i limiti e gli elementi di accettazione nel testo.
##Come affrontare l'inserimento condiviso di fatture e ricevute? Conclusione di una frase
Quando si ricevono due documenti dallo stesso portale, è più chiaro mantenere due contratti separati e utilizzare il campo obbligatorio kind per selezionarne uno, piuttosto che utilizzare un oggetto ampio che possa contenere tutto.
| la tua situazione | Pratiche consigliate | motivo |
|---|---|---|
| La stessa interfaccia deve ricevere fatture e ricevute | Mantieni due contratti separati, selezionati con il campo tipo obbligatorio | Un oggetto grande con tutti i campi opzionali può contenere qualsiasi cosa, ma è difficile spiegare cosa viene ricevuto. |
| Organizza le filiali con oneOf | Ogni ramo utilizza const per correggere il tipo | oneOf richiede la corrispondenza di esattamente un ramo. La sovrapposizione dei campi del ramo causerà un errore nell'input legale. |
| Inserisci un tipo mancante o un conflitto di campo | Restituisce un messaggio di errore chiaro che mostra campi e origini in conflitto | Mostrare solo "nessuna corrispondenza" non può aiutare a individuare il problema |
| Il classificatore non è in grado di distinguere tra tipi di documenti | Mantieni lo stato sconosciuto ed entra nella coda indipendente per essere classificato | Scegliere un ramo a caso produrrà solo un falso "successo" |
| Verifica della struttura superata | Ciò non significa che la classificazione sia corretta, né significa che i documenti siano autentici. | La fiducia nella classificazione, la verifica della struttura e l'autenticità aziendale sono tre livelli diversi |
Perché non puoi utilizzare un oggetto ampio?
Rischio di rendere tutti i campi facoltativi
Quando un'interfaccia accetta sia fatture che ricevute, è facile scrivere oggetti di grandi dimensioni con "tutti i campi facoltativi". Un oggetto del genere può effettivamente ricevere una varietà di input, ma al costo di:
- Non è possibile capire dalla struttura quale documento si sta ricevendo.
- Gli elementi obbligatori e quelli facoltativi dei due documenti si mescolano tra loro e le regole di verifica diventano sempre più confuse.
- Quando si verifica un errore, è difficile spiegare esattamente dove l'input non è quello previsto.
Sarebbe più chiaro mantenere due contratti separati e selezionarne uno con un campo di tipo esplicito.
oneOf non è uno qualsiasi
La sovrapposizione dei rami causerà il fallimento dell'input legale.
oneOf richiede che l'input corrisponda esattamente a un ramo. Se entrambi i rami passano contemporaneamente, la verifica complessiva fallirà.
Se i rami contengono solo pochi campi opzionali, è probabile che si sovrappongano in modo significativo. Al momento, l'input legale non supera la verifica.
Utilizza kind e const per eliminare le sovrapposizioni
Utilizzando il campo kind richiesto più il valore fisso di const è possibile stabilire confini chiari tra i rami ed eliminare tali sovrapposizioni in anticipo.
Per maggiori dettagli sulle regole di combinazione, si riferisce a Regole di combinazione dello schema JSON.
Un protocollo di deviazione eseguibile
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"})
Si tratta di un record di esempio semplificato, non di un modello completo di campo di una fattura reale. Il codice dimostra la selezione di branch e il rifiuto di campi ridondanti; aliquote fiscali, intestazioni e importi devono essere definiti separatamente.
Se l'azienda consente campi aggiuntivi, i namespace per questi campi dovrebbero essere chiaramente definiti invece di rimuovere silenziosamente tutti i vincoli.
Non mostrare solo messaggi di errore "mismatch"
Viene mostrato solo il "disallineamento", e né gli utenti né il personale di manutenzione possono sapere dove si trova il problema. La tabella sottostante elenca diverse caratteristiche di input comuni e i relativi metodi di feedback:
| Funzionalità di input | Dubbi reali | Suggerisci un feedback |
|---|---|---|
| una sorta di carenza | Non si può scegliere l'accordo | Si prega di fornire il tipo di documento |
| Campi di tipo e numero in conflitto | Le due strutture sono mescolate | Visualizza campi contrastanti e le loro fonti |
| Stringhe vuote numerate | La chiave esiste ma non ha valore | Guardando indietro all'area numerata |
| Tipo sconosciuto | L'accordo attuale non copre questo | Inserisci la coda indipendente per essere classificati |
Anche i tipi incerti hanno bisogno di un'uscita
Se il classificatore non riesce a distinguere tra fatture e ricevute, lo stato sconosciuto dovrebbe essere mantenuto invece di selezionare casualmente una filiale per ottenere un "successo".
Ci sono tre diversi livelli che devono essere considerati separatamente:
- Fiducia nelle categorie: Quanto il sistema è sicuro nel giudicare i tipi di documento.
- Verifica della struttura: Inserisci se il contratto selezionato è stato soddisfatto.
- Autenticità aziendale: Se i documenti stessi siano autentici e validi.
La verifica strutturale non può essere dimostrata a posteriori come corretta, né può dimostrare che il documento è autentico.
Il tipo di documento dovrebbe essere mantenuto anche nel processo di traduzione
Lo stesso campo può richiedere terminologia diversa in documenti diversi. Quando si utilizza la terminologia OmniDoc e i flussi di lavoro di revisione bilingue, fornire tipi di documento con liste di consegna aiuta i revisori a comprendere il contesto del numero e dell'importo.
Non lasciare che un oggetto JSON ampio cancelli queste differenze.
📊 Confronto tra i nuclei
| Metodo | Il tipo di documento può essere chiaramente definito? | Manifestazioni quando i rami si sovrappongono | Gestione di tipi sconosciuti |
|---|---|---|---|
| Oggetti ampi con tutti i campi opzionali | È difficile spiegare cosa sia stato ricevuto | Non applicabile; non ci sono confini di ramificazione tra i campi | Facilmente inghiottiti da bersagli ampi e difficili da notare |
| Due contratti indipendenti + tipo richiesto | Seleziona chiaramente usando il campo kind | Usa const per fissare i valori e ridurre la sovrapposizione | Lascia lo stato sconosciuto ed entra nella coda per essere ordinato |
🎯 Quale metodo ti si addice?
Se devi ricevere sia fatture che ricevute contemporaneamente
Mantieni due contratti separati e imposta kind come campo richiesto.
Se i tuoi campi di ramo si sovrappongono ampiamente
Correggi kind con const in ogni branch per evitare input legittimi che corrispondano contemporaneamente a più branch.
Se il tuo sistema permette campi aggiuntivi
Prima chiarisce lo spazio di nomi del campo aggiuntivo, poi decidi come rilassare i vincoli.
Se il tuo classificatore non è abbastanza sicuro
Mantieni lo stato sconosciuto e invia i documenti alla coda per essere ordinati; non selezionare forzatamente i rami.
❓ Domande Frequenti (FAQ)
1. Perché non usare semplicemente un oggetto in cui tutti i campi sono opzionali?
Un partner del genere può fingere qualsiasi cosa, eppure è difficile capire esattamente cosa riceve.
2. Perché oneOf causa un fallimento valido dell'inserimento?
oneOf richiede esattamente l'abbinamento di un ramo. Se entrambi i rami passano contemporaneamente, il controllo complessivo fallirà. Questa situazione è probabile quando i campi di ramo si sovrappongono ampiamente.
3. A cosa dovresti prestare attenzione quando permetti campi aggiuntivi?
Il namespace per il campo aggiuntivo dovrebbe essere chiaramente definito, invece di rimuovere silenziosamente tutti i vincoli.
4. E se il classificatore non riesce a determinare il tipo di documento?
Mantieni lo stato sconosciuto e entra in una coda indipendente da classificare; non selezionare casualmente un ramo per assemblare un ramo di successo.
5. Superare la verifica strutturale dimostra l'autenticità dei documenti?
No. La fiducia nella classificazione, la verifica strutturale e l'autenticità aziendale sono tre livelli distinti; la verifica strutturale non può dimostrare l'autenticità dei documenti.
📝 Riassunto
Quando si inseriscono fatture e ricevute nella stessa voce, conserva due contratti separati e selezionali utilizzando il campo richiesto kind, rendendo chiaramente visibile il tipo di documento inserito. La verifica dei rami, il feedback degli errori e le esportazioni di tipo sconosciuto dovrebbero essere progettate insieme.


