Modular Design: sales, CRM and internal tools
- ~2,000
- automated tests on the order system
- 3
- email languages on the order system
- ~70%
- of CRM email sorted by rules; a model sorts the rest
Buongiorno, vorremmo ordinare 40 pezzi dell'articolo 1042 e 15 dell'articolo 2210, con consegna entro il 15 dicembre. Stesso prezzo dell'ultimo ordine? Grazie, Giulia
- CustomerMatched to account✓
- Art. 104240 pcs✓
- Art. 221015 pcs · 9 in stock!
- DeliveryBy 15 Dec✓
- PriceAs last order✓
A customer email comes in, here in Italian.
Most of the systems I build look different from the outside and almost identical underneath: something comes in, something reads it, something checks it, an action follows, and a person needs to see what happened. So I build those steps as tested blocks, per system, with AI agents proposing, rules checking and a person approving. This page explains that approach and shows the sales systems and CRM built with it, and the internal platform in general terms.
Why I build this way
Most of the automations and tools I have built look different from the outside and almost identical underneath. Each one has something that comes in, something that reads it, something that checks it, an action that follows, and a follow-up that has to happen later. And in every case, someone needs to see what the system did.
In many companies the same internal processes are repeated by hand: collect what is needed, check it against the rules, decide, and keep track as things change. It is slow, hard to audit and easy to get wrong. Small companies lose hours to the same sales and order work every week: emails in several languages, orders typed over by hand, follow-ups that slip, and a CRM nobody keeps up to date.
A script that does the whole job end to end is the fastest way to automate that, and I still write them for one-off analyses. The trouble starts at the second run. A new input format arrives, the same step is needed in a different workflow, and the script turns out to hold three responsibilities in one function, a configuration value in a filename and no record of what it did last Tuesday.
- Something comes intrigger
- Something reads itintake
- Something checks itcheck
- An action followsaction
- A follow-up happens laterwatch
- Someone sees what it diddashboard
What a block is
A block is the opposite trade-off. It does one step, with:
- a contract: a typed input, a typed output and a schema it validates against;
- tests against real examples, including the ugly ones;
- monitoring and logs, so a failure is visible the day it happens rather than the week someone notices;
- an explicit answer to "what happens when this goes wrong": retry, park for a person, or stop.
Building a block costs more than writing the equivalent lines in a script. That cost is paid once; every later workflow in that system starts from parts that already run.
block: read-order-email input: Email output: Order (validated schema) tests: real examples, ugly ones too logs: every run on failure: retry park for a person stopMade-up example of one block
Agents propose, people approve
The systems I architect and build rest on one principle: agents propose, people approve. A language model reads what comes in and fills a fixed schema. The model is the least interesting part; the schema validation and the confidence threshold around it are what make it usable. Rules then compare the proposal against reference data, such as a customer list or a price list, and anything that does not match waits for a person.
Where that line sits is a decision per system, not a constant. Steps with a side effect outside the system get extra care: sending an invoice has to be idempotent, so running it twice for the same order does not produce two invoices.
Every block reports what it did into one shared log, which is what lets a person trust a system they did not write.
- Something comes ininput
- An AI agent proposesAI agent
- Rules check itrules
- A person accepts or overridesperson
- It is applied, with an audit recordrecord
The same steps in other shapes
The pattern is the one I have used for years in data work. The house-price index study for Eurostat followed it: scraping was the intake, deduplication and validation were the check, the hedonic regression was the action, and the report was the follow-up. Each system has its own blocks, and what differs most is where the person sits. What does not change is that each block is built, tested and monitored as a unit.
- StepOrder emailHouse-price index
- IntakeRead the emailScraping
- CheckReference dataDeduplication, validation
- ActionInvoiceHedonic regression
- Follow-upReminderReport
Where blocks are the wrong choice
Blocks have a tax. A one-off analysis that answers one question and is then archived does not need contracts and monitoring; a notebook is the right tool. A domain that is still being discovered also resists early abstraction: drawing block boundaries before the steps are understood produces blocks with the wrong seams, and those are harder to fix than a script. My rule of thumb is to write the script first, run it until the second run hurts, and only then cut it into blocks along the seams that the second run exposed.
The rest of this page shows the systems built this way.
An order-intake agent and light ERP for a trading company
Orders, quote requests and negotiations arrive by email in three languages. The system reads the mailbox, classifies and extracts each message through a workflow engine built from agent blocks, proposes the order, quote or counter-offer, and puts anything that needs a decision in a "needs you" queue. Every change is audited and can be undone; invoices, contracts and commissions run in a light ERP behind an adapter, so the company's own ERP can replace it.
The order system is in acceptance testing with the owner after four test rounds, with about 2,000 automated tests.
An internal CRM and outreach engine for a small B2B data firm
Contact and deal pipeline, mailbox sync across accounts, email classification (rules handle about 70%, a model the rest) and AI-drafted outreach and replies. Every AI-written email is saved as a draft; a person sends it. The CRM runs internally.
- Mailboxes sync across accountssync
- Rules sort about 70% of emailrules
- A model sorts the restmodel
- AI drafts the outreach or replyAI agent
- A person sends itperson
How the sales systems run
Data is pseudonymised before any text reaches an external model; one model gateway holds the keys, enforces budgets and runs on EU hosting. Partly on Azure, with Microsoft 365 mail integration; the rest on Docker on EU servers, with nightly off-site backups and staging environments.
A modular internal platform
As architect and lead developer: a platform where every workflow is assembled from small blocks. AI agents propose decisions, a person decides, and every decision can be traced.
The platform is in progress, and the client stays anonymous.
Earlier platform work
Before these systems I moved a data platform on eight production servers to Airflow, Iceberg and FastAPI.
Written with AI, checked by me.
Back to projects