{"id":29193104,"url":"https://github.com/maksudulhaque2000/assignment-3-l2","last_synced_at":"2026-05-08T15:02:30.758Z","repository":{"id":302363361,"uuid":"1005901172","full_name":"maksudulhaque2000/Assignment-3-L2","owner":"maksudulhaque2000","description":"A robust Library Management API built with Node.js, Express, TypeScript, and MongoDB (Mongoose). Features CRUD for books, borrowing system with availability control, and borrowed books summary via aggregation.","archived":false,"fork":false,"pushed_at":"2025-07-02T17:59:22.000Z","size":53,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-18T05:48:32.582Z","etag":null,"topics":["backend","dotenv","eslint","expressjs","mongodb","mongoose","nodejs","nodemon","typescript"],"latest_commit_sha":null,"homepage":"https://assignment-3-l2-three.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maksudulhaque2000.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-21T03:47:33.000Z","updated_at":"2025-07-04T18:33:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"f45d0732-44e5-4e3f-a143-a955e05bf6d0","html_url":"https://github.com/maksudulhaque2000/Assignment-3-L2","commit_stats":null,"previous_names":["maksudulhaque2000/assignment-3-l2"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/maksudulhaque2000/Assignment-3-L2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maksudulhaque2000%2FAssignment-3-L2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maksudulhaque2000%2FAssignment-3-L2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maksudulhaque2000%2FAssignment-3-L2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maksudulhaque2000%2FAssignment-3-L2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maksudulhaque2000","download_url":"https://codeload.github.com/maksudulhaque2000/Assignment-3-L2/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maksudulhaque2000%2FAssignment-3-L2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273287679,"owners_count":25078575,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","dotenv","eslint","expressjs","mongodb","mongoose","nodejs","nodemon","typescript"],"created_at":"2025-07-02T02:07:34.239Z","updated_at":"2026-05-08T15:02:30.753Z","avatar_url":"https://github.com/maksudulhaque2000.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📚 Library Management API\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./src/public/server.png\" height=\"400\" width=\"800\" alt=\"Library Management API\"/\u003e\n\u003c/div\u003e\n\nA polished library management backend built with **Express.js**, **TypeScript**, and **MongoDB (Mongoose)**. The API manages books, tracks borrow transactions, enforces inventory rules, and returns consistent JSON responses for client applications or API testing tools.\n\n## Live Project\n\n- [Live Deployment](https://assignment-3-l2-three.vercel.app/)\n\n## Overview\n\nThis project is a RESTful API for a basic library management system. It supports full CRUD for books, borrowing records, filtering and pagination for book listings, and a summarized borrowed-books report. The codebase uses TypeScript, Mongoose schema validation, custom error handling, and reusable response helpers to keep the API predictable and maintainable.\n\n## Key Features\n\n- Book CRUD operations with MongoDB persistence.\n- Book listing with `genre` filtering, dynamic sorting, pagination, and result limits.\n- Borrow flow that validates book IDs, checks inventory, deducts copies, and stores borrow records.\n- Borrowed-books summary grouped by book with total borrowed quantity.\n- Automatic `available` flag management based on `copies` count.\n- Strong validation for required fields, enum values, unique ISBN, positive integer quantities, and non-negative copies.\n- Consistent success and error response structure.\n- Centralized error middleware for validation errors, duplicate keys, cast errors, and custom API errors.\n- CORS enabled for API consumption from external clients.\n\n## Tech Stack\n\n- **Runtime:** Node.js\n- **Framework:** Express.js 5\n- **Language:** TypeScript\n- **Database:** MongoDB\n- **ODM:** Mongoose\n- **Utilities:** dotenv, cors\n- **Tooling:** nodemon, ts-node, ESLint\n\n## Project Structure\n\n```bash\nsrc/\n├── app.ts\n├── config/\n│   └── db.ts\n├── controllers/\n│   ├── book.controller.ts\n│   └── borrow.controller.ts\n├── middleware/\n│   └── errorHandler.ts\n├── models/\n│   ├── book.model.ts\n│   └── borrow.model.ts\n├── routes/\n│   ├── book.routes.ts\n│   └── borrow.routes.ts\n├── utils/\n│   ├── apiError.ts\n│   └── apiResponse.ts\n└── types.ts\n```\n\n## API Flow\n\n- The server starts from `src/app.ts`.\n- Database connection is initialized through `src/config/db.ts`.\n- Book endpoints live under `/api/books`.\n- Borrow endpoints live under `/api/borrow`.\n- All unhandled routes return a structured 404 response.\n- Errors are normalized by the global error handler before being sent to the client.\n\n## Environment Variables\n\nCreate a `.env` file in the project root with the following values:\n\n```env\nMONGODB_URI=your_mongodb_connection_string\nPORT=3000\n```\n\n`MONGODB_URI` is required. If it is missing, the app exits during startup.\n\n## Installation\n\n1. Clone the repository.\n\n   ```bash\n   git clone https://github.com/maksudulhaque2000/Assignment-3-L2.git\n   cd Assignment-3-L2\n   ```\n\n2. Install dependencies.\n\n   ```bash\n   npm install\n   ```\n\n3. Configure environment variables.\n   ```bash\n   MONGODB_URI=your_mongodb_connection_string\n   PORT=3000\n   ```\n\n## Available Scripts\n\n- `npm run dev` - Start the app in development mode with `nodemon` and `ts-node`.\n- `npm run build` - Compile TypeScript to JavaScript.\n- `npm start` - Run the compiled production build from `dist/app.js`.\n- `npm run lint` - Run ESLint across the project.\n- `npm run lint:fix` - Run ESLint and automatically fix what it can.\n\n## Running the Project\n\nDevelopment:\n\n```bash\nnpm run dev\n```\n\nProduction build:\n\n```bash\nnpm run build\nnpm start\n```\n\nThe API will be available at `http://localhost:3000` by default.\n\n## Response Format\n\nSuccessful responses use the shared response shape created by `ApiResponse`:\n\n```json\n{\n  \"statusCode\": 200,\n  \"data\": {},\n  \"message\": \"Success\",\n  \"success\": true\n}\n```\n\nError responses are centralized by the error handler and follow this pattern:\n\n```json\n{\n  \"message\": \"Validation failed\",\n  \"success\": false,\n  \"error\": {}\n}\n```\n\n## Book Model\n\nEach book document includes:\n\n- `title`\n- `author`\n- `genre`\n- `isbn`\n- `description`\n- `copies`\n- `available`\n- timestamps\n\nValidation rules:\n\n- `title`, `author`, `genre`, `isbn`, and `copies` are required.\n- `genre` must be one of `FICTION`, `NON_FICTION`, `SCIENCE`, `HISTORY`, `BIOGRAPHY`, or `FANTASY`.\n- `isbn` must be unique.\n- `copies` must be a non-negative integer.\n- `available` is updated automatically from the `copies` value.\n\n## Borrow Model\n\nEach borrow document includes:\n\n- `book` reference\n- `quantity`\n- `dueDate`\n- timestamps\n\nValidation rules:\n\n- `book` is required and must reference a valid book ID.\n- `quantity` must be a positive integer.\n- `dueDate` is required.\n\n## API Endpoints\n\nBase URL:\n\n```bash\nhttp://localhost:3000/api\n```\n\n### Root Health Message\n\n- `GET /`\n- Returns a welcome message for the API.\n\n### Books\n\n#### Create a Book\n\n- `POST /books`\n\nRequest body:\n\n```json\n{\n  \"title\": \"The Theory of Everything\",\n  \"author\": \"Stephen Hawking\",\n  \"genre\": \"SCIENCE\",\n  \"isbn\": \"9780553380163\",\n  \"description\": \"An overview of cosmology and black holes.\",\n  \"copies\": 5\n}\n```\n\nSuccess response:\n\n```json\n{\n  \"statusCode\": 201,\n  \"data\": {\n    \"title\": \"The Theory of Everything\",\n    \"author\": \"Stephen Hawking\"\n  },\n  \"message\": \"Book created successfully\",\n  \"success\": true\n}\n```\n\n#### Get All Books\n\n- `GET /books`\n\nQuery options:\n\n- `filter` - filter by genre.\n- `sortBy` - sort by `title`, `author`, `genre`, `isbn`, `copies`, `createdAt`, or `updatedAt`.\n- `sort` - `asc` or `desc`.\n- `limit` - number of records per page.\n- `page` - page number.\n\nExample:\n\n```bash\nGET /books?filter=FANTASY\u0026sortBy=createdAt\u0026sort=desc\u0026limit=5\u0026page=1\n```\n\nThe response includes pagination metadata:\n\n```json\n{\n  \"statusCode\": 200,\n  \"data\": [],\n  \"message\": \"Books retrieved successfully\",\n  \"success\": true,\n  \"pagination\": {\n    \"currentPage\": 1,\n    \"itemsPerPage\": 5,\n    \"totalItems\": 0,\n    \"totalPages\": 0\n  }\n}\n```\n\n#### Get Book by ID\n\n- `GET /books/:bookId`\n\n#### Update Book\n\n- `PUT /books/:bookId`\n\n#### Delete Book\n\n- `DELETE /books/:bookId`\n\n### Borrowing\n\n#### Borrow a Book\n\n- `POST /borrow`\n\nRequest body:\n\n```json\n{\n  \"book\": \"64ab3f9e2a4b5c6d7e8f9012\",\n  \"quantity\": 2,\n  \"dueDate\": \"2025-07-18T00:00:00.000Z\"\n}\n```\n\nBehavior:\n\n- Validates the book ID.\n- Checks available copies before borrowing.\n- Deducts `copies` using the model static method.\n- Saves a borrow record only after inventory is updated.\n\n#### Borrowed Books Summary\n\n- `GET /borrow`\n\nReturns a grouped summary of borrowed books with:\n\n- book title\n- ISBN\n- total borrowed quantity\n\n## Error Handling\n\nCommon API errors are handled centrally:\n\n- `400` for validation failures, invalid IDs, and business-rule violations.\n- `404` for missing books or unknown routes.\n- `409` for duplicate key conflicts such as repeated ISBN values.\n- `500` for unexpected server-side issues.\n\n## Example Success / Error Notes\n\n- On a successful borrow request, the API stores the borrow record and decreases the corresponding book copy count.\n- If a borrow request exceeds available stock, the API returns a `400` error with the message `Not enough copies available to borrow.`\n- If a book ID is invalid, the API returns a `400` error before touching the database.\n\n## Useful Notes\n\n- CORS is enabled globally.\n- The API is ready to be used from Postman, Insomnia, or any frontend client.\n- The app connects to MongoDB during startup and exits if the database connection fails.\n\n## Contact\n\nIf you want to connect or see more work, use the links below.\n\n## Creator Links\n\n- [Portfolio](https://maksudul-haque.vercel.app/)\n- [GitHub](https://github.com/maksudulhaque2000)\n- [LinkedIn](https://www.linkedin.com/in/maksudulhaque2000/)\n- [Facebook](https://www.facebook.com/maksudulhaque2000)\n- [YouTube](https://www.youtube.com/@maksudulhaque2000)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaksudulhaque2000%2Fassignment-3-l2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaksudulhaque2000%2Fassignment-3-l2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaksudulhaque2000%2Fassignment-3-l2/lists"}