books/docs/architecture/api-specification.md
Greg fa8acef423 Epic 1, Story 1.1: Project Initialization & Repository Setup
- Initialize Git repository with main branch
- Create comprehensive .gitignore for Node.js, React, and environment files
- Set up directory structure (frontend/, backend/, docs/)
- Create detailed README.md with project overview and setup instructions
- Add .env.example with all required environment variables
- Configure Prettier for consistent code formatting

All acceptance criteria met:
 Git repository initialized with appropriate .gitignore
 Directory structure matches Technical Assumptions
 README.md created with project overview and setup docs
 .env.example file with all required environment variables
 Prettier config files added for code formatting consistency

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 15:12:30 +01:00

11 KiB

API Specification

REST API Specification

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