Docteller document assessment provider
This provider is used to assess documents using the external service from DocTeller. Its primary function is to analyze a document's content (like an identity document or tax statement) and extract key data points.
The provider's process is a single API call:
- API Call (readDocument): The document bytes are packaged into a multipart/form-data request and sent to the DocTeller API.
- Validation and Consolidation: The response is validated for readability and successful data extraction.
- V1 - DocTellerDocumentAssessmentProvider
- V2 - DocTellerDocumentAssessmentV2Provider
Implementation class​
DocTellerDocumentAssessmentProvider
Required settings​
resourceUri: The base URL for the DocTeller APIAPI_KEY: The mandatory API key for authentication, read from settings or a vault.
Configuration​
docTellerProviderConfigurations (required): A list of configurations, one per document type. Each entry has:
documentTypes(required): Document types handled by this configuration (e.g.cni_nouvelle_verso,cni_nouvelle_recto,passeport).fieldMapping(required): A list of field mappings. Each mapping has:docTellerFieldName(required): Field name as returned by DocTeller.inputFieldPath(required): Path onDocumentAssessmentDataPoints(combines dossier and party fields).inputFieldType(optional):STRING(default) orDATE.alphaNumeric(optional): Whentrue, strips non-alphanumeric characters. Defaultfalse.
Implementation class​
DocTellerDocumentAssessmentV2Provider
Required settings​
resourceUri: The base URL for the DocTeller APIAPI_KEY: The mandatory API key for authentication, read from settings or a vault.
Key differences from V1​
| V1 | V2 | |
|---|---|---|
| Party mapping | party.individual.* paths via docTellerProviderConfigurations | party.individual.* paths via partyConfigurations (paths are relative to the party payload, main party at party.*) |
| Dossier mapping | Not supported | associatedParties[*].* or dossier.* paths via dossierConfigurations (paths are relative to the dossier payload) |
| Gender mapping | No dedicated support | inputFieldType: ENUM with enumValues map (e.g. {"F": "FEMALE", "H": "MALE"}) |
| Array fields | Not supported | [*] wildcard expands a DocTeller list into indexed slots |
| Array → scalar | Not supported | listStrategy: FIRST or JOIN, combinable with any inputFieldType |
| Explicit indices | Allowed | Forbidden - use [*] only |
| Persists extracted data | No - only surfaces fields in the assessment text | Yes - the extracted data is pushed onto the party or dossier |
| Per-document-type mocks | Single default mock | Looks up DocTeller_<documentType>.json on the classpath, falls back to DocTeller_default.json |
When to use partyConfigurations vs dossierConfigurations​
Document assessment runs once per trigger point. The Harmoney platform triggers assessment for three types of document subjects:
| Document attached to | Subject type | Use |
|---|---|---|
| A party (individual, company, ...) | Party | partyConfigurations |
| A party's identity record | IndividualIdentity | partyConfigurations |
| A dossier | Dossier | dossierConfigurations |
Routing is driven by the document subject's documentSubjectType together with the matched configuration's documentTypes (and, for party configs, documentSubjectTypes):
- A
partyConfigurationsentry is picked when itsdocumentTypescontains the uploadeddocumentTypeand itsdocumentSubjectTypescontains the document subject's type. - A
dossierConfigurationsentry is picked when itsdocumentTypescontains the uploadeddocumentTypeand the document subject's type isDOSSIER. - If neither matches, the provider returns
NOT_APPLICABLEwithout downloading the document or calling DocTeller, so an uncovered document type costs nothing.
Each party configuration must declare a documentSubjectTypes list. Only party-related types are accepted: INDIVIDUAL, INDIVISION, PARTNERSHIP, COMPANY. A subject type of DOSSIER always routes to dossierConfigurations.
When a partyConfigurations entry matches, the extracted fields are pushed onto the party the document is attached to (the Party itself, or the party behind the IndividualIdentity). If the document subject is a dossier, nothing is saved.
When a dossierConfigurations entry matches, the extracted fields are pushed onto the dossier.
Practical guideline: use partyConfigurations for identity documents (CNI, passport) that are uploaded to a party profile; use dossierConfigurations for documents such as tax statements or bank statements that are uploaded at dossier level.
Field types​
inputFieldType controls how a raw DocTeller value is converted before it is written to the target path.
| Type | Behaviour |
|---|---|
STRING (default) | Value is passed through unchanged. With alphaNumeric: true non-alphanumeric characters are stripped, which is how identity card numbers lose their separators. |
DATE | String value is parsed as LocalDate, trying dd.MM.yyyy, dd/MM/yyyy, and ISO-8601 in order. Unparseable values are dropped. |
ENUM | String value is uppercased, trimmed, and looked up in the required enumValues map. Missing keys are dropped. |
LIST | Collapses an array-typed DocTeller value into a scalar and writes it unconverted. Requires listStrategy. |
LIST strategy​
LIST is intended for mappings where the DocTeller field is an array (e.g. numeros_fiscaux: ["3055210564329"]) but the target Harmoney path is a scalar (e.g. party.company.vatNumber). Use the [*] wildcard syntax instead when the target is itself a list.
listStrategy is not limited to inputFieldType: LIST. It can be combined with any type: the array is
collapsed first, then the resulting scalar is converted according to inputFieldType. Use this when
DocTeller returns a single-element array for a value that is not a string, for example
date_etablissement: ["15.01.2024"] into a scalar date field:
inputFieldType | listStrategy | Result |
|---|---|---|
DATE | FIRST | First element is parsed as a date |
ENUM | FIRST | First element is looked up in enumValues |
LIST | FIRST or JOIN | Collapsed value is written as a string, no further conversion |
| Strategy | Result |
|---|---|
FIRST | Takes the first element of the array. Empty array → field is skipped. |
JOIN | Concatenates every element by calling toString(). The delimiter field is inserted between elements; it defaults to ", " when omitted. Null elements are skipped. |
If the raw value is not an array, LIST passes it through unchanged.
Validation contract​
For every document returned by DocTeller the V2 provider asserts:
- The DocTeller-detected
document_typeequals the upload'sdocumentType(case-insensitive). readable,detect_success, andread_successare alltrue.- The detected
document_typeappears in the matched configuration'sdocumentTypeslist. - The document carries at least two extracted fields.
Failing any check yields an NOK assessment with the configured error message; failing none triggers the consolidation step. Because of (1) and (3), documentTypes should list both the upload-side label (e.g. TAX_DEMAND_FORM) and the DocTeller-detected label (e.g. avis_impot) whenever they differ.
Automatic completions on the party​
DocTeller does not return certain Harmoney-side flags that are required when the party is saved. The provider fills these in before saving, so configurations do not have to:
taxInformations[*].isPrimary— sets the first entry totrueif no entry is flagged primary.taxInformations[*].useResidentialAddress— sets totruewhen neitheruseResidentialAddressnoraddressis provided.company.vatLiable— sets totruewhen avatNumberwas mapped butvatLiableis unset; otherwise the update is rejected because VAT liability is not set.
These run for the main party and every entry in associatedParties.