ruby 3.3.1
-
Authentication and Authorization
- Users should be able to register, log in, and log out
- Two types of users: Librarian and Member
- Only Librarian users should be able to add, edit, or delete books
-
Book Management
- Ability to add a new book with details like title, author, genre, ISBN, and total copies
- Ability to edit and delete book details
- Search functionality: Users should be able to search for a book by title, author, or genre
-
Borrowing and Returning
- Member users should be able to borrow a book if it's available. They can't borrow the same book multiple times
- The system should track when a book was borrowed and when it's due (2 weeks from the borrowing date)
- Librarian users can mark a book as returned
-
Dashboard
- Librarian: A dashboard showing:
- total books
- total borrowed books
- books due today (list)
- list of members with overdue books
- Member: A dashboard showing:
- books they've borrowed with their due dates
- any overdue books
- Librarian: A dashboard showing:
-
API Endpoints
- Develop a RESTful API that allows CRUD operations for books and borrowings
- Ensure proper status codes and responses for each endpoint
- Testing should be done with RSPEC (Spec files should be included for all the requirements above)
-
Frontend (optional)
- While the main focus is on Ruby on Rails, you can choose to integrate the backend with a frontend framework of your choice (React, Vue, etc.). The frontend should be responsive and user-friendly
This project uses asdf.
Follow the installation instructions
After installation you need to follow these steps:
# Add ruby plugin on asdf
$ asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git
# Install ruby plugin
$ asdf install ruby 3.3.1
# run setup script to initialize database and install dependencies
$ bin/setup
# run project
$ bin/rails s
# initialize the database with the seed data
$ bin/rails db:setup
# run all specs and generate coverage files
$ bin/rspec
# run all specs without coverage files (run in this mode when you want to run faster and don't need to look at the coverage)
$ NO_COVERAGE=true bin/rspec
# run linter
$ bin/rubocop
Considering that librarians work an 8-hour day without breaks, our authentication token for all types of users is valid for 8 hours.
After this time the user will need to authenticate again.
We will use the versioned API in case a modification occurs in the future that breaks the interface.
The dates for both borrow creation and return are being received by parameter because of the timezone issue. In my opinion, the backend should always work using dates in UTC, leaving the responsibility for the timezone with the presentation layer.
email: admin@test.com
password: 12345678
email: member@test.com
password: member123
First we need to know the URL the project is running at. The default is http://localhost:3000/
In the Header of the login response, there is the authorization field with the data to use our API
user
(required): user data to log in.email
(required): user mail.password
(required): password.
POST /login
{
"user": {
"email": "admin@test.com",
"password": "12345678"
}
}
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
DELETE /logout
user
(required): user data to create an user.name
(required): user name.email
(required): user mail.password
(required): password.
POST /signup
{
"user": {
"name": "John Doe",
"email": "john@doe.com",
"password": "12345678"
}
}
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows Librarians to promote Members to be Librarians.
user
(required): user data.role
(required): user role (librarian | member).
PATCH /v1/users/:id
{
"user": {
"role": "librarian"
}
}
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows you to list all books in the library.
expression
(optional): used to filter books.
GET /v1/books?expression=development
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows you to show a specific book.
GET /v1/books/:id
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows you to create a new book.
book
(required): book data to create a book.title
(required): book title.author
(required): book author.genre
(required): book genre.isbn
(optional): book isbn.total_copies
(optional): total os copies.
POST /v1/books
{
"book": {
"title": "IT",
"author": "Stephen King",
"genre": "Terror, Horror"
}
}
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows you to update a specific book.
book
(required): book data to create a book.title
(required): book title.author
(required): book author.genre
(required): book genre.isbn
(optional): book isbn.total_copies
(optional): total os copies.
PATCH /v1/books/:id
{
"book": {
"title": "IT",
"author": "Stephen King",
"genre": "Terror, Horror"
}
}
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows you to destroy a specific book.
DELETE /v1/books/:id
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows you to create a new borrow.
borrow
(required): borrow data to create a borrow.book_id
(required): book to be borrowed.borrowed_at
(required): borrow date (UTC).format: YYYY-MM-DD
POST /v1/borrow
{
"borrow": {
"book_id": 1,
"borrowed_at": "2024-06-13",
}
}
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
This endpoint allows you to return a book.
borrow
(required): book data to create a book.returned_at
(required): returned date (UTC).format: YYYY-MM-DD
PATCH /v1/borrows/:id
{
"borrow": {
"returned_at": "2024-06-13"
}
}
It is necessary to add the Authorization field in the header with the credentials you copied on the login endpoint.
GET /v1/dashboard