Publicado originalmente en mi blog.
Soy estudiante de Ingeniería en Computación y desarrollador. Este año construí tres cosas muy distintas entre sí, y cada una me obligó a desaprender algo. Las dejo aquí porque los problemas interesantes no siempre fueron los que esperaba.
1. Leer una báscula industrial por puerto serie
El encargo era sustituir el software de pesaje de camiones de una planta. Yo venía de desarrollo web, así que mi primer instinto fue pedir el peso cuando lo necesitara, como una petición HTTP.
No funciona así. Una báscula no expone una API: emite tramas continuas por el puerto serie, sin que se las pidas y a su propio ritmo. El flujo manda, y hay que escucharlo.
Eso definió la arquitectura: un proceso leyendo el puerto de forma continua, un backend en FastAPI que retransmite por WebSocket, y dos estaciones de escritorio viendo el mismo peso en el mismo instante.
Pero el reto de verdad no fue el hardware. Fue el modelo de estados. Un pesaje pasa por en_planta → pendiente_aprobacion → aprobado/rechazado → completado, y un registro completado no se puede tocar: es un documento con consecuencias contables. Diseñé el esquema asumiendo que alguien va a intentar editarlo y que la respuesta correcta del sistema es impedirlo.
Catorce tablas en PostgreSQL, migraciones con Alembic y pruebas con Pytest sobre SQLite aislado. Esto último no fue opcional: cuando un bug cambia un peso facturable, no te enteras en desarrollo, te enteras en una factura.
Lo que aprendí: integrar hardware te quita suposiciones que en web das por hechas. Que los datos llegan cuando los pides. Que puedes reintentar. Que el estado vive en tu base.
2. Epa: una app social donde el problema era la privacidad
Epa es una app móvil para que los estudiantes de mi universidad organicen planes en el campus: mapa de actividades, grupos y mensajería, con acceso cerrado por correo institucional.
Suena a CRUD. No lo es, porque dos funciones inocentes resultaron delicadas:
Ubicación. Mostrar dónde está la gente es útil y también es vigilancia. La resolví como opt-in con caducidad automática: compartes tu ubicación por un rato y expira sola. Nadie tiene que acordarse de apagarla.
Media efímera. "Efímero" en el cliente no significa nada: cualquiera intercepta la petición. La entrega de archivos la controla el servidor, no la app.
Stack: React Native con Expo, TypeScript, Expo Router, NativeWind y Zustand del lado del cliente; Express, Prisma y PostgreSQL del lado del servidor.
Lo que aprendí: en una app social, las decisiones difíciles casi nunca son técnicas. Son sobre qué le permites hacer a un usuario con los datos de otro.
3. BeatWave: una PWA de música que funciona sin internet
Tenía mi música en un servidor Navidrome propio y quería escucharla en el teléfono sin depender de una app de terceros. Así salió BeatWave: una PWA instalable que consume la API Subsonic de mi servidor.
La parte divertida fue el offline. Guardar pistas en IndexedDB y servirlas desde un service worker es directo en teoría; en la práctica el trabajo está en decidir qué pasa cuando la red vuelve a medias, cuando el caché y el servidor no coinciden, o cuando el usuario cierra la app a mitad de descarga.
También integré la Media Session API, que es de esas cosas que casi nadie nota y todos esperan: controles en la pantalla de bloqueo, con carátula y título. Cuando falta, la app se siente rota aunque funcione.
Stack: React 19, TypeScript, Vite y vite-plugin-pwa.
Lo que aprendí: offline-first no es "cachear cosas". Es aceptar que tu app va a vivir permanentemente en un estado intermedio entre conectada y desconectada.
Lo que tienen en común
Que en los tres el problema real estaba en otro lado del que yo pensaba. En el primero creí que era el hardware y era el modelo de datos. En el segundo creí que era el mapa y era la privacidad. En el tercero creí que era el reproductor y era la sincronización.
Escribo sobre lo que construyo en gmarinelly.com, y el código está en GitHub.
Si trabajas con integración de hardware, offline-first o apps móviles, me interesa mucho leer cómo lo resolviste tú.
Top comments (0)