- Overview
- Base Configuration
- Authentication Endpoints
- User Management Endpoints
- Book Management Endpoints
- Transaction Endpoints
- Review Endpoints
- Notification Endpoints
- Statistics Endpoints
- Error Handling
- Database Schema
Project: Digilibz - Digital Library Management System
Version: 0.0.1-SNAPSHOT
Java Version: 17
Spring Boot Version: 4.0.0
Database: MySQL
- Spring Boot 4.0.0
- Spring Data JPA
- Spring Security (BCrypt)
- MySQL Connector
- Hibernate Validator
- Lombok
- SpringDoc OpenAPI
Default Port: 8080
Context Path: /
Azure Deployment Port: 80
Allowed Origins:
http://localhost:3000http://localhost:5173http://localhost:5174
Allowed Methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
Allowed Headers: All (*)
Credentials: Enabled
Max Age: 3600 seconds
- Password Encoding: BCrypt
- CSRF: Disabled
- All endpoints: Permit All (currently no JWT implementation)
Endpoint: POST /api/auth/login
Description: Authenticate regular user (non-admin)
Request Body:
{
"email": "user@example.com",
"password": "password123"
}Success Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"name": "John Doe",
"role": "USER",
"token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}Error Responses:
401 Unauthorized - Invalid credentials or admin trying to login:
{
"error": "Invalid password"
}{
"error": "Unauthorized: Use admin login page"
}Validation:
- Email must exist in database
- Password must match hashed password
- User role must be USER (not ADMIN)
- Returns token (UUID format)
Endpoint: POST /api/auth/login/admin
Description: Authenticate admin user only
Request Body:
{
"email": "admin@example.com",
"password": "adminpass123"
}Success Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"email": "admin@example.com",
"name": "Admin User",
"role": "ADMIN",
"token": "a1b2c3d4-e5f6-7890-abcd-ef1234567891"
}Error Responses:
403 Forbidden - Non-admin trying to login or invalid credentials:
{
"error": "Unauthorized: Admin access only"
}Validation:
- Email must exist in database
- Password must match hashed password
- User role must be ADMIN
- Returns token (UUID format)
Endpoint: POST /api/users/register
Description: Register new user with USER role
Request Body:
{
"email": "newuser@example.com",
"password": "password123",
"name": "New User",
"phone": "08123456789"
}Validation Rules:
email: Valid email format, uniquepassword: Required, not blankname: Required, not blankphone: Required, unique
Success Response (201 Created):
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"email": "newuser@example.com",
"password": "$2a$10$encoded_password_hash",
"name": "New User",
"role": "USER",
"phone": "08123456789"
}Error Responses:
400 Bad Request - Validation error:
{
"timestamp": "2024-12-26T10:30:00",
"status": 400,
"error": "Bad Request",
"message": "email: Invalid email format; password: Password is required; ",
"path": "/api/users/register"
}409 Conflict - Duplicate email or phone:
{
"timestamp": "2024-12-26T10:30:00",
"status": 409,
"error": "Conflict",
"message": "Datanya duplikat!",
"path": "/api/users/register"
}Endpoint: POST /api/users/register/admin
Description: Register new user with ADMIN role
Request Body:
{
"email": "newadmin@example.com",
"password": "adminpass123",
"name": "New Admin",
"phone": "08198765432"
}Success Response (201 Created):
{
"id": "550e8400-e29b-41d4-a716-446655440003",
"email": "newadmin@example.com",
"password": "$2a$10$encoded_password_hash",
"name": "New Admin",
"role": "ADMIN",
"phone": "08198765432"
}Same validation and error responses as Register User
Endpoint: GET /api/users
Description: Retrieve all users with optional role filter
Query Parameters:
role(optional): Filter by role (ADMIN or USER)
Examples:
GET /api/users
GET /api/users?role=USER
GET /api/users?role=ADMIN
Success Response (200 OK):
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user1@example.com",
"name": "User One",
"role": "USER",
"phone": "08123456789"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"email": "admin@example.com",
"name": "Admin User",
"role": "ADMIN",
"phone": "08198765432"
}
]Notes:
- Password is NOT included in response
- Returns empty array if no users found
- Role filter is case-insensitive
Endpoint: GET /api/users/{id}
Description: Retrieve specific user by ID
Path Parameters:
id: User UUID
Example:
GET /api/users/550e8400-e29b-41d4-a716-446655440000
Success Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"name": "John Doe",
"role": "USER",
"phone": "08123456789"
}Error Response:
404 Not Found:
HTTP Status: 404
Body: (empty)
Endpoint: PUT /api/users/{id}
Description: Update user data
Path Parameters:
id: User UUID
Request Body (all fields optional):
{
"email": "newemail@example.com",
"password": "newpassword123",
"name": "Updated Name",
"role": "ADMIN",
"phone": "08111222333"
}Success Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "newemail@example.com",
"password": "$2a$10$new_encoded_password_hash",
"name": "Updated Name",
"role": "ADMIN",
"phone": "08111222333"
}Error Responses:
400 Bad Request - Email or phone already in use:
HTTP Status: 400
Body: null
404 Not Found - User not found:
HTTP Status: 404
Body: null
Validation:
- If email changed, must be unique
- If phone changed, must be unique
- Password is re-hashed if provided
- Only provided fields are updated
Endpoint: DELETE /api/users/{id}
Description: Delete user by ID
Path Parameters:
id: User UUID
Success Response (200 OK):
{
"status": "success",
"message": "User deleted successfully"
}Error Response:
500 Internal Server Error:
{
"status": "error",
"message": "Error details here"
}Side Effects:
- Cascades delete to related notifications
- Cascades delete to related reviews
- Cascades delete to related transactions
Endpoint: GET /api/books
Description: Retrieve all books with optional filters
Query Parameters:
search(optional): Search by title (case-insensitive, partial match)category(optional): Filter by exact categoryyears(optional): Filter by publication year
Examples:
GET /api/books
GET /api/books?search=java
GET /api/books?category=Programming
GET /api/books?years=2023
GET /api/books?search=spring&category=Programming&years=2023
Success Response (200 OK):
[
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"title": "Clean Code",
"author": "Robert C. Martin",
"category": "Programming",
"year": 2008,
"description": "A handbook of agile software craftsmanship",
"image": "https://example.com/images/cleancode.jpg",
"quota": 10,
"rackNumber": "A-101",
"isbn": "978-0132350884",
"language": "English",
"availableCopies": 8,
"lateFee": 5000.00,
"canBorrow": true,
"rating": 4.85
}
]Field Descriptions:
id: Unique UUIDquota: Total copies ownedavailableCopies: Currently available copieslateFee: Late fee per day (in Rupiah)canBorrow: Whether book can be borrowedrating: Average rating (0.00-5.00)
Endpoint: GET /api/books/recommended
Description: Get random recommended books
Query Parameters:
max(optional): Maximum number of books to return
Examples:
GET /api/books/recommended
GET /api/books/recommended?max=5
Success Response (200 OK):
[
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"title": "Clean Code",
"author": "Robert C. Martin",
"category": "Programming",
"year": 2008,
"description": "A handbook of agile software craftsmanship",
"image": "https://example.com/images/cleancode.jpg",
"quota": 10,
"rackNumber": "A-101",
"isbn": "978-0132350884",
"language": "English",
"availableCopies": 8,
"lateFee": 5000.00,
"canBorrow": true,
"rating": 4.85
}
]Notes:
- Returns books in random order
- If
maxnot specified, returns all books - Uses SQL RAND() function for randomization
Endpoint: GET /api/books/{id}
Description: Retrieve book details with reviews
Path Parameters:
id: Book UUID
Query Parameters:
max(optional): Maximum reviews to return (default: 5)
Example:
GET /api/books/650e8400-e29b-41d4-a716-446655440000?max=10
Success Response (200 OK):
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"title": "Clean Code",
"author": "Robert C. Martin",
"category": "Programming",
"year": 2008,
"description": "A handbook of agile software craftsmanship",
"image": "https://example.com/images/cleancode.jpg",
"quota": 10,
"rackNumber": "A-101",
"isbn": "978-0132350884",
"language": "English",
"availableCopies": 8,
"lateFee": 5000.00,
"canBorrow": true,
"rating": 4.85,
"reviews": [
{
"id": "750e8400-e29b-41d4-a716-446655440000",
"bookTitle": "Clean Code",
"authorName": "John Doe",
"date": "2024-12-20T10:30:00",
"rating": 5.0,
"content": "Excellent book for learning clean coding practices!"
}
]
}Error Response:
404 Not Found:
{
"timestamp": "2024-12-26T10:30:00",
"status": 404,
"error": "Not Found",
"message": "No value present",
"path": "/api/books/650e8400-e29b-41d4-a716-446655440000"
}Endpoint: POST /api/books
Description: Create new book
Request Body:
{
"title": "Design Patterns",
"author": "Gang of Four",
"category": "Programming",
"year": 1994,
"description": "Elements of Reusable Object-Oriented Software",
"image": "https://example.com/images/designpatterns.jpg",
"quota": 5,
"rackNumber": "A-102",
"isbn": "978-0201633610",
"language": "English",
"availableCopies": 5,
"lateFee": 5000.00,
"canBorrow": true,
"rating": 4.75
}Required Fields:
title: Uniqueauthorisbn: Unique
Success Response (200 OK):
{
"id": "650e8400-e29b-41d4-a716-446655440001",
"title": "Design Patterns",
"author": "Gang of Four",
"category": "Programming",
"year": 1994,
"description": "Elements of Reusable Object-Oriented Software",
"image": "https://example.com/images/designpatterns.jpg",
"quota": 5,
"rackNumber": "A-102",
"isbn": "978-0201633610",
"language": "English",
"availableCopies": 5,
"lateFee": 5000.00,
"canBorrow": true,
"rating": 4.75
}Error Response:
409 Conflict - Duplicate title or ISBN:
{
"timestamp": "2024-12-26T10:30:00",
"status": 409,
"error": "Conflict",
"message": "Datanya duplikat!",
"path": "/api/books"
}Endpoint: PUT /api/books/{id}
Description: Update book details
Path Parameters:
id: Book UUID
Request Body (all fields required):
{
"title": "Updated Title",
"author": "Updated Author",
"category": "Updated Category",
"year": 2024,
"description": "Updated description",
"image": "https://example.com/new-image.jpg",
"quota": 15,
"rackNumber": "B-201",
"isbn": "978-1234567890",
"language": "Indonesian",
"availableCopies": 12,
"lateFee": 7500.00,
"canBorrow": false,
"rating": 4.90
}Success Response (200 OK):
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"title": "Updated Title",
"author": "Updated Author",
"category": "Updated Category",
"year": 2024,
"description": "Updated description",
"image": "https://example.com/new-image.jpg",
"quota": 15,
"rackNumber": "B-201",
"isbn": "978-1234567890",
"language": "Indonesian",
"availableCopies": 12,
"lateFee": 7500.00,
"canBorrow": false,
"rating": 4.90
}Error Response:
404 Not Found:
HTTP Status: 404
Body: (empty)
Endpoint: DELETE /api/books/{id}
Description: Delete book by ID
Path Parameters:
id: Book UUID
Success Response (200 OK):
{
"timestamp": "2024-12-26T10:30:00",
"status": 200,
"message": "Book successfully deleted",
"path": "/api/books/650e8400-e29b-41d4-a716-446655440000"
}Error Response:
404 Not Found:
{
"timestamp": "2024-12-26T10:30:00",
"status": 404,
"error": "Not Found",
"message": "No value present",
"path": "/api/books/650e8400-e29b-41d4-a716-446655440000"
}Side Effects:
- Cascades delete to related reviews
- Cascades delete to related transaction items
Endpoint: POST /api/transactions
Description: Create new borrow transaction
Request Body:
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"items": [
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"title": "Clean Code",
"image": "https://example.com/images/cleancode.jpg",
"author": "Robert C. Martin"
},
{
"id": "650e8400-e29b-41d4-a716-446655440001",
"title": "Design Patterns",
"image": "https://example.com/images/designpatterns.jpg",
"author": "Gang of Four"
}
],
"totalFee": 10000,
"paymentMethod": "Bank Transfer",
"paymentEvidence": "https://example.com/receipts/payment123.jpg",
"dateFrom": "2024-12-26",
"dateTo": "2025-01-09"
}Field Descriptions:
userId: User making the transactionitems: Array of books to borrowtotalFee: Total transaction fee (in Rupiah)paymentMethod: Payment method usedpaymentEvidence: URL/path to payment proofdateFrom: Borrow start date (ISO format)dateTo: Return due date (ISO format)
Success Response (200 OK):
{
"message": "Transaction successfully created",
"data": "INV-20241226-A3F"
}Response Data:
- Returns generated invoice code format:
INV-YYYYMMDD-XXX - XXX is 3-character random alphanumeric
Automatic Actions:
- Sets status to PENDING
- Sets type to BORROW
- Generates unique invoice code
- Creates notification for user
- Links all books to transaction
Error Response:
500 Internal Server Error:
{
"message": "Failed to create transaction",
"error": "User not found"
}Endpoint: GET /api/transactions/invoice
Description: Retrieve transaction details by invoice code
Query Parameters:
invoiceCode(required): Invoice code
Example:
GET /api/transactions/invoice?invoiceCode=INV-20241226-A3F
Success Response (200 OK):
{
"id": "850e8400-e29b-41d4-a716-446655440000",
"invoiceCode": "INV-20241226-A3F",
"dateRange": {
"from": "2024-12-26",
"to": "2025-01-09"
},
"status": "PENDING",
"type": "BORROW",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "John Doe",
"email": "user@example.com",
"phone": "08123456789",
"role": "USER"
},
"totalFee": 10000.0,
"paymentMethod": "Bank Transfer",
"paymentEvidence": "https://example.com/receipts/payment123.jpg",
"items": [
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"title": "Clean Code",
"author": "Robert C. Martin",
"image": "https://example.com/images/cleancode.jpg",
"lateFee": 5000.00
},
{
"id": "650e8400-e29b-41d4-a716-446655440001",
"title": "Design Patterns",
"author": "Gang of Four",
"image": "https://example.com/images/designpatterns.jpg",
"lateFee": 5000.00
}
]
}Status Values:
- PENDING: Awaiting approval
- APPROVED: Approved by admin
- DECLINED: Rejected by admin
- OVERDUE: Past due date
Type Values:
- BORROW: Borrowing books
- RETURN: Returning books
Error Response:
500 Internal Server Error:
{
"message": "Failed...",
"error": "Transaction not found"
}Endpoint: GET /api/transactions
Description: Retrieve transactions with multiple filters
Query Parameters (all optional):
search: Search by invoice code or user namestatus: Filter by status (PENDING, APPROVED, DECLINED, OVERDUE, all)type: Filter by type (BORROW, RETURN, all)userId: Filter by specific user ID
Examples:
GET /api/transactions
GET /api/transactions?status=PENDING
GET /api/transactions?type=BORROW
GET /api/transactions?userId=550e8400-e29b-41d4-a716-446655440000
GET /api/transactions?search=INV-20241226
GET /api/transactions?status=APPROVED&type=BORROW
Success Response (200 OK):
[
{
"id": "850e8400-e29b-41d4-a716-446655440000",
"invoiceCode": "INV-20241226-A3F",
"dateRange": {
"from": "2024-12-26",
"to": "2025-01-09"
},
"status": "PENDING",
"type": "BORROW",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "John Doe",
"email": "user@example.com",
"phone": "08123456789",
"role": "USER"
},
"totalFee": 10000.0,
"paymentMethod": "Bank Transfer",
"paymentEvidence": "https://example.com/receipts/payment123.jpg",
"items": [
{
"id": "650e8400-e29b-41d4-a716-446655440000",
"title": "Clean Code",
"author": "Robert C. Martin",
"image": "https://example.com/images/cleancode.jpg",
"lateFee": 5000.00
}
]
}
]Filter Logic:
search: Searches in invoice code (contains) and user name (case-insensitive)status: Use "all" to get all statusestype: Use "all" to get all types- Multiple filters are combined with AND logic
Endpoint: PUT /api/transactions
Description: Update transaction status and/or type
Query Parameters:
invoiceCode(required): Invoice codestatus(required): New status (approved, declined, pending, overdue)type(optional): New type (borrow, return)
Examples:
PUT /api/transactions?invoiceCode=INV-20241226-A3F&status=approved
PUT /api/transactions?invoiceCode=INV-20241226-A3F&status=approved&type=return
Success Response (200 OK):
{
"message": "Status transaksi berhasil diperbarui"
}Automatic Notification Generation:
For BORROW transactions:
approved: "Borrow Request Approved" (REMINDER)declined: "Borrow Request Declined" (ALERT)overdue: "Borrow Request Overdue" (ALERT)pending: "Borrow Request Pending" (INFO)
For RETURN transactions:
approved: "Return Approved" (REMINDER)declined: "Return Declined" (ALERT)overdue: "Return Overdue" (ALERT)pending: "Return Pending" (INFO)
Error Responses:
400 Bad Request - Invalid status or type:
{
"message": "Status tidak valid. Gunakan 'approved', 'declined', 'pending', atau 'overdue'"
}{
"message": "Tipe transaksi tidak valid. Gunakan 'borrow' atau 'return'"
}{
"message": "Transaksi dengan kode invoice tidak ditemukan"
}500 Internal Server Error:
{
"message": "Gagal memperbarui status transaksi"
}Endpoint: GET /api/reviews
Description: Get reviews with optional book filter
Query Parameters:
bookId(optional): Filter by book IDmax(optional): Maximum reviews to return (default: 5)
Examples:
GET /api/reviews
GET /api/reviews?bookId=650e8400-e29b-41d4-a716-446655440000
GET /api/reviews?max=10
GET /api/reviews?bookId=650e8400-e29b-41d4-a716-446655440000&max=10
Success Response (200 OK):
[
{
"id": "750e8400-e29b-41d4-a716-446655440000",
"bookTitle": "Clean Code",
"authorName": "John Doe",
"date": "2024-12-20T10:30:00",
"rating": 5.0,
"content": "Excellent book for learning clean coding practices!"
},
{
"id": "750e8400-e29b-41d4-a716-446655440001",
"bookTitle": "Clean Code",
"authorName": "Jane Smith",
"date": "2024-12-21T14:15:00",
"rating": 4.5,
"content": "Very helpful book, recommended for all developers."
}
]Field Descriptions:
id: Review UUIDbookTitle: Title of reviewed bookauthorName: Name of user who wrote reviewdate: Review creation timestamprating: Rating value (0.0-5.0)content: Review text content
Notes:
- If no
bookIdprovided, returns reviews for all books - Returns most recent reviews first
- Pagination handled by
maxparameter
Endpoint: POST /api/reviews
Description: Create new book review
Request Body:
{
"bookId": "650e8400-e29b-41d4-a716-446655440000",
"review": {
"authorId": "550e8400-e29b-41d4-a716-446655440000",
"rating": 5,
"content": "This book changed my perspective on writing code. Highly recommended!"
}
}Field Requirements:
bookId: Must exist in databaseauthorId: Must exist in databaserating: Integer 1-5content: Review text
Success Response (200 OK):
{
"bookId": "650e8400-e29b-41d4-a716-446655440000",
"author": "550e8400-e29b-41d4-a716-446655440000",
"rating": 5.0,
"content": "This book changed my perspective on writing code. Highly recommended!"
}Automatic Actions:
- Sets current timestamp as review date
- Links review to book and user
Error Responses:
404 Not Found - Book not found:
{
"message": "Book not found with id: 650e8400-e29b-41d4-a716-446655440000"
}404 Not Found - User not found:
{
"message": "User not found with id: 550e8400-e29b-41d4-a716-446655440000"
}Endpoint: GET /api/notifications
Description: Get all notifications for specific user
Query Parameters:
userId(required): User ID
Example:
GET /api/notifications?userId=550e8400-e29b-41d4-a716-446655440000
Success Response (200 OK):
[
{
"id": "950e8400-e29b-41d4-a716-446655440000",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"password": null,
"name": "John Doe",
"role": "USER",
"phone": "08123456789"
},
"title": "Transaction Pending",
"message": "Your transaction with invoice code INV-20241226-A3F is pending and will be reviewed by an admin until approved.",
"type": "INFO",
"date": "2024-12-26T10:30:00",
"read": false
},
{
"id": "950e8400-e29b-41d4-a716-446655440001",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"password": null,
"name": "John Doe",
"role": "USER",
"phone": "08123456789"
},
"title": "Borrow Request Approved",
"message": "Your borrow request with invoice code INV-20241226-A3F has been approved.",
"type": "REMINDER",
"date": "2024-12-26T11:00:00",
"read": true
}
]Notification Types:
INFO: General informationREMINDER: Important remindersALERT: Urgent alerts (declined, overdue)
Notes:
- Ordered by date (most recent first)
- User password is null in response
readindicates if notification has been read
Endpoint: PUT /api/notifications
Description: Mark notification as read
Query Parameters:
notifId(required): Notification ID
Example:
PUT /api/notifications?notifId=950e8400-e29b-41d4-a716-446655440000
Success Response (200 OK):
{
"id": "950e8400-e29b-41d4-a716-446655440000",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"password": null,
"name": "John Doe",
"role": "USER",
"phone": "08123456789"
},
"title": "Transaction Pending",
"message": "Your transaction with invoice code INV-20241226-A3F is pending...",
"type": "INFO",
"date": "2024-12-26T10:30:00",
"read": true
}Error Response:
400 Bad Request:
{
"error": "Notification with ID 950e8400-e29b-41d4-a716-446655440000 not found"
}Endpoint: POST /api/notifications
Description: Create new notification for user
Query Parameters:
userId(required): User IDtitle(required): Notification titlemessage(required): Notification messagetype(required): Notification type (INFO, REMINDER, ALERT)
Example:
POST /api/notifications?userId=550e8400-e29b-41d4-a716-446655440000&title=Custom%20Alert&message=This%20is%20a%20test%20notification&type=INFO
Success Response (200 OK):
{
"id": "950e8400-e29b-41d4-a716-446655440002",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"password": null,
"name": "John Doe",
"role": "USER",
"phone": "08123456789"
},
"title": "Custom Alert",
"message": "This is a test notification",
"type": "INFO",
"date": "2024-12-26T12:00:00",
"read": false
}Automatic Actions:
- Sets current timestamp
- Sets
readto false - Links to specified user
Error Response:
400 Bad Request:
{
"error": "User with ID 550e8400-e29b-41d4-a716-446655440000 not found"
}Endpoint: DELETE /api/notifications/{notifId}
Description: Delete notification by ID
Path Parameters:
notifId: Notification UUID
Example:
DELETE /api/notifications/950e8400-e29b-41d4-a716-446655440000
Success Response (200 OK):
{
"message": "Notification deleted successfully"
}Error Response:
400 Bad Request:
{
"error": "Notification with ID 950e8400-e29b-41d4-a716-446655440000 not found"
}Endpoint: GET /api/statistic
Description: Get comprehensive dashboard statistics
Query Parameters:
max(optional): Maximum recent reviews to return (default: 5)
Example:
GET /api/statistic
GET /api/statistic?max=10
Success Response (200 OK):
{
"message": "Data statistik berhasil diambil",
"data": {
"totalBook": 150,
"totalUser": 250,
"totalTransaction": 500,
"totalNotifications": 1200,
"averageReview": 4.35,
"totalReview": 380,
"recentReviews": [
{
"id": "750e8400-e29b-41d4-a716-446655440000",
"bookTitle": "Clean Code",
"authorName": "John Doe",
"date": "2024-12-26T10:30:00",
"rating": 5.0,
"content": "Excellent book!"
},
{
"id": "750e8400-e29b-41d4-a716-446655440001",
"bookTitle": "Design Patterns",
"authorName": "Jane Smith",
"date": "2024-12-25T14:20:00",
"rating": 4.5,
"content": "Very informative!"
}
]
}
}Statistics Included:
totalBook: Total number of books in librarytotalUser: Total number of users (USER role only, excludes ADMIN)totalTransaction: Total number of transactions (all statuses)totalNotifications: Total number of notificationsaverageReview: Average rating across all reviews (rounded to 2 decimals)totalReview: Total number of reviewsrecentReviews: Most recent reviews (limited bymaxparameter)
Notes:
totalUsercounts only USER role, not ADMINaverageReviewreturns 0.0 if no reviews exist- Recent reviews ordered by date (newest first)
All errors follow this structure:
{
"timestamp": "2024-12-26T10:30:00",
"status": 404,
"error": "Not Found",
"message": "Detailed error message",
"path": "/api/endpoint"
}200 OK - Request successful
201 Created - Resource created successfully
400 Bad Request - Invalid request or validation error
401 Unauthorized - Authentication failed
403 Forbidden - Access denied
404 Not Found - Resource not found
409 Conflict - Duplicate resource
500 Internal Server Error - Server error
Validation Errors (400):
{
"timestamp": "2024-12-26T10:30:00",
"status": 400,
"error": "Bad Request",
"message": "email: Invalid email format; password: Password is required; ",
"path": "/api/users/register"
}Duplicate Entry (409):
{
"timestamp": "2024-12-26T10:30:00",
"status": 409,
"error": "Conflict",
"message": "Datanya duplikat!",
"path": "/api/users/register"
}Not Found (404):
{
"timestamp": "2024-12-26T10:30:00",
"status": 404,
"error": "Not Found",
"message": "No value present",
"path": "/api/books/invalid-id"
}Server Error (500):
{
"timestamp": "2024-12-26T10:30:00",
"status": 500,
"error": "Internal Server Error",
"message": "Error details",
"path": "/api/endpoint"
}CREATE TABLE users (
id CHAR(36) PRIMARY KEY NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
name VARCHAR(255),
role ENUM('ADMIN', 'USER') NOT NULL,
phone VARCHAR(255) UNIQUE
);CREATE TABLE books (
id CHAR(36) PRIMARY KEY NOT NULL,
title VARCHAR(255) NOT NULL UNIQUE,
author VARCHAR(255) NOT NULL,
category VARCHAR(255),
year INTEGER,
description TEXT,
image VARCHAR(255),
quota INTEGER,
rack_number VARCHAR(255),
isbn VARCHAR(255) NOT NULL UNIQUE,
language VARCHAR(255),
available_copies INTEGER,
late_fee DECIMAL(10,2),
can_borrow BOOLEAN DEFAULT true,
rating DECIMAL(3,2)
);CREATE TABLE transactions (
id CHAR(36) PRIMARY KEY NOT NULL,
user_id CHAR(36) NOT NULL,
invoice_code VARCHAR(255) NOT NULL UNIQUE,
date_from DATE NOT NULL,
date_to DATE NOT NULL,
total_fee DOUBLE NOT NULL,
status ENUM('PENDING', 'APPROVED', 'DECLINED', 'OVERDUE') NOT NULL,
type ENUM('BORROW', 'RETURN') NOT NULL,
payment_method VARCHAR(255),
payment_evidence VARCHAR(255),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);CREATE TABLE transaction_items (
id CHAR(36) PRIMARY KEY NOT NULL,
transaction_id CHAR(36) NOT NULL,
book_id CHAR(36) NOT NULL,
FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE,
FOREIGN KEY (book_id) REFERENCES books(id) ON DELETE CASCADE
);CREATE TABLE reviews (
id CHAR(36) PRIMARY KEY NOT NULL,
book_id CHAR(36) NOT NULL,
author_id CHAR(36) NOT NULL,
date TIMESTAMP NOT NULL,
rating DOUBLE NOT NULL,
content TEXT NOT NULL,
FOREIGN KEY (book_id) REFERENCES books(id) ON DELETE CASCADE,
FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE
);CREATE TABLE notifications (
id CHAR(36) PRIMARY KEY NOT NULL,
user_id CHAR(36) NOT NULL,
title VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
type ENUM('INFO', 'REMINDER', 'ALERT') NOT NULL,
date TIMESTAMP NOT NULL,
`read` BOOLEAN NOT NULL DEFAULT false,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);# Production application.properties template
spring.datasource.url=jdbc:mysql://your-azure-mysql.mysql.database.azure.com:3306/digilibz?useSSL=true
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
spring.jpa.hibernate.ddl-auto=validate
server.port=80
logging.level.root=WARN
logging.level.com.digilibz=INFOProject Repository: [GitHub URL]
Issue Tracking: [Issues URL]
Version: 0.0.1-SNAPSHOT
Last Updated: December 26, 2024