feat(propuesta): pasarela paso a paso con autodetección de ubicación y FAB
deploy-branch / deploy (push) Failing after 6s
deploy-branch / teardown (push) Skipped

- Campo universal de ubicación (Google Maps/Waze/OSM/coordenadas/dirección)
  sobre proveedores extensibles (src/utils/ubicacion) con resolver e inferencia
  inversa Nominatim (nombre/provincia pre-rellenados, alias cooficiales)
- FAB flotante abajo a la derecha que abre la pasarela en un modal accesible
  (Escape, foco contenido, responsive); sin descripción ni puntuación;
  avisos de duplicado y filtro de palabras dentro del modal
- Aviso PWA reposicionado: tarjeta abajo a la izquierda en móvil,
  botón compacto arriba a la izquierda en PC (no tapa el FAB)
- Suite de pruebas: 88 unitarias/componente (vitest + RTL, offline) y
  10 de integración (supertest + SQLite :memory: y Nominatim real opt-in)
- CI: workflow de Gitea Actions con npm test + build en push/PR e
  integración manual
This commit is contained in:
2026-08-16 01:35:02 +02:00
parent d48b74cbd4
commit 003b1e209f
53 changed files with 4896 additions and 253 deletions
+9 -2
View File
@@ -1,5 +1,5 @@
import express from "express";
import { fileURLToPath } from "url";
import { fileURLToPath, pathToFileURL } from "url";
import { dirname, join } from "path";
import db from "./db.js";
import { randomUUID } from "crypto";
@@ -169,5 +169,12 @@ app.get(/^\/(?!api\/).*/, (_req, res) => {
res.sendFile(join(__dirname, "../dist/index.html"));
});
// Escucha solo cuando se ejecuta como script (`node server/index.js`); al ser
// importado (p. ej. por las pruebas con supertest) se exporta la app sin puerto.
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server listening on http://localhost:${PORT}`));
const esPuntoDeEntrada = process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href;
if (esPuntoDeEntrada) {
app.listen(PORT, () => console.log(`Server listening on http://localhost:${PORT}`));
}
export default app;