UpLinked · LinkedIn content automation
developer: full stack, agents, prompt system, migration, billing uplinked.appthe appI built the backend, AI workflows, migration and billing for UpLinked’s move from Bubble to Convex, turned it into serious high-tech software, together with the two very tech savvy founders
UpLinked interviews entrepreneurs about their work, helps turn their answers into LinkedIn posts, and schedules publication. Bart and Thierry had an existing Bubble product with customers and their writing already in it. Our four-person team rebuilt it on Convex; I owned the backend, agents, prompt system, migration and billing, and merged the team’s pull requests.
Let the product team improve the prompts
The wording, model choices and post templates live in an editable system with drafts, versions and rollback. A change can reach the app within a minute without a code deployment.
The boundary is deliberate: people can change how an agent is instructed, while the structure of the tools it calls stays in code. Feedback on a generated post is tied to the prompt version that produced it, so we can investigate which change helped or hurt.
Keep the interview alive
An AI response can take long enough for someone to close a tab. I moved the work into background actions and let the interface subscribe to the saved conversation. Returning to the app brings the conversation back.
That introduced some less obvious failures. Duplicate starts produced two greetings; stalled responses left the typing indicator running indefinitely. I added an atomic check to claim each start and a timeout that offers a retry when a response gets stuck. The recovery matters as much as the successful answer.
Move the existing customers across
The migration brought 196,000 rows out of Bubble. My first approach tried to process too much data at once and ran out of memory. I split the import into small jobs, linked records to their old IDs and made each job safe to repeat.
Customers reactivated their accounts to find their profiles, posts and subscriptions in the rebuilt app. The first days exposed some missing knowledge data; I brought that across through the same repeatable import. The new app now runs at the address the Bubble version used.
Publishing needs one source of truth
A calendar bug made the consequence of inconsistent state very clear: moving a post changed its displayed date, but its old publishing job could still run. I brought the date and job changes into one operation and made stale jobs check their scheduled time before publishing. That keeps the calendar and the action it promises together.