Adrian Toma crea apps web.

Desarrollador full-stack. Aquí puedes ver todo sobre mis proyectos: un juego musical multijugador y una tienda de discos.

Ver CV (PDF, se abre en una pestaña nueva)

Ciudad
Zaragoza, España
Stack
Angular, C# / .NET
Busco
Puesto junior, España o remoto
Idiomas
Español nativo, inglés C1

Cronotune, un juego multijugador musical

De dos a seis jugadores escuchan un fragmento y colocan la canción en su propia línea temporal según el año de lanzamiento. Es mi trabajo de fin de grado (TFG) y está publicado.

Página de inicio de Cronotune: Guess the year, build the timeline

Todos juegan a la vez

En una partida en directo, las colocaciones, los tiempos agotados y las reconexiones pueden llegar a la misma sala en el mismo instante. Por eso el servidor es dueño del estado de la partida: cada sala procesa una acción a la vez, y los límites de turno corren en el servidor, nunca en un temporizador del navegador.

Sistema antitrampas

Bueno, no exactamente... pero me aseguré de que nadie pueda mirar la pestaña de red para sacar ventaja. El audio llega con un token de corta duración ligado a la sala. El título, el artista y el año llegan al navegador solo cuando se resuelve la ronda.

Las fechas de lanzamiento son complicadas

Una canción puede tener varias fechas de lanzamiento y los datos online pueden ser un caos... así que creé una herramienta C# sin conexión que compara cuatro fuentes. Una canción solo entra en juego cuando dos coinciden con un año de margen, y una de ellas es MusicBrainz o Wikidata.

Dancing Queen, ABBASuena
Año de lanzamiento de Dancing Queen según cada fuente. Suena porque MusicBrainz y Wikidata coinciden.
FuenteAñoCoincide
Spotify1992No
Deezer2005No
MusicBrainz1976Sí
Wikidata1976Sí
  • Angular 22
  • .NET 10
  • PostgreSQL 16
  • SignalR
  • Docker
  • GitHub Actions

Pressing Room, una tienda de discos

La web de una tienda de discos ficticia que vende vinilo, CD y casete: catálogo, carrito, checkout y una colección con cada disco que ha comprado el cliente. El pago es simulado.

Página de inicio de Pressing Room: Analog sound, digital ease

Nunca te fíes del carrito

El carrito vive en el navegador, así que cualquiera podría editarlo para pagar menos. Por eso el checkout solo envía los identificadores de los discos y las cantidades, y el servidor pone los precios y comprueba el stock. Si una línea falla, se rechaza el pedido entero y el stock no se toca.

Los pedidos antiguos no deberían cambiar

Si un pedido apuntara al disco tal como está ahora, cambiar un precio o borrar un disco reescribiría el historial del cliente. Por eso cada línea copia el artista, el título, el formato y el precio en el momento de la compra. Comparé las alternativas y dejé la decisión por escrito en un ADR.

El administrador no puede comprar

Ocultar un botón no basta, porque cualquiera puede llamar a la API directamente. Por eso los roles se comprueban dos veces: guards de ruta en Angular y middleware en la API. El administrador gestiona el catálogo, y el carrito y el checkout le quedan cerrados.

Quién puede usar cada parte de la tienda
VisitanteClienteAdmin
CarritoSíSíNo
CheckoutNoSíNo
ColecciónNoSíNo
Gestionar discosNoNoSí
  • Angular 20
  • Angular Material
  • Node.js
  • Express
  • Docker

Partió de un diseño estático, la plantilla Angular de mi equipo y un backend Node genérico.

Angular delante..NET detrás.Linux debajo.

Estoy terminando el CFGS de Desarrollo de Aplicaciones Web (DAW) en el Centro San Valero de Zaragoza, tras unas prácticas de frontend en ALTEN España con Angular y TypeScript.

Ahora mismo estoy preparando la certificación AWS Solutions Architect Associate, aunque ironicamente todo lo que construyo acaba desplegado en mi propio VPS. Simplemente me gusta gestionar mis propias cosas: tengo autoalojados unos cuantos servidores y servicios, todos en Linux, y paso demasiado tiempo editando mis dotfiles.

Trayectoria

Sept. – nov. 2026
Desarrollador frontend en prácticas, ALTEN España
2024 – 2026
CFGS DAW, Centro San Valero
Idiomas
Español y rumano nativos, inglés C1