# Book Reading Tracker - Product Requirements Document (PRD) **Project:** Book Reading Tracker **Author:** John (Product Manager) πŸ“‹ **Created:** 2025-12-01 **Status:** Draft v1.0 **Related Documents:** - Project Brief: `docs/brief.md` - Brainstorming Session: `docs/brainstorming-session-results.md` --- ## Goals and Background Context ### Goals - Enable book club members to track daily reading progress and meet deadlines consistently - Provide actionable pace calculations that tell users exactly how many pages to read per day - Create a frictionless mobile-first experience with <10 second logging workflow - Deliver MVP within 4-6 weeks with zero ongoing operational costs - Validate concept for single-user deployment before considering multi-user expansion - Maintain simplicity and focus - solve the deadline problem without feature bloat ### Background Context Book club participants face a recurring challenge: finishing assigned books by discussion deadlines. Missing these deadlines results in spoiler exposure and diminished participation quality. Existing solutions (Goodreads, habit trackers, spreadsheets) don't provide deadline-focused pace calculation or frictionless mobile logging. This PWA addresses the gap by combining Open Library book metadata, simple daily logging, dynamic pace calculation, and visual status indicators. Built for self-hosting on Coolify infrastructure to ensure zero ongoing costs, full privacy, and complete control. The MVP focuses ruthlessly on the core problem: helping users meet book club deadlines through clear, actionable feedback on reading pace. ### Change Log | Date | Version | Description | Author | |------|---------|-------------|--------| | 2025-12-01 | 1.0 | Initial PRD created from Project Brief | John (PM) | --- ## Requirements ### Functional **FR1:** System shall integrate with Open Library API to search books by title, author, or ISBN **FR2:** System shall display book search results with cover images, title, author, and page count **FR3:** System shall allow user to select a book from search results and add it to their reading list **FR4:** System shall require user to set a deadline date when adding a book to the reading list **FR5:** System shall display active books in a list view on the main screen **FR6:** System shall allow user to log current page number for any active book via a quick-tap workflow (tap book β†’ enter page β†’ save) **FR7:** System shall calculate required pages per day as: (Total Pages - Current Page) Γ· (Days Until Deadline) **FR8:** System shall calculate actual reading pace as a rolling 7-day average of pages read per day **FR9:** System shall display both required pace and actual pace with clear labeling **FR10:** System shall show pages remaining and days remaining for each active book **FR11:** System shall provide color-coded status indicator: - Green: Actual pace β‰₯ Required pace (on track) - Yellow: Actual pace within 10% of required pace (slightly behind) - Red: Actual pace >10% below required pace (falling behind) **FR12:** System shall display a calendar view showing dates when user logged progress **FR13:** System shall highlight current date and deadline dates on the calendar **FR14:** System shall persist all book data and reading logs in PostgreSQL database **FR15:** System shall function as a Progressive Web App (PWA) installable via "Add to Home Screen" **FR16:** System shall work offline for viewing existing data and logging entries (sync when online) **FR17:** System shall validate page number inputs (must be numeric, >0, ≀ total pages) **FR18:** System shall prevent logging page numbers that are less than previously logged page for the same book (can only move forward) **FR19:** System shall recalculate required pace automatically each day as deadline approaches **FR20:** System shall cache book metadata from Open Library to reduce API calls and improve performance ### Non Functional **NFR1:** Page load time shall be <2 seconds on 3G mobile connection **NFR2:** Log entry save operation shall complete in <1 second **NFR3:** Application shall be mobile-responsive and fully functional on screen sizes from 320px to 1920px width **NFR4:** Application shall support last 2 versions of Chrome, Safari, Firefox, and Edge browsers **NFR5:** Application shall use HTTPS for all communications (enforced by Coolify/PWA requirements) **NFR6:** Application shall sanitize all user inputs to prevent XSS attacks **NFR7:** Application shall use parameterized queries or ORM to prevent SQL injection **NFR8:** Application shall deploy as Docker containers to Coolify infrastructure **NFR9:** Database shall have automated backup mechanism via Coolify PostgreSQL management **NFR10:** Application shall respect Open Library API rate limits and implement appropriate caching/retry logic **NFR11:** Frontend bundle size shall be optimized for mobile (<500KB initial load) **NFR12:** Application shall handle Open Library API failures gracefully with user-friendly error messages **NFR13:** PWA service worker shall cache static assets and implement cache-first strategy for offline support **NFR14:** Application shall be accessible and usable with keyboard navigation for basic workflows **NFR15:** All REST API endpoints shall validate inputs and return appropriate HTTP status codes and error messages --- ## User Interface Design Goals ### Overall UX Vision The Book Reading Tracker emphasizes **simplicity, speed, and clarity** above all else. The interface is designed for daily micro-interactions (<10 seconds) on mobile devices. Visual design is minimal and text-focused, prioritizing information density and fast comprehension over decorative elements. Key principles: - **Mobile-first:** Every interaction optimized for thumb-friendly tapping - **Information hierarchy:** Most critical data (required pace, status) immediately visible - **Minimal chrome:** No unnecessary navigation, buttons, or decorative elements - **Fast feedback:** Immediate visual confirmation of actions (page logged, status updated) ### Key Interaction Paradigms **3-Tap Logging Workflow:** The core interaction is logging progress in 3 taps: 1. Tap book card from list 2. Tap/enter page number in modal 3. Tap save button **Pull-to-Refresh:** Standard mobile pattern for refreshing book list and recalculating paces **Color-Coded Status:** No need to read text - green/yellow/red instantly communicates on-track status **Calendar as Read-Only Reference:** Calendar is informational (show logged days, deadlines), not primary logging interface in MVP ### Core Screens and Views **1. Book List Screen (Home/Main)** - Primary screen showing all active books - Each book card displays: cover thumbnail, title, author, required pace, actual pace, status indicator - "Add Book" button prominently placed - Bottom navigation (if needed): Home, Calendar **2. Add Book Screen** - Search input field - Search results list with cover images - Book detail preview with deadline date picker - "Add to Reading List" button **3. Log Progress Modal** - Triggered by tapping book card - Shows book title/cover for context - Number input for current page - "Save" and "Cancel" buttons - Displays last logged page and date **4. Book Detail Screen** - Full book information (cover, title, author, total pages) - Detailed progress metrics (pages read, days elapsed, pace trend) - Calendar view for this specific book - "Log Progress" button - Edit deadline option - Remove book option **5. Calendar View Screen** - Month view with dots/indicators on logged days - Deadline dates marked distinctly - Current date highlighted - Tap date to see details (read-only in MVP) **6. Settings Screen (Minimal)** - App version - Data export (future) - Link to documentation/help ### Accessibility **WCAG AA Compliance (Target):** - Minimum color contrast ratios (4.5:1 for normal text) - Color-coded status also includes text labels (not relying on color alone) - Keyboard navigable (tab order, enter to submit) - Semantic HTML for screen readers - Touch targets minimum 44x44px ### Branding **Minimal, Functional Aesthetic:** - No specific brand identity required for MVP - Clean, modern design with focus on readability - Neutral color palette (grays, blues) with accent colors for status (green/yellow/red) - System fonts or simple web-safe font stack - Book cover images provide visual variety **Visual Style:** - Text-heavy, data-forward design - Generous white space for mobile clarity - Card-based layout for book list - Subtle shadows/borders for depth ### Target Device and Platforms **Web Responsive (Mobile-First):** - **Primary:** Mobile browsers (iOS Safari, Android Chrome) - **Secondary:** Desktop browsers for occasional access - **PWA Installation:** Supported on both mobile and desktop **Supported Platforms:** - iOS (last 2 versions of Safari) - Android (last 2 versions of Chrome) - Desktop (Chrome, Firefox, Safari, Edge - last 2 versions) --- ## Technical Assumptions ### Repository Structure **Monorepo:** The project will use a single Git repository containing both frontend and backend code, organized as follows: ``` books/ β”œβ”€β”€ frontend/ # React + Vite PWA β”‚ β”œβ”€β”€ src/ β”‚ β”‚ β”œβ”€β”€ components/ # React components β”‚ β”‚ β”œβ”€β”€ pages/ # Page components β”‚ β”‚ β”œβ”€β”€ hooks/ # Custom React hooks β”‚ β”‚ β”œβ”€β”€ services/ # API client, utilities β”‚ β”‚ β”œβ”€β”€ assets/ # Images, icons β”‚ β”‚ └── App.jsx # Root component β”‚ β”œβ”€β”€ public/ # Static assets, PWA manifest β”‚ β”œβ”€β”€ index.html β”‚ β”œβ”€β”€ vite.config.js β”‚ β”œβ”€β”€ package.json β”‚ └── Dockerfile β”œβ”€β”€ backend/ # Node.js + Express API β”‚ β”œβ”€β”€ src/ β”‚ β”‚ β”œβ”€β”€ routes/ # API route handlers β”‚ β”‚ β”œβ”€β”€ controllers/ # Business logic β”‚ β”‚ β”œβ”€β”€ services/ # External integrations (Open Library) β”‚ β”‚ β”œβ”€β”€ middleware/ # Auth, validation, error handling β”‚ β”‚ └── server.js # Express app entry β”‚ β”œβ”€β”€ prisma/ # Prisma schema and migrations β”‚ β”‚ └── schema.prisma β”‚ β”œβ”€β”€ package.json β”‚ └── Dockerfile β”œβ”€β”€ docker-compose.yml # Local development orchestration β”œβ”€β”€ .env.example # Environment variable template β”œβ”€β”€ docs/ # Project documentation └── README.md ``` **Rationale:** - Monorepo simplifies coordination between frontend and backend changes - Shared tooling and dependencies easier to manage - Single repository for deployment to Coolify - Aligns with AI-assisted development workflow (Claude Code can see full context) ### Service Architecture **Monolithic Architecture with Separate Frontend/Backend Containers:** - **Frontend Container:** React PWA served by Vite production build (static files) - **Backend Container:** Node.js + Express REST API - **Database:** PostgreSQL container (managed by Coolify) **Communication Flow:** ``` User (Browser) ↓ HTTPS Frontend (PWA) ↓ REST API calls Backend (Express) ↓ Prisma ORM PostgreSQL Database External: Open Library API (book search) ``` **Rationale:** - Simple, proven architecture for MVP scope - Easy to deploy and debug with only 3 containers - No need for microservices complexity at this scale - Aligns with "simplest thing that works" principle - Frontend and backend can be developed and deployed independently **Deployment:** - Both containers deployed to single Coolify instance - Reverse proxy (Caddy/Nginx) handles routing and SSL - Environment-based configuration (dev, production) ### Testing Requirements **Unit + Integration Testing:** **Frontend:** - **Unit Tests:** Component testing with Vitest and React Testing Library - **Coverage Target:** >70% for critical business logic (pace calculation, validation) - **Tests Required For:** - Pace calculation logic - Form validation - Date manipulation utilities - API service layer **Backend:** - **Unit Tests:** Route handlers and business logic with Jest - **Integration Tests:** API endpoints with test database - **Coverage Target:** >80% for API routes and core logic - **Tests Required For:** - All REST API endpoints (CRUD operations) - Pace calculation algorithms - Open Library API integration (mocked) - Database operations (via Prisma) **Manual Testing:** - Mobile device testing (iOS Safari, Android Chrome) - PWA installation and offline functionality - Cross-browser compatibility - Responsive design validation **No E2E Testing in MVP:** - Manual user acceptance testing sufficient for single-user MVP - E2E framework (Playwright/Cypress) can be added post-MVP if needed **Rationale:** - Balances test coverage with development velocity - Focuses testing on business-critical logic (pace calculation) - Manual testing acceptable for UI/UX validation in MVP - Automated tests provide regression safety for future development ### Additional Technical Assumptions and Requests **Frontend Technology Stack:** - **React 18+** with functional components and hooks - **Vite** for build tooling and dev server - **Tailwind CSS** for styling (utility-first, mobile-friendly) - **React Context API** for state management (no Redux/Zustand needed) - **Axios** or **Fetch API** for HTTP requests - **vite-plugin-pwa** for PWA functionality and service worker - **date-fns** for date manipulation (lightweight alternative to Moment.js) **Backend Technology Stack:** - **Node.js 20+ LTS** - **Express 4.x** for REST API - **Prisma** as ORM for PostgreSQL - **dotenv** for environment configuration - **cors** middleware for cross-origin requests - **helmet** for security headers - **express-validator** for input validation **Database:** - **PostgreSQL 15+** - **Prisma migrations** for schema management - **Connection pooling** configured in Prisma **Development Tools:** - **Git** for version control - **ESLint** for code linting - **Prettier** for code formatting - **Docker** and **Docker Compose** for local development - **Postman/Insomnia** for API testing during development **Environment Variables:** - `DATABASE_URL` - PostgreSQL connection string - `API_PORT` - Backend API port (default: 3000) - `FRONTEND_URL` - Frontend URL for CORS configuration - `NODE_ENV` - Environment (development, production) - `OPEN_LIBRARY_API_URL` - Open Library API base URL **Error Handling and Logging:** - Backend: Centralized error handling middleware - Frontend: Error boundary components for React error handling - Logging: Console logging in development, structured logging in production (Winston or Pino) **API Design Conventions:** - RESTful endpoints following standard conventions - JSON request/response bodies - HTTP status codes: 200 (success), 201 (created), 400 (bad request), 404 (not found), 500 (server error) - Consistent error response format: `{ error: "message", details: {} }` **Code Quality:** - Use ESLint + Prettier with shared configuration - Consistent naming conventions (camelCase for JS, kebab-case for files) - Component naming: PascalCase for React components - Meaningful variable and function names - Comments for complex business logic **Performance Optimization:** - Lazy loading for non-critical components - Image optimization for book covers (cached from Open Library) - API response caching where appropriate - Database query optimization (indexes on frequently queried fields) --- ## Epic List ### Epic 1: Foundation & Core Infrastructure **Goal:** Establish project structure, development environment, database schema, and basic API/frontend scaffolding with a simple health check endpoint to validate deployment pipeline. ### Epic 2: Book Search & Management **Goal:** Enable users to search for books via Open Library API and add them to their reading list with deadline dates, creating the foundation for all tracking features. ### Epic 3: Progress Logging & Pace Calculation **Goal:** Implement the core value proposition - allow users to log daily page numbers and display calculated required pace vs. actual pace with color-coded status indicators. ### Epic 4: Calendar View & Data Visualization **Goal:** Provide users with a calendar view showing logged reading activity and deadline markers, completing the basic MVP feature set. ### Epic 5: PWA Features & Production Readiness **Goal:** Add Progressive Web App capabilities (offline support, installability), finalize mobile responsiveness, and prepare application for production deployment to Coolify. --- ## Epic 1: Foundation & Core Infrastructure **Epic Goal:** Set up the complete development environment and project infrastructure including Git repository, frontend/backend scaffolding, database schema, Docker configuration, and a health check endpoint to validate the entire stack works end-to-end before building features. ### Story 1.1: Project Initialization & Repository Setup As a **developer**, I want **a properly structured monorepo with frontend and backend directories**, so that **I have a clean foundation for building the application with all necessary tooling configured**. **Acceptance Criteria:** 1. Git repository initialized with appropriate `.gitignore` for Node.js, React, and environment files 2. Directory structure matches Technical Assumptions section (frontend/, backend/, docs/) 3. README.md created with project overview, setup instructions, and tech stack documentation 4. `.env.example` file created listing all required environment variables 5. Root-level `package.json` created (if using monorepo workspace tools) or separate package.json files in frontend/ and backend/ 6. EditorConfig or Prettier config files added for consistent code formatting ### Story 1.2: Frontend Scaffolding with Vite + React As a **developer**, I want **a Vite + React application scaffold with Tailwind CSS configured**, so that **I can start building UI components with the chosen tech stack**. **Acceptance Criteria:** 1. Vite project created in `frontend/` directory using `npm create vite@latest` 2. React 18+ configured as the framework 3. Tailwind CSS installed and configured (`tailwind.config.js`, `postcss.config.js`) 4. Base styles imported in main CSS file (`@tailwind base; @tailwind components; @tailwind utilities;`) 5. Sample component renders successfully showing Tailwind styles work 6. ESLint and Prettier configured for React/JavaScript 7. Development server runs successfully on `http://localhost:5173` (or configured port) 8. `package.json` scripts include: `dev`, `build`, `preview`, `lint` ### Story 1.3: Backend Scaffolding with Node.js + Express As a **developer**, I want **a Node.js Express API scaffold with basic middleware configured**, so that **I can start building REST API endpoints**. **Acceptance Criteria:** 1. Express application created in `backend/src/server.js` 2. Required dependencies installed: `express`, `cors`, `helmet`, `dotenv`, `express-validator` 3. Middleware configured: CORS (allowing frontend origin), Helmet (security headers), JSON body parser 4. Environment configuration loaded via `dotenv` at startup 5. Server listens on port from environment variable (default: 3000) 6. Basic error handling middleware implemented (catches errors, returns JSON response) 7. Health check endpoint created: `GET /api/health` returns `{ status: "ok", timestamp: "..." }` 8. `package.json` scripts include: `dev` (nodemon for auto-reload), `start` (production) 9. ESLint configured for Node.js/Express patterns ### Story 1.4: Database Schema Definition with Prisma As a **developer**, I want **a Prisma schema defining Books and ReadingLogs tables**, so that **I have a clear data model ready for implementation**. **Acceptance Criteria:** 1. Prisma installed in `backend/` directory (`npm install prisma @prisma/client`) 2. Prisma initialized with PostgreSQL provider (`npx prisma init`) 3. `prisma/schema.prisma` file defines the following models: **Books Model:** ```prisma model Book { id Int @id @default(autoincrement()) title String @db.VarChar(500) author String? @db.VarChar(500) totalPages Int coverUrl String? @db.VarChar(1000) deadlineDate DateTime @db.Date isPrimary Boolean @default(false) status String @default("reading") @db.VarChar(50) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt readingLogs ReadingLog[] @@index([deadlineDate]) @@index([status]) } ``` **ReadingLogs Model:** ```prisma model ReadingLog { id Int @id @default(autoincrement()) bookId Int logDate DateTime @db.Date currentPage Int createdAt DateTime @default(now()) updatedAt DateTime @updatedAt book Book @relation(fields: [bookId], references: [id], onDelete: Cascade) @@unique([bookId, logDate]) @@index([bookId]) @@index([logDate]) } ``` 4. Schema includes appropriate indexes for performance (bookId, logDate, deadlineDate) 5. Relationship defined: Book has many ReadingLogs (one-to-many) 6. Unique constraint on ReadingLog ensures one entry per book per day ### Story 1.5: Database Setup & Initial Migration As a **developer**, I want **the database schema migrated to a PostgreSQL database**, so that **the application can persist data**. **Acceptance Criteria:** 1. `DATABASE_URL` environment variable configured in `.env` file 2. Prisma migration created: `npx prisma migrate dev --name init` 3. Migration successfully creates `Book` and `ReadingLog` tables in PostgreSQL 4. Prisma Client generated and can be imported in backend code 5. Database connection verified (Prisma Client can connect successfully) 6. Migration files committed to Git (`prisma/migrations/`) 7. Instructions in README.md for running migrations in new environments ### Story 1.6: Docker Configuration for Local Development As a **developer**, I want **Docker Compose configuration for running the full stack locally**, so that **I can develop and test the application in a containerized environment matching production**. **Acceptance Criteria:** 1. `Dockerfile` created in `frontend/` directory: - Multi-stage build (build stage + nginx/serve stage for production) - Development stage uses Vite dev server - Production stage serves static build files 2. `Dockerfile` created in `backend/` directory: - Node.js base image (node:20-alpine or similar) - Installs dependencies and runs Prisma generate - Exposes API port - Runs `npm start` command 3. `docker-compose.yml` created in project root defining services: - **postgres:** PostgreSQL 15+ with volume for data persistence - **backend:** Builds from backend/Dockerfile, depends on postgres, exposes API port - **frontend:** Builds from frontend/Dockerfile, exposes dev server port, depends on backend - Environment variables configured via `.env` file 4. `docker-compose up` successfully starts all three containers 5. Frontend accessible at `http://localhost:5173` (or configured port) 6. Backend API accessible at `http://localhost:3000/api/health` 7. Database accessible on PostgreSQL port with credentials from .env 8. Hot reload works for both frontend and backend in development mode 9. README.md updated with Docker setup and usage instructions ### Story 1.7: CI/CD Deployment Configuration for Coolify As a **developer**, I want **deployment configuration ready for Coolify**, so that **I can deploy the application to production infrastructure**. **Acceptance Criteria:** 1. Production `docker-compose.yml` or Coolify configuration file created 2. Environment variable template documented for Coolify deployment 3. Build and deployment process documented in `docs/deployment.md`: - How to configure Coolify project - Required environment variables - Database connection setup - SSL/HTTPS configuration (handled by Coolify) - Health check endpoints for monitoring 4. Production Dockerfiles optimized (multi-stage builds, minimal image size) 5. Database migration strategy documented (how to run migrations on deployment) 6. Backup and restore procedures documented for PostgreSQL --- ## Epic 2: Book Search & Management **Epic Goal:** Enable users to search for books using the Open Library API and add selected books to their reading list with deadline dates, providing the foundation for all progress tracking features. ### Story 2.1: Open Library API Integration Service As a **developer**, I want **a backend service that queries the Open Library API**, so that **users can search for books by title, author, or ISBN**. **Acceptance Criteria:** 1. Service module created in `backend/src/services/openLibraryService.js` 2. Function `searchBooks(query)` implemented: - Makes HTTP request to `https://openlibrary.org/search.json?q={query}` - Parses response and extracts relevant fields: title, author, first_publish_year, cover_i, number_of_pages, isbn - Returns array of book objects with normalized structure - Handles API errors gracefully (returns empty array or error object) 3. Function limits results to top 20 books for performance 4. Book cover URLs constructed using cover_i: `https://covers.openlibrary.org/b/id/{cover_i}-M.jpg` 5. Service includes error handling for network failures and invalid responses 6. Service respects rate limits (implements basic request throttling if needed) 7. Unit tests written for service (mocked HTTP responses) ### Story 2.2: Book Search API Endpoint As a **user**, I want **an API endpoint to search for books**, so that **the frontend can retrieve book search results**. **Acceptance Criteria:** 1. API endpoint created: `GET /api/books/search?q={query}` 2. Endpoint validates query parameter (required, non-empty, max length 200 characters) 3. Endpoint calls `openLibraryService.searchBooks(query)` 4. Returns JSON response with book results: ```json { "results": [ { "olid": "OL12345W", "title": "The Name of the Wind", "author": "Patrick Rothfuss", "publishYear": 2007, "coverUrl": "https://covers.openlibrary.org/b/id/123456-M.jpg", "totalPages": 662 } ] } ``` 5. Returns 400 error if query parameter is missing or invalid 6. Returns 500 error if Open Library API fails, with user-friendly error message 7. Endpoint returns 200 with empty results array if no books found 8. Caches search results for 1 hour (in-memory cache acceptable for MVP) 9. Integration test written for endpoint (mocked Open Library service) ### Story 2.3: Add Book API Endpoint As a **user**, I want **an API endpoint to add a book to my reading list**, so that **I can start tracking progress for that book**. **Acceptance Criteria:** 1. API endpoint created: `POST /api/books` 2. Endpoint accepts JSON request body: ```json { "title": "The Name of the Wind", "author": "Patrick Rothfuss", "totalPages": 662, "coverUrl": "https://covers.openlibrary.org/b/id/123456-M.jpg", "deadlineDate": "2025-03-15" } ``` 3. Endpoint validates all required fields: title, totalPages (>0), deadlineDate (valid date, not in past) 4. Author and coverUrl are optional 5. Endpoint creates new Book record in database via Prisma 6. Sets `status` to "reading" by default 7. Returns 201 status with created book object including generated ID 8. Returns 400 error if validation fails with specific error messages 9. Returns 500 error if database operation fails 10. Unit and integration tests written covering success and error cases ### Story 2.4: List Active Books API Endpoint As a **user**, I want **an API endpoint to retrieve my active books**, so that **the frontend can display my current reading list**. **Acceptance Criteria:** 1. API endpoint created: `GET /api/books` 2. Endpoint queries database for all books with `status = "reading"` 3. Returns JSON array of book objects: ```json { "books": [ { "id": 1, "title": "The Name of the Wind", "author": "Patrick Rothfuss", "totalPages": 662, "coverUrl": "https://covers.openlibrary.org/b/id/123456-M.jpg", "deadlineDate": "2025-03-15", "isPrimary": false, "status": "reading", "createdAt": "2025-12-01T10:00:00Z" } ] } ``` 4. Books ordered by deadline date (soonest first) 5. Returns 200 status with empty array if no active books 6. Returns 500 error if database query fails 7. Integration test written ### Story 2.5: Book Search UI Component As a **user**, I want **a search interface to find and select books**, so that **I can add them to my reading list**. **Acceptance Criteria:** 1. "Add Book" screen/modal component created in `frontend/src/pages/AddBook.jsx` 2. Search input field with placeholder "Search by title, author, or ISBN" 3. Search triggers API call to `/api/books/search?q={query}` on form submit or button click 4. Loading indicator displayed while search is in progress 5. Search results displayed as a list/grid with: - Book cover thumbnail (or placeholder if no cover) - Title (bold) - Author - Total pages - "Select" button 6. Clicking "Select" button navigates to book detail view with pre-filled data 7. Empty state message shown if no results found 8. Error message shown if API call fails 9. Search input debounced (300ms delay) if implementing search-as-you-type 10. Component is mobile-responsive (card layout stacks vertically on small screens) ### Story 2.6: Add Book Form UI As a **user**, I want **a form to confirm book details and set a deadline**, so that **I can add the book to my reading list with a finish date**. **Acceptance Criteria:** 1. Add book form component created (can be part of AddBook screen or separate) 2. Form displays selected book information (cover, title, author, total pages) as read-only 3. Form includes: - Deadline date picker (required) - "Add to Reading List" button - "Cancel" or "Back" button 4. Deadline date picker validates: - Date must be in the future - User-friendly date selection interface (mobile-optimized) 5. Clicking "Add to Reading List" calls `POST /api/books` with form data 6. Loading state shown while API call is in progress 7. Success: User redirected to home screen (book list) with success message 8. Error: Error message displayed below form, user can retry 9. Form validation prevents submission if deadline is invalid 10. Form is mobile-responsive and thumb-friendly ### Story 2.7: Book List Display UI As a **user**, I want **to see all my active books on the home screen**, so that **I can quickly view my reading list and select a book to log progress**. **Acceptance Criteria:** 1. Home screen component created in `frontend/src/pages/Home.jsx` 2. Component fetches active books from `GET /api/books` on mount 3. Books displayed as cards/list items showing: - Cover thumbnail (left side) - Title and author (prominent) - Total pages and deadline date - Placeholder text for pace calculation (to be implemented in Epic 3) 4. "Add Book" button prominently displayed (e.g., floating action button or top-right) 5. Empty state shown if no books (with "Add your first book" message and CTA) 6. Loading state shown while fetching books 7. Error state shown if API call fails (with retry button) 8. Tapping a book card navigates to book detail screen (or triggers log progress modal - Epic 3) 9. List ordered by deadline date (soonest first) 10. Component is mobile-responsive with smooth scrolling --- ## Epic 3: Progress Logging & Pace Calculation **Epic Goal:** Implement the core value proposition by allowing users to log their current page number daily, calculating required pace vs. actual pace, and displaying clear status indicators, enabling users to track if they're on track to meet deadlines. ### Story 3.1: Log Progress API Endpoint As a **user**, I want **an API endpoint to log my current page for a book**, so that **my reading progress is tracked in the system**. **Acceptance Criteria:** 1. API endpoint created: `POST /api/books/:bookId/logs` 2. Endpoint accepts JSON request body: ```json { "currentPage": 150, "logDate": "2025-12-01" // Optional, defaults to today } ``` 3. Endpoint validates: - `bookId` exists in database - `currentPage` is numeric, >0, and ≀ book's totalPages - `logDate` is a valid date (defaults to today if not provided) - `currentPage` is >= last logged page for this book (can't go backward) 4. Endpoint creates or updates ReadingLog record: - If log exists for this book+date, update currentPage - If no log exists, create new ReadingLog record 5. Returns 201 (created) or 200 (updated) with the created/updated log object 6. Returns 400 error if validation fails with specific error message 7. Returns 404 error if book not found 8. Returns 500 error if database operation fails 9. Unit and integration tests written covering all cases ### Story 3.2: Pace Calculation Service As a **developer**, I want **a service that calculates required pace and actual pace**, so that **the application can show users if they're on track**. **Acceptance Criteria:** 1. Service module created in `backend/src/services/paceCalculationService.js` 2. Function `calculateRequiredPace(totalPages, currentPage, deadlineDate)` implemented: - Calculates pages remaining: `totalPages - currentPage` - Calculates days remaining: `deadlineDate - today` (in days) - Returns required pages/day: `pagesRemaining / daysRemaining` - Handles edge cases: - If deadline is today or past: returns very high number or "Overdue" - If already finished (currentPage >= totalPages): returns 0 - If days remaining = 0: returns pages remaining (all today) 3. Function `calculateActualPace(bookId, days = 7)` implemented: - Queries last N days of ReadingLogs for the book - Calculates pages read per day over that period (rolling average) - Formula: `(latestPage - pageNDaysAgo) / N` - Returns actual pages/day - If insufficient data (<2 logs), returns null or 0 4. Function `calculateStatus(requiredPace, actualPace)` implemented: - Compares required vs. actual pace - Returns status: "on-track", "slightly-behind", "behind" - Logic: - `actualPace >= requiredPace`: "on-track" - `actualPace >= requiredPace * 0.9`: "slightly-behind" (within 10%) - `actualPace < requiredPace * 0.9`: "behind" 5. Service includes comprehensive unit tests with various scenarios ### Story 3.3: Get Book Progress API Endpoint As a **user**, I want **an API endpoint that returns my book progress with pace calculations**, so that **the frontend can display whether I'm on track**. **Acceptance Criteria:** 1. Endpoint created: `GET /api/books/:bookId/progress` 2. Endpoint queries book details and all reading logs for the book 3. Endpoint uses paceCalculationService to calculate: - Current page (from latest log) - Pages remaining - Days remaining - Required pages/day - Actual pace (7-day average) - Status (on-track/slightly-behind/behind) 4. Returns JSON response: ```json { "bookId": 1, "currentPage": 150, "totalPages": 662, "pagesRemaining": 512, "deadlineDate": "2025-03-15", "daysRemaining": 45, "requiredPace": 11.4, "actualPace": 12.0, "status": "on-track", "lastLoggedDate": "2025-12-01" } ``` 5. Returns 404 if book not found 6. Returns 500 if calculation or database query fails 7. Handles cases where no logs exist yet (currentPage = 0, actualPace = null) 8. Integration test written ### Story 3.4: Enhanced Book List API with Progress Data As a **user**, I want **the book list API to include progress calculations**, so that **I can see my pace status for all books at once**. **Acceptance Criteria:** 1. Modify `GET /api/books` endpoint to include progress data for each book 2. For each book, calculate and include: - currentPage (from latest log, or 0 if no logs) - requiredPace - actualPace - status - daysRemaining - pagesRemaining 3. Response structure: ```json { "books": [ { "id": 1, "title": "The Name of the Wind", "author": "Patrick Rothfuss", "totalPages": 662, "coverUrl": "...", "deadlineDate": "2025-03-15", "currentPage": 150, "pagesRemaining": 512, "daysRemaining": 45, "requiredPace": 11.4, "actualPace": 12.0, "status": "on-track" } ] } ``` 4. Calculation logic reuses paceCalculationService functions 5. Optimized query to fetch all books and their latest logs efficiently (avoid N+1 queries) 6. Returns 500 if calculation fails, with error details 7. Integration test updated to verify progress data included ### Story 3.5: Log Progress Modal UI As a **user**, I want **a quick modal to log my current page**, so that **I can update my progress in just a few taps**. **Acceptance Criteria:** 1. Modal component created in `frontend/src/components/LogProgressModal.jsx` 2. Modal triggered by tapping a book card from the home screen 3. Modal displays: - Book title and cover (for context) - "What page are you on?" prompt - Number input field (autofocused, numeric keyboard on mobile) - Last logged: "Page X on [date]" (if exists) - "Save" button (primary CTA) - "Cancel" button or close icon 4. Input validation: - Must be a number - Must be > 0 and ≀ total pages - Must be β‰₯ last logged page (show error if trying to go backward) 5. Clicking "Save" calls `POST /api/books/:bookId/logs` with currentPage 6. Loading state shown while API call is in progress 7. Success: Modal closes, home screen refreshes to show updated progress 8. Error: Error message displayed in modal, user can retry 9. Modal is mobile-optimized (large touch targets, easy to dismiss) 10. Modal accessible via keyboard (Esc to close, Enter to submit) ### Story 3.6: Progress Visualization on Book Cards As a **user**, I want **to see my pace status directly on each book card**, so that **I can quickly understand if I'm on track without opening details**. **Acceptance Criteria:** 1. Book card component updated to display progress data from API 2. Each card shows: - **Required Pace:** "Target: 11 pages/day" - **Actual Pace:** "Your pace: 12 pages/day (last 7 days)" (or "No data yet" if insufficient logs) - **Pages Remaining:** "512 pages left" - **Days Remaining:** "45 days until deadline" 3. **Color-coded status indicator** (badge or border): - 🟒 Green: "On track" (status = "on-track") - 🟑 Yellow: "Slightly behind" (status = "slightly-behind") - πŸ”΄ Red: "Behind pace" (status = "behind") 4. Status indicator includes both color AND text label (accessibility) 5. If no logs yet, show neutral state: "Start logging to track pace" 6. Component styling is mobile-responsive and readable on small screens 7. Progress data updates after logging a new entry (home screen refresh) ### Story 3.7: Book Detail Screen with Progress Details As a **user**, I want **a detailed view of a single book showing comprehensive progress information**, so that **I can dive deeper into my reading stats for that book**. **Acceptance Criteria:** 1. Book detail screen created in `frontend/src/pages/BookDetail.jsx` 2. Screen accessed by tapping on a book card (alternative to log modal, or secondary action) 3. Screen displays: - Book cover (large) - Title and author - Total pages and deadline date - **Progress Summary:** - Current page: "Page 150 of 662" - Progress bar showing % complete - Pages remaining and days remaining - **Pace Metrics:** - Required pace: "11.4 pages/day to finish on time" - Actual pace: "12.0 pages/day (last 7 days)" - Status indicator with color and text - **Last Logged:** "Last updated: Page 150 on Dec 1, 2025" 4. "Log Progress" button prominently displayed 5. "Edit Deadline" button (future story, can be placeholder) 6. "Remove Book" button (future story, can be placeholder) 7. Screen is mobile-responsive 8. Back button to return to home screen 9. Screen fetches data from `GET /api/books/:bookId/progress` --- ## Epic 4: Calendar View & Data Visualization **Epic Goal:** Provide users with a calendar view showing which days they logged reading progress and marking deadline dates, completing the core MVP feature set and enabling users to visualize their reading habits. ### Story 4.1: Get Reading Logs for Calendar API Endpoint As a **user**, I want **an API endpoint that returns all my logged days for a book**, so that **the frontend can display them on a calendar**. **Acceptance Criteria:** 1. API endpoint created: `GET /api/books/:bookId/logs` 2. Endpoint queries all ReadingLog records for the specified book 3. Returns JSON array of logs: ```json { "logs": [ { "id": 1, "logDate": "2025-12-01", "currentPage": 150 }, { "id": 2, "logDate": "2025-11-30", "currentPage": 138 } ] } ``` 4. Logs ordered by logDate descending (most recent first) 5. Returns 404 if book not found 6. Returns 200 with empty array if no logs exist 7. Returns 500 if database query fails 8. Integration test written ### Story 4.2: Calendar Component UI (Basic) As a **user**, I want **a calendar view showing the days I logged reading progress**, so that **I can visualize my reading consistency**. **Acceptance Criteria:** 1. Calendar view component created in `frontend/src/components/Calendar.jsx` 2. Component displays a month view calendar (current month by default) 3. Previous/next month navigation buttons 4. Days with logged reading progress marked with a dot or highlight 5. Current date highlighted distinctly 6. Deadline date marked with a special indicator (🎯 or colored border) 7. Component fetches logs from `GET /api/books/:bookId/logs` on mount 8. Component fetches book details (for deadline date) from `GET /api/books/:bookId` 9. Days without logs appear as normal calendar days (no indicator) 10. Calendar is mobile-responsive (readable on small screens) 11. Uses a lightweight calendar library (e.g., `react-calendar`, or custom-built if simple enough) 12. Loading state shown while fetching data 13. Error state shown if API calls fail ### Story 4.3: Calendar Screen Integration As a **user**, I want **a dedicated calendar screen accessible from navigation**, so that **I can view my reading activity over time**. **Acceptance Criteria:** 1. Calendar screen component created in `frontend/src/pages/CalendarView.jsx` 2. Screen includes: - Book selector (if multiple books exist) to choose which book's calendar to view - Calendar component showing logged days and deadline for selected book - Legend explaining visual indicators (dot = logged, highlighted = deadline, etc.) 3. Default: Shows calendar for primary book (or first book if no primary) 4. Book selector displays as dropdown or horizontal scrollable list with book covers/titles 5. Changing selected book updates calendar display 6. Screen accessible from bottom navigation or menu (if navigation exists) 7. Mobile-responsive layout 8. Back button to return to home screen ### Story 4.4: Calendar View on Book Detail Screen As a **user**, I want **to see the calendar for a specific book on its detail screen**, so that **I don't have to navigate to a separate calendar view**. **Acceptance Criteria:** 1. Book detail screen (from Story 3.7) updated to include Calendar component 2. Calendar component rendered below progress metrics section 3. Calendar automatically shows logs for the current book (no book selector needed) 4. Calendar can be collapsed/expanded to save screen space (optional, nice-to-have) 5. Calendar updates when a new log is added for the book 6. Mobile-responsive: Calendar doesn't overwhelm small screens (possibly scrollable) --- ## Epic 5: PWA Features & Production Readiness **Epic Goal:** Transform the application into a fully functional Progressive Web App with offline support, installability, and mobile optimizations, then finalize production deployment to Coolify to deliver a complete, production-ready MVP. ### Story 5.1: PWA Manifest & Service Worker Setup As a **user**, I want **the app to be installable on my mobile device**, so that **it feels like a native app and is easily accessible from my home screen**. **Acceptance Criteria:** 1. PWA manifest file created in `frontend/public/manifest.json`: - App name: "Book Reading Tracker" (or final name) - Short name: "ReadTrack" (or similar) - Description, theme color, background color - Icons for various sizes (192x192, 512x512 minimum) - `display: "standalone"` for app-like experience - `start_url: "/"` and `scope: "/"` 2. `vite-plugin-pwa` configured in `vite.config.js` 3. Service worker generated for offline caching 4. Static assets (JS, CSS, images) cached for offline access 5. API responses cached with network-first or cache-first strategy where appropriate 6. "Add to Home Screen" prompt appears on supported browsers 7. App icon and splash screen display when launched from home screen 8. Service worker updates automatically when new version deployed 9. App works offline (cached pages accessible, with graceful degradation for API calls) 10. PWA audit (Lighthouse) passes with score >80 ### Story 5.2: Offline Support & Sync Strategy As a **user**, I want **to log reading progress even when offline**, so that **I don't lose data if I don't have internet connection**. **Acceptance Criteria:** 1. Service worker caches critical app shell (HTML, CSS, JS) 2. Reading logs can be entered offline and stored in IndexedDB (or similar local storage) 3. When connection restored, queued logs sync to backend API automatically 4. UI indicates when user is offline (banner or icon) 5. UI indicates when data is being synced 6. Conflicts handled gracefully (e.g., if same book/date logged offline then online) 7. User can view previously loaded book list and progress data offline 8. Search for new books disabled offline (requires API call) 9. Offline mode tested on mobile devices (airplane mode) ### Story 5.3: Mobile Responsiveness & Touch Optimization As a **user**, I want **the app to work smoothly on my phone with touch-friendly interactions**, so that **it's easy to use on small screens**. **Acceptance Criteria:** 1. All screens tested and responsive on screen sizes: 320px, 375px, 414px, 768px, 1024px, 1920px 2. Touch targets minimum 44x44px for all interactive elements (buttons, links, inputs) 3. Form inputs use appropriate input types (`type="number"` for page numbers, `type="date"` for dates) 4. Mobile keyboards optimized (numeric keyboard for page input) 5. Scroll behavior smooth and natural on mobile (no janky scrolling) 6. No horizontal scrolling on mobile (all content fits within viewport) 7. Text readable without zooming (minimum 16px font size for body text) 8. Images and covers optimized for mobile (lazy loading, appropriate sizes) 9. Pull-to-refresh works on home screen for updating book list 10. Tested on real devices: iOS (iPhone) and Android ### Story 5.4: Performance Optimization As a **user**, I want **the app to load quickly and respond instantly**, so that **I can log my progress without waiting**. **Acceptance Criteria:** 1. Lighthouse performance score >80 on mobile, >90 on desktop 2. First Contentful Paint <1.5 seconds on 3G connection 3. Time to Interactive <3 seconds on 3G connection 4. Frontend bundle size <500KB (gzipped) 5. Images optimized (compressed, appropriate formats, lazy loaded) 6. API responses compressed (gzip enabled on backend) 7. Critical CSS inlined or loaded first 8. Non-critical JavaScript lazy loaded 9. Database queries optimized (indexes used, no N+1 queries) 10. API response times <200ms for common endpoints (GET /api/books, POST /api/books/:id/logs) ### Story 5.5: Error Handling & User Feedback As a **user**, I want **clear error messages and feedback when something goes wrong**, so that **I understand what happened and how to fix it**. **Acceptance Criteria:** 1. All API errors return user-friendly error messages (not technical stack traces) 2. Frontend displays error messages in a consistent UI pattern (toast notifications, inline errors) 3. Network errors handled gracefully ("Unable to connect. Please check your internet connection.") 4. Validation errors show specific field-level feedback ("Deadline must be in the future") 5. Loading states shown for all async operations (spinners, skeleton screens) 6. Success feedback shown after actions (e.g., "Book added!" or "Progress logged!") 7. 404 errors handled with "Not Found" page and navigation back to home 8. 500 errors handled with "Something went wrong" message and retry option 9. Empty states provide clear CTAs ("No books yet. Add your first book!") 10. Offline state clearly communicated to user ### Story 5.6: Production Deployment to Coolify As a **developer**, I want **the application deployed to Coolify production environment**, so that **it's accessible to the user via a public URL with HTTPS**. **Acceptance Criteria:** 1. Coolify project configured with: - Frontend container (serving React build via nginx or similar) - Backend container (Node.js Express API) - PostgreSQL database container 2. Environment variables configured in Coolify (DATABASE_URL, API URL, etc.) 3. Database migrations run successfully on production database 4. HTTPS enabled via Coolify (automatic SSL with Let's Encrypt) 5. Custom domain configured (if applicable) or Coolify subdomain used 6. Health check endpoints monitored (`/api/health`) 7. Application accessible via public URL 8. PWA installable from production URL 9. Database backups configured (automated via Coolify PostgreSQL management) 10. Deployment documented in `docs/deployment.md` with rollback procedure ### Story 5.7: Testing & Quality Assurance As a **developer**, I want **comprehensive testing to ensure the MVP works correctly**, so that **we can ship a reliable product**. **Acceptance Criteria:** 1. Unit tests written for: - Frontend: Pace calculation logic, form validation, utility functions - Backend: API endpoints, paceCalculationService, openLibraryService 2. Integration tests written for: - All backend API endpoints with test database - Frontend API integration (mocked backend responses) 3. Test coverage >70% for critical business logic (pace calculation, logging, validation) 4. Manual testing checklist completed: - Add book flow (search, select, set deadline, add) - Log progress flow (tap book, enter page, save) - View book list with progress metrics - View calendar with logged days - Install PWA on mobile device - Use app offline, sync when online - Responsive design on multiple screen sizes 5. Cross-browser testing completed (Chrome, Safari, Firefox on desktop; Safari iOS, Chrome Android) 6. Accessibility testing (keyboard navigation, screen reader basics) 7. Performance testing (Lighthouse audits pass thresholds) 8. Critical bugs fixed, known issues documented --- ## Checklist Results Report *(This section will be populated after running the PM checklist. For now, proceeding to Next Steps.)* **Note to Developer:** Before finalizing this PRD, run the PM checklist (`.bmad-core/checklists/pm-checklist.md`) to validate completeness, identify gaps, and ensure all requirements are testable and implementable. --- ## Next Steps ### UX Expert Prompt **UX Expert**, please review this PRD and create wireframes or design specifications for the Book Reading Tracker app. Focus on: - Mobile-first design for all screens (Book List, Add Book, Log Progress Modal, Book Detail, Calendar) - Visual hierarchy emphasizing pace metrics and status indicators - Touch-friendly interactions and input patterns - Minimal, text-forward aesthetic with clear information density - Color palette for status indicators (green/yellow/red) with accessibility considerations Refer to the **User Interface Design Goals** section for detailed requirements. Deliverables: Wireframes (low-fi or high-fi) for core screens and interaction patterns. ### Architect Prompt **Architect**, please review this PRD and create the technical architecture document for the Book Reading Tracker app. Use this PRD as input and focus on: - Detailed API endpoint specifications (request/response schemas, validation rules, error codes) - Database schema refinement (indexes, constraints, relationships) - Frontend component architecture (component tree, state management strategy, routing) - Service layer design (backend services, external API integration patterns) - Security considerations (input validation, CORS, HTTPS, data privacy) - Deployment architecture (Docker container configuration, Coolify setup, environment management) - Testing strategy (unit, integration, E2E considerations) Refer to the **Technical Assumptions** section for technology stack decisions. Deliverables: Architecture document detailing system design, API specs, component diagrams, and deployment plan. --- *PRD created using BMAD-METHODβ„’ framework* *Based on Project Brief (docs/brief.md) and Brainstorming Session (docs/brainstorming-session-results.md)*