Building Arcatech custom CRM

Building Arcatech custom CRM

By Yuriy Zhar 4 min read
I built a custom CRM using Elixir and Phoenix LiveView that uses AI to identify parts from photos, translate messages, and automate conversations with suppliers over WhatsApp.

Arcatech’s real problem wasn’t parts. It was memory.

If you’re reading this, you’ve probably seen a “simple” workflow turn into chaos once it hits real customers. This is the story of taking a WhatsApp-driven business and giving it a brain without breaking how people actually work.

What I found after living inside their chats

Arcatech doesn’t really sell “parts.” They sell answers. Fast ones. Most requests arrive as a blurry photo in a WhatsApp message with the emotional energy of “help” and the technical specificity of “this thing.” No part number. No model. Sometimes not even a sentence. Just an image of a greasy chunk of metal under bad lighting.

At first I treated this like a data problem. Build a catalog. Normalize names. Add fields. Make it clean. That’s the usual move. It also failed immediately because the work wasn’t happening in a database. It was happening in chat threads. The “source of truth” was whoever remembered a similar photo from three months ago.

The useful conclusion was simple: the business wasn’t broken, but the workflow was. Humans were doing the work of a system. They were translating, searching, copying, asking suppliers, waiting, re-asking, and then reconstructing context from message history. The cost wasn’t just time. It was attention. And attention doesn’t scale.

When the business runs on chat, your real database is everyone’s memory.

Once I stopped trying to “fix the data” and started trying to “fix the flow,” the solution became obvious: build a CRM that behaves like an operations brain. Real-time. Multilingual. Supplier-aware. AI-assisted. And most important: designed around the messy way requests actually arrive.

The day I realized spreadsheets were the trap

The first week looked productive. It was also a lie. I had clean fields, a tidy table, and the satisfying feeling of order. Then a customer sent a photo of a part that was technically “already in the system,” except the naming didn’t match, the supplier used a different description, and the only meaningful identifier was the shape in the image.

That’s when it clicked. Parts don’t have stable identities in this world. Not reliably. They have “close enough.” They have “looks like the one from last time.” They have five different names depending on which supplier you ask. Any system that assumes stable naming becomes a system that forces humans to do extra work. And Arcatech did not need extra work.

So I stopped designing for perfection. I designed for speed and traceability. The goal wasn’t to build the world’s best catalog. The goal was to help a person answer a customer in minutes with the best available information, and to leave a trail that makes the next request easier.

Building an “operations brain” instead of another tool

I built the backbone in Elixir with Phoenix LiveView. Not because it’s trendy. Because the workflow needed real-time coordination without turning into a frontend zoo. Messages come in. Supplier replies arrive at unpredictable times. Multiple requests are in flight. People need to see what changed right now, not after a refresh, and not by asking around.

Early on, I tried to keep everything “manual but faster.” A nicer inbox. Better tagging. A small set of templates. It looked safer. It also kept the pain intact. It made chaos more organized, but it didn’t remove the repeated work.

The turning point was treating every request as a guided process. A queue with state. A thread with memory. Something that can say, “We’ve seen this before,” or “We haven’t, but here are three similar items,” and then move the request forward without forcing a human to copy text between apps.

The core behavior became straightforward: accept a customer message or photo, attach it to a request, track what’s known, ask the right suppliers, collect replies, and produce a clean quote in the customer’s language. It’s not flashy. It’s just what the business needed done, reliably, every day.

The AI part worked only after I stopped expecting magic

I didn’t want a “chatbot CRM.” That’s how you end up with a confident system that says the wrong thing quickly. Arcatech needed something stricter: an agent that behaves like a cautious operator. It can move work forward, but it must show its work and ask for approval at the only moment that actually matters: pricing.

The early failure mode was predictable. If you let an agent improvise, it will. It will guess part names. It will invent structure where there isn’t any. It will sound convincing while being wrong. In this domain, wrong is expensive. So I narrowed the agent’s job. It doesn’t decide everything. It does the boring parts humans hate doing repeatedly.

In practice, that meant using AI in small, controlled places: classify and match images when names are missing, draft supplier inquiries, extract price and availability from messy replies, and translate messages cleanly. For translation I used Gemini because it’s fast and cheap. For reasoning and orchestration I used GPT-5 (preview) because it handles multi-step workflows well. Each model does one job. No heroics.

The real design win was the “one question” moment. After supplier data is extracted and stored, Arcatech gets a clean prompt: supplier price, availability, delivery time, and context. Then one decision: “What’s the final price?” That’s where humans stay in control, and it’s the point that protects the business.

WhatsApp was the hardest part because it refuses to be a system

Everything important happened on WhatsApp. Customers live there. Suppliers live there. And WhatsApp does not want to be automated in the way Arcatech needed. There isn’t a free official API that fits this workflow. You either pay for the Business API and accept the constraints, or you deal with WhatsApp Web and all the fragility that implies.

I went down the “just integrate it directly” path first. It was tempting. Keep everything in one app. One deploy. One mental model. Then you hit reality: WhatsApp sessions drop, QR logins expire, and anything that touches a web client is the kind of thing that breaks at 2 a.m. If you mix that into your core CRM, you turn one failure into a whole-system failure.

So I backed out and did the boring thing: isolate WhatsApp into its own Go microservice using Whatsmeow. Go isn’t Elixir. That’s fine. The boundary mattered more than the language. The service maintains the WhatsApp session, sends and receives messages, and talks to the CRM over WebSockets. Stateless. Replaceable. Easy to restart without dragging the rest of the system down with it.

I also considered making the Go service behave like an Erlang node. It’s the kind of idea that sounds elegant in a diagram. In production it buys you cluster headaches and debugging pain. WebSockets gave clear boundaries, simpler monitoring, safer deployments, and fewer ways to fail in surprising ways. Sometimes the smartest move is refusing to be clever.

What changed for Arcatech after it shipped

Everything runs on Fly.io: two Elixir instances for redundancy, one Go instance for WhatsApp, MongoDB Atlas as the database, and external LLM APIs for the AI tasks. The system handles concurrency cleanly and fails in contained ways. If WhatsApp has a bad day, the CRM still works and requests don’t vanish into chat history.

The bigger change was cultural. Arcatech stopped living inside scattered threads. Requests became traceable objects with state. Replies were captured, structured, and linked. Pricing decisions became explicit instead of implicit. And multilingual communication stopped being a bottleneck because translation was built into the flow instead of being an extra step someone had to remember.

It was built in about four weeks, not because it was simple, but because the target was clear: match the workflow the business already had, and remove the parts that were wasting human attention. The system didn’t ask Arcatech to change who they are. It stopped asking them to be a database.

If you’re building something similar, here’s the test that matters: when a customer sends a photo with no context, can your system move forward without panic, without guesswork, and without requiring a hero to remember the last time it happened? That’s what an operations brain is for.

Next steps are practical: keep tightening the “one question” approval point, add more supplier-specific extraction patterns as you see new reply formats, and measure time-to-quote like it’s a core metric. Because in this business, speed isn’t a feature. It’s the product.

Windsurf
Recommended Tool

Windsurf

All my projects and even this website is build using Windsurf Editor. Windsurf is the most intuitive AI coding experience, built to keep you and your team in flow.

Share this article:
Yuriy Zhar

Yuriy Zhar

github.com

Passionate web developer. Love Elixir/Erlang, Go, TypeScript, Svelte. Interested in ML, LLM, astronomy, philosophy. Enjoy traveling and napping.

Get in Touch

If you need a developer who delivers fast, reliable, real-world solutions, reach out. Let’s turn your idea or project into something that works.

Stay updated

Subscribe to our newsletter and get the latest articles delivered to your inbox.