# API Specification ## REST API Specification ```yaml openapi: 3.0.0 info: title: Book Reading Tracker API version: 1.0.0 description: REST API for tracking book reading progress and calculating reading pace to meet deadlines servers: - url: http://localhost:3000/api description: Local development server - url: https://books.yourdomain.com/api description: Production server (Coolify deployment) paths: /health: get: summary: Health check endpoint description: Returns API status and timestamp for monitoring responses: '200': description: API is healthy content: application/json: schema: type: object properties: status: type: string example: "ok" timestamp: type: string format: date-time /books/search: get: summary: Search for books description: Search Open Library API for books by title, author, or ISBN parameters: - name: q in: query required: true schema: type: string maxLength: 200 description: Search query (title, author, or ISBN) responses: '200': description: Search results content: application/json: schema: type: object properties: results: type: array items: type: object properties: olid: type: string title: type: string author: type: string publishYear: type: integer coverUrl: type: string totalPages: type: integer '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/ServerError' /books: get: summary: Get all active books description: Retrieve all books with status='reading' including progress calculations responses: '200': description: List of active books with progress content: application/json: schema: type: object properties: books: type: array items: allOf: - $ref: '#/components/schemas/Book' - type: object properties: currentPage: type: integer pagesRemaining: type: integer daysRemaining: type: integer requiredPace: type: number actualPace: type: number nullable: true status: type: string enum: [on-track, slightly-behind, behind] '500': $ref: '#/components/responses/ServerError' post: summary: Add a new book description: Add a book to the user's reading list with a deadline requestBody: required: true content: application/json: schema: type: object required: - title - totalPages - deadlineDate properties: title: type: string maxLength: 500 author: type: string maxLength: 500 nullable: true totalPages: type: integer minimum: 1 coverUrl: type: string maxLength: 1000 nullable: true deadlineDate: type: string format: date responses: '201': description: Book created successfully content: application/json: schema: $ref: '#/components/schemas/Book' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/ServerError' /books/{bookId}: get: summary: Get book by ID description: Retrieve a specific book with full details parameters: - $ref: '#/components/parameters/BookId' responses: '200': description: Book details content: application/json: schema: $ref: '#/components/schemas/Book' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' delete: summary: Delete a book description: Remove a book and all associated reading logs parameters: - $ref: '#/components/parameters/BookId' responses: '204': description: Book deleted successfully '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' /books/{bookId}/progress: get: summary: Get book progress description: Calculate and return reading progress with pace metrics parameters: - $ref: '#/components/parameters/BookId' responses: '200': description: Progress calculations content: application/json: schema: $ref: '#/components/schemas/ProgressCalculation' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' /books/{bookId}/logs: get: summary: Get reading logs for a book description: Retrieve all reading logs for a specific book parameters: - $ref: '#/components/parameters/BookId' responses: '200': description: Reading logs content: application/json: schema: type: object properties: logs: type: array items: $ref: '#/components/schemas/ReadingLog' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' post: summary: Log reading progress description: Create or update a reading log entry for a specific date parameters: - $ref: '#/components/parameters/BookId' requestBody: required: true content: application/json: schema: type: object required: - currentPage properties: currentPage: type: integer minimum: 1 logDate: type: string format: date description: Date of the log (defaults to today if not provided) responses: '201': description: Log created successfully content: application/json: schema: $ref: '#/components/schemas/ReadingLog' '200': description: Log updated successfully (if log already existed for this date) content: application/json: schema: $ref: '#/components/schemas/ReadingLog' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' components: schemas: Book: type: object properties: id: type: integer title: type: string author: type: string nullable: true totalPages: type: integer coverUrl: type: string nullable: true deadlineDate: type: string format: date isPrimary: type: boolean status: type: string enum: [reading, finished, paused] createdAt: type: string format: date-time updatedAt: type: string format: date-time ReadingLog: type: object properties: id: type: integer bookId: type: integer logDate: type: string format: date currentPage: type: integer createdAt: type: string format: date-time updatedAt: type: string format: date-time ProgressCalculation: type: object properties: bookId: type: integer currentPage: type: integer totalPages: type: integer pagesRemaining: type: integer deadlineDate: type: string format: date daysRemaining: type: integer requiredPace: type: number format: float actualPace: type: number format: float nullable: true status: type: string enum: [on-track, slightly-behind, behind] lastLoggedDate: type: string format: date nullable: true Error: type: object properties: error: type: string description: Error message details: type: object description: Additional error details nullable: true parameters: BookId: name: bookId in: path required: true schema: type: integer description: Unique book identifier responses: BadRequest: description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' example: error: "Validation failed" details: field: "deadlineDate" message: "Deadline must be in the future" NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' example: error: "Book not found" ServerError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' example: error: "Internal server error" details: null ``` ---