Skip to content

About

Frontend SPA for Peace Houses management (Christian church). React 19 + TypeScript, Vite, TanStack Query, React Router 7, React Hook Form, Zod and Hexagonal Architecture for authentication. Includes members, meetings, attendance and visitors.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

House of Peace Frontend

SPA para la gestión de Casas de Paz de una iglesia cristiana. El proyecto cubre autenticación, casas, miembros, reuniones, asistencia y visitantes. La feature de autenticación está implementada con arquitectura hexagonal.

Stack

Área Herramienta
UI React 19
Lenguaje TypeScript
Build y desarrollo Vite
Routing React Router 7
Estado del servidor TanStack Query
Formularios React Hook Form
Validación Zod
Cliente HTTP Axios
Mocks HTTP MSW
Testing Vitest + Testing Library
Calidad ESLint + Prettier
Paquetes pnpm

Requisitos

  • Node.js 20 o superior.
  • pnpm 9 o superior.
  • Backend disponible en http://localhost:3000 para trabajar sin mocks.

Instalación

pnpm install
cp .env.example .env.local
pnpm dev

La aplicación queda disponible en http://localhost:5173.

Variables de entorno

# URL del backend sin /api/v1.
VITE_API_URL=http://localhost:3000

# true: intercepta las peticiones con MSW.
# false: utiliza el backend real.
VITE_ENABLE_MOCKS=true

Vite solo expone al navegador variables que comienzan con VITE_. Reinicia el servidor de desarrollo después de cambiar .env.local.

Desarrollo con mocks

VITE_ENABLE_MOCKS=true

MSW simula login, refresh, usuario actual y logout. En este modo, la pantalla de login muestra el aviso de credenciales demo.

Desarrollo con el backend real

VITE_API_URL=http://localhost:3000
VITE_ENABLE_MOCKS=false

El frontend agrega automáticamente el prefijo /api/v1. Para el usuario de desarrollo provisto por el backend:

Correo: admin@peacehouses.test
Contraseña: password123

Comandos

pnpm dev             # Servidor de desarrollo
pnpm build           # Typecheck y build de producción
pnpm preview         # Previsualiza el build

pnpm typecheck       # Verificación de TypeScript
pnpm lint            # Verificación de ESLint
pnpm lint:fix        # ESLint con correcciones automáticas
pnpm format          # Aplica Prettier
pnpm format:check    # Comprueba el formato sin modificar archivos

pnpm test            # Ejecuta todos los tests una vez
pnpm test:watch      # Tests en modo watch
pnpm test:coverage   # Reporte de cobertura

Antes de entregar cambios se recomienda ejecutar:

pnpm format:check
pnpm typecheck
pnpm lint
pnpm test
pnpm build

Estructura general

src/
├── app/                 # Router, providers y composición global
├── components/          # Componentes y layouts reutilizables
├── features/            # Features con reglas y adaptadores propios
│   └── auth/            # Autenticación hexagonal
├── lib/                 # Configuración compartida y utilidades
├── mocks/               # Handlers y worker de MSW
├── styles/              # Estilos globales
├── test/                # Setup global de Vitest
├── views/               # Vistas asociadas a rutas
└── main.tsx             # Entrada de la aplicación

Los prototipos HTML originales de escritorio y móvil se conservan en docs/prototypes/. Son referencias de diseño independientes del build de Vite.

Los consumidores externos deben importar autenticación desde su API pública:

import { AuthProvider, useAuth, useLogin } from '@/features/auth'

La composición concreta es una excepción y solo debe importarse desde la raíz de providers:

import { authDependencies } from '@/features/auth/composition/authDependencies'

Arquitectura hexagonal de autenticación

src/features/auth/
├── domain/
│   ├── entities/        # User y Role
│   ├── errors/          # AuthError
│   ├── models/          # Credentials, tokens y sesión
│   └── ports/           # Contratos de repositorios
├── application/
│   ├── Login.ts
│   ├── RestoreSession.ts
│   └── Logout.ts
├── infrastructure/
│   ├── http/            # Axios, DTO, schemas y mappers
│   └── storage/         # Tokens en memoria/localStorage
├── presentation/
│   ├── context/         # Estado y provider de React
│   ├── errors/          # Mensajes seguros para la UI
│   ├── guards/          # Rutas públicas y protegidas
│   ├── hooks/           # useAuth y useLogin
│   └── validation/      # Validación del formulario
├── composition/          # Ensamblaje de puertos y adaptadores
└── index.ts              # API pública de la feature

Dirección de dependencias

domain ← application
domain ← infrastructure
domain ← presentation
application + infrastructure + presentation ← composition

Reglas:

  • El dominio no importa React, Axios, almacenamiento ni configuración.
  • Los casos de uso dependen de puertos del dominio.
  • Infraestructura implementa los puertos y traduce HTTP al dominio.
  • Presentación administra estado de UI y ejecuta casos de uso mediante AuthServices.
  • Composición es el único lugar que construye implementaciones concretas.

Flujo de autenticación

Login

LoginView
  → useLogin
  → AuthProvider
  → Login
  → AxiosAuthRepository
  → POST /auth/login
  → validación Zod
  → mapper DTO a dominio
  → BrowserTokenRepository

El backend devuelve el access token con el nombre token:

{
  "success": true,
  "data": {
    "token": "jwt",
    "refreshToken": "opaque-token",
    "user": {}
  }
}

El mapper lo convierte internamente a accessToken. Los modelos del dominio no dependen de los nombres utilizados por el backend.

Almacenamiento de tokens

Access token  → memoria
Refresh token → localStorage (hop.refreshToken)

El access token se pierde al recargar la página. Si existe refresh token, RestoreSession renueva los tokens y consulta /auth/me.

Refresh automático

El cliente autenticado:

  1. Agrega Authorization: Bearer <accessToken>.
  2. Ante un 401 solicita tokens nuevos.
  3. Comparte una sola llamada de refresh entre peticiones concurrentes.
  4. Reintenta cada petición original una sola vez.
  5. Limpia la sesión y notifica a React si el refresh falla.

No se intenta refresh automático para:

/auth/login
/auth/refresh
/auth/logout

/auth/me sí es un recurso protegido y puede activar refresh.

Logout

Logout es best-effort: intenta invalidar el refresh token en el backend y siempre elimina la sesión local, incluso si hay un error de red.

Frontera HTTP

Las respuestas Axios entran como datos desconocidos. Infraestructura:

  1. Valida { success, data } o { success, error }.
  2. Valida los DTO con Zod.
  3. Convierte DTO a modelos del dominio mediante mappers.
  4. Convierte errores HTTP en AuthError.

Las respuestas malformadas producen INVALID_RESPONSE. La UI traduce los códigos conocidos a mensajes seguros y no muestra detalles técnicos.

Testing

Los tests están colocados junto al código que verifican e incluyen:

  • casos de uso con puertos simulados;
  • adaptadores Axios y almacenamiento;
  • refresh concurrente y prevención de ciclos;
  • DTO malformados;
  • provider y mensajes de presentación;
  • formulario de login;
  • integración completa UI → casos de uso → Axios → MSW → storage.

Seguridad

  • El access token no se persiste.
  • El refresh token se guarda actualmente en localStorage porque ese es el contrato soportado por el backend.
  • No deben registrarse tokens o credenciales en consola.
  • Para mayor protección frente a XSS, una evolución futura puede mover el refresh token a una cookie HttpOnly, Secure y SameSite, coordinando el cambio con el backend.

Convenciones

  • Usa @/ para importar desde src/.
  • Consume cada feature desde su index.ts; evita imports profundos, excepto en la raíz de composición.
  • Mantén las reglas de negocio fuera de componentes React.
  • Define contratos externos como DTO y conviértelos al dominio.
  • Coloca los tests junto al archivo o flujo probado.
  • Registra nuevas vistas en src/app/router.tsx.

About

Frontend SPA for Peace Houses management (Christian church). React 19 + TypeScript, Vite, TanStack Query, React Router 7, React Hook Form, Zod and Hexagonal Architecture for authentication. Includes members, meetings, attendance and visitors.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages