How I built an autonomous system that gathers official information for a tax consultancy firm

Summary

From 40h/week to 1h/month

Time spent on these tasks

That monthly hour corresponds to the time spent on manual reconciliation for the cases the system cannot resolve on its own due to lack of information or context.

+18%

CSAT improvement

Their clients' satisfaction improved from the second month after implementation onward, due to the faster information flow and the removal of the bottleneck.

-77.5%

Deadline reduction

The deadline was 40 days and delivery happened in just 9. That means 31 days ahead of the maximum deadline.

Revenue increase

Triggered by a newly activated service

This system led to a second phase: a system that found grants and subsidies for their clients based on their CNAEs, locations, etc.

Problem

This tax consultancy, like most in Spain, still handled many tasks manually, and they reached out to me to figure out what they could do to improve their processes. They were aware of the issue, but they did not know exactly what could be automated or how far that automation could go.

I embedded myself in their processes for 3 days, identified several workflows that could be improved, and presented them with a proposal that outlined several improvement opportunities and how to carry them out. Given the nature of the firm, they started by accepting one specific proposal, which is the one we cover in this case study.

One of their recurring tasks consisted of periodically gathering client information that was scattered across different official public websites such as BOE, BORME, BDNS, SNPSAP, etc.

Almost all official websites make information difficult to consume because of poor user experience, inconsistent file formats, and a lack of data standardization across platforms. In this case, the firm was spending an average of 40 hours per week across 3 employees on tasks related to Business Intelligence, Compliance and official notifications, company formation and corporate procedures, among others.

Result

I built an autonomous system, almost invisible to the firm, with no learning curve of any kind.

A tool for the firm that passively gathers all official information related to its clients every day; stores it in each company's record inside the firm's ERP/CRM; and notifies the team about the updates it collects.

My work

AI Builder Product Designer UX Researcher Prompt Engineer AI Product Engineer Full-Stack Developer

Duration

9 days

Goals

  • reduce operational costs
  • automate manual tasks
  • remove bottlenecks
  • reduce human error
  • differentiate from competitors
  • enable new services (bonus)

Problem

User or business pain

Gathering information and cross-referencing it against our clients is unproductive but necessary work. And we spend too many hours on it.

Constraints

[ME]\

How much time do we have?

Ideally this should be ready before next quarter, so we have 40 days.

Eder Iraizoz

Can I have a few meetings with the team that currently handles this work?

We are very busy. The more you can do without involving them, the better.

Eder Iraizoz

OK. Let's do it.

Research

I needed to better understand the company's current workflow in order to figure out how to improve the process. To do that, some of the questions I needed to answer were the following:

  1. What was the current workflow and what constraints shaped it? To answer that, I interviewed the most experienced employee doing this work, since the methodology was the same across the 3 of them.

  2. Which sources contain the necessary information and in what formats? I needed to know whether the sources exposed that information through an API, or in CSV, XML, PDF, etc. I needed to know whether I could extract it easily and programmatically, or whether I would instead need to rely on scraping or similar solutions.

  3. How frequently are those sources updated and how stable are they? I needed to know whether the URLs would be predictable, whether they changed often, and whether we might run into issues that would require us to build fallbacks, etc.

  4. What software do they use to store client information, and in what way? It was important to know whether the company's ERP and/or CRM was off-the-shelf or custom-built, and whether it exposed an API I could use to cross-reference the data.

  5. Are there any data protection limitations? I assumed that in the case of self-employed individuals (natural persons), we would have certain limitations on data capture or storage. I wanted to confirm that.

Findings

Some of the most important findings from my research were the following:

  • Some sources offered an API, but most only exposed an XML file or a PDF.
  • In the case of older PDFs, they were sometimes literally scanned printed sheets, so in order to build historical coverage I had to integrate a mix of methods to process that data.
  • The information sources did not offer normalized data. In fact, they were highly inconsistent. And in several cases there were typos and spelling mistakes already present in the source data, which made normalization harder.
  • They used a commercial ERP, so the parsed and normalized information could be integrated through its API.
  • There were indeed data protection limitations in the case of self-employed individuals.

Decisions

  • We could afford to evolve the initial idea for the tool into something more effective: from a tool that manually facilitated access to the data, to a passive system that stores information and notifies the consultancy firm. That reduced the time spent even further.
  • Because there was no API, it was necessary to use different methods to extract, normalize, match and store the data obtained. Methods such as scraping, OCR, RegEx, and even AI-based validation and comparison in some cases.
  • Official sources anonymize the public data of self-employed individuals, so we could not use their data coming from most of those sources.
  • It was agreed that, in a second phase, we would implement a system to discover new grants and subsidies to offer to their clients, which would enable them to offer a new service.

Technology

I considered using a self-hosted N8N setup to automate this process. But in the end I decided to build it in code mainly for the following reasons:

  • The implementation is more complex than it appears, and designing it cleanly in N8N would probably require several interconnected workflows, each with dozens of nodes. That makes auditing and modification harder.
  • The company has no department or technical knowledge for this. So spinning up N8N on a server for a single automation, which they still would not have been able to maintain on their own, felt like overengineering.
  • For a case like this, reading and auditing code is easier today than reading a workflow in N8N. Modification and maintenance would be more flexible and straightforward if the system were well-documented, modular code that any programmer could understand, rather than something that would require finding someone with N8N experience.

Solution

The resulting product could be summarized as follows:

An autonomous system that consolidates different official information sources in a modular and scalable way, and reconciles each new update with the profile of the corresponding client in the consultancy firm's ERP.

Prototype

I built an initial prototype to test the quality of the information, the reliability of reconciliation between data coming from different sources, and to determine the probability of failure and uncover extreme cases we would need to solve.

Final design

I chose a design pattern called "Medallion" to organize the data logically in a Data Lakehouse, with the goal of progressively improving data quality, structure and reliability as it flows through three distinct layers: Bronze, Silver and Gold.

Bronze Layer (Raw Data)

This is the entry point for all information. Data is stored exactly as it comes from the source (in raw format), without applying filters or transformations.

  • Purpose: Keep a complete, immutable history. It makes it possible to reprocess data if failures occur or to run audits at any time.
  • Type of data: JSON, flat files (CSV, Excel), or continuous streaming flows from APIs, databases, etc.

Silver Layer (Cleaned Data)

This is where data from the Bronze layer is filtered, cleaned and transformed. Different information sources are integrated and standardized into a coherent model.

  • Purpose: Create a single, trustworthy source of business-grade data.
  • Key operations: Duplicates are removed, errors are corrected, format issues are resolved, and data integrity is validated.

Gold Layer (Aggregated Data)

This is the presentation and final consumption layer. The refined data is modeled into business-oriented schemas (fact and dimension tables).

  • Purpose: Optimize the data for reports, dashboards, LLMs, APIs, etc.
  • Type of data: Information that, in this case, is ready to be consumed by the API that will store it inside each company's profile in the consultancy firm's ERP.

Edge cases: errors, empty states, permissions, loading and failures

Some of the most important edge cases were:

  • What happens if the data starts from scarce, incorrect or orthographically different input? For those cases, I created a triple-check system. It first tries to solve the reconciliation deterministically. If it cannot reconcile it, the item moves to an AI fallback. If the AI system still cannot reconcile it, it falls back to a manual system. Technically, it is a system that scores similarities and establishes possible information matches which, if they are not reconciled automatically, are shown in a manual validation dashboard. After many tests with hundreds of records, roughly 4% of the information ended up in this unavoidable manual fallback because of the limitations of the source data itself.
  • What happens when a new company becomes a client of the consultancy and some historical data is needed for it? Thanks to the Medallion system, we store raw information. For these cases, I created a simple form where a date range can be entered and, when an action button is pressed, the system goes through the files for those dates and gathers the historical information about that company from the different sources.
  • What happens if a data source stops updating because of a failure, a URL change, or any other reason? The system knows the update frequency of each source, and if it does not receive data 12 hours after the expected time, it sends a notification to the consultancy firm and the technical team, which in this case was me.
  • What happens if the ERP API changes? I implemented a solution similar to the previous point. In this case, the notification also returned the API changelog within a short date range in which the system had been interrupted.

Delivery

Deployment was carried out on a very lightweight and inexpensive Hetzner VPS. The handoff consisted of credentials for a dashboard external to the ERP and, otherwise, an invisible system for the firm that works autonomously and does not require any learning curve.

Impact

From 40h/week to 1h/month

Time spent on these tasks

That monthly hour corresponds to the time spent on manual reconciliation for the cases the system cannot resolve on its own due to lack of information or context.

+18%

CSAT improvement

Their clients' satisfaction improved from the second month after implementation onward, due to the faster information flow and the removal of the bottleneck.

-77.5%

Deadline reduction

The deadline was 40 days and delivery happened in just 9. That means 31 days ahead of the maximum deadline.

Revenue increase

Triggered by a newly activated service

This system led to a second phase: a system that found grants and subsidies for their clients based on their CNAEs, locations, etc.

Learnings

This implementation led me to learn:

  • How to use the ERP API the company relied on
  • The Medallion design pattern and how to implement it