Skip to content

Arquitectura del software#

Repositorio#

El proyecto vive en un único monorepo:

El desarrollo activo ocurre en la rama dev. Los pull requests deben apuntar a dev. La rama main sigue los lanzamientos de producción.


Tecnologías#

Las tecnologías se eligieron siguiendo tres principios: software abierto, mobile-first y posicionamiento GIS. También se priorizaron herramientas con buena adopción comunitaria y documentación.

Frontend (web/)#

Tecnología Rol
TypeScript JavaScript tipado
Next.js Framework React, enrutamiento por archivos, SSR
React UI basada en componentes
Pigeon Maps Mapas interactivos (ligero, sin dependencias externas)
RxJS Gestión reactiva del estado
react-icons Iconos (set Bootstrap)

Backend (api/)#

Tecnología Rol
Node.js Runtime de JavaScript
NestJS Framework backend modular (OOP + DI)
TypeORM ORM de base de datos con soporte de migraciones
PostgreSQL Base de datos relacional
PostGIS Extensión espacial para consultas geográficas
H3 Indexación espacial hexagonal de Uber
Redis Caché y cola
Handlebars Plantillas de email

Estructura del monorepo#

helpbuttons/
├── api/                        # Backend NestJS
│   ├── src/
│   │   ├── app/                # Bootstrap, config global, validadores
│   │   ├── config/             # Módulo de configuración
│   │   ├── data/
│   │   │   ├── migrations/     # Migraciones TypeORM (ejecutar en orden)
│   │   │   └── seed/           # Seeders y datos de ejemplo
│   │   └── modules/            # Módulos de funcionalidades
│   ├── locales/                # Strings i18n de la API (en, es, cat, eu, pt)
│   └── Dockerfile
│
├── web/                        # Frontend Next.js
│   ├── public/
│   │   ├── assets/             # Imágenes, SVGs, assets de enrutamiento
│   │   └── locales/            # Strings i18n del frontend (en, es, cat, eu, pt)
│   └── src/
│       ├── components/         # Componentes UI compuestos
│       ├── elements/           # Elementos UI atómicos (botones, formularios...)
│       ├── layouts/            # Wrappers de layout de página
│       ├── pages/              # Rutas Next.js
│       ├── services/           # Servicios cliente de la API por dominio
│       ├── shared/             # DTOs, entidades y tipos compartidos
│       ├── state/              # Estado global de la app (basado en RxJS)
│       └── store/              # Event store
│
├── plugins/                    # Sistema de plugins
├── postgres/                   # Imagen Docker personalizada de PostgreSQL
├── docker-compose.yml
├── env.sample
└── README.md

Módulos del backend (api/src/modules/)#

Cada módulo gestiona su entidad, DTO, servicio, controlador y cualquier guard o estrategia relacionada.

Módulo Responsabilidad
auth/ Autenticación JWT, guards, estrategias de login
button/ Entidad Button — publicaciones geolocalizadas
network/ Redes — contenedores comunitarios
user/ Perfiles de usuario
user-credential/ Gestión de contraseñas y credenciales
post/ Comentarios y respuestas en botones
group-message/ Mensajería grupal entre usuarios
activity/ Feed de actividad
tag/ Creación y suscripción a etiquetas
geo/ Geocodificación (Komoot / Pelias / modo simulación)
invite/ Sistema de enlaces de invitación
mail/ Notificaciones email vía SMTP + plantillas Handlebars
storage/ Almacenamiento de archivos e imágenes
setup/ Asistente de configuración inicial
deleteme/ Eliminación de cuenta

Convenciones de carpetas del frontend (web/src/)#

La convención de nombres para archivos y carpetas sigue el orden FUNCIÓN-TIPO: - BtnCircle — Btn es la función (elemento botón), Circle es el tipo - CardNotification — Card es la función, Notification es el tipo - Excepción: cuando una clase de dominio tiene muchos elementos relacionados, el nombre de la clase va primero: ButtonNew, ButtonCard, NetworkNew, NetworkCard

elements/#

Bloques de construcción atómicos reutilizados en toda la app: Accordion, Avatar, Btn, BtnCircle, Checkbox, Dropdown, Form, campos, iconos, etc.

components/#

Grupos de elementos que implementan una funcionalidad: button/, feed/, map/, popup/, nav/, network/, search/, user/, etc.

layouts/#

Wrappers de layout a nivel de página que no son páginas completas en sí mismas.

pages/#

Cada subcarpeta aquí es una ruta Next.js. Cada página tiene su propio directorio con index.tsx.

services/#

Una carpeta por modelo de dominio, con funciones que llaman a la API: Buttons, Networks, Users, Tags, Feed, Geo, Posts.

state/#

Estado global basado en RxJS, dividido por dominio: Activity, Alerts, Button, Explore, Map, Networks, Profile, Users, etc.

store/#

El event store personalizado. Ver la documentación del Store en la versión inglesa para ejemplos completos de código.


Añadir un nuevo atributo a un modelo#

Este es el flujo estándar para extender un modelo de dominio:

1. Backend — definir en entidad y DTO:

api/src/modules/network/network.entity.ts   # definición de columna en DB
api/src/modules/network/network.dto.ts      # validación de petición POST

2. Generar y ejecutar migración:

yarn migration:generate src/data/migrations/add-mi-atributo
yarn migration:run

3. Frontend — añadir al formulario de configuración:

web/src/pages/Configuration/index.tsx       # añadir campo al manejador de envío

El mismo patrón aplica a button/, user/ y cualquier otro módulo.


Internacionalización (i18n)#

La app incluye traducciones para: inglés, español, catalán, euskera, portugués.

  • Strings de la API: api/locales/<lang>/
  • Strings del frontend: web/public/locales/<lang>/

Para añadir un nuevo idioma, copia una de las carpetas de locales existentes y traduce los strings.