Sounity · Personalized reports
A prompt chain in a chat window became a platform that sells, writes, renders and delivers personalized reports.
Sounity sells long, personalized reports. I turned a manual process into the whole system: pipeline, admin, custom renderer, shop integration, delivery and the email sequence afterwards.
- Client
- Sounity
- Period
- since August 2025
- Stack
- n8n, Supabase, Rails, React, Gemini, OpenRouter, Shopify, Brevo, Kamal, Hetzner
Starting point
Sounity writes personal reports for its customers. Long texts, carefully designed, as PDFs. At first this was done by hand: enter the data, work through a series of prompts in a chat window, copy the result into a layout. That took time per customer and depended on one person.
The team didn’t want to build this in n8n themselves. They wanted it to run. These days I’m responsible for all the technology behind the product at Sounity.
What I build here
The report pipeline
It started in August 2025 with a multi-step prompt loop. A single prompt produces text that’s too compressed and flat. Several steps in sequence hold length and quality. That became a chain of around 40 prompts per report, orchestrated in n8n, each building block as its own sub-workflow so I can test parts individually. The prompts live in Google Docs and are loaded at runtime, so the team keeps writing where they’re used to. Gemini is the main model, and OpenRouter steps in when something breaks. Later came reports for two people, which link their own records and run through their own sequence.
Admin and customer portal
Since March 2026 the team has its own admin. Sessions, report types, prompts, models and reasoning settings come together there, without anyone touching code. Every session shows the full prompt history, and failed reports can be restarted with one click. Small things that matter day to day: the team renews expired form links itself from the session list, and a Shopify product without an assigned report type triggers an alert right away instead of a customer buying into the void.
A custom renderer instead of layout from the model
The LLM was reliable on content, not on layout. So I split the job. The model writes clean Markdown with fixed headings, and a custom HTML/PDF renderer turns that into pages with a cover, backgrounds, graphics and clean page breaks. In the admin, the team sets the cover image, logo and backgrounds per report type. Tests check that no text runs off the page and that the table of contents matches the text.
Prompt harness
When 40 prompts work together, a small change easily breaks something at the other end. So in July 2026 I built a regression test for prompts: real drafts from production run through it, and a contract checks that the structure is right. In the last run before the switch, all 29 report types were valid, and 50 out of 50 production drafts came back cleanly formatted on the first try. Only then did the new formatting step go live, with backups of the old n8n workflows as a way back.
Shop, delivery and monitoring
Payment happens in the Shopify shop. After that the customer gets a personal link to the form, the pipeline starts, and at the end there’s a private download page with all reports and audio versions. For the audio versions I experimented with podcast and audio models that turn a report into an episode to listen to. Collecting data only after purchase was much cleaner than squeezing everything into checkout. Errors in n8n land automatically in an ops repo, where an agent pre-sorts them. A watchdog speaks up when someone has paid but never filled in their form.
Away from the Node services, toward Rails
Over the months, several small Node services had piled up: render API, graphics renderer, gateway, worker. On September 7, 2026 I started moving them into a Rails app. No big bang: n8n stayed, only the small processes moved. Every interface stayed exactly the same, tests check input against output, and the graphics came out of the new code byte-identical. On September 18 I switched over, then re-rendered every report type in production and put each next to historical PDFs of the same type. Shortly after, the first real purchase went through cleanly. Monitoring now checks the whole pipeline, including worker and queue, not just whether the home page responds.
Sounity Moment: a trade show prototype
On September 24 a request came in for a trade show that weekend: not a full report, but a short excerpt that makes people curious. Instead of a new sequence, I made it a new report type. Same pipeline, two prompts instead of 40, its own compact layout, no email. Visitors fill in a short form on a tablet and land straight on their download page. The readable version is there after a few seconds, and the PDF follows.
The sequence after purchase
Since October 2026, every report kicks off a personal email series over four weeks. A model writes the emails from the purchased report, and Brevo sends them. New sign-ups confirm their address before anything goes out. The team maintains the sequence’s texts and buttons in the admin and can test any sequence in fast-forward.
How I work
I build most things with agents, often several in parallel in their own cloud environments, and check myself what goes live. At Sounity that means: production gets read first, then proven, then changed. Before every larger switch, real documents sit next to the old ones. I also try things and throw them away. I tested a custom job engine next to n8n twice and dropped it both times, because Rails does the same thing more simply.
Coordination with the Sounity team is short and direct, usually on a call. The transcript turns straight into the work order.
Results
A manual process became a product that sells, writes, renders and delivers without anyone stepping in. New report types are configuration, not a new project. The team changes prompts, models, layouts and email texts itself.
Carsten Bruns put it this way early on: a report that used to take 20 to 30 minutes now gets created automatically.
Got a similar problem? Get in touch.