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.
