Primer prototipo
This commit is contained in:
@@ -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.
|
||||
@@ -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`.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user