A client brought us a paper visa application form, two A4 sides, and asked us to put it online. We counted the fields: 17, six of which were 'enter N/A if not applicable' types. My first instinct wasn't data modeling — it was one question: who reviews this form?
First We Built It Exactly Like the Paper Form
V1 faithfully carried all 17 fields, plus passport scan upload and multi-step saving. jQuery validation on the frontend, PHP on the backend, attachments in a server directory with paths in MySQL. Then we filled it in ourselves and got impatient at field 9 — father's name, mother's name, spouse's occupation. For a short-stay tourist visa, most applicants simply can't fill these in.
On the client side, a lady reviewed the documents. We sent her the test link; she finished and called us. Her first sentence: this form is worse than the paper one.
Cutting Fields Wasn't a Guess
The next week we sat in their office, printed all 17 fields, stuck them on a wall, and asked about each one: 'Do you look at this when you review?' Fields she read stayed on the left; the rest moved right. Six ended up on the right: father's name, mother's name, spouse info, former name, religion, backup contact. 'Former name' and 'backup contact' stayed as optional; the other 4 were removed and replaced with an admin remark box. 17 became 11, with only 8 required.
This step involved zero technical skill, and it was worth more than all the code that followed.
The Day an Attachment Actually Vanished
Multi-step saving worked like this: each step POSTed to the backend, filled fields went into the session, and the final step wrote everything to the database. All tests passed. On day three after launch, an applicant uploaded at step 2, took a phone call, came back twenty minutes later, tapped Next — and the attachment was gone.
The cause wasn't hard to find: sessions expired after 24 minutes by default, and we stored the uploaded file's temp name in the session while the file itself sat in the tmp directory — where a server cleanup script swept through hourly, deleting anything untouched for 30 minutes. Two timeouts collided.
The fix was crude but effective: the moment an attachment uploaded, it moved straight into its permanent directory; we inserted a draft row into the database first to get an id, and named the file with that id. Each subsequent step only updated that row's fields — no more session-based file storage. The draft table got an updated_at, with a cron job clearing drafts untouched for 7 days. We also added a 'previous step' button, which hadn't existed — it was forward-only before.
Those 11 Fields Changed Twice More
The first time was 2017: the client added 'accompanying minors,' because when a family of three traveled, the children's documents had to be tied to the main applicant. We didn't stuff it into the main table — it became a detail sub-table, one row per person, with just a count in the main table. We deliberately left the 8 required fields untouched, wary of recreating a form people abandon halfway.
The second time was 2019: 'passport issue place' went from a dropdown to auto-filled. OCR wasn't in place yet — we read the machine-readable zone from the scan; if unreadable, the field stayed empty and flagged 'to be completed,' never hard-blocking. The reviewer said she only ever glanced at that field: if it's there, cross-check it; if not, no big deal.
Interestingly, of the 6 fields we cut, 'backup contact' returned two years later — in a new position: no longer a column on the form, but an optional box under 'if we cannot reach you.' The client said it wasn't about the data; customer service had genuinely hit cases where an applicant's phone was off and the home number was the only option.
The Reviewer's Ledger
After the form had run for over two years, the client tallied rejection reasons once: the top reason had shifted from 'missing fields' to 'blurry photo.' That's no longer about field count — it's the upload step. We later added a line of small print beside the upload button — 'get all four corners, avoid glare' — which worked better than any validation change.
The wall where those fields had been pinned was a whiteboard by the time we visited last year, with the month's tour schedule written on it — neater handwriting than our old paper. A new colleague once asked why v1 copied the paper form instead of building what we thought was right. My answer: because the reviewer had worked off that paper for a dozen years. You first have to know where her eyes land before you can talk about removing fields. That reasoning never made it into a document; it does now. Those 8 required fields stayed untouched until the 2025 rebuild — eight years, and nobody asked to add anything back.
Aftermath
In its first three months the form collected 2,000-plus applications. The client said the most visible change was fewer phone calls: most returns used to be mistakes or omissions; now required-field validation blocks them on the frontend, with format errors flagged on the spot.
We never peeled our field printouts off that wall when we left. Word is they moved two more to the right side themselves.

