Overview
Adoptme uses Mongoose for MongoDB object modeling, defining three core collections: Users, Pets, and Adoptions. Each model includes schema validation, default values, and relationships between collections. All models are located insrc/dao/models/ and use Mongoose’s schema-based approach for data structure and validation.
User Model
The User model represents registered users who can adopt pets. Located insrc/dao/models/User.js.
Schema Definition
Fields
User’s first name
User’s last name
User’s email address. Must be unique across all users. Used for authentication.
Hashed password using bcrypt with 10 salt rounds. Never stored in plain text.
User role for authorization. Default is
'user'. Can be used for admin/moderator roles.Array of ObjectId references to Pet documents. Represents pets adopted by this user.Each item contains:
_id(ObjectId) - Reference to a Pet document
Relationships
- One-to-Many with Pets: A user can have multiple pets (stored in
petsarray) - One-to-Many with Adoptions: A user can create multiple adoption records
The
pets field stores references (ObjectIds) to Pet documents, enabling Mongoose population for retrieving full pet details.Password Security
Passwords are hashed before storage using bcrypt fromsrc/utils/index.js:
- 10 salt rounds for bcrypt hashing
- Async hashing to avoid blocking
- Comparison function for login validation
Pet Model
The Pet model represents animals available for adoption. Located insrc/dao/models/Pet.js.
Schema Definition
Fields
Pet’s name
Species of the pet (e.g., “dog”, “cat”, “rabbit”)
Pet’s date of birth. Used to calculate age.
Adoption status.
false means available for adoption, true means already adopted.Reference to the User who adopted this pet. Null if not adopted.References the
Users collection.File path to pet’s image. Set when uploading via
/api/pets/withimage endpoint.Example: /src/public/img/pet-12345.jpgRelationships
- Many-to-One with Users: A pet can have one owner (or none if not adopted)
- One-to-One with Adoptions: Each pet can have one adoption record
Image Upload
Pets can have images uploaded via thePOST /api/pets/withimage endpoint using Multer middleware:
image field:
Adoption Model
The Adoption model represents the relationship between users and adopted pets. Located insrc/dao/models/Adoption.js.
Schema Definition
Fields
Reference to the User who is adopting the pet.References the
Users collection.Reference to the Pet being adopted.References the
Pets collection.Relationships
The Adoption model creates a Many-to-Many relationship between Users and Pets:- Many-to-One with Users: Multiple adoptions can belong to one user
- Many-to-One with Pets: Multiple adoption records can reference pets (historical records)
The Adoption model acts as a junction table, recording the relationship between users and pets when an adoption occurs.
Usage Example
When a user adopts a pet:- Create an Adoption record linking the user and pet
- Update the Pet’s
adoptedfield totrue - Update the Pet’s
ownerfield with the user’s ID - Add the pet’s ID to the User’s
petsarray
Data Transfer Objects (DTOs)
DTOs transform and validate data between layers, ensuring clean separation and security.User DTO
Located insrc/dto/User.dto.js, the User DTO removes sensitive information when creating JWT tokens:
- Combines
first_nameandlast_nameinto a singlenamefield - Excludes password from JWT payload for security
- Includes only necessary fields:
name,role,email
Pet DTO
Located insrc/dto/Pet.dto.js, the Pet DTO validates and sets defaults for pet creation:
- Sets default values for optional fields
- Ensures
adoptedis alwaysfalsefor new pets - Provides fallback
birthDateif not specified - Validates presence of required fields
Model Relationships Diagram
Collection Names
| Model | Collection Name | Document Count |
|---|---|---|
| User | Users | Variable |
| Pet | Pets | Variable |
| Adoption | Adoptions | Variable |
Validation Rules
Field Validation Summary
Field Validation Summary
User Validation
first_name: Required, stringlast_name: Required, stringemail: Required, string, unique indexpassword: Required, string (stored as bcrypt hash)role: Optional, string, defaults to'user'pets: Optional, array of ObjectIds, defaults to[]
Pet Validation
name: Required, stringspecie: Required, stringbirthDate: Optional, Dateadopted: Optional, boolean, defaults tofalseowner: Optional, ObjectId referenceimage: Optional, string (file path)
Adoption Validation
owner: Optional, ObjectId reference to Userspet: Optional, ObjectId reference to Pets
Best Practices
Follow these best practices when working with Adoptme data models:
- Always use DTOs - Transform data between layers using User.dto.js and Pet.dto.js
- Hash passwords - Use
createHash()utility before storing passwords - Validate references - Ensure referenced documents exist before creating relationships
- Set adopted status - Update
Pet.adoptedwhen creating an Adoption record - Use population - Leverage Mongoose’s
.populate()to retrieve referenced documents - Handle unique constraints - Catch duplicate email errors on user registration
- Default values - Let DTOs and schemas handle defaults consistently
Next Steps
- Learn about Authentication flows
- Explore the Architecture design patterns
- See API Reference for endpoint usage