Skip to content

Featured Projects

A curated selection of projects that showcase my work as a Frontend Tech Lead—architecture, performance, and hands-on problem solving.


Logistics Management App (React)

Company: GOITECH – Advanced Logistics Technology
Dates: May 2025 – Present
Role: Frontend Tech Lead

Scope: Back-office web app for logistics operations: orders, incidents, customers, drivers, routes, etc.
Optimized for large datasets, URL-driven filters, server-side sorting/pagination, and fast operator workflows.

1. Core Technologies (with versions)

  • Runtime & Build: Node.js 22 LTS, Vite 5.4, pnpm 9
  • Language: TypeScript 5.6 (strict mode)
  • Framework: React 18.3 (Hooks, Suspense-ready), React Router 6.27
  • Data/State:
    • TanStack Query 5.x (server state, caching, mutations)
    • Zustand 4.x (lightweight client state)
    • MSW 2.x (API mocking in dev/tests)
  • Tables & Virtualization:
    • TanStack Table 8.x
    • TanStack Virtual 3.x
  • Styling/UI: Tailwind CSS 3.4, CSS Modules (scoped), Headless UI
  • HTTP: Fetch API + small wrapper (retry, timeout, zod validation)
  • Forms: React Hook Form 7.x + Zod 3.x (schema-first)
  • Utilities: date-fns 3.x, lodash-es 4.x

2. Quality & DX

  • Lint/Format: ESLint 9.x (flat config), Prettier 3.3, strict TS, import sorting
  • Commit & CI: commitlint + conventional commits, GitHub Actions (lint, typecheck, test, build)
  • Env/config: typed env via zod guard; .env per environment

3. Testing Strategy

  • E2E: Cypress 13.x (critical flows: auth, filters, exports)
  • Unit/Component/Page: Vitest 2.x + React Testing Library 14.x
  • Data/mutations: MSW for deterministic API mocks; contract tests with Zod
  • Coverage goals: 80% on critical features (orders, incidents)

4. Architecture & Patterns

  • Feature-first modules: features/orders, features/incidents, etc.
  • Server state vs client state:
    • Server state → TanStack Query (lists, detail, mutations, cache invalidation)
    • Client state → Zustand (UI-only concerns: drawer, columns, wizard steps)
  • URL-driven filters: URL as single source of truth
  • Table column definitions: central, reusable, type-safe
  • Data access layer: thin API client with interceptors (auth, errors)
  • Schema-first contracts: Zod for request/response validation
  • Error boundaries: feature-scoped with fallback UIs
  • Suspense-ready: queries designed for progressive adoption
  • Accessibility: semantic HTML, keyboard navigation, color-contrast checks
  • i18n-ready: English default, Spanish prepared

5. Performance Tactics

  • Virtualization for large tables
  • Query caching & background refresh
  • Code-splitting per route/feature
  • Memoized renderers & selectors
  • Skeletons/shimmers for perceived speed

6. Security & Auth (app-side)

  • Auth context consuming backend cookies/session (httponly, secure)
  • CSRF-safe mutation helpers
  • Input validation at boundaries (Zod)

7. Folder Structure (excerpt)

bash
src/
  app/
    providers/        # queryClient, theme, i18n
    router/           # routes.tsx, guards
    layout/           # AppLayout, Nav, TopBar
  features/
    orders/
      api/            # getOrders.ts, updateOrder.ts, schemas.ts
      components/     # OrdersTable.tsx, FiltersBar.tsx
      hooks/          # useOrdersListQuery.ts, useOrderMutations.ts
      types/          # order.ts
      pages/          # OrdersListPage.tsx, OrderDetailPage.tsx
      columns/        # ordersColumns.ts
    incidents/ ...
    customers/ ...
  shared/
    api/              # client.ts, errors.ts
    hooks/            # useUrlFilters.ts, useColumnVisibility.ts
    ui/               # Table, Modal, Drawer, Form
    utils/            # dates.ts, download.ts
    config/           # env.ts

8. Key Screens & Flows

  • Orders List: server-side sorting/pagination, URL-driven filters, virtualized table
  • Order Detail: lazy sub-cards, fine-grained PATCH mutations
  • Incidents & Customers: consistent patterns for reuse

9. Agnostic-by-Design

Although the recent build is React 18 + TanStack centric, decisions remain framework-agnostic.
If SEO/TTFB dominate → Astro + HTMX.
If complex interactivity → React, Vue 3, or Svelte.
Data layer (contracts, URL filters) remains portable.

10. Deliverables & Metrics

  • TTFR: < 2s on corporate laptops
  • Lists: 10k+ rows via virtualization
  • Reliability: green E2E on core flows; visual smoke tests on CI
  • Accessibility: keyboard-navigable; no critical axe violations

Version Matrix

  • React 18.3, React Router 6.27
  • TanStack Query 5.x, Table 8.x, Virtual 3.x
  • Zustand 4.x
  • TypeScript 5.6
  • Vite 5.4
  • Tailwind 3.4
  • Vitest 2.x, RTL 14.x, Cypress 13.x
  • Zod 3.x, MSW 2.x
  • Node 22 LTS, pnpm 9

Brain: Integration with the Routing App and Performance Improvements

Company: GOITECH – Advanced Logistics Technology
Dates: Oct 2024 – Present
Role: Frontend Tech Lead
Tech: Vue 3 · Pinia · TypeScript

Currently, at Brain, I lead the integration with the routing application —similar to Routific— that the company uses to optimize route and delivery management.

I proposed developing Veins as a standalone product to offer it as an external service, facilitating its evolution. The integration with Brain was implemented via an iframe, enabling bidirectional communication between both apps.

Over time, we faced challenges synchronizing temporary tokens (access and refresh tokens) due to application isolation, which affected authentication and user experience.

Since Veins needed to be migrated to Vue 3, we took the opportunity to address the authentication issues and improve performance. In this context, I developed a custom virtual scroller with drag & drop support for the timeline component —capable of handling large volumes of data (up to 400 routes with ~30 stops and 14 hours of duration). This led to a significant performance boost and a much smoother user experience.

We also enhanced the map’s tool panels, making them flexible and resizable to adapt to different operational needs.

These improvements optimized operational efficiency and user experience, laying a solid foundation for future enhancements and the potential offering of Veins as an independent service.


Brain Challenges: File-Input and WebAssembly

Company: GOITECH – Advanced Logistics Technology
Dates: Jun 2023 – Aug 2023
Role: Frontend Tech Lead
Tech: Vite · React.js · TypeScript · WebAssembly (C/Rust)

This project started when our client requested an improved bulk order upload experience. They wanted a step-by-step visual tool to guide users: preview uploaded columns, assign headers, review errors, and finalize imports.

Part 1: First Impressions and Project Context

At first, we experimented with free libraries to prototype the solution. One library looked promising, but it lacked essential features for adding custom business logic on top of columns. The author had essentially forked the free version into a commercial one with the missing features locked, which forced us to rethink our approach.

This experience highlighted the need for a more independent and extensible solution, even under strict time constraints.


Part 2: React, the Prototype, and the Encoding Problem

Since the Vue ecosystem didn’t offer a solid fit at that moment, I suggested using React for a standalone micro-app embedded via iframe. Using the react-spreadsheet-import library, we quickly built a prototype that even remembered users’ previous mappings for headers —saving them extra steps.

However, we soon encountered a major issue: users often uploaded files encoded in legacy formats such as Windows-1252, while the backend strictly expected UTF-8. This mismatch caused corrupted addresses and inaccurate geolocation.

To address this, I proposed developing a WebAssembly (WASM) module capable of converting from Windows-1252 (or any encoding) to UTF-8. Despite the tight schedule, the idea was approved.


Part 3: ChatGPT-4, Rust, and the Success of Wasm

I first implemented the conversion in C using libiconv, but the build process was tedious and the binaries unstable. With ChatGPT-4’s help, I shifted to Rust, leveraging its excellent memory management and powerful libraries like encoding_rs.

In a short time, I created a stable WASM module that:

  • Converted files from legacy encodings to UTF-8.
  • Correctly passed files from the web layer into WASM without corruption.
  • Integrated seamlessly into the React app’s workflow.

This Rust-based module has been in production for almost two years, significantly improving user experience by handling diverse file encodings reliably.


Impact

  • Delivered a scalable and resilient import tool under severe time constraints.
  • Introduced WebAssembly into production, unlocking future technical opportunities.
  • Strengthened the frontend team’s confidence in adopting Rust for critical components.


Brain Challenges – Change Detector Utility

Company: GOITECH – Advanced Logistics Technology
Dates: Nov 2022 – Jan 2023
Role: Frontend Tech Lead
Tech: Vue 3 · TypeScript · JavaScript

Part 1: Origins and Early Iterations of the Change Detection System

Building a reliable utility to detect changes in Vue forms has been a multi-year, multi-iteration process. I don’t remember exactly when the need first arose, but from the earliest versions of Brain to the most recent ones, the entity detail views have required forms where users can edit existing data.

A typical case is when a user changes an amount — for example, from €120 to €130 — and then changes it back to €120. Our goal was to avoid sending an unnecessary PATCH request to the backend, in order to optimize resources.

Additionally, this tool has enabled the current detail cards in Brain to activate the save button only when data has truly changed, providing users with a clear and intuitive visual cue when there are valid modifications.

The first version of this utility was developed in Vue 2. It was a simple function that performed a deep comparison between two structures, but it had major limitations: it didn’t handle reactivity well, lacked an effective system to establish a snapshot for future comparisons, and was generally unstable. It was eventually removed because it caused more issues than it solved.


Part 2: Reinvention in Vue 3 and the Final Solution

With the migration to Vue 3 and the switch to a card-based design for entity detail views, the need for a reliable change detection system resurfaced. This time, with more experience, I approached the problem with renewed confidence.

Leveraging Vue 3’s native reactivity, I created a composable that first generated a snapshot of the structure to compare, and then injected a proxy into the object to monitor changes. While this approach was promising, it still lacked perfect reactivity and had issues when comparing different data types, collections, arrays, and primitive values. Additionally, variations in object key order could lead to false positives.

To address this, we integrated the lightweight and specialized library deep-diff for structural comparison. We also added a preprocessing step to sort the structures before passing them to the library, preventing false positives caused by key order differences.

Finally, we implemented the reactive model using Ref, allowing us to create computed properties that react to model changes and reliably detect actual modifications.

This latest iteration has been running error-free and stably for over two years, significantly improving both the user experience and the efficiency of form management.


Brain Challenges – Wizard System

Company: GOITECH – Advanced Logistics Technology
Dates: Mar 2019 – May 2019 (Part 1) · Jul 2022 – Sep 2022 (Part 2)
Role: Frontend Tech Lead
Tech: Vue 2 · Vue 3 · Webpack · Vite · Mixins · Plugins · JavaScript

Part 1: The First Wizard — The Swiss Army Knife

The first wizard we built was like crafting a Swiss watch: wonderful, yet tremendously complex. It was extremely helpful in guiding users through sequential, dependent actions, while also allowing for flexibility to jump between screens based on specific conditions.

Built with Vue 2, the design relied on a configuration file to define which component corresponded to each screen, which one was the first, the last, and what came next. This made it possible to define non-linear paths and dynamically jump between steps based on flow logic.

One of the main challenges was managing data communication between components that were unaware of each other. The wizard acted both as a data store for the information being collected and as a data conduit toward subsequent screens.

Technically, it used a <component :is /> pattern to dynamically load views based on the configuration file and interaction logic. A myriad of mixins served as a common interface for the views, and through deep logic, both the data and the next screen were computed within those mixins.


Part 2: Migration to Vue 3 and the Birth of ViewRouter

With the arrival of Vue 3, it was time to retire our beloved Swiss army knife. As complexity increased, maintainability and scalability became more difficult — and the ability to evolve was the cornerstone of the project.

The decision to build our own library stemmed from the need for adaptability and flexibility imposed by the business’s complex and ambitious ideas. Existing tools didn’t offer the level of control or the agility we needed to meet those demands.

My design pattern was inspired by Vue Router, but embedded inside the component itself. That’s how ViewRouter was born — a component that encapsulated all the wizard logic in just 60 lines of Vue code.

By preserving the same configuration principles, we simplified the setup: just a list of dynamically loaded components, without attributes to define position or order. Now, it was up to the consumer of the library to decide where to go and when to finish. Like a stack, the user simply called push("componentName", [dataForNextView]) — and that was it.

This minimalist approach virtually eliminated errors and expanded the usability of the utility without requiring further changes to the core.


Brain – Migration to Vue 3, TypeScript, and Tailwind CSS

Company: GOITECH – Advanced Logistics Technology
Dates: Jan 2020 – Jan 2021
Role: Frontend Tech Lead
Tech: Vue 3 · Pinia · Tailwind CSS · TypeScript · Vite · ESLint · Husky · Heroicons · PostCSS

After several years of consolidating Brain with Vue 2, the time came to take a technological leap to ensure the product’s long-term sustainability and growth. The release of Vue 3 and its new Composition API generated excitement and some uncertainty in the community — but unlike what happened with AngularJS, Vue 3 showed great respect for existing projects, enabling a gradual and well-planned migration.

As technical lead, my role was to deeply understand the Composition API, its benefits and differences compared to the classic API, and prepare the team to embrace the transition. Discovering the new <script setup> syntax was key — it made me fall in love with this evolution, which brings a minimalist, function-oriented approach and better TypeScript support.

The migration wasn’t just technological, but also cultural. We introduced TypeScript to improve code robustness, using global types that made learning and adoption easier for the team. We switched from Vuex to Pinia as our state management solution, benefiting from a simpler and more modern API.

At the same time, the arrival of Tailwind CSS revolutionized how we handled styling. Though initially skeptical — worried about losing control over CSS and cluttering the HTML with “messy” classes — I quickly realized the boost in productivity and gained a more practical and efficient understanding of CSS.

This new tech stack — Vue 3 with Composition API and <script setup>, TypeScript, Pinia, Tailwind CSS, along with complementary tools like Husky and ESLint — gave birth to Brain 3.0: a more maintainable, scalable, and modern version of the product aligned with current best practices.

Throughout the migration, I maintained constant communication with the team, delivering talks and workshops to ensure everyone understood the new concepts and techniques, fostering a successful and collective adoption.


Brain – Testing and Quality with Jest and Cypress

Company: GOITECH – Advanced Logistics Technology
Dates: Feb 2019 – Dec 2019
Role: Frontend Tech Lead
Tech: Vue.js · Jest · Cypress.io · E2E

It was time to ensure product quality through automated testing. We chose Jest to implement unit tests following the Test-Driven Development (TDD) philosophy, and Cypress for end-to-end (E2E) testing — aiming for a balance that would guarantee both stability and broad coverage.

The first batch of E2E tests we implemented followed a full-flow approach: navigating through the entire app until reaching the specific functionality to test. However, we soon identified two main issues with this method: tests could fail due to unrelated intermediate errors, and the lack of control over test data made them non-deterministic and less representative.

To overcome these limitations, we evolved our E2E strategy by adopting best practices recommended by Cypress: more focused, unit-like tests with strict control over data. We enabled token-based authentication via URL parameters, allowing direct navigation to specific routes without unnecessary intermediate steps — resulting in faster, more precise testing.

Additionally, we developed utilities to generate generic test data by calling the API before each test. This ensured a clean, controlled environment for every run, improving reliability and reducing false positives.

This combined testing approach allowed us to release new features with greater confidence, reduce regressions, and enhance the user experience in a complex and ever-evolving application.


Brain Challenges – Filters System

Company: GOITECH – Advanced Logistics Technology
Dates: Dec 2018 – Feb 2019 (Part 1) · Aug 2018 – Feb 2019 (Part 2)
Role: Frontend Tech Lead
Tech: Vue.js · JavaScript · Webpack

Part 1: Architecture Design and Early Challenges

After launching the first version of Brain, one of the most significant challenges was creating a powerful and flexible filtering system for list views. Each module in Brain typically has two main views: a list and a detail. The usefulness of the list view heavily depends on how effectively filters can handle large volumes of orders in a fast and precise way.

We faced the challenge of supporting numerous filters that users could stack, combine, and remove easily. Additionally, the selected filter values dynamically affected other functions across the application, introducing high complexity both technically and in terms of user experience. It was also essential for filters to be shareable between users, allowing a specific URL to fully recreate the same filtered list as configured by the user.

To solve this, I designed a syntax compatible with the browser URL to describe each filter’s structure. This configuration lived in a file within each module that required filters and defined all the necessary elements for a filter to work: an internal ID, the corresponding API parameter, allowed logical operations, the component used for selecting values, and the associated data sets.

Visually, filters were managed through a component that allowed users to add, remove, and modify filters. Each filter had its own logic and form — whether for dates (with options like “before”, “after”, “range”, or “last n months”) or for selecting statuses, customers, or other criteria.

This semantic and modular architecture not only simplified technical implementation but also delivered a clear, intuitive, and powerful user experience.


Part 2: List View Loading and Dynamic Filter Usage

The filtering process in the list view is divided into two core phases: loading the list view and dynamic filter usage.

List View Loading
When the list view is loaded, the URL parameters are interpreted and converted into active filters. Some filters, such as those based on relative dates (e.g., “last 3 months”), are updated dynamically to remain valid relative to the current date. The action responsible for fetching the list builds the necessary query parameters for the backend request, handling technical details like converting local date-times to UTC.

Thanks to this mechanism, the application can load the filtered list directly as defined by the URL — enabling users to share personalized views and easily replicate configurations.

Dynamic Filter Usage
While interacting with the view, users can add, remove, or modify filters through an intuitive interface that handles each filter type according to its specific logic. For example, a single visual date range filter may be split into multiple backend parameters such as delivery_after and delivery_before. These values are stored in internal memory managed by the filter-machine library, ensuring that any part of the module can access and operate on them in real time.

When filters are applied or modified, the list is updated via backend calls that reflect the active criteria, guaranteeing quick and consistent responses — even with large datasets.

This flexible and scalable design has been key in enhancing user experience and operational efficiency within Brain, making it easier to manage complex and highly variable information.


Brain v1 – Context, Decisions, and Modular Architecture

Company: GOITECH – Advanced Logistics Technology
Dates: Aug 2018 – Dec 2018
Role: Frontend Tech Lead
Tech: Vue 2 · Vuex · Vue Router · Vue i18n · Sass · Lodash.js · Axios

When I joined GOITECH, I faced a major challenge: migrating the management of all orders — previously handled through Airtable and several automated scripts — to a new application that would become the backbone of the company, focused on logistics and the delivery of bulky packages, with some installation services.

After a meeting with the CTO and the technical lead (covering backend, frontend, and DevOps), I was assigned to lead the initiative, so I met with my team for the first time. After reviewing the development status and the designs, I decided to start from scratch using a scaffold generated with Vue 2 to accelerate the launch.

The tech stack for this first version of Brain included:

  • JavaScript
  • Vue 2 as the frontend framework
  • Vuex for state management
  • Vue Router for navigation
  • Vue I18n for internationalization
  • date-fns for date handling
  • Axios for HTTP/HTTPS requests
  • Sass for styling (with no initial CSS framework)
  • Lodash for utility functions

I designed an architecture based on two key principles: semantics and scalability. To me, it was essential that the codebase be logically organized and easy to navigate. To achieve this, I mirrored the product’s visual structure in the source code, creating one module per core entity: orders, issues, customers, and teams.

Each module contained all relevant code: views, components, utilities, and state logic. This fractal-like structure made the codebase highly maintainable and scalable, enabling each team to work independently on their respective module.


Part 2: Global Organization, Configuration, and Outcomes

Above the specific modules, we created a common layer to house generic components, shared utilities, Vue 2 plugins, internationalization (i18n) support, and backend service calls.

Configuration files for state management (Vuex modules), routing, and the application’s entry point were also placed outside the modules to ensure clarity and proper separation of concerns.

At the root of the src directory, we included build-related configurations: framework setup, Sass styling, package manifests, and the ESLint linter configuration.

This well-structured and professional architecture proved capable of handling up to 20,000 packages per day across the Iberian Peninsula at its peak — demonstrating its robustness, scalability, and maintainability.

The success of this technical foundation laid the groundwork for the future evolution of the product and made it easier to introduce new features and modules over the years.


OKN Redesign

Company: OKN Learning
Dates: Feb 2018 – Aug 2018
Role: Frontend Developer
Tech: Webpack · Babel.js · ESLint · Jest · Storybook · JSDoc · Sass · Vue · Vuex

I was part of the team responsible for the complete redesign of the OKN e-learning product, with the goal of modernizing its architecture and user experience. The new system was designed to be fully responsive, working seamlessly across devices — from mobile to desktop.

We proposed an architecture based on reusable components and centralized state management, with a strong focus on quality through unit testing (TDD) and end-to-end (E2E) testing. I led the definition of the technology stack and the establishment of development best practices, including:

  • Vue.js with Vuex, Vue Router, and Vue I18n
  • SCSS + PostCSS for style management
  • Webpack, Babel, and linting with ESLint (Airbnb config)
  • Jest for unit testing (TDD) and Cypress for E2E testing
  • Storybook for isolated component development
  • Documentation using JSDoc 3
  • Extensive use of ES6/ES7 JavaScript features
  • Git Flow workflow and Linux-based development environments

[BBVA] BBVANet – Third-Party International Funds

Company: Grupo Onetec
Dates: Jun 2017 – Feb 2018
Role: Frontend Developer
Tech: Backbone.js · Gulp.js · Jasmine Framework · Cucumber · Scrum · Node.js

I contributed to the development of the section that allows clients to search for and subscribe to international investment funds within the BBVANet platform. My main responsibility was integrating design mockups into the existing architecture based on Backbone.js, implementing the presentation logic and connecting the UI with the rest of the application.

I actively participated in an agile Scrum environment, collaborating closely with designers, QA, and backend developers to ensure alignment between design, behavior, and functionality.

Technologies used:

  • JavaScript ES5
  • Backbone.js
  • Gulp (task automation)
  • Node.js
  • Jasmine (unit testing)
  • Cucumber with Java (functional testing)

[GRUPO PSA] OPV Tablet

Company: Aslam New Information Technology
Dates: May 2014 – Jun 2017
Role: Frontend Developer
Tech: Node.js · Grunt · Backbone.js · Marionette · Require.js · Less · Underscore · TPL · jQuery · jQuery Mobile · Swipe · iScroll · Moment.js

Tablet application developed to support the vehicle sales process in PSA Group dealerships, deployed across 5 countries with plans to expand to 16 markets where the group operates. The app allows managing the entire sales process, including financing, and incorporates CRM features, used vehicle sales, and a dedicated vehicle inspection section.

From a technical perspective, the application was built on Backbone.js, Marionette, and Require.js, following a modular architecture where each module was divided into views, controllers, and models. Models handled communication with REST services, abstracting and hiding the data access logic.

For the build process, Grunt was used to generate specific versions of the app depending on the dealership brand (Peugeot or Citroën), adapting both JavaScript and CSS resources. The build and packaging process was integrated with a tool called Constructor, which launched Grunt as part of the build pipeline and handled signing of native releases.

Technologies used:

  • Node.js
  • Grunt
  • Backbone.js
  • Marionette
  • Require.js
  • Less
  • Underscore
  • TPL (templates)
  • jQuery + jQuery Mobile
  • Swipe
  • iScroll
  • Moment.js

[GRUPO PSA] OPV Tablet Constructor

Company: Aslam New Information Technology
Dates: Oct 2015 – Jun 2017
Role: Frontend Developer
Tech: JavaScript (ES6) · Node.js · Grunt · Apache Cordova

Build application designed to generate native releases of the hybrid OPV Tablet app used by PSA Group dealerships in 5 countries. Due to the complexity of compilation —derived from customization per brand, country, and specific technical requirements— it became necessary to develop a tool that automated the entire process: from compiling the source code to generating a signed application ready for publication in the App Store or Google Play.

The application was fully autonomous for Android, including automatic download and configuration of the SDK. During the build process, it dynamically modified the source code of an Android plugin that replaced the standard WebView, adapting it to functional requirements of the app.

The solution was conceived as scalable and extensible, able to adapt to future cross-platform releases.


[GRUPO PSA] Slideshow

Company: Aslam New Information Technology
Dates: Oct 2016 – Jan 2017
Role: Frontend Developer
Tech: WebSockets (Atmosphere) · JavaScript (ES6) · Node.js · Webpack · Grunt · Babel · Backbone.js · Marionette 3

Web application developed for use in car dealerships and automotive sector events, such as the Geneva Motor Show. Its main function was to display car model ranges in high definition through a carousel-like interface optimized for large-format screens.

Once launched, the application behaved as a persistent service, connecting to a WebSocket channel and waiting for instructions. Users, from mobile or desktop apps, sent the car model they wanted to visualize, and the app displayed it in real time with high-quality images.

The project required high performance, modularity, and instant response, especially for exhibition environments with heavy traffic.


[GRUPO PSA] Jenkins for OPV Tablet Constructor

Company: Aslam New Information Technology
Dates: Jan 2015 – Feb 2016
Role: DevOps Engineer
Tech: Jenkins · GitLab

I configured a Mac Mini running Jenkins to automate and industrialize the build process of the OPV Tablet application. Jenkins was integrated with the OPV Tablet Constructor tool, enabling the team to manage signed versions efficiently.

As part of the infrastructure, I also installed an internal GitLab server for version control. GitLab was used as the central repository, facilitating collaborative work, code traceability, and Jenkins integration. This provided a GitHub-like experience, but in a self-hosted environment.


NextInit

Company: Stratesys Consulting
Dates: Feb 2014 – May 2014
Role: Android Developer
Tech: Android · Retrofit · Gson · ActionBarSherlock · JSON · REST APIs

Android app designed to promote innovation inside organizations. It combined UI/UX design with backend integration, following best practices for modular architecture.

Interface design included:

  • Creation of custom drawables (selectors, shapes, layer-list, animation-list, nine-patch images).
  • Adaptation of icons to multiple densities (mdpi, hdpi, xhdpi, xxhdpi).
  • Implementation of multiple layout types: ScrollView, GridLayout, ListView, ViewPager, RelativeLayout, FrameLayout, ExpandableListView, custom widgets, and progress bars.
  • Management of portable resources: dimensions, strings, colors, styles, and arrays.

Programming and architecture:

  • Integration with libraries such as ActionBarSherlock, ActionBar-PullToRefresh, Retrofit, Gson.
  • JSON serialization/deserialization.
  • Image caching for improved performance.
  • Clear MVC separation: controllers (REST API), fragments (presentation logic), adapters (data binding), and models (deserialization).
  • Secure HTTPS connections.

BMR

Company: Stratesys Consulting
Dates: Jan 2014 – Apr 2014
Role: Android Developer
Tech: ZXing · ABAP-OO

Native Android app for managing meeting rooms, integrated with SAP as backend, exposed via REST.

Key features:

  • Custom QR code scanner based on ZXing for booking management.
  • Augmented reality interface for scanning QR codes in real time.

This combined advanced SAP integration with native mobile features, delivering a modern corporate solution.


Telefónica Soluciones

Company: Stratesys Consulting
Dates: Jan 2007 – Dec 2013
Role: ABAP Developer
Tech: ABAP-OO · SAP ECC

Six-year project as ABAP/OO developer on SAP ECC.

Responsibilities included:

  • Custom report development (ALV, classic, interactive).
  • Creation of Module Pools with complex user logic.
  • Implementation of RFCs and remote functions for integration with external systems.
  • Code optimization and performance analysis.
  • Collaboration with functional teams to adapt SAP to business requirements.

Telefónica Soluciones – SAP Migration

Company: Stratesys Consulting
Dates: Apr 2010 – Dec 2013
Role: ABAP Developer
Tech: SAP ECC

Migration project from SAP R/3 4.7 to SAP ECC 6.0.

Tasks:

  • Analyze customized code to identify errors, obsolete dependencies, and changes in standard interfaces.
  • Review and adapt extended standard code (user-exits, BADIs, enhancements).
  • Coordinate with functional and technical teams to validate adjustments before production.

vimMobile

Company: Stratesys Consulting
Dates: May 2013 – Aug 2013
Role: Mobile Developer
Tech: PhoneGap · SAP VIM

Hybrid app developed with PhoneGap for managing approvals/rejections of SAP-VIM (Vendor Invoice Management) documents from iOS, Android, and Windows Phone.

Lightweight interface optimized for mobility, enabling direct approval/rejection from mobile without SAP GUI.


PET PROJECT – Decision Helper Engine

Dates: May 2013 – Jun 2013
Role: Fullstack Developer
Tech: Android

Collaborative tool for horizontal decision-making, ensuring all participants had equal weight in the process.

The flow was divided into three phases:

  1. Creation Phase – Users create questions or join existing ones.
  2. Decision Phase – Participants propose alternatives and rank them.
  3. Results Phase – The system calculates averages and selects the top option reflecting consensus.

🔗 Project Link


Uralita

Company: Stratesys Consulting
Dates: Jan 2011 – Feb 2013
Role: Developer
Tech: VBScript · Visual Basic .NET · ABAP

Worked on Esker platform (document management system) integrating automation processes with SAP.

Tasks:

  • Develop automation processes in VBScript and VB.NET.
  • Send invoices from Esker to SAP for processing.
  • Support SAP maintenance (workflow, ABAP enhancements).

BusinessAppWHR

Company: Stratesys Consulting
Dates: Oct 2012 – Dec 2012
Role: Android Developer
Tech: Android · SAP Backend

Android reporting system to provide real-time warehouse logistics data, integrated with SAP backend.


PET PROJECT – HWT

Dates: Oct 2012 – Nov 2012
Role: C++ Developer
Tech: C++ · HTML · jQuery · ICU · PugiXML

Cross-platform C++ UI library for rendering HTML-based widgets with uniform appearance.

Features: Labels, Inputs, Buttons, TextAreas, CheckBoxes, ListBoxes, GridList, alerts, custom FileBrowser.

Technical challenges solved:

  • Dynamic callbacks between client-server.
  • Limitations of HTML local access (solved with custom file browser).
  • Modular design similar to Qt.

🔗 Repository


DocumentumEye

Company: Stratesys Consulting
Dates: May 2012 – Jul 2012
Role: Mobile Developer
Tech: Documentum · Android

Mobile app integrated with Documentum to consult, organize, and manage documents remotely from mobile devices.


PET PROJECT – HTMLMask

Dates: Jan 2012 – Feb 2012
Role: C++ Developer
Tech: C++ · HTML · XML · libmicrohttpd · PugiXML

HTML interface generator to automate console commands.

Concept: Instead of manually editing long command-line parameters (e.g., ffmpeg), users could build reusable HTML forms to execute commands.

🔗 Repository


PET PROJECT – GotoSAP

Dates: Mar 2011 – Apr 2011
Role: Go Developer
Tech: Go · SAP SDK

Functional prototype of a Go-based SAP connector, wrapping SAP NetWeaver RFC SDK with a C layer.

Allowed Go programs to call SAP RFCs directly, managing complex structures/tables.


Repsol IPF

Company: Stratesys Consulting
Dates: Oct 2010 – Jan 2011
Role: ABAP Developer
Tech: SAP

Archiving project for SAP Treasury module, designed to reduce system load by moving historical data to archive tables while keeping them accessible.


Ferrovial (FI Reports)

Company: Stratesys Consulting
Dates: Sept 2008 – Jan 2009
Role: ABAP Developer
Tech: SAP FI

Developed custom financial reports in SAP FI module, with filtering, grouping, and exporting features.


Memora – SAP MM

Company: Stratesys Consulting
Dates: Aug 2008 – Oct 2008
Role: ABAP Developer
Tech: SAP MM · ABAP

Developed custom BAPIs for Material Management module, integrating Web Dynpro ABAP interfaces.


Ferrovial – SAP BW Extractors

Company: E.S.I.
Dates: Oct 2006 – Dec 2006
Role: ABAP Developer
Tech: SAP BW

Developed custom DataSources in ABAP for feeding SAP BW, ensuring data quality and transfer efficiency.


Rovi

Company: Stratesys Consulting
Dates: Aug 2006 – Sept 2006
Role: ABAP Developer
Tech: ABAP

Maintained and evolved existing SAP ABAP solutions.


Telefónica Servicios Audiovisuales – SAP Migration

Company: Stratesys Consulting
Dates: Jun 2006 – Aug 2006
Role: ABAP Developer
Tech: SAP R/3

Migration project from SAP R/3 4.6b to 4.7, ensuring smooth data extraction, transformation, and load (ETL).