Backend API for the pet management mobile application. This REST API provides comprehensive pet management features including pet profiles, health records, medications, vaccinations, vet visits, weight tracking, route tracking, and calendar events.
- Authentication & Authorization: JWT-based authentication with role-based access control
- Multi-User Support: Sub-users with different permission levels
- Pet Management: Complete pet profiles with sharing capabilities
- Health Records: Track medications, vaccinations, and vet visits
- Weight Tracking: Monitor pet weight over time
- Route Tracking: GPS-based route tracking for walks
- Calendar Events: Schedule and manage pet-related events
- Avatar Management: Upload and manage pet and user profile images
- Security: Rate limiting, CORS, Helmet, and secure password hashing
- Runtime: Node.js
- Framework: Express.js
- Database: PostgreSQL
- Authentication: JWT (jsonwebtoken)
- Password Hashing: bcrypt
- File Upload: Multer
- Security: Helmet, CORS, express-rate-limit
- Validation: validator
- Node.js (v14 or higher)
- PostgreSQL (v12 or higher)
- npm or yarn
npm installCreate a .env file in the backend directory:
cp .env.example .envUpdate the .env file with your configuration:
PORT=3000
DATABASE_URL=postgresql://username:password@localhost:5432/petapp
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_EXPIRES_IN=7d
NODE_ENV=development
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8081Ensure PostgreSQL is running and create the database:
createdb petappApply the database schema:
psql -U your_username -d petapp -f ../database.sqlDevelopment mode (with hot-reload):
npm run devProduction mode:
npm startThe server will start on http://localhost:3000 (or the PORT specified in .env).
For testing with Docker Compose:
docker-compose -f docker-compose.ci.yml upThis will start both PostgreSQL and the API server.
http://localhost:3000/api
Check API health status
Response:
{
"status": "ok",
"timestamp": "2026-02-19T10:00:00.000Z"
}Register a new user account
Request Body:
{
"email": "user@example.com",
"username": "johndoe",
"password": "SecurePass123",
"name": "John Doe"
}Response (201):
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"name": "John Doe"
},
"token": "jwt-token"
}
}Authenticate user and receive JWT token
Request Body:
{
"email": "user@example.com",
"password": "SecurePass123"
}Logout current user (requires authentication)
Update user email address (requires authentication)
Update user password (requires authentication)
Delete user account (requires authentication)
Get all sub-users linked to the authenticated user's account
Remove a sub-user linking
Update sub-user role for a specific pet
Get all pets for the authenticated user
Create a new pet profile
Get pet details by ID
Get complete pet data including all medications, vaccinations, weights, and vet visits
Update pet details
Delete a pet profile
Generate a temporary share code for pet access
Redeem a share code to gain access to a pet
Get all users who have access to a pet
Remove a user's access to a pet
Get all medications for the user's pets
Add a new medication record
Update medication record
Delete medication record
Get all vaccinations for the user's pets
Add a new vaccination record
Update vaccination record
Delete vaccination record
Get all available vet visit types
Get all vet visits for the user's pets
Add a new vet visit record
Update vet visit record
Delete vet visit record
Get all weight records for the user's pets
Add a new weight record
Update weight record
Delete weight record
Get all routes for the authenticated user
Create a new route with GPS coordinates
Get a specific route by ID with all coordinates
Get all routes for a specific pet
Delete a route
Get all calendar events for the user's pets
Get calendar events for a specific pet
Get a single calendar event by ID
Create a new calendar event
Update a calendar event
Delete a calendar event
Get current avatar for authenticated user
Get current avatar for a specific pet
Get avatar by ID
Download avatar file
Upload a new avatar (replaces existing)
Delete an avatar
Most endpoints require authentication. Include the JWT token in the Authorization header:
Authorization: Bearer <your-jwt-token>
- Minimum 8 characters
- Maximum 128 characters
- Must contain at least one uppercase letter
- Must contain at least one lowercase letter
- Must contain at least one number
- Minimum 3 characters
- Maximum 30 characters
- Can only contain letters, numbers, and underscores
- Must be unique
- Rate Limiting: 300 requests per 15 minutes for general endpoints, 100 for authentication
- CORS: Configurable allowed origins via environment variables
- Helmet: Security headers protection
- JWT: Secure token-based authentication
- bcrypt: Password hashing with salt rounds
- Input Validation: Comprehensive request validation
- SQL Injection Protection: Parameterized queries via pg library
All endpoints return consistent error responses:
{
"success": false,
"message": "Error description",
"errors": ["Optional array of validation errors"]
}Common HTTP status codes:
200: Success201: Created400: Bad Request / Validation Error401: Unauthorized403: Forbidden404: Not Found409: Conflict (e.g., duplicate email)429: Too Many Requests (rate limit exceeded)500: Internal Server Error
server/
├── database.sql # PostgreSQL database schema
├── LICENSE # License information
├── README.md # This documentation
│
└── backend/ # Main application directory
├── docker-compose.ci.yml # Docker Compose for CI/testing
├── Dockerfile # Container definition
├── package.json # Node.js dependencies and scripts
│
├── src/ # Source code
│ ├── index.js # Application entry point & server config
│ ├── PRIVACY_POLICY.html
│ │
│ ├── config/ # Configuration modules
│ │ ├── database.js # PostgreSQL connection pool
│ │ └── jwt.js # JWT token configuration
│ │
│ ├── controllers/ # Business logic & request handlers
│ │ ├── authController.js # User authentication & account management
│ │ ├── avatarController.js # Avatar upload & retrieval
│ │ ├── calendarEventController.js # Calendar event CRUD operations
│ │ ├── medicationController.js # Medication tracking
│ │ ├── petController.js # Pet profile management & sharing
│ │ ├── routeController.js # GPS route tracking
│ │ ├── vaccinationController.js # Vaccination records
│ │ ├── vetVisitController.js # Vet visit tracking
│ │ └── weightController.js # Weight monitoring
│ │
│ ├── middleware/ # Request processing pipeline
│ │ ├── authenticateToken.js # JWT validation
│ │ ├── avatarUpload.js # Multer file upload config
│ │ ├── resolveEffectiveUser.js # Multi-user & sub-user resolution
│ │ ├── validateLogin.js # Login input validation
│ │ ├── validateRegistration.js # Registration input validation
│ │ ├── validateSubUserRegistration.js # Sub-user creation validation
│ │ └── validateSubUserRoleUpdate.js # Role update validation
│ │
│ ├── models/ # Database access layer
│ │ ├── Avatar.js # Avatar database operations
│ │ ├── CalendarEvent.js # Calendar event queries
│ │ ├── Medication.js # Medication CRUD
│ │ ├── Pet.js # Pet profile & sharing logic
│ │ ├── Route.js # GPS route storage
│ │ ├── User.js # User & authentication queries
│ │ ├── Vaccination.js # Vaccination records
│ │ ├── VetVisit.js # Vet visit data
│ │ └── Weight.js # Weight tracking
│ │
│ ├── routes/ # API endpoint definitions
│ │ ├── avatarRoutes.js # /api/avatars/*
│ │ ├── calendarEventRoutes.js # /api/calendar-events/*
│ │ ├── medicationRoutes.js # /api/medications/*
│ │ ├── petRoutes.js # /api/pets/*
│ │ ├── routeRoutes.js # /api/routes/*
│ │ ├── userRoutes.js # /api/auth/*
│ │ ├── vaccinationRoutes.js # /api/vaccinations/*
│ │ ├── vetVisitRoutes.js # /api/vet-visits/*
│ │ └── weightRoutes.js # /api/weights/*
│ │
│ ├── services/ # Business logic services (reserved for future use)
│ │
│ ├── types/ # Type definitions (reserved for future use)
│ │
│ └── utils/ # Helper functions & utilities
│ ├── generateToken.js # JWT token generation
│ ├── hashPassword.js # bcrypt password hashing
│ └── shareCode.js # Pet sharing code generation
│
└── uploads/ # File storage
└── avatars/ # User & pet avatar images
npm run devEnsure Docker is running and execute:
docker-compose -f docker-compose.ci.yml upSee LICENSE file in the root directory.