TLDR

I built an AI chat app that tracks symptoms and, crucially, spots symptom patterns I’d never notice on my own. The trackers on the market weren’t doing that so I decided to build one myself. The first version used three separate tools: Lovable, n8n, and Supabase. It worked, but the pattern detection didn’t — and looking back, the architecture was probably more than a chat app actually needed. So I just rebuilt it in Replit.  And now I’m curious whether the combination of structured data and better models means the pattern detection will actually work this time.

One tool. One afternoon. And the experience reinforced something for me: the build got dramatically faster, but it was the product thinking that made it work. The thinking that I’d already done a year ago. The tools changed. The product discovery and decisions carried straight over.

The before picture: three tools

About a year ago, I started building the app because I was frustrated. All the symptom tracking apps out there all felt like homework — forms to fill in, scales to rate things on, categories to pick from. But the bigger problem was that none of them were doing the thing I actually wanted: spotting patterns and giving me the heads up on when symptoms might reoccur based on those patterns. I didn’t just want to log that I had a headache. I wanted something that would eventually tell me “hey, you tend to get headaches two days after this particular cluster of symptoms” — a heads-up, not a record.

So I had an idea: what if tracking symptoms felt like texting a friend? You just say “I’ve got a headache and I’m exhausted” and the app handles the rest — logging what it hears, asking the right follow-up questions, and quietly building up enough data to start finding patterns. The chat was the interface. The pattern detection was the point.

I built the first version across three tools. Supabase for the database. n8n to handle the automation and orchestration — listening for events, triggering the AI, routing data. Lovable for the frontend.

Three tools sounds manageable. And honestly, the architecture was sound:  event-driven, each tool doing what it was best at. But in practice it meant three logins, three billing accounts, and three sets of seams where everything connected to everything else. For a complex workflow system, that trade-off makes sense. For what was essentially a chat app. It was probably more orchestration than I needed.

A good chunk of my building time went into the integration layer rather than the product itself. Did the Supabase event actually fire? Did n8n receive it? Was the data hitting the right table in the right format? When something didn’t work, the first question wasn’t “what’s wrong” but “which of the three tools is the thing that’s broken right now?”

That’s just the nature of distributed systems — even simple ones. The architecture wasn’t wrong. But for a chat app that takes a message, processes it, and writes back a response, it was a lot of moving parts.

How the original architecture worked

I want to be specific about this, because the architecture wasn’t arbitrary — it was a deliberate event-driven design, and understanding why I built it that way is part of what makes the contrast with today so interesting.

Supabase was the source of truth. Every user message was written to a messages table the moment it was sent. But Supabase wasn’t just storage — it was also the event emitter. Using database webhooks, Supabase would fire an event on each new row insert: a new message lands in the table, a webhook fires, and something downstream gets notified.

That “something” was n8n. n8n sat in the middle as the orchestration layer, listening for those incoming webhook events. When a new message arrived, n8n would kick off a workflow: take the message, call the AI with the right context and prompt, parse the response, extract any structured data — symptoms, severity, triggers — and write that data back to the appropriate Supabase tables.

The whole system was event-driven, not request/response. Nothing was polling. Nothing was waiting. A row insert in Supabase propagated outward through the system automatically — triggering n8n, triggering the AI, triggering the writes back. Each user message set off a chain of discrete, observable steps.

And one of the more powerful aspects of this pattern: you can have multiple n8n workflows listening to the same Supabase table. One handles the AI response. Another handles tagging. Another handles something else entirely. They all fire from the same row insert, they run independently, and if one breaks it doesn’t take the others down with it.

That design is solid. Event-driven architectures scale well, the steps are auditable, and each tool is doing what it’s best at. If I were building something with complex multi-step workflows — branching logic, multiple integrations, scheduled tasks — this is exactly the architecture I’d want. But fundamentally I was building a chat app. A user sends a message, the AI processes it, data gets written back. The three-tool setup gave me capabilities I didn’t really need, and the overhead of maintaining the connections between them was disproportionate to the complexity of what I was actually building.

The original architecture — event-driven across three tools

The now picture

I came to Replit because of the noise around it — the Agent, the funding, the builder community talking about it constantly. The obvious alternatives were Bolt.new and Lovable, both of which I was already familiar with (Lovable was part of my original stack).

I’ll be honest, I didn’t fully know what to expect from Replit going in. I knew it was more than just vibe-coding, but I didn’t anticipate what “more” actually meant until I was in it. Specifically: I could see the database! Live. Right there. I sent a message in the chat, flipped over, and watched the row appear in the table.

In the old build, confirming that a message had been correctly written to Supabase, that the webhook had fired, that n8n had received it and processed it correctly - that was a verification process across three different tools. Not because the tools were bad, but because that’s what a distributed architecture requires. Here it was just: look. It’s there. That whole category of work - verifying that events are flowing between systems, checking whether data is landing in the right shape - largely just disappeared. Not because it was unnecessary before, but because the single-tool setup meant it no longer applied.

The chat interface

The messages table — conversation history logged in real time

symptom_logs — structured data extracted from natural conversation

symptom_triggers — cause and context captured automatically

And what that will free up won’t be just time. It will be attention. Instead of asking “is the pipe working,” I will now be able to focus on the user side of the app, the side that I am invested in! I can ask better questions: what should severity actually mean? Should “I feel ok today” log anything at all? What’s the right empty state copy for a patterns dashboard when someone is just getting started? Those are product decisions. The kind of thinking that actually makes the difference between something people use and something they don’t.

The database surprised me

Here’s the thing I didn’t expect: Replit’s AI didn’t just throw everything into one table. It created a properly normalised structure — four tables: users, sessions, messages, and symptom_logs — and the symptom_logs table was actually better than what I’d designed in Supabase a year ago.

In my original build, the AI was doing pattern detection by pulling from raw chat history — essentially re-reading old conversations and trying to extract symptoms from natural language every single time. Replit instead created dedicated columns for symptom_name, severity (with a proper enum enforcing the ok/bad/very bad scale), category (another enum), and notes — all linked back to the message that produced them via a foreign key. Clean, queryable, structured data.

It’s worth sitting with that for a second. An AI agent, working off my product brief, independently arrived at a more normalised data architecture than my original. Not because I’m bad at data modelling — but because in the first build I had so many other things to think about (the orchestration, the webhooks, the agent routing) that I defaulted to the simplest thing that worked. Replit didn’t have that constraint. It could think about the schema purely in terms of what theproduct needed, not what was easiest to wire up.

That said — it wasn’t perfect. It missed triggers and remedies as separate fields, which is something I only spotted because I’d spent a year living with the product and knew what data the pattern detection would eventually need. The AI got the structure better than I did originally, but it still needed human product thinking to spot the gaps.

The 8 minutes that weren’t really 8 minutes

Replit built the working app in about 8 minutes. That number is real, but it needs context because taken at face value it sounds like hype.

Those 8 minutes were working off specs and prompts that I had spent weeks fine-tuning while building, testing and using the original version. Build –> Measure -> Learn. Every decision about what the AI should ask, how it should interpret a user’s response, what counts as a symptom worth logging, how severity should be calibrated — all of that had been designed, tested, broken, and fixed in the first build. It got distilled into prompts. Those prompts went into the Replit spec. And Replit executed against that accumulated knowledge almost instantly.

The original app wasn’t wasted effort. It was the R&D phase. The first version,  with all its orchestration overhead, was where the actual product thinking happened. The discovery. The user testing. Some evaluation. The second version was fast because all of that was already done.

This points to something I see a lot of people getting wrong about AI-assisted building. There’s this idea that the tools replace the thinking…that you can just describe what you want and the AI figures it out. And sometimes that’s true for a prototype. But for something you actually want people to use? The better your specs, the more precisely you’ve thought through the product, the faster and more accurately the AI can build. Vague inputs produce vague outputs. The 8 minutes was the payoff on weeks of thinking, not a shortcut around it.

What actually changed

The shift wasn’t just speed, though it was faster. It’s that the nature of the work changed. When the tooling collapsed into one place, I stopped being a systems integrator and started being a product builder.

The AI extracts structured data from natural conversation in real time - symptom name, severity, likely trigger - and writes it to a database without the user ever filling in a form. Getting that working in the first build was a multi-tool, multi-day project. In Replit, it was an afternoon.

And this isn’t ancient history. The first version was twelve months ago. That’s the part that still catches me off guard — not how far things have come, but how fast.

The trade-off I’m watching

But there’s something I want to be honest about, because if I only told the “it’s faster and better” story I’d be leaving out the interesting part.

With the original stack, I could see everything. n8n gave me full visibility into the orchestration. I could watch each workflow trigger, inspect the prompt being assembled, see exactly what context the agent was pulling in, and pinpoint where it failed. It was like having the bonnet open while the engine ran.

With Replit, I’ve traded that transparency for speed and simplicity. The AI is essentially a black box now. I can see the inputs (my chat) and the outputs (its responses and the data it writes), but the middle bit - how it’s deciding what to log, what patterns to surface, how it’s interpreting severity - that’s hidden.

I had observability built into my architecture before. Now I need to build it into my testing process instead. That’s a real shift, and I’m not sure yet whether it’s a good trade. More on that in Part 2.

What’s next

The app is working. The chat logs symptoms. The database captures them correctly. The severity calibration is right, the empty state sets honest expectations, and the pattern detection is queued up and waiting for enough data to say something meaningful.

The Patterns page — waiting for enough data to surface insights

So now I’m going to actually use it. For a couple of weeks, as a real user, checking in daily and seeing what it picks up. Part 2 will be about what it got right, what it missed, how you evaluate an AI product when you can’t see inside the machine — and whether the patterns it surfaces are actually useful or just plausible-sounding noise.

The pattern detection piece is what I’m most curious about. It’s the reason I built Trickel in the first place — not the chat, not the logging, but the ability to spot connections I’d never notice on my own. In the original build, pattern detection was limited by two things: the data structure (raw chat history that the AI had to re-parse every time) and the context window (which is why I had those “last 70 days” lookups in n8n — I couldn’t feed it everything). Now I’ve got structured data from day one and models that can reason over much longer sequences. Will that actually produce better patterns? Or is the hard part not “can the AI see the data” but “can it tell the difference between a real pattern and a coincidence”? That’s what I want to find out.

The build was the easy part. The interesting question is whether it works.

Keep Reading