Copec Empresa

Copec Empresa

An Angular web platform and Flutter mobile app for Copec Empresa, letting companies manage fleets, fuel cards, transactions and billing across Copec’s corporate network.

Copec Empresa is the B2B side of Copec’s digital ecosystem — the platform corporate customers use to manage their fleets, fuel cards, transactions and billing across Copec’s service stations. Where Copec Remittances is built for individual users of App Copec, Copec Empresa is built for company administrators and the drivers operating under them. I joined as tech lead on a product that had already been running in production for roughly four years, picking up both surfaces of it: an Angular web platform aimed at fleet administrators, and a Flutter mobile app aimed at drivers and on-the-go account managers.

Context and problem

Copec’s corporate customers range from small businesses with a handful of vehicles to large fleets running thousands of fuel transactions a month. Each of them needs visibility into who is fueling, where, when, and how much — plus the ability to issue and revoke cards, set spending limits, reconcile invoices, and audit usage. By the time I joined, Copec Empresa had been serving those customers in production for about four years. The codebase, the integrations, and the user expectations were already there; the job was to keep it healthy and move it forward without disrupting what was working.

Coming into a four-year-old product as tech lead meant the first weeks were less about decisions and more about reading: understanding why the code looked the way it did, where the load-bearing assumptions lived, which patterns were intentional and which had calcified, and where the integration with Copec’s corporate backend was sensitive. Only after that did it make sense to start changing things.

How it works

The web platform is an Angular SPA used by fleet administrators to manage cards, drivers, vehicles, spending rules and reporting. It runs as a client-side application without prerendering — the audience is authenticated corporate users behind a login, so the SEO and first-paint pressures that drove the prerendering choice on Copec Remittances didn’t apply here. The mobile app is a Flutter codebase aimed at drivers and field managers — quick balance lookups, transaction history, card status, and the operational tasks that don’t need a full desktop view.

Both clients talk to the same set of corporate APIs maintained by Copec’s backend team. The split between web and mobile is deliberate and predates my involvement: administrators get the depth and density of a desktop UI, while drivers and managers in the field get something tuned for short, focused interactions. Authentication, account scoping and security flows are shared across the two clients.

Challenges

Inheriting a four-year-old codebase. The product had real users, real history, and real reasons for being shaped the way it was. Every “why is this like this?” had an answer, but the answer was usually in a decision made years before — sometimes still load-bearing, sometimes obsolete but harmless, occasionally obsolete and quietly dangerous. Telling those apart, before changing anything, was the first job. Refactoring eagerly in a mature codebase is one of the most efficient ways to break a product, and I wanted to avoid that.

Two surfaces, one product. Leading both an Angular web platform and a Flutter mobile app meant keeping two stacks aligned on a single product story. Some flows belong only on the web (bulk operations, reporting, account-wide configuration), some belong only on mobile (quick lookups, on-the-road actions), and a few need to feel the same in both places. Maintaining that mental model across both clients — without forcing artificial symmetry — was a continuous part of the tech-lead role.

Integrating with a security-hardened backend. As with Copec Remittances, Copec’s backend had a robust security layer and a structured process for any change to API contracts. With two clients consuming those APIs, every change had a bigger blast radius. Keeping integration predictable required treating the API contract as the source of truth and being conservative about what either client assumed beyond it.

Brand and reliability expectations. Corporate customers using Copec Empresa make business decisions on top of what the platform reports. Wrong balances, missing transactions or inconsistent state aren’t acceptable. The bar for correctness was set by the product’s role in their operations, not by what was technically convenient — and after four years in production, that bar had only gotten higher.

Key decisions and trade-offs

The first decision I made was the one not to make: I deliberately avoided large refactors in the early months. The code worked, the users depended on it, and rewriting parts of a mature product to match preferences I’d developed elsewhere would have been a bad trade. Changes happened where they earned their keep — a real bug, a real product need, a real maintenance pain — rather than because the code didn’t look like a greenfield project would have.

Once I had a clearer picture of the product, I formalised the API contract as the only place where web and mobile would meet. Anything beyond that — UI patterns, navigation, even some shared concepts — could diverge if it made sense for the audience. That gave both clients room to evolve without forcing every change through a cross-stack negotiation.

DecisionTrade-off
Read before changing — no large refactors in the first monthsSlower visible velocity early on, but avoided breaking load-bearing behaviour that had no obvious owner
Two clients (Angular web + Flutter mobile) on a shared API, kept as-isPreserved a working product structure, at the cost of carrying some legacy decisions forward
Shared API contract as the integration boundaryPredictable integration with Copec’s backend, but cross-client changes need careful sequencing
Audience-specific feature sets across web and mobileEach surface stays focused on its real use case, but adds an explicit decision about where every new feature lives

What I learned

Taking over a mature product is a different job from starting one. Greenfield rewards decisiveness; inheriting four years of production code rewards patience. The valuable contribution as tech lead, at least in the first stretch, was reading carefully, asking small questions, and resisting the urge to rewrite things just because I would have written them differently. Most of what looked questionable turned out to be there for a reason; the parts that didn’t, I could change later with much more confidence.

I also got a sharper sense of how to size the difference between B2B and B2C work. Corporate customers are patient with depth but unforgiving about correctness. They’ll learn a more complex UI if it lets them do their job, but they will not tolerate a balance that’s wrong or a transaction that’s missing — and they especially won’t tolerate it from a product they’ve been relying on for years.

Tech stack

  • Angular SPA for the web platform (client-side, behind authentication).
  • Flutter for the mobile companion app.
  • Copec’s corporate backend API (managed externally) for fleet, card, transaction and billing data.
  • Shared authentication and account-scoping flows across both clients.

Closing reflection

Copec Empresa was a project where the technical foundations were already in place and the real work was about stewarding a mature product without breaking what worked. Two clients, two audiences, one corporate backend, and four years of history that had to be respected before it could be changed. Stepping in as tech lead on a product like that taught me that the job is mostly judgement — about what to leave alone, what to fix, and when — and that good judgement is built by reading the code and the users carefully before acting.


© 2026. All rights reserved.