Skip to content

Laravel in Wellington

Laravel development for Wellington government and public bodies

A Laravel development company for Wellington agencies and national bodies. Macrons in the database, where the wrong collation makes two spellings of one name into two different people.

Wellington's public sector data contains te reo Māori, where vowel length changes the word, so a macron is spelling rather than styling. That turns a collation choice - normally an afterthought nobody writes down - into a correctness decision.

The practical consequence is that the same name exists in a database twice, once with macrons and once without, because people type it both ways and the system treated them as different strings. One person becomes two records, and nobody notices until a report counts them separately.

Wellington search has to be forgiving, storage has to be precise

Most people type without macrons most of the time, especially on a phone, and they expect to find the record anyway.

With an accent-sensitive collation they will not. The stored name has a macron, the search term does not, the comparison fails, and the user concludes the record is absent - then creates it again, which is how the duplicate arrives.

The arrangement that works separates the two requirements. The exact value, with its macrons, is what gets stored, because rewriting somebody's name into a form the system prefers is the wrong direction in any context and particularly in this one. Comparison is accent-insensitive, through a collation chosen deliberately on the columns that need it or a derived column used only for matching.

Search forgives. Storage does not alter. Those are different jobs and they need different mechanisms.

The same Laravel change exposes the duplicates already there

Changing the collation does two things, and the second one is work.

It prevents new duplicates, because a unique constraint can now see that two spellings are the same string. And it reveals the pairs that already exist, which previously coexisted happily and now violate the constraint.

That is a deduplication exercise rather than a migration, and it is better encountered knowingly than discovered when the constraint fails in production. The approach is the same as any identity resolution problem - propose matches, let somebody who knows the people confirm them, and make the merge reversible, because some proposed matches are two genuinely different people.

Laravel validation that rejects the language

The quietest version of this problem is a form that will not accept the characters at all.

A validation rule restricting a name to unaccented Latin letters, copied from an example years ago, rejects a macronised vowel as invalid input. From the developer's side nothing is wrong; from the user's side the system has told them their name is not a name.

It is worth auditing every name, address and free-text field for that rule specifically. The related check is field length measured in bytes rather than characters, because a macronised vowel is more than one byte and a column sized in bytes truncates mid-character - which produces stored values that are not valid text at all.

The country-level ground for New Zealand - the privacy regime, data residency expectations, invoicing - is on the New Zealand market page.

A Wellington name does not fit the fields it was given

First name, middle name, last name is a model of one naming convention, and a public body serves everybody.

People have one name. People have names where the family name comes first. People have names longer than the column, names with macrons, names with apostrophes and hyphens that validation routinely rejects, and names they go by that are not the names on their documents. Every one of those is an ordinary New Zealander and the system either records them correctly or records something else and calls it their name.

What works is a full name field that holds the name as the person gives it, with structured parts recorded separately when something genuinely needs them rather than as the primary storage. A preferred name sits alongside the legal name and is what appears on screens and in correspondence, because using somebody's legal name when they have told you otherwise is both rude and, in some contexts, a disclosure.

Length limits deserve a mention because they are set carelessly and break in public. Thirty characters is not enough. Neither is the assumption that a sorting order derived from a last name column is meaningful when a third of records were entered as a single string. Sorting and matching are separate concerns from storage and should be built from derived fields that can be recomputed, not from the field the person filled in.

Laravel validation for a Wellington form somebody filled in on paper

Data transcribed from paper is incomplete in ways an online form prevents, and a system that refuses incomplete records simply does not get used.

The distinction that matters is between empty, unknown and declined. A date of birth that was left blank, a date of birth the person does not know, and a date of birth the person chose not to give are three different facts, and storing all three as null loses information that somebody will later need - most obviously whether it is worth asking again. Three states, stored explicitly, cost one column and answer the question permanently.

Validation then has to be tiered. A record can be saved with gaps, because the transcriber has the form in front of them and will not be able to invent the missing field. A record can only be submitted for a decision when the fields that decision requires are present. Those are different rule sets attached to different transitions, not one set of required fields on a model, and conflating them is why staff learn to type a placeholder into mandatory fields.

Placeholders are the real cost of getting this wrong. Once somebody has typed a date of birth of the first of January 1900 to get past a required field, the data contains a value that looks real, passes every check, and is false. That is considerably worse than a gap, and it is created entirely by validation that left no legitimate way to say "not known".

Commercially

Scope fixed in writing before work starts, priced per project.

Invoiced by Codefacture Yazılım A.Ş. in Türkiye, in US dollars by bank transfer, with no Turkish VAT under the export-of-services exemption.

The regulatory and commercial ground for this city is on the New Zealand market page.

Frequently asked questions

Why does searching for a Māori name sometimes return nothing?
Because the stored value has a macron and the search term does not, or the reverse, and the collation treats them as different strings. Somebody typing without macrons - which is most people, most of the time - finds nothing, and concludes the record does not exist. The fix is a collation that ignores accents for comparison, chosen deliberately on the relevant columns, with the exact form still stored faithfully. Search should be forgiving while storage stays precise.
Can the same collation choice create duplicates instead?
It prevents one kind and reveals another, which is why both halves matter. With an accent-sensitive collation, a unique constraint lets the same name exist twice with and without macrons, and you get two records for one person. With an accent-insensitive one, the constraint catches it. What that then exposes is the records already created before the change, which is a deduplication exercise rather than a migration and is better done knowingly than discovered later.
Should we normalise the stored value?
No - store exactly what was entered, including the macrons, and normalise only for comparison. Rewriting somebody's name to a form the system finds convenient is the wrong direction, and in this context it is also disrespectful. The pattern that works keeps the exact value in one column and uses collation or a derived comparison column for matching, so the original is never lost.
Our forms reject macronised characters as invalid.
A validation rule somewhere is restricting input to a Latin alphabet without accents, usually copied from an example years ago. It is worth auditing every name, address and free-text field for that, because the failure is silent from the developer's side and insulting from the user's. The same applies to any field length measured in bytes rather than characters, since a macronised vowel is more than one byte.
Call us+1 848 272 7583WhatsApp+90 850 308 5436Emailinfo@codefacture.comContact page