Senior Software Engineer (Contractor) · Feb 2022 – Jul 2023
Bamboo Energy
Barcelona-based clean-energy SaaS, spun out of an energy-research institute. The platform lets demand-aggregators and energy communities monetise the flexibility of their distributed assets — HVAC, batteries, EV chargers, PV, industrial loads — in the Spanish wholesale and ancillary-service electricity markets. I built the web app from absolute scratch — only the backend API existed when I joined — and stayed through eighteen months of feature work.
- Sites
- Devices
- Markets
- Activations

~70%
Of the product surface is time-series charts — built on one reusable engine
Greenfield
Built the frontend from absolute scratch — only the backend API existed when I joined
End-to-end
Devices module — from data model to telemetry charts and setpoint commands
Single-flight
Request layer that cancels in-flight duplicates, paired with a 15-min live-mode loop
Stack
What I owned
- Frontend architecture, module-registration plugin, and per-domain Vuex stores
- Reusable chart engine, request-cancellation layer, role-based access matrix
- End-to-end delivery of the devices module, the auth flow, and the admin "view-as" pattern
What I didn't
- Backend services and the Python/FastAPI API surface (consumed, not authored)
- Forecasting and optimisation algorithms (research team's work)
- Infrastructure and DBA work beyond the frontend deploy pipeline
"I built the web app of an energy-aggregation platform from absolute scratch — only the backend API existed when I joined — through to production used by aggregators, energy-community managers, and end customers in the Spanish flexibility markets."
The work
Owned end-to-end
Building the frontend from scratch
Challenge
Stock Nuxt 2 enforces a file-type-first directory layout — top-level pages/, components/, store/, and so on. That stops scaling once a product has many business domains: cross-domain code lives next to itself by accident, and finding the code for a feature means walking five sibling folders. The platform needed a layout where a domain's pages, components, store, services and models live together.
What I built
- A custom Nuxt module that, for each declared domain, recursively registered its components, generated routes from the module's pages folder, and dynamically imported its Vuex store via a build-time template
- A redirect of the framework's well-known directories to a single core/ module, so Nuxt finds nothing in the root and everything inside src/modules/<name>/
- Per-domain folders containing the feature's pages, components, store, services and models — colocated rather than scattered
- A four-kind models discipline per domain (response models / entities / view-models / state) so domain shapes never bled across boundaries
Outcome
Adding a new business area became a one-folder change plus a single line in the module list. Cross-module dependencies flow only through shared/ and core/, so ownership stays clear and finding the code for a feature stops involving the framework's well-known directories.
Lesson
Fighting a framework convention is a last resort, but when product structure outgrows the framework's defaults, the cost of fighting once beats the cost of paying every sprint.
Sidebar expanded — each labelled item maps to its own slice under src/modules/.
Owned end-to-end
Building the frontend from scratch
Challenge
Stock Nuxt 2 enforces a file-type-first directory layout — top-level pages/, components/, store/, and so on. That stops scaling once a product has many business domains: cross-domain code lives next to itself by accident, and finding the code for a feature means walking five sibling folders. The platform needed a layout where a domain's pages, components, store, services and models live together.
What I built
- A custom Nuxt module that, for each declared domain, recursively registered its components, generated routes from the module's pages folder, and dynamically imported its Vuex store via a build-time template
- A redirect of the framework's well-known directories to a single core/ module, so Nuxt finds nothing in the root and everything inside src/modules/<name>/
- Per-domain folders containing the feature's pages, components, store, services and models — colocated rather than scattered
- A four-kind models discipline per domain (response models / entities / view-models / state) so domain shapes never bled across boundaries
Outcome
Adding a new business area became a one-folder change plus a single line in the module list. Cross-module dependencies flow only through shared/ and core/, so ownership stays clear and finding the code for a feature stops involving the framework's well-known directories.
Lesson
Fighting a framework convention is a last resort, but when product structure outgrows the framework's defaults, the cost of fighting once beats the cost of paying every sprint.
Sidebar expanded — each labelled item maps to its own slice under src/modules/.
Screenshots are from a non-production environment used during the consulting engagement. No proprietary code, customer data, or implementation-specific source is shown. Internal entity names and quantitative metrics have been generalized or omitted; the work and decisions described are mine.