A simple library management system to manage books and borrowers.
- Functional Requirements
- Non-functional Requirements
- Tools Used
- Getting Started
- Database Schema
- Project Structure
- Add a book with details like title, author, ISBN, available quantity, and shelf location.
- Update a book’s details.
- Delete a book.
- List all books.
- Search for a book by title, author, or ISBN.
- Register a borrower with details like name, email, and registered date (Keep the user details as simple as possible).
- Update borrower’s details.
- Delete a borrower.
- List all borrowers.
- A borrower can check out a book. The system should keep track of which books are checked out and by whom.
- A borrower can return a book.
- A borrower can check the books they currently have.
- The system should keep track of due dates for the books and list books that are overdue
The system should be optimized for reading operations since searching and listing books/borrowers will be frequent operations. This is done by adding a full-text search index on the title and author name fields. This index will speed up the read requests in favor of the less likely used write requests. For better scalability, a standalone search database could be used e.g. Elasticsearch. Which could be used for the searching endpoints to retrieve documents faster. Moreover, Elasticsearch supports horizontal scalability which will increase the reliability and availability of the system.
The API server is a stateless app making it easier to scale up and down with the load. For future improvement, a node-exporter module could be integrated to aggregate metrics about the API like response time and memory usage to determine bottlenecks and set scaling policy.
The database schema is open for extensibility by adding reviews, reservations, and staff. Also, the modular structure of the project helps in adding new modules easily. Checkout the Project Structure, and Database Schema sections for more about it.
Currently implemented
- All the API endpoint inputs are validated to ensure better security.
- A robust error handling is implemented to handle most user errors and prevent leaking any information on unhandled errors.
- The API adds security headers to every request.
Future improvements
- Refresh tokens could be used to allow scalable user logouts, and prevent multiple login requests during a session.
- Distributed rate limiting using a Redis backend could be implemented to lock user accounts to prevent password guessing. Also could be used to block DoS attacks.
- NodeJs
- ExpressJs
- MySQL
- Github Actions
- Docker
-
Rename the
.env.examplefile to.env. -
Run the
docker-compose upcommand which will set up a database, seed it, and run the API server after that.- You can remove the
seed-dbservice to use the API on your own. - All seeds users have the same password:
123456789
User Roles borrower@test.com borrower staff@test.com staff - You can remove the
You can access the API docs at this local URL: http://localhost:3000/docs/
├───.github
│ └───workflows <- GitHub templates and CI files.
└───src <- Contains App code.
├───db
│ └───migrations
├───docs <- Auto-generated API docs.
│ └───assets
├───middlewares <- Common middlewares between modules.
├───modules <- Contains a module for each entity.
│ ├───auth
│ ├───book
│ │ ├── book.controller.js
│ │ ├── book.model.js
│ │ ├── book.route.js
│ │ ├── book.service.js
│ │ └── index.js <- Contains exports from module
│ ├───bookAuthor
│ ├───bookLoan
│ ├───borrower
│ ├───health
│ └───user
├───routes
├───utils
│ └───exceptions
├─── logger.js
├─── config.js
├─── seeder.js
├─── app.js
└─── server.js