The first flow tutorial compared two simple names. This third example is more realistic. It uses checks from Identità Single Work Permit Vetting where the same fact can be written in several different ways.
This tutorial is based on the Vetting SOP, especially:
- Work Contract, points 8–9, page 8;
- Covering Letter, points 2–5, page 8; and
- Proof of Advertisement, points 1–3, page 9.
The important lesson is:
Compare the meaning of the data, not only the printed letters.
For example, €1,248 per month and €14,976 per year use different words and
numbers, but describe the same yearly salary.
What you will add¶
We will configure four checks already used by the Identità flow:
| Key | Check | Why standardisation matters |
|---|---|---|
K05 |
Nationality | Maltese, Malta, and MLT can mean the same country. |
K09 |
Employer / company name | Capital letters, punctuation, and Ltd versus Limited should not create a false mismatch. |
K13 |
Job title / occupation | One advertisement can list many jobs. Only one advertised job needs to match the proposed job. |
K14 |
Wage / salary | Monthly, weekly, and annual amounts must be changed to the same pay period before comparison. |
We will use document sources from the existing Identità flow. We will not use the Residence Application Form as a document. As explained in the NIDMS tutorial, those facts come from another system and belong in profile variables.
Before you start¶
Open Identità Single Work Permit Vetting and select Edit. Its document catalogue and steps should already include the document types used below:
- Travel Document;
- Curriculum Vitae;
- Work Contract;
- Position Description;
- Covering Letter;
- Proof of Advertisement; and
- Declaration of Suitability.
If you are building a smaller practice flow, add those document steps first. A cross-check can only select document types accepted by the flow.
Note
This tutorial uses a focused subset of each real Identità check. The full production flow can compare the same fact across more documents.
1. Understand the standardisation path¶
For each value, Ziffa should keep the printed value and also prepare a clean value for comparison:
printed value -> extracted field -> standardised value -> comparison
Examples:
| Printed value | Standardised value used for comparison |
|---|---|
Maltese |
MLT |
Harbour Care Ltd. |
company-name tokens used for a fuzzy similarity score |
Care Assistants; Nurses; Cleaners |
three separate job-title candidates |
EUR 1,248 per month |
approximately EUR 14,976 per year |
Standardisation may remove harmless differences. It must not erase important
differences. Harbour Care Ltd and Harbour Hotel Ltd are not the same
company. Care Assistant and Staff Nurse are not the same job.
The method depends on the field. Country and money fields have structured, type-aware handling. Company names and job titles use fuzzy similarity, so a borderline result still needs smart or human review.
2. Add K05 — Nationality¶
The Identità flow uses this check because a country can appear as a country name, a nationality word, or a three-letter country code.
Create the check:
| Option | Value |
|---|---|
| Key | K05 |
| Name | Nationality |
| Match type | Exact |
| Severity | Flag |
| Mismatch action | Flag to officer |
| Description | Convert country names and nationality words to ISO Alpha-3 before comparing. |
| SOP reference | Passport 2 |
Add these field sets:
- Travel Document →
nationality - Curriculum Vitae →
nationality
The nationality fields should use the Country field type. This asks
extraction to return one standard three-letter country code.
Example:
| Travel Document | Curriculum Vitae | Result |
|---|---|---|
MLT |
Maltese extracted as MLT |
Pass |
MLT |
Italian extracted as ITA |
Mismatch |
Do not use a fuzzy text check to make different country names look close. A country code is a small, exact fact once it has been standardised.
3. Add K09 — Employer / company name¶
The employer can be named on the contract, covering letter, advertisement, and declaration of suitability. These documents may format the same company name differently.
Create the check:
| Option | Value |
|---|---|
| Key | K09 |
| Name | Employer / company name |
| Match type | Fuzzy |
| Severity | Block |
| Mismatch action | Flag to officer |
| SOP reference | Contract / Form / Advert / Suitability |
| Description | Compare the employer while allowing harmless differences in case, punctuation, spacing, and common company suffixes. |
Add these field sets:
- Work Contract →
employer_name - Covering Letter →
employer_name - Proof of Advertisement →
employer_name - Declaration of Suitability →
employer_name
A useful fuzzy check should treat these as likely the same:
HARBOUR CARE LIMITED
Harbour Care Ltd.
Harbour Care Ltd
It should not quietly accept:
Harbour Care Ltd
Harbour Hotel Ltd
If the difference is uncertain, the safe result is Needs human review. Fuzzy does not mean “accept anything similar.”
Note
The fuzzy check does not maintain a registry of company aliases or trading names. If one document uses a brand and another uses a different legal company name, an officer must verify that relationship.
4. Add K13 — Job title from a multi-job advertisement¶
This is the most important check in this example.
The SOP says that the advertised job title must correspond to the work contract, position description, and covering letter. A difficulty is that one advertisement can contain several vacancies:
Care Assistants, Senior Care Assistants, Nurses, Cleaners,
Maintenance Technicians, Security Officers
The proposed job might simply be:
CARE ASSISTANT
The check must ask, “Is the proposed job among the advertised jobs?” It must not compare the whole long advertisement list with one short title.
Create the check:
| Option | Value |
|---|---|
| Key | K13 |
| Name | Job title / occupation |
| Match type | Fuzzy |
| Severity | Block |
| Mismatch action | Flag to officer |
| SOP reference | Form 4a / Contract 8 / PD 2 / Advert 3 |
| Description | Compare wording across job documents. Treat every job in the advertisement as a separate candidate. |
Add these field sets:
- Work Contract →
job_title - Position Description →
job_title - Covering Letter →
job_title - Proof of Advertisement →
job_titles - Declaration of Suitability →
job_title
The Proof of Advertisement field is different:
- its field type is StringList;
- extraction must keep every advertised job;
- the field set must be marked as carrying multiple values; and
- the check passes when one advertised candidate matches the proposed job.
When you add the Proof of Advertisement field set, turn on multiple values. This tells Ziffa to compare each advertised job separately. Do not save the advertisement as one ordinary value; that would compare the whole list with one job and create false results.
Try three job-title examples¶
| Proposed job | Jobs in advertisement | Expected result |
|---|---|---|
Care Assistant |
Care Assistants, Nurses, Cleaners |
Pass — one candidate matches. |
Senior Care Assistant |
Care Assistants, Senior Care Assistants, Nurses |
Pass — the more specific candidate exists. |
Staff Nurse |
Care Assistants, Cleaners, Security Officers |
Mismatch — no advertised candidate matches. |
Small changes such as singular versus plural or capital letters are harmless. A different occupation is not harmless.
5. Add K14 — Wage / salary¶
Salary comparison is not an ordinary text comparison. First put every amount into the same currency and pay period.
Create the check:
| Option | Value |
|---|---|
| Key | K14 |
| Name | Wage / salary |
| Match type | Exact |
| Severity | Block |
| Mismatch action | Flag to officer |
| SOP reference | Contract 8,9 / PD |
| Description | Compare salary amounts after converting their pay periods to an annual amount. |
Add these field sets:
- Work Contract →
gross_salary+salary_frequency - Position Description →
gross_salary+salary_frequency
Use the correct field types:
gross_salary→ MoneyAmount;salary_frequency→ PayPeriod; and- a salary range from another source → SalaryBand.
The check can then understand:
| Work Contract | Position Description | Expected result |
|---|---|---|
EUR 1,248 per month |
EUR 14,976 per year |
Pass after annualisation. |
EUR 300 per week |
EUR 15,600 per year |
Pass after annualisation. |
EUR 1,248 per month |
EUR 12,000 per year |
Blocking mismatch. |
Do not use fuzzy text matching for money. A salary can be printed differently while still having an exact mathematical meaning.
Note
The check standardises pay periods but does not itself perform
foreign-exchange conversion. During extraction, MoneyAmount values in an
explicit foreign currency are converted to EUR before comparison. Manually
imported MoneyAmount values must already be EUR, while foreign-currency
salary bands and free-text amounts still require review.
6. Keep advertisement rules separate¶
The Proof of Advertisement has two kinds of rules:
- Document validation rules check the advertisement itself.
- Cross-document checks compare it with other documents.
In the full Identità flow, the advertisement validation rules check that:
- its publication date is within two months of the application;
- the standard route ran for at least 21 days; and
- the fast-track route ran for at least 14 days.
K13 is different. It checks that the advertised job corresponds to the other
job documents.
Do not put the publication date, advertising channel, duration, employer, and job title into one large fuzzy value. Separate checks give a reviewer a clear answer about what failed.
7. Test one complete example¶
Imagine extraction returns:
Travel Document nationality: MLT
CV nationality: Maltese -> MLT
Contract employer: Harbour Care Limited
Covering letter employer: HARBOUR CARE LTD.
Advertisement employer: Harbour Care Ltd
Contract job: CARE ASSISTANT
Position description job: Care Assistant
Covering letter job: Care Assistant
Advertisement jobs: Care Assistants, Nurses, Cleaners
Contract salary: EUR 1,248 per month
Position description salary: EUR 14,976 per year
The expected result is:
| Check | Expected result | Why |
|---|---|---|
K05 Nationality |
Pass | Both sources become MLT. |
K09 Employer |
Pass or human review | The legal suffix and punctuation differ, but the company appears to be the same. |
K13 Job title |
Pass | Care Assistant matches one item in the advertisement. |
K14 Salary |
Pass | The monthly amount becomes the same annual amount. |
Now change the contract job to Staff Nurse. K13 must become a mismatch
unless a nursing job is one of the advertisement candidates. The other checks
can still pass. Separate checks tell the reviewer exactly what changed.
8. Final check¶
The example is correctly modelled when:
- each check compares one clear fact;
- document fields use types that help standardisation;
- the advertisement keeps all job titles as separate candidates;
- harmless formatting differences do not cause an automatic failure;
- different countries, companies, occupations, or salary amounts are not hidden by fuzzy matching;
- uncertain fuzzy results go to human review; and
- the run result shows the original values so the reviewer can understand the decision.
This is the main rule for difficult checks: standardise enough to remove noise, but never enough to remove meaning.
Next tutorial¶
Now use the complete flow with a real document pack, review its findings, work through the next actions, and download the final report: Create and review a fully vetted application.