I am a software developer from Galicia, Spain; Wanna chat? :)
I am a software developer from Galicia, Spain; Wanna chat? :)
Stack: Node.js (Express, Drizzle ORM, Zod), Asterisk 20 (ARI), SolidJS, FFmpeg, Vosk (STT), Piper (TTS), SQLite.
A custom VoIP and live-streaming engine designed for interactive show call-ins. Viewers
can dial in, queue up, and enter the live broadcast, while the system dynamically generates
video layouts and manages real-time audio.
VoIP & Call Queue Orchestration: The system integrates an Asterisk 20 PBX trunk
with a Node.js orchestrator via the Asterisk REST Interface (ARI). It implements an interactive
voice response (IVR) queueing system using a FIFO queue. Incoming numbers are securely hashed
using HMAC-SHA256 for privacy and cross-referenced against a custom ban database. A custom
text-to-speech (TTS) pipeline powered by Piper generates voice menus, and caller names are
transcribed on the fly using the Vosk STT engine.
Real-time Streaming & Audio Ducking: When a caller goes live on the broadcast,
their voice RTP stream is routed through a Node.js UDP proxy to a dynamic FFmpeg recording
session. The video output is composed of an interactive HTML/CSS overlay page (built with
SolidJS) rendered via a headless Chromium browser running on a virtual X11 frame buffer (Xvfb).
The FFmpeg pipeline captures this virtual frame buffer and encodes it in real time while using a
custom ZeroMQ control channel to perform automatic audio ducking—fading out background music
when callers speak.
Dashboard & Metrics: An administrative control panel built with SolidJS and
Vite allows hosts to monitor call queues, ban disruptive callers, tweak configuration
parameters, and view server performance metrics alongside historical call statistics visualized
using Apache ECharts.
Link to channel - Code in private repo
Stack: Python (Flask, Prefect), SolidJS, PostgreSQL, Paged.js, TinyMCE.
A comprehensive reporting system built for a private client to consolidate cybersecurity data
from multiple sources (FortiSOAR, Sekoia, etc.).
Data Pipeline: Scheduled Prefect flows fetch data from APIs every few hours,
normalize it, and store it in PostgreSQL. I designed a hybrid schema using standard indexed
columns for critical data and a JSONB column to dump the full raw API response.
This approach ensures complex future queries and schema evolution without needing a separate
Document database.
Frontend & Backend: A Flask API serves as the bridge between the database and a
SolidJS frontend. The frontend choice was made keeping the existing team in mind, who were not
familiar with React or Solid. SolidJS was chosen because it uses JSX—meaning any skills they
learn are easily transferable to React if they ever need them—but offers a much simpler mental
model with fewer complex re-render gotchas and bugs. Analysts use this interface to generate,
review, and edit reports for specific clients and timeframes.
Reporting Engine: The frontend includes pre-defined report pages that can be
heavily customized using a TinyMCE WYSIWYG editor. Finally, Paged.js is used to handle complex
print pagination, transforming the web view into a pixel-perfect, exportable A4 document.
Private client project. No repository or live links available.
Stack: PHP (Slim Framework), SolidJS, API Proxy (BrightData).
A digital art gallery requiring minimal maintenance that unifies dispersed inventories
(Artelista and Etsy), orchestrating data from sources without an official API.
Headless Architecture: A decoupled architecture was implemented where the PHP
backend (Slim Framework) acts exclusively as a REST API, while the presentation is handled by
SolidJS.
Scraping and Anti-Bot Proxy: A scraper was developed to extract the catalog
from Etsy and Artelista. Since the server is hosted in the US, prices were returned in dollars.
To get local prices and evade strong anti-bot protections from these sites (like DataDome), the
BrightData API Proxy was integrated, which handles anti-bot management and geo-routing.
Background Caching: For simplicity, configuring cron jobs was avoided. The
system uses a JSON cache: the first visit after the file expires (7 days) triggers a data update
via an asynchronous background process, supported by a lock file system to prevent simultaneous
executions.
Hybrid Curation: The artist has a control panel from which she can modify
attributes, reorder, and hide artworks. The backend processes the scraped JSON file and applies
these manual preferences before serving the data.
Link to site - Code in private repo
Stack: NodeJS w/ Puppeteer, Axios, Cheerio, Handlebars, SQLite.
OpenAI API, Azure Image Recognition, Apify.
PHP w/ PicoCMS.
Website aimed at foreigners coming to A Coruña. It showcases some informational info, a calendar
of events, and services aimed at this demographic.
What's interesting about this site, is that it scrapes events from plenty of sites using
Puppeteer, handles the result with SQLite and Handlebars, and uploads the calendar to a static
site.
But some events are only published in Instagram, and that poses many challenges.
So I decided to download the posts from instagram accounts, push the post image through image
recognition / OCR (Azure API), then use a ChatGPT API with Function Calling to retrieve how many
events there are in a given post, and its critical info (dates, title, etc).
I wouldn't say it's flawless, but I managed to get a 80% solution for very little money.
I'm quite happy with my Function Calling JSON definition, it works pretty well despite LLMs not
being deterministic.
Stack: React, HTML, CSS, Vanilla JS.
In this project, I've got ~ 1 week to implement a Figma design into working templates. About
three months to implement other complex logic.
I built the core application using React for the main architecture and state management, while
implementing some specific, highly interactive components using Vanilla CSS and Javascript.
I made: React architecture, templates for every screen, and some complex/heavy logic components
like a meal compositor with several screens, and a training page with moving cards, timers, etc.
This was a team of four people total.