At CanalisLabs I built frontend applications in Next.js and TypeScript for an insurer’s core platform, covering quotes, policies, endorsements and claims. The piece I was personally credited with was policy document generation.
The problem
The insurer issues policies across several products, each with its own document template. The business needed to change the wording itself, without raising an engineering request every time, and documents still had to be filled with real policy data.
So the question was how to give non-engineers real control over a document without letting them break it.
Make the variables impossible to guess wrong
Templates stayed editable inside the system. The key decision was what sat beside the editor: a list of every available variable, each with a description. Picking one inserts it as a {{variable}} placeholder, resolved from the policy data at generation time.
Try it here. Click a variable to insert it, or edit the text however you like.
This policy, PL-20418, is issued to Jordan Lee with cover of $250,000. Beneficiary:
That list is what made it self-service. Someone editing a template never has to know or guess a variable name.
A missing value should be a gap, not an error
Policies don’t always have every value. If a variable has no value, it resolves to an empty string. In the demo, the beneficiary has no value, so its line simply ends.
The alternatives are both worse. A raw {{placeholder}} reaching a customer looks broken, and failing the whole document over one optional field stops the work. I also made sure the output came out properly formatted, not just correct in content, because this is a document people keep.
A bug that looked like success
While setting up endorsements, I noticed that an approved endorsement wasn’t updating its policy. The approval appeared to succeed, but the policy stayed as it was.
I was on the frontend, consuming APIs owned by backend developers. Before raising it, I reviewed my own code and confirmed I was sending the right payload, so I was escalating a real problem rather than my own bug. Then I sat with the backend developer and we tested it together until we could reproduce it reliably, which is what made it fixable.
“This is broken” can start an argument. “I’ve verified my payload and I can reproduce it” gets it fixed.