Laravel in Leeds
Laravel development for Leeds health, legal and insurance
A Laravel development company for Leeds health, legal and insurance firms. The copies of personal data nobody counted - exception reports, queue payloads, the search index, last night's backup.
Leeds is where health, legal and insurance work concentrates, and all three handle the categories of personal data that carry the heaviest obligations.
The surprising part is where the exposure actually sits. Teams spend their effort on the database - access control, encryption, careful queries - and the database is usually the best-protected copy of the data in the whole system. The problem is the other copies, and most applications have more of them than anybody has counted.
Leeds logs hold what the database holds
An exception report contains the data that caused the exception. That single sentence is the whole issue.
A validation failure on a form holding a diagnosis logs the diagnosis. A database error logs the query, and the query carries its parameters. A failed job logs its payload. An HTTP client logs a request body. Send all of that to a hosted exception reporting service and the organisation has a third-party processor holding special category data, which nobody declared and no agreement covers.
The remedies are specific rather than architectural. Sensitive fields are redacted where they are logged rather than filtered later. Job payloads carry identifiers instead of data. Exception context excludes request bodies by default. And the reporting runs on infrastructure the organisation controls, because the alternative is a conversation with an information governance team that does not end well.
Count the Laravel copies before promising deletion
A deletion request is a promise about every copy, not about a row.
The list is longer than it looks. The database. Last night's backup, which still holds what production deleted this morning. The search index, holding a denormalised copy maintained by code nobody has opened in a year. Queue payloads sitting in Redis. An audit table that recorded the values as they changed. A CSV exported for a meeting in March, which has no lifecycle, no owner and no expiry.
Until that inventory exists, deletion is aspirational. Once it exists, deletion can be built as one operation that fans out and confirms rather than a database call followed by optimism. A soft delete is not a delete covers the first mistake; the inventory covers the rest.
Minimisation is a schema decision in Leeds casework
The cheapest way to protect data is not to hold it, and in health and legal work that is more achievable than it sounds.
Claims systems accumulate fields because somebody once asked for them. A date of birth is collected when an age band would do. A full address is stored when a postcode district answers the actual question. A free-text note holds a clinical detail that nothing in the system uses.
Each of those is a liability with no corresponding value, and each is cheaper to remove now than to defend later. The useful exercise is to ask, field by field, which question it answers and who asked - and to find that a surprising number answer nothing at all.
A Leeds subject access request is a query nobody wrote
Somebody asks for everything the organisation holds about them. That request is a database query, and in most applications it is a query nobody has ever written.
The reason is that the schema was designed around work rather than around people. A claim has a claimant. A case has a client. An appointment has a patient. A message has a sender, who may be a staff member writing about someone else. The person appears in six tables under four different column names, and in two of them only as free text. Answering the request means somebody opens the schema and goes looking, which takes a week and misses things.
The arrangement that works is to make each model answer for itself. A model that holds anything about a person declares what it holds and how to find it by subject, and the request becomes a composition of those answers rather than an excavation. New tables either implement that contract or are visibly absent from it, which is the point - the gap is in a list rather than in somebody's memory.
The output matters as much as the gathering. A subject access response is read by a person, sometimes by their solicitor, so it is a document rather than a JSON dump. Free-text notes are the hard part, because a note about one person frequently names another, and the second person's data has to be withheld. That is a redaction step with a human in it, and building the response pipeline so a human can review before release is the difference between a process that can run and one that cannot.
Laravel authorisation when the record is a patient, not a row
The question is almost never whether a user may read patients. It is whether they may read this patient.
That distinction is where most access control in health and legal applications leaks. A policy answers correctly on the detail page, because that is where it was written, and then the same record arrives through a route that never asked. Search is the usual one - the index was built without the scoping rule, so a query returns names from outside the user's caseload even though clicking through would be refused. Exports are the second. A report that aggregates across the whole dataset is fine until a column holds a name.
What holds up is a single scoped query that every route reaches the data through, including search and export, so the scope cannot be bypassed by taking a different path to the same table. The index is built from that scoped query rather than from the raw table, and an export is generated through it too.
Reads need auditing here, not only writes. In a health or legal context the interesting event is that a member of staff opened a record they had no reason to open, and that leaves no trace in a system which only logs changes. Logging every read is noisy and worth it, provided the log is queryable by subject and by staff member - an audit nobody can search is an expense rather than a control.
Commercially
Scope fixed in writing before work starts, priced per project. The country-level ground - UK data protection obligations on a supplier, consent, invoicing - is on the United Kingdom market page.
Invoiced by Codefacture Yazılım A.Ş. in Türkiye, in pounds by bank transfer, with no Turkish VAT under the export-of-services exemption.
