Publicar
Crear un producto con su descripción y su fotografía, tomada con la cámara o elegida de la galería.
Ver las pantallasMundo Otaku · Aplicación móvil full-stack
La aplicación permite publicar objetos de cultura otaku, proponer intercambios entre personas y conversar en tiempo real mientras se negocia. Mi proyecto de título de 2024, recuperado y modernizado en 2026.
Ver la app en usoDiseño y desarrollo individual · Flutter + NestJS + PostgreSQL
Abrir el primer tomo Tomo 01 · Producto
Tomo 01 · Producto
Tipo
Proyecto de título individual
Ámbito
App móvil + API + base de datos + despliegue
Estado
Demo técnica · evidencia Android
Tecnologías
Flutter · Dart · NestJS · TypeScript · PostgreSQL · Docker
01 / El producto
Dos personas que quieren intercambiar objetos necesitan tres cosas seguidas: verlos, proponer el trato y poder hablar mientras lo cierran.
Mundo Otaku reúne ese recorrido en una sola aplicación: publicar un producto con su fotografía, encontrarlo en el catálogo de productos, proponer un intercambio a su dueño y abrir un chat en tiempo real para negociarlo. Lo diseñé y desarrollé como proyecto de título, de principio a fin y sin reparto de tareas con otras personas; en 2026 lo retomé para auditar el código heredado, corregir debilidades reales de seguridad y concurrencia, construir una suite de pruebas y desplegar su API en Render.
La explicación técnica se apoya en código y documentación del proyecto. Las capturas siguientes proceden de videos Android aprobados y muestran acciones concretas, con sus límites.
Crear un producto con su descripción y su fotografía, tomada con la cámara o elegida de la galería.
Ver las pantallasOfrecer un intercambio sobre el producto de otra persona y seguir su estado en listas de propuestos y recibidos.
Ver el recorridoAbrir un chat en tiempo real sobre WebSockets para acordar los detalles antes de cerrar el trato.
Ver el chatUna primera mirada
Un recorrido breve para ubicar el producto: acceso, catálogo, ficha, estante e historial. Después puedes seguir los capítulos para ver las acciones y sus decisiones técnicas.
Diseñé y desarrollé el proyecto individual: interfaz Flutter, API NestJS y modelo de datos. En la recuperación de 2026 trabajé en autorización, consistencia de intercambios, pruebas, despliegue y modernización del cliente.
Ir directamente a ingeniería →La persona inicia sesión, recorre el catálogo, abre la ficha de Komi-san, consulta sus fotografías y visita Mi estante. Después entra en Chats y ve un historial existente.
Tomo 02 · Descubrir
02 / El producto en uso
Cinco recorridos principales y tres complementarios. Las capturas muestran cada estado; los videos permiten seguir la acción. Todas las tomas provienen de la app Android en un teléfono físico.
01 / Recorrido principal
El catálogo lleva de una búsqueda concreta a la ficha, las fotografías y la persona que publica. Ese contexto permite decidir qué producto interesa antes de iniciar un intercambio.

Catálogo de productos y filtros en la app Android. Flujo 03 · 16 s del video aprobado.

La búsqueda «Komi» deja visible un resultado; el teclado ocupa parte de la pantalla. Flujo 03 · 25 s del video aprobado.

Ficha de Komi-san con portada, autor de la publicación, etiquetas y descripción. Flujo 03 · 40 s del video aprobado.
Ver también la búsqueda en video · 35 s
Se escribe Komi en la búsqueda, se abre el resultado y se examina la ficha. El teclado permanece visible durante parte del recorrido y el cierre dedica varios segundos al detalle.
Tomo 03 · Publicar
02 / Recorrido principal
Publicar reúne validación, selección de una imagen y actualización del estante. La regla del tomo depende del tipo de producto: un manga exige un número y admite el tomo 0.

El formulario pide revisar campos al intentar guardar sin tomo; parte del texto del error queda cortado en la interfaz. Flujo 06 · 35 s del video aprobado.

Clasificación, descripción y etiquetas completas de Blue Lock antes de elegir la portada. Flujo 06 · 68.5 s del video aprobado.

El formulario muestra la portada de Blue Lock antes de guardar el producto. Flujo 06 · 86 s del video aprobado.

Blue Lock aparece en Mi estante, que en ese momento muestra cinco productos. Flujo 06 · 100 s del video aprobado.

La app pide confirmar la eliminación de Blue Lock. Flujo 06 · 115 s del video aprobado.

El estante vuelve a cuatro productos y Blue Lock ya no aparece en esta vista. Flujo 06 · 125 s del video aprobado.
Seguir la acción
El formulario muestra los datos de Blue Lock y la portada elegida. La publicación aparece en Mi estante. Luego se solicita su eliminación y el estante vuelve a mostrarse sin ese producto.
Tomo 04 · Proponer
03 / Recorrido principal
La persona elige qué ofrece, confirma y puede seguir la propuesta en Enviadas. Cancelarla es una acción explícita; esta grabación muestra el recorrido completo de esa decisión.

Desde Jujutsu Kaisen, el selector muestra Bleach entre los productos propios que se pueden ofrecer. Flujo 07 · 42 s del video aprobado.

Diálogo de confirmación antes del envío. Flujo 07 · 48 s del video aprobado.

La lista Enviadas incluye la propuesta nueva junto a otra anterior. Flujo 07 · 70 s del video aprobado.

Detalle de Bleach ofrecido por Jujutsu Kaisen, con la opción de cancelar. Flujo 07 · 76 s del video aprobado.

La app pide confirmar la cancelación de esa propuesta. Flujo 07 · 80 s del video aprobado.

La propuesta nueva ya no figura en la lista Enviadas visible. Flujo 07 · 90 s del video aprobado.
Seguir la acción
Se ofrece Bleach por Jujutsu Kaisen, se confirma la propuesta y se consulta en Enviadas. Después se solicita y confirma su cancelación.
Tomo 05 · Responder
04 / Recorrido principal
Recibidas permite revisar los dos productos antes de responder. Aquí se rechaza una oferta distinta de la anterior: primero se actualiza la lista, después se abre el detalle y se confirma el rechazo.

Demo 2 ve solo una propuesta previa de Claymore en Recibidas. Flujo 09 · 26 s del video aprobado.

Tras deslizar para actualizar, aparece además la oferta nueva de Hajime no Ippo. Flujo 09 · 29 s del video aprobado.

Demo 2 entregaría Jujutsu Kaisen volumen 4 y recibiría Hajime no Ippo volumen 01. Flujo 09 · 38 s del video aprobado.

El diálogo pide confirmar el rechazo de esa propuesta. Flujo 09 · 44 s del video aprobado.

La tarjeta nueva desaparece y aparece «Se ha rechazado la solicitud»; la de Claymore permanece. Flujo 09 · 51 s del video aprobado.
Seguir la acción
Demo 2 actualiza Recibidas. Aparece una propuesta de Hajime no Ippo por Jujutsu Kaisen, se abre su detalle y se confirma el rechazo. La tarjeta desaparece de la lista y se muestra un aviso.
Tomo 06 · Conversar
05 / Recorrido principal
El contador avisa de un mensaje cuando la conversación está cerrada. Al abrirla, la persona puede responder desde el teléfono y recibir una réplica sin salir del chat.

Lista de Chats con el contador del intercambio de Komi-san en 0. Flujo 08 · 24 s del video aprobado.

El contador pasa a 1 con la lista abierta; Demo 2 fue simulada por API y Socket.IO. Flujo 08 · 28 s del video aprobado.

Chat abierto con un mensaje entrante; el historial conserva textos repetidos de un intento anterior. Flujo 08 · 32 s del video aprobado.

Respuesta de Demo 1 visible bajo el historial anterior. Flujo 08 · 53 s del video aprobado.

La respuesta de Demo 2 aparece al final mientras el chat sigue abierto. Flujo 08 · 58 s del video aprobado.
Seguir la acción
El contador pasa de 0 a 1 con la conversación cerrada. Demo 1 entra al chat, escribe desde el teléfono y recibe una réplica mientras la pantalla sigue abierta. Demo 2 se controla mediante API y Socket.IO; el historial incluye textos de una toma anterior.
Tomo 07 · Más detalle
Validación, personalización y lectura de propuestas completan la experiencia. Conservo estos tres recorridos para mostrar el trabajo de interfaz con mayor profundidad.
06 / Más detalle
Los formularios muestran qué corregir en los campos de acceso y registro. Estas capturas se concentran en la respuesta visible de la interfaz; las reglas del servidor se explican en Ingeniería.
07 / Más detalle
Un filtro sin productos, el cambio de tema y los estilos Capítulos y Webtoon muestran cómo se adapta la experiencia alrededor del recorrido principal.

El filtro Ropa presenta su estado vacío en el catálogo. Flujo 04 · 25 s del video aprobado.

Menú en tema claro con estilo «Capítulos» seleccionado. Flujo 04 · 37 s del video aprobado.

Menú en tema oscuro y estilo «Webtoon» seleccionado. Flujo 04 · 55 s del video aprobado.
08 / Más detalle
Este recorrido complementario deja ver ambas caras de una propuesta que ya estaba pendiente. Sirve para estudiar su presentación, sin atribuirle una aceptación o un rechazo que no aparecen en la toma.
Tomo 08 · Ingeniería
03 / El intercambio
El modelo conecta cuatro niveles: la persona, el producto que publica, la propuesta de intercambio que otra persona le hace y la conversación que nace de esa propuesta. Es donde aparecen las reglas más interesantes del backend.
04 / La conversación
El chat usa WebSockets con Socket.IO: el flujo 08 muestra una respuesta mientras la conversación está abierta. Del lado del servidor, un adaptador propio restringe desde qué orígenes se acepta una conexión, junto con la autenticación del canal.
05 / Una capa más abajo
Una propuesta de intercambio atraviesa la app, un contrato HTTP documentado, reglas de autorización y una base de datos relacional que tiene que decidir quién gana cuando dos personas actúan a la vez.
Explicación basada en el código local de la API. La aceptación y las carreras entre solicitudes no están demostradas en los videos de esta página.
Ruta A / Camino limpio
Ruta B / Condición de carrera
Esta fue una de las correcciones concretas de la auditoría de 2026 sobre el código heredado, no una propiedad del proyecto original.
Diagrama basado en el código del proyecto. No ejecuta la aplicación ni realiza peticiones a su backend.
Este es mi proyecto de título de 2024. En septiembre de 2026 se recuperaron los datos y las imágenes, se revisaron reglas de acceso y concurrencia y se amplió la automatización de pruebas. El cliente pasó a Flutter 3.47.5 y Riverpod 3; el controlador de chat anterior basado en GetX se retiró. La modernización conserva el producto y permite seguir desarrollándolo sobre una base actualizada.
El cliente Flutter separa cada funcionalidad en tres capas —dominio, infraestructura y presentación— con estado reactivo en Riverpod, enrutamiento declarativo con GoRouter, cliente HTTP Dio y validación de formularios con Formz. El backend NestJS se organiza en módulos por dominio con inyección de dependencias y documenta su API REST con Swagger/OpenAPI.
Repository para el acceso a datos con TypeORM; Adapter para restringir el origen de las conexiones de Socket.IO; Strategy para poder cambiar de proveedor de almacenamiento de imágenes sin tocar el resto del sistema. A eso se suman guards e interceptores propios de NestJS para autenticación y para el procesamiento de archivos subidos.
Passport con JWT, contraseñas protegidas mediante hash con bcrypt, autorización basada en la propiedad del recurso, un mecanismo propio de revocación de tokens al cerrar sesión, almacenamiento seguro de credenciales en el dispositivo con flutter_secure_storage, y validación declarativa de la entrada con class-validator, class-transformer y Joi.
La API usa Docker y Docker Compose, con integración continua en GitHub Actions que ejecuta pruebas y análisis estático en los eventos configurados. El despliegue corre en Render con una base de datos PostgreSQL administrada en Neon, y las migraciones versionadas de TypeORM mantienen la integridad del esquema entre versiones.
La aplicación no incorpora ninguna funcionalidad de inteligencia artificial: no hay dependencias de IA ni de aprendizaje automático en su backend ni en su cliente. Lo que sí hubo fue un uso estructurado de asistentes de programación durante la recuperación del proyecto, con un protocolo propio de traspaso de contexto entre sesiones y reglas explícitas —por ejemplo, no confirmar cambios en el repositorio sin mi aprobación. Las decisiones de arquitectura, alcance y estética, y la validación final, siempre fueron mías.
Tomo 09 · Verificación
06 / Calidad y alcance
Resultados registrados en el proyecto fuente, contrastados con su historial y documentación. Son verificaciones fechadas; no una ejecución nueva de las suites desde este portafolio.
| Comprobación | Resultado registrado | Fecha y alcance |
|---|---|---|
| Cliente Flutter | 181 / 181 | 27 sep 2026 · análisis sin hallazgos y APK debug construida. |
| API: pruebas unitarias | 52 / 52 | 25 sep 2026 · reglas y servicios del backend. |
| API: pruebas E2E | 40 / 40 | 25 sep 2026 · incluye normalización del correo en el acceso. |
| Recorridos web con Playwright | 8 / 8 | 25 sep 2026 · pruebas del cliente y la API locales. |
| Persistencia tras reinicio | 15 sep 2026 | Producto y dos fotos conservaron JSON y hashes tras reiniciar la API desplegada. |
Las grabaciones Android son del 26 y 27 de septiembre de 2026, en un Galaxy SM-S938B con Android 16. Las esperas están editadas: no sirven para medir tiempos de respuesta. Las pruebas web y las grabaciones Android corresponden a verificaciones diferentes.
Los videos muestran publicar, cancelar, rechazar y conversar; no muestran un intercambio aceptado de principio a fin ni una prueba de carga. El flujo 08 usa una contraparte simulada por API/Socket.IO y el 09 muestra refresco manual. Las decisiones de autorización, concurrencia y almacenamiento se sustentan en código y comprobaciones del proyecto.
Este proyecto permite conversar sobre desarrollo móvil, diseño de APIs, bases de datos relacionales, seguridad de aplicaciones, concurrencia, testing automatizado y despliegue en la nube: un recorrido completo por una misma pieza de software, hecha de principio a fin por una sola persona.