Files
borrow-system/Docs/backend_API_docs/README.md

7.1 KiB

Borrow System Backend API

Base URL: http://localhost:8002

Authentication

Most endpoints under /api require a Bearer JWT.

  1. Login to get a token
  • POST /api/login
  • Body: { "username": string, "password": string }
  • Response 200: { "message": "Login successful", "token": string }
  • Response 401: { "message": "Invalid credentials" }

Example:

curl -s -X POST http://localhost:8002/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"password1"}'
  1. Use the token for all protected endpoints
  • Header: Authorization: Bearer <token>

The middleware authenticate verifies tokens and attaches req.user = { username, role }.

Environment:

  • SECRET_KEY: HMAC secret for JWT
  • DB_HOST, DB_USER, DB_PASSWORD, DB_NAME: MySQL connection
  • ADMIN_ID: Admin API key for /apiV2

Data model (items)

Items (as returned by endpoints) have:

  • id: number
  • item_name: string
  • can_borrow_role: number (minimum role required)
  • inSafe: 0/1 (not in locker / in locker)

See the full schema in backend/scheme.sql.


App API (JWT) — /api

All routes below require Authorization: Bearer <token> unless noted.

GET /api/items

Returns items filtered by the user role:

  • role == 0: all items
  • role > 0: items with can_borrow_role >= role

Implements: getItemsFromDatabase

Response 200:

[
  { "id": 1, "item_name": "Laptop", "can_borrow_role": 1, "inSafe": 1 },
  ...
]

Example:

curl -s http://localhost:8002/api/items \
  -H "Authorization: Bearer $TOKEN"

GET /api/loans

Returns all loans.

Implements: getLoansFromDatabase

Response 200:

[
  {
    "id": 1,
    "username": "alice",
    "loan_code": 1001,
    "start_date": "2025-08-01T09:00:00.000Z",
    "end_date": "2025-08-10T09:00:00.000Z",
    "returned_date": null,
    "created_at": "2025-08-01T09:00:00.000Z",
    "loaned_items_id": [1, 2],
    "loaned_items_name": ["Laptop", "Projector"]
  }
]

GET /api/userLoans

Returns loans for the authenticated user.

Implements: getUserLoansFromDatabase

Response 200:

  • On success: Loan[]
  • If none found: "No loans found for this user" (string)

Tip: Treat a non-array response as “no loans”.

DELETE /api/deleteLoan/:id

Deletes a loan by numeric ID.

Implements: deleteLoanFromDatabase

  • 200: { "message": "Loan deleted successfully" }
  • 500: { "message": "Failed to delete loan" }

Example:

curl -s -X DELETE http://localhost:8002/api/deleteLoan/42 \
  -H "Authorization: Bearer $TOKEN"

POST /api/borrowableItems

Returns items available in the given time range (excludes items with overlapping loans). Also enforces role filtering.

Implements: getBorrowableItemsFromDatabase

Request body:

{ "startDate": "2025-08-01T09:00:00Z", "endDate": "2025-08-02T09:00:00Z" }
  • 200: Item[]
  • 400: { "message": "startDate and endDate are required" }
  • 500: { "message": "Failed to fetch borrowable items" }

Example:

curl -s -X POST http://localhost:8002/api/borrowableItems \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startDate":"2025-08-01T09:00:00Z","endDate":"2025-08-02T09:00:00Z"}'

POST /api/createLoan

Creates a loan for the authenticated user.

Implements: createLoanInDatabase

Request body:

{
  "items": [1, 2, 3], // array of item IDs (required)
  "startDate": "2025-08-01T09:00:00Z", // required
  "endDate": "2025-08-02T09:00:00Z" // required
}

Notes:

  • IDs are coerced to numbers; invalid entries are dropped.
  • Date range must be valid and startDate < endDate.
  • Overlaps with existing loans cause 409 Conflict.
  • On success, returns the generated loanCode.

Responses:

  • 201:
{
  "message": "Loan created successfully",
  "loanId": 123,
  "loanCode": 1007
}
  • 400: { "message": "Items array is required" | "No valid item IDs provided" | "Invalid date range" | ... }
  • 409: { "message": "Items not available in the selected period" }
  • 500: { "message": "Failed to create loan" }

Example:

curl -s -X POST http://localhost:8002/api/createLoan \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"items":[1,2],"startDate":"2025-08-01T09:00:00Z","endDate":"2025-08-02T09:00:00Z"}'

Admin API — /apiV2

These endpoints are protected by a static admin key in the path. Set ADMIN_ID in environment. No JWT required.

GET /apiV2/items/:key

Returns all items (no role filtering).

Implements: getItemsFromDatabaseV2

  • 200: Item[]
  • 403: { "message": "Access denied" }

Example:

curl -s http://localhost:8002/apiV2/items/$ADMIN_ID

POST /apiV2/controlInSafe/:key/:itemId/:state

Updates inSafe state (0 or 1) for an item by ID.

Implements: changeInSafeStateV2

  • state: "0" or "1"
  • 200: { "message": "Item state updated successfully" }
  • 400: { "message": "Invalid state value" }
  • 403: { "message": "Access denied" }
  • 500: { "message": "Failed to update item state" }

Example:

curl -s -X POST http://localhost:8002/apiV2/controlInSafe/$ADMIN_ID/5/0

Error handling summary

  • 400 Bad Request: invalid payloads or missing fields
  • 401 Unauthorized: missing/invalid JWT (for /api routes)
  • 403 Forbidden: wrong admin key (for /apiV2 routes)
  • 409 Conflict: loan overlaps with selected period
  • 500 Internal Server Error: unexpected server/database errors

Running locally

With Docker Compose: docker-compose.yml

Environment required by backend:

  • DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
  • SECRET_KEY
  • ADMIN_ID

References: