- 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>
11 KiB
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