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

408 lines
11 KiB
Markdown

# 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
```
---