Una plataforma completa de adopción de mascotas construida con Node.js, Express, MongoDB, Next.js 15 y TanStack Query. Esta aplicación proporciona una solución full-stack para conectar mascotas con familias amorosas a través de refugios y organizaciones de adopción.
- Aplicación React moderna con Next.js 15
- Estado del servidor gestionado con TanStack Query v5
- Interfaz de usuario con Shadcn/ui y Tailwind CSS
- TypeScript para type safety completo
- Optimistic updates y cache inteligente
- API REST con Node.js y Express
- Base de datos MongoDB con Mongoose
- Autenticación JWT con roles
- Validación con Zod
- Documentación con Swagger
- Perfiles detallados de mascotas con fotos
- Registros de salud y rasgos de personalidad
- Subida múltiple de imágenes con Cloudinary
- Seguimiento de estado (Disponible, Pendiente, Adoptado)
- Búsqueda de mascotas por ubicación y tipo
- Consultas geoespaciales con MongoDB
- Filtrado basado en distancia
- Filtros de búsqueda avanzados
- Aplicaciones de adopción completas
- Seguimiento de estado y notificaciones
- Programación de reuniones
- Coordinación de visitas domiciliarias
- Mascotas favoritas con alertas personalizadas
- Notificaciones por email para actualizaciones
- Seguimiento en tiempo real del proceso de adopción
- Framework: Next.js 15 (App Router)
- Styling: Tailwind CSS + Shadcn/ui
- State Management: TanStack Query v5
- HTTP Client: Axios
- Language: TypeScript
- Forms: React Hook Form + Zod
- Runtime: Node.js + Express.js
- Database: MongoDB with Mongoose ODM
- Authentication: JWT with role-based access
- Validation: Zod for data validation
- File Upload: Multer + Cloudinary
- Email: Nodemailer
- Documentation: Swagger/OpenAPI
- Security: Helmet, CORS, Rate Limiting
pet-adoption-platform/
├── api/ # Backend API
│ ├── src/
│ │ ├── controllers/ # Route controllers
│ │ ├── routes/ # API routes
│ │ ├── models/ # Mongoose models
│ │ ├── middlewares/ # Custom middleware
│ │ ├── services/ # Business logic services
│ │ ├── validations/ # Zod validation schemas
│ │ ├── utils/ # Utility functions
│ │ ├── config/ # Configuration files
│ │ └── app.js # Main application file
│ ├── tests/ # API tests
│ ├── package.json
│ └── server.js
├── client/ # Frontend Next.js
│ ├── app/ # Next.js App Router
│ ├── components/ # React components
│ ├── lib/ # Utilities and configurations
│ │ ├── api-client.ts # Axios configuration
│ │ ├── query-client.ts # TanStack Query config
│ │ ├── types.ts # TypeScript types
│ │ └── services/ # API service functions
│ ├── hooks/ # Custom React hooks
│ ├── styles/ # Global styles
│ ├── public/ # Static assets
│ └── package.json
└── package.json # Root workspace configuration
- Node.js (v18 or higher)
- MongoDB (local or Atlas)
- Cloudinary account (for image uploads)
- Email service (Gmail, SendGrid, etc.)
-
Clone the repository
git clone <repository-url> cd pet-adoption-platform
-
Install all dependencies
npm run setup
-
Environment Setup
API Environment (
api/.env):cd api cp env.example .envUpdate
api/.envwith your configuration:# Server Configuration PORT=3000 NODE_ENV=development # Database Configuration MONGODB_URI=mongodb://localhost:27017/pet-adoption # JWT Configuration JWT_SECRET=your-super-secret-jwt-key JWT_EXPIRES_IN=7d # CORS Configuration CORS_ORIGIN=http://localhost:3001 # Cloudinary Configuration CLOUDINARY_CLOUD_NAME=your-cloud-name CLOUDINARY_API_KEY=your-api-key CLOUDINARY_API_SECRET=your-api-secret
Client Environment (
client/.env.local):# API Configuration NEXT_PUBLIC_API_URL=http://localhost:3000/api NODE_ENV=development
-
Start the development servers
# Start both API and Client with one command npm run dev # Or start individually: npm run dev:api # API on http://localhost:3000 npm run dev:client # Client on http://localhost:3001
-
Access the applications
- Frontend: http://localhost:3001
- API: http://localhost:3000
- API Documentation: http://localhost:3000/api-docs
- Health Check: http://localhost:3000/health
npm run dev- Start both API and Client in development modenpm run dev:api- Start only the API servernpm run dev:client- Start only the Next.js client
npm run test- Run all testsnpm run test:api- Run API testsnpm run test:client- Run client testsnpm run test:endpoints- Test API endpointsnpm run test:connection- Test API connection from client
npm run build- Build the client for productionnpm run start:api- Start API in production modenpm run start:client- Start client in production mode
npm run setup- Install all dependenciesnpm run clean- Clean all node_modulesnpm run reset- Clean and reinstall everythingnpm run lint- Run linting on all packagesnpm run lint:fix- Fix linting issues
The client uses TanStack Query v5 for server state management. Key features:
- Automatic caching with smart invalidation
- Background updates and refetching
- Optimistic updates for better UX
- Error handling with retry logic
- DevTools for debugging queries
import { usePets, useToggleFavorite } from '@/hooks/use-pets';
function PetsList() {
const { data: pets, isLoading, error } = usePets({
page: 1,
limit: 12,
filters: { species: ['dog'] }
});
const toggleFavorite = useToggleFavorite();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{pets?.data.map(pet => (
<PetCard
key={pet._id}
pet={pet}
onToggleFavorite={() => toggleFavorite.mutate({
petId: pet._id,
isFavorite: false
})}
/>
))}
</div>
);
}For detailed usage instructions, see TanStack Query Guide.
POST /api/auth/register- Register new userPOST /api/auth/login- User loginPOST /api/auth/verify-email- Verify email addressPOST /api/auth/forgot-password- Request password resetPOST /api/auth/reset-password- Reset passwordGET /api/auth/me- Get current user profile
GET /api/users/profile- Get user profilePUT /api/users/profile- Update user profilePOST /api/users/change-password- Change passwordPOST /api/users/upload-avatar- Upload profile picture
GET /api/pets- Search pets with filtersGET /api/pets/:id- Get pet detailsPOST /api/pets- Create new pet (Shelter only)PUT /api/pets/:id- Update pet (Shelter only)DELETE /api/pets/:id- Delete pet (Shelter only)POST /api/pets/:id/images- Upload pet images
POST /api/adoptions- Submit adoption applicationGET /api/adoptions/my-applications- Get user's applicationsGET /api/adoptions/:id- Get application detailsPUT /api/adoptions/:id/status- Update application status (Shelter)POST /api/adoptions/:id/schedule-meeting- Schedule meeting
GET /api/favorites- Get favorite petsPOST /api/favorites/:petId- Add to favoritesDELETE /api/favorites/:petId- Remove from favoritesPUT /api/favorites/:petId/toggle- Toggle favorite status
GET /api/shelters- Get all sheltersGET /api/shelters/:id- Get shelter detailsGET /api/shelters/:id/pets- Get shelter's petsGET /api/shelters/my/dashboard- Shelter dashboard
{
email: String,
password: String (hashed),
firstName: String,
lastName: String,
role: ['user', 'shelter', 'admin'],
phone: String,
address: {
street: String,
city: String,
state: String,
zipCode: String,
coordinates: { latitude: Number, longitude: Number }
},
preferences: {
petTypes: [String],
maxDistance: Number,
notifications: { email: Boolean, push: Boolean }
},
isVerified: Boolean,
isActive: Boolean
}{
name: String,
type: ['dog', 'cat', 'bird', 'rabbit', 'hamster', 'fish', 'reptile', 'other'],
breed: String,
age: { years: Number, months: Number },
gender: ['male', 'female', 'unknown'],
size: ['small', 'medium', 'large', 'extra-large'],
description: String,
personality: [String],
goodWith: { children: Boolean, dogs: Boolean, cats: Boolean },
healthInfo: {
vaccinated: Boolean,
spayedNeutered: Boolean,
microchipped: Boolean,
specialNeeds: String
},
images: [{ url: String, publicId: String, isPrimary: Boolean }],
shelter: ObjectId,
status: ['available', 'pending', 'adopted', 'unavailable'],
adoptionFee: Number,
location: { address: String, coordinates: Object }
}{
pet: ObjectId,
adopter: ObjectId,
shelter: ObjectId,
status: ['pending', 'approved', 'rejected', 'completed', 'cancelled'],
applicationData: {
experience: String,
livingSpace: String,
workSchedule: String,
reason: String,
emergencyContact: Object,
veterinarian: Object
},
statusHistory: [{ status: String, date: Date, note: String }],
meetingScheduled: { date: Date, location: String, notes: String }
}npm start # Start production server
npm run dev # Start development server with nodemon
npm test # Run tests
npm run test:watch # Run tests in watch mode
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint errorsThis project uses ESLint for code linting. Run npm run lint to check for issues and npm run lint:fix to automatically fix them.
Tests are written using Jest and Supertest. Run npm test to execute the test suite.
Ensure all required environment variables are set in production:
NODE_ENV=productionMONGODB_URI- MongoDB connection stringJWT_SECRET- Strong secret for JWT signingCLOUDINARY_*- Cloudinary credentialsEMAIL_*- Email service configuration
- Create a MongoDB Atlas cluster
- Create a database user
- Whitelist your IP address
- Get the connection string and update
MONGODB_URI
- Create a Cloudinary account
- Get your cloud name, API key, and API secret
- Update the Cloudinary environment variables
Interactive API documentation is available at /api-docs when the server is running. The documentation is generated using Swagger/OpenAPI specifications.
- Authentication: JWT-based authentication
- Authorization: Role-based access control
- Rate Limiting: Prevents API abuse
- Input Validation: Zod schema validation
- Security Headers: Helmet middleware
- CORS: Configurable cross-origin requests
- Password Hashing: bcrypt for secure password storage
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
For support, email [email protected] or create an issue in the repository.
Happy Pet Adoption! 🐾❤️