VetCare — Sistema de gestión veterinaria full-stack MERN
Aplicación full-stack para gestión integral de clínicas veterinarias con MERN (MongoDB, Express 5, React 19, Node.js). Arquitectura monorepo con TypeScript, autenticación JWT, RBAC, historial clínico FHIR, facturación, inventario y agendamiento.
Descripción del proyecto
VetCare es un sistema de gestión veterinaria que cubre el ciclo completo de operación de una clínica, construido con el stack MERN (MongoDB, Express 5, React 19, Node.js) y TypeScript de extremo a extremo. Arquitectura monorepo con autenticación JWT, control de roles (RBAC) con 5 roles diferenciados, historial clínico alineado con FHIR, facturación con pagos parciales, inventario con trazabilidad e internacionalización completa (ES/EN).
Alcance técnico
| Métrica | Valor |
|---|---|
| Endpoints REST | ~85 |
| Colecciones MongoDB | 20 |
| Módulos funcionales | 8 |
| Tests E2E (Playwright) | 51 |
| Tests unitarios (Vitest) | 51 |
| Páginas del Frontend | 16 |
Módulos funcionales
- Auth (10 endpoints) — Registro, login, logout, confirmación de email, refresh de tokens, reset de contraseña
- Users (6) — Gestión administrativa, reactivación, soft-delete
- Catálogos (9) — Especies, razas y precios con vigencias temporales
- Pacientes (8) — Registro de mascotas, historial médico (Charts), asociación con dueño
- Agendamiento (12) — Horarios del staff, citas con validación de solapamiento, veterinario sustituto
- Clínico (17) — Encounters, consultations, observations, prescriptions (alineado con FHIR)
- Financiero (9) — Facturas con ítems detallados, pagos parciales, numeración secuencial
- Inventario (10) — Stock con SKU, transacciones inmutables, umbrales de reorden
Todos los endpoints documentados en OpenAPI 3.1 con UI interactiva de Scalar.
Tech Stack
Backend
| Tecnología | Rol |
|---|---|
| Bun 1.0+ / Node.js 18+ | Runtime principal |
| Express.js 5.2 | Framework HTTP |
| TypeScript 5.9 | Tipado estricto |
| MongoDB 8.0 | Base de datos documental |
| Mongoose 9.1 | ODM con esquemas tipados |
| Zod 4.3 | Validación de schemas en runtime |
| JWT 9.0 | Autenticación stateless |
| bcrypt 6.0 | Hash de contraseñas |
| Pino 10.3 | Logging estructurado |
| Helmet 8.1 | Headers de seguridad HTTP |
| express-rate-limit 8.2 | Limitación de peticiones por IP |
| Nodemailer 7.0 | Emails transaccionales |
| Scalar 0.8 | Documentación OpenAPI 3.1 |
Frontend
| Tecnología | Rol |
|---|---|
| React 19.2 | Biblioteca de UI |
| Vite 7.3 | Build tool y dev server |
| TypeScript 5.9 | Tipado estricto |
| TanStack Query 5.90 | Estado del servidor (cache, refetch, mutations) |
| Zustand 5.0 | Estado del cliente (auth, UI) |
| React Router 7.x | Enrutamiento con code splitting |
| Zod 4.3 | Validación de formularios |
| Axios 1.13 | Cliente HTTP con interceptores |
| Radix UI | Primitivos accesibles (WCAG 2.1 AA) |
| CSS Modules | Estilos con scope aislado |
| i18next 25.8 | Internacionalización (ES/EN) |
DevOps
| Tecnología | Rol |
|---|---|
| Docker Compose | MongoDB 8.0 replica set + Mailpit |
| Biome 2.3 | Linter y formatter unificado |
| Playwright 1.58 | Tests E2E cross-browser |
| Vitest 4.0 | Tests unitarios |
| dependency-cruiser | Validación de fronteras arquitectónicas |
| commitlint | Commits convencionales |
| Makefile | 40+ comandos de automatización |
Arquitectura
Arquitectura del sistema
Backend — Capas + Repository Pattern
Las fronteras entre capas se validan automáticamente con dependency-cruiser y un test arquitectónico que previene importaciones prohibidas.
Frontend — Feature-Driven + Estado en 3 capas
| Capa de estado | Herramienta | Uso |
|---|---|---|
| URL State | useSearchParams | Paginación, filtros, modales |
| Server State | TanStack Query | Datos de API con cache y revalidación |
| Client State | Zustand | UI state, sincronización de auth |
Modelo de datos — 20 colecciones
Patrón Linked Profile: Colecciones separadas por rol enlazadas a Users — consultas por rol ~4x más rápidas, working set 75% menor.
Seguridad y autenticación
RBAC — 6 roles
Stack de seguridad
- Helmet — Headers HTTP (CSP, HSTS, X-Frame-Options)
- Rate Limiting — 100 peticiones / 15 min por IP
- CORS — Control de origen por whitelist
- bcrypt — Hash de contraseñas con salt rounds
- JWT — Access token (15 min) + Refresh token (7 días)
- Soft Deletes — Pista de auditoría (
deletedAt), nunca se eliminan datos permanentemente
Principios SOLID aplicados
| Principio | Implementación |
|---|---|
| SRP | Controllers solo orquestan request/response, Services contienen reglas de negocio, Repositories encapsulan queries |
| OCP | registrationPolicy.ts usa mapas declarativos — agregar un rol nuevo no requiere modificar código existente |
| LSP | Todos los repositorios implementan contratos comunes (IRepository), middleware con firmas intercambiables |
| ISP | IAccountRepository separado en IAccountConfirmationRepository + IPasswordResetRepository — 11 interfaces por dominio |
| DIP | Servicios dependen de abstracciones (interfaces), repositorios inyectados como parámetros |
Testing — 3 niveles
E2E (Playwright) — 51 tests
- 12 spec files con cobertura CRUD completa de los 85 endpoints
- Módulos: auth, catálogos, pacientes, agendamiento, clínico, financiero, inventario, usuarios, RBAC
- Soporte bilingüe (EN/ES) en selectores
- Integración con Mailpit para flujos de confirmación por email
Unitarios (Vitest) — 51 tests
- Utilidades, estado (authStore), componentes (Button, RoleGuard, ProfilePage), hooks (useAuthQueries)
- Test arquitectónico
layerBoundaries.test.ts— reglas de dependencias entre capas
Arquitectónicos
- dependency-cruiser valida 7 reglas de fronteras entre capas (G1-G7)
- Previene importaciones prohibidas entre capas
Calidad de código
- Biome 2.3 — Linter y formatter unificado, reglas WCAG a11y, organización automática de imports
- TypeScript Strict Mode —
noUncheckedIndexedAccess,exactOptionalPropertyTypes,verbatimModuleSyntax - Conventional Commits — commitlint con Husky hooks, pre-commit: format + lint, pre-push: tests completos
Repositorio
🔗 github.com/Vic-Lara-Gilles/Mern-veterinary-Review
Lenguajes: TypeScript 90.6% · CSS 7.4%