Primer prototipo

This commit is contained in:
2026-05-20 14:05:55 +02:00
parent c2ab9a46d4
commit c06300833b
22 changed files with 1115 additions and 2 deletions
+51
View File
@@ -0,0 +1,51 @@
# Casos de uso
Este documento describe los casos de uso del prototipo. El objetivo es mantener
el alcance acotado para minimizar el coste de mantenimiento.
## Actores
- **Visitante**: cualquier persona que accede a la aplicación. No requiere
autenticación. Puede consultar el mapa y contribuir con nuevas entradas.
- **Revisor**: persona designada por la organización que aprueba o rechaza las
contribuciones. Su flujo está fuera del frontend del prototipo (ver
alternativas de implementación).
## Casos de uso del prototipo
### CU-01: Explorar negocios en el mapa
- El visitante abre la aplicación.
- Ve un mapa centrado en una ubicación por defecto con marcadores de los
negocios aprobados.
- Puede hacer zoom y desplazarse libremente.
### CU-02: Ver detalles de un negocio
- El visitante selecciona un marcador en el mapa.
- La barra lateral muestra los detalles del negocio: nombre, categoría,
dirección, descripción corta y enlace/contacto si existe.
- Al seleccionar otro marcador, la barra lateral se actualiza.
### CU-03: Contribuir con un nuevo negocio
- El visitante abre el formulario de contribución desde la interfaz principal.
- Rellena los campos mínimos: nombre, categoría, dirección, descripción y
contacto opcional. La ubicación se obtiene geocodificando la dirección o
haciendo clic en el mapa.
- Envía el formulario. La entrada queda en estado "pendiente de revisión" y no
aparece en el mapa hasta ser aprobada.
- El visitante recibe confirmación visual del envío.
## Fuera de alcance del prototipo
Decisiones tomadas para mantener el proyecto simple (ver
`02-implementation-alternatives.md` para el razonamiento):
- Autenticación de usuarios.
- Panel de moderación dentro de la aplicación. La revisión se hace en el
backend (por ejemplo, en el dashboard del proveedor de datos elegido).
- Edición o eliminación de negocios por el visitante.
- Búsqueda avanzada, filtros complejos o categorías jerárquicas.
- Comentarios, valoraciones, fotos múltiples o multimedia.
- Internacionalización. El prototipo usa un único idioma.
Estos casos pueden añadirse después si la comunidad lo pide, pero no forman
parte del prototipo.
+85
View File
@@ -0,0 +1,85 @@
# Alternativas de implementación
Este documento registra las decisiones técnicas tomadas y por qué. El criterio
guía es **mínimo coste de mantenimiento** para una organización sin ánimo de
lucro, siguiendo KISS y evitando YAGNI.
## 1. Framework frontend
| Opción | Pros | Contras |
|---|---|---|
| **React + Vite** (elegido) | Ecosistema enorme, fácil encontrar contribuidores, build rápido. | Requiere build step. |
| Next.js | SSR, rutas, imágenes. | Demasiado para una SPA de una página; aumenta complejidad y coste de hosting. |
| Vanilla JS | Sin dependencias. | Más código manual, menos contribuidores familiarizados. |
**Decisión**: React + Vite. Es el stack más común y los contribuidores
potenciales lo conocen. Vite mantiene la configuración mínima.
## 2. Mapa
| Opción | Pros | Contras |
|---|---|---|
| **Leaflet + OpenStreetMap** (elegido) | Open source, sin claves API, sin coste, tiles gratuitos. | Menos pulido que Mapbox. |
| Mapbox GL | Más bonito, mejor rendimiento. | Requiere API key y tiene cuotas de pago. |
| Google Maps | Familiar. | Requiere facturación activada, cuotas estrictas, no encaja con espíritu open source. |
**Decisión**: Leaflet con tiles de OpenStreetMap. Cero coste, sin claves, y la
librería `react-leaflet` lo hace trivial de integrar.
## 3. Backend y almacenamiento de datos
| Opción | Pros | Contras |
|---|---|---|
| **Backend-as-a-Service** (Supabase o similar) elegido | Sin servidor que mantener, base de datos gestionada, panel de moderación incluido en su dashboard. Plan gratuito generoso. | Dependencia de un proveedor. |
| Backend propio (Node + Postgres) | Control total. | Hay que mantenerlo, pagarlo, securizarlo. Alto coste para una ONG. |
| Archivo JSON en el repositorio | Sin backend, máxima simplicidad. | Las contribuciones tendrían que llegar como Pull Requests, fricción alta para no-técnicos. |
**Decisión**: BaaS tipo Supabase. Para el prototipo, la capa de datos se
abstrae en `src/services/businessRepository.js`, así que cambiar de proveedor
después es localizado. El prototipo entregado usa un **mock en memoria** para
no acoplar a un proveedor concreto antes de que la organización lo decida.
## 4. Moderación
| Opción | Pros | Contras |
|---|---|---|
| **Aprobación desde el dashboard del BaaS** (elegido) | Cero código extra. El revisor cambia un campo `status` de `pending` a `approved`. | Requiere acceso al dashboard. |
| Panel de moderación dentro de la app | Más cómodo. | Requiere autenticación, roles, vistas extra: explosión de complejidad. |
**Decisión**: La moderación vive fuera del frontend público. El modelo de
datos incluye un campo `status` (`pending` / `approved` / `rejected`). El
frontend solo lee los `approved`.
## 5. Estilos
| Opción | Pros | Contras |
|---|---|---|
| **CSS plano con variables** (elegido) | Cero dependencias, fácil de leer, los contribuidores con HTML/CSS básico pueden colaborar. | Sin utilidades. |
| Tailwind | Productivo. | Cadena de build extra, curva de aprendizaje. |
| CSS-in-JS | Componentes encapsulados. | Runtime extra, peor accesibilidad para nuevos contribuidores. |
**Decisión**: CSS plano. La app es de una página; no se justifica más.
## 6. Gestión de estado
**Decisión**: `useState` y `useEffect` de React. No hay Redux, Zustand ni
Context global. La app es pequeña; añadir una librería de estado sería YAGNI.
## 7. Geocodificación de direcciones del formulario
**Decisión para el prototipo**: el usuario hace clic en el mapa para fijar la
ubicación, o introduce lat/lng. Geocodificación automática vía Nominatim
(OpenStreetMap) queda como mejora futura con bajo coste de añadir.
## 8. Tests
**Decisión**: el prototipo no incluye suite de tests para no inflarlo, pero la
estructura (servicios separados de componentes, funciones puras donde posible)
facilita añadirlos. Cuando se incorporen, **Vitest** es la elección natural por
integrarse con Vite sin configuración.
## 9. Despliegue
**Decisión recomendada**: **GitHub Pages** o **Cloudflare Pages** (gratuitos
para open source). Una SPA estática construida con `vite build` se despliega
sin coste y sin servidor. Ver `docs/06-github-setup.md`.
+49
View File
@@ -0,0 +1,49 @@
# Registro de decisiones
Lista corta y cronológica de decisiones que merecen ser revisadas más
adelante. Formato ADR ligero.
## D-001: SPA de una sola página
**Contexto**: el uso principal es ver un mapa y unos detalles.
**Decisión**: una sola página, sin router. El formulario es un panel/modal en
la misma vista.
**Consecuencia**: si en el futuro hay vistas adicionales (estadísticas, perfil
del negocio en URL propia), habrá que introducir React Router. Reevaluar
cuando aparezca el segundo caso de uso navegable.
## D-002: Capa de servicios
**Decisión**: todo acceso a datos pasa por `src/services/businessRepository.js`.
**Razón**: cumplir Dependency Inversion (SOLID). Los componentes no saben si
los datos vienen de un mock, de Supabase o de un JSON.
**Consecuencia**: cambiar de proveedor es modificar un único archivo.
## D-003: Modelo de datos mínimo
Campos del negocio:
- `id` (string)
- `name` (string)
- `category` (string)
- `address` (string)
- `description` (string)
- `contact` (string, opcional)
- `lat` (number)
- `lng` (number)
- `status` (`pending` | `approved` | `rejected`)
- `createdAt` (ISO string)
Sin slugs, sin fotos, sin tags. Reevaluar tras feedback de la comunidad.
## D-004: Sin autenticación en el prototipo
**Razón**: el visitante no necesita cuenta. El moderador opera en el panel del
backend.
**Reevaluar si**: aparecen casos de uso que requieran identidad (favoritos,
edición por el dueño del negocio).
## D-005: Idioma
El prototipo está en español, sin i18n. Si la organización quiere expandirse,
añadir `react-i18next` cuando exista una segunda lengua real, no antes.
## D-006: Mock de datos en el prototipo
El repositorio entregado usa un mock en memoria con varios negocios de
ejemplo. La organización debe decidir el backend antes de pasar a producción.
La interfaz del repositorio (`getApproved`, `submit`) está pensada para
mapearse 1:1 a Supabase u otro BaaS.
+40
View File
@@ -0,0 +1,40 @@
# Gobernanza
Este proyecto es mantenido por **[NOMBRE DE LA ORGANIZACIÓN]**, una entidad
sin ánimo de lucro. Estas pautas son deliberadamente breves; queremos invertir
el esfuerzo en código y comunidad, no en burocracia.
## Roles
- **Mantenedores**: personas con permisos de merge en `main`. Son nombradas
por la organización. Responsables de revisar PRs, etiquetar issues y publicar
releases.
- **Contribuidores**: cualquiera que envíe un Pull Request, abra un issue o
participe en las discusiones.
- **Moderadores de contenido**: personas con acceso al panel del backend para
aprobar o rechazar los negocios enviados por los visitantes. No
necesariamente coinciden con los mantenedores del código.
## Toma de decisiones
- Decisiones pequeñas (bugs, mejoras menores): las toma quien revisa el PR.
- Decisiones de diseño o que afecten al modelo de datos: discusión pública en
un issue durante al menos 7 días. Cierra el debate un mantenedor buscando
consenso. Si no lo hay, decide la organización.
- Las decisiones relevantes se registran en `docs/03-decisions.md`.
## Código de conducta
Adoptamos el [Contributor Covenant](https://www.contributor-covenant.org/). En
resumen: trata a las personas con respeto. Las violaciones se reportan al
correo `[CORREO_CONTACTO]` y las gestiona la organización.
## Licencia
El proyecto se publica bajo **MIT**. Las contribuciones se entienden
licenciadas bajo los mismos términos.
## Releases
Versionado semántico (semver). Los mantenedores publican versiones cuando
acumulan cambios suficientes. No hay calendario fijo.
+46
View File
@@ -0,0 +1,46 @@
# Cómo contribuir
¡Gracias por querer ayudar! El proyecto se mantiene gracias a la comunidad.
## Antes de empezar
1. Mira los [issues abiertos](../../issues), sobre todo los marcados
`good first issue`.
2. Si tu cambio es grande, abre un issue antes de programar para discutirlo.
## Flujo
1. Haz fork del repositorio.
2. Crea una rama desde `main`: `git checkout -b mi-cambio`.
3. Escribe el código siguiendo las pautas de abajo.
4. Asegúrate de que la app arranca: `npm install && npm run dev`.
5. Abre un Pull Request hacia `main` describiendo el cambio.
## Pautas de código
- **Mantén la app simple.** Si dudas entre dos soluciones, elige la más corta
y obvia. Este proyecto evita la complejidad a propósito.
- **Sigue la estructura existente.** Componentes en `src/components`, acceso a
datos en `src/services`.
- **No añadas dependencias sin necesidad.** Cada nueva librería es coste de
mantenimiento.
- **SOLID y Clean Code aplicados con sentido común.** Nombres claros,
funciones cortas, una responsabilidad por archivo.
- **Estilo**: 2 espacios de indentación, comillas dobles en JSX y simples en JS.
## Tipos de contribución
- **Código**: bugs, mejoras, nuevas funciones acordadas en issues.
- **Documentación**: cualquier archivo de `docs/` o el README.
- **Diseño**: propuestas en issues con mockups.
- **Reportar negocios**: usa la propia aplicación; no es necesario un PR.
## Revisión
Un mantenedor revisará tu PR. Puede pedir cambios. Una vez aprobado, hará
merge. Sé paciente: somos voluntarios.
## Reconocimiento
Todas las personas que han contribuido aparecen automáticamente en la pestaña
de Contributors del repositorio.
+76
View File
@@ -0,0 +1,76 @@
# Configuración del repositorio en GitHub
Pasos para dejar listo el repositorio. Pensado para que lo hagas una sola vez.
## 1. Crear el repositorio
1. En GitHub, crea un repositorio en la cuenta de la organización.
Recomendado: nombre corto, kebab-case, por ejemplo `business-map`.
2. Marca **Public**.
3. **No** inicialices con README, .gitignore ni licencia (ya vienen en este
prototipo).
4. Sube el código:
```bash
git init
git add .
git commit -m "Prototipo inicial"
git branch -M main
git remote add origin git@github.com:ORG/business-map.git
git push -u origin main
```
## 2. Ajustes básicos (Settings → General)
- **Features**: deja activos Issues y Discussions. Desactiva Wikis y Projects
hasta que se usen.
- **Pull Requests**: marca "Allow squash merging" como única opción y "Always
suggest updating pull request branches".
- **Archive**: deja desactivado.
## 3. Protección de la rama `main` (Settings → Branches)
Añade una regla para `main`:
- Require a pull request before merging.
- Require approvals: 1.
- Dismiss stale approvals when new commits are pushed.
- Do not allow bypassing the above settings.
## 4. Plantillas
Las plantillas ya están en `.github/` del prototipo:
- `ISSUE_TEMPLATE/bug.md`
- `ISSUE_TEMPLATE/feature.md`
- `PULL_REQUEST_TEMPLATE.md`
## 5. Documentos visibles en GitHub
Para que GitHub los muestre como insignias del repositorio:
- `README.md` (raíz).
- `LICENSE` (raíz).
- `docs/05-contributing.md`: súbelo además como `CONTRIBUTING.md` en la raíz o
enlázalo desde el README.
- `CODE_OF_CONDUCT.md` recomendado en la raíz (Contributor Covenant oficial).
## 6. Despliegue gratuito
Opción recomendada: **Cloudflare Pages** o **GitHub Pages**.
Para GitHub Pages con Vite:
1. Settings → Pages → Build and deployment → Source: **GitHub Actions**.
2. Añade un workflow en `.github/workflows/deploy.yml` (no incluido en el
prototipo para mantenerlo mínimo; añadirlo cuando se decida la URL final).
3. Ajusta `base` en `vite.config.js` al path del repo.
## 7. Etiquetas iniciales sugeridas
Crea en Issues → Labels:
- `good first issue` (verde)
- `bug` (rojo)
- `enhancement` (azul)
- `documentation` (gris)
- `discussion` (morado)
## 8. Discussions
Activa Discussions con las categorías: Announcements, Ideas, Q&A. Sirven como
foro de baja fricción para la comunidad.