CLAUDE.md 8.6 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Startup Instructions

IMPORTANT: At the start of each conversation, automatically check for open issues and milestones in the Gogs repository:

  1. Check Milestones: Fetch from https://git.mrbamm.xyz/api/v1/repos/blance/absRecommend/milestones?token=bf7d69fd1c0c918719e842c8f8aea97df30aba60

    • List all milestones with their progress (open/closed issue counts)
    • If there are active milestones, ask which milestone to focus on for feature planning
  2. Check Open Issues: Fetch from https://git.mrbamm.xyz/api/v1/repos/blance/absRecommend/issues?state=open&token=bf7d69fd1c0c918719e842c8f8aea97df30aba60

    • Group issues by milestone if they have one
    • List standalone issues separately
    • If there are open issues, list them and ask which ones to work on
  3. Working Priority:

    • For standalone issues: Work in order of tag (Error, Issue, Request) and then by age (oldest first)
    • For milestone-based work: Focus on issues within the selected milestone as a cohesive feature set
  4. When Completing Issues:

    • Add a detailed comment explaining the fix using the Gogs API
    • Close the issue
    • If all issues in a milestone are completed, mention that the milestone is complete

Project Overview

Audiobookshelf Recommendation System - A FastAPI web application that syncs with Audiobookshelf to track listening history and provide AI-powered book recommendations using Google Gemini.

Development Commands

Running the Application

# Start the development server (with auto-reload)
python main.py

# Or using uvicorn directly
./venv/bin/python main.py

The application runs on http://0.0.0.0:8000 by default (configurable via .env).

Dependency Management

# Install/update dependencies
./venv/bin/pip install -r requirements.txt

# Upgrade specific packages
./venv/bin/pip install --upgrade google-generativeai

Database

The application uses SQLite with async support via aiosqlite. Database is auto-initialized on startup.

# Database file location
./absrecommend.db

# To reset database, simply delete the file
rm absrecommend.db

Architecture

Application Structure

app/
├── main.py           # FastAPI routes and application setup
├── models.py         # SQLAlchemy ORM models (Book, ListeningSession, Recommendation)
├── database.py       # Database initialization and session management
├── config.py         # Pydantic settings (loads from .env)
├── abs_client.py     # Audiobookshelf API client
├── recommender.py    # AI recommendation engine (Gemini integration)
├── templates/        # Jinja2 HTML templates
└── static/           # CSS and JavaScript files

Key Architectural Patterns

Async-First Design: The entire application uses async/await with:

  • AsyncSession for database operations
  • httpx.AsyncClient for HTTP requests to Audiobookshelf
  • FastAPI's async route handlers

Dependency Injection: FastAPI dependencies are used for:

  • get_db() - Provides database sessions to routes
  • Configuration loaded via get_settings() with caching

Single-User Architecture (Current State):

  • Application uses a single global Audiobookshelf API token from environment
  • All data is shared (no user isolation)
  • AudiobookshelfClient and BookRecommender are initialized once at startup

Data Flow for Sync Operation:

  1. User triggers /api/sync endpoint
  2. Fetches user's mediaProgress from Audiobookshelf /api/me endpoint
  3. For each book with progress, fetches full item details
  4. Creates/updates Book records (shared across all data)
  5. Creates/updates ListeningSession records with timestamps and progress
  6. Stores started_at and finished_at from Audiobookshelf (millisecond timestamps converted to datetime)

AI Recommendation Flow:

  1. Query finished books from database (top 20 by finish date)
  2. Format reading history with title, author, genres, finish status
  3. Send to Gemini (models/gemini-2.5-flash) with structured prompt
  4. Parse JSON response into Recommendation records
  5. Store recommendations in database

Database Models

Book - Shared book metadata from Audiobookshelf

  • Primary key: id (Audiobookshelf book ID)
  • Stores metadata: title, author, narrator, description, genres (JSON), tags (JSON), duration, cover URL
  • No user association (shared across all users)

ListeningSession - User progress tracking

  • Links to Book via book_id
  • Progress tracking: progress (0.0-1.0), current_time (seconds), is_finished
  • Timestamps: started_at, finished_at, last_update
  • rating field exists but not currently populated

Recommendation - AI-generated suggestions

  • Fields: title, author, description, reason (explanation), genres (JSON)
  • dismissed flag to hide recommendations
  • Currently no user association

External API Integration

Audiobookshelf API (app/abs_client.py):

  • Authentication: Bearer token in Authorization header
  • Key endpoints used:
    • GET /api/me - User info with mediaProgress array (all listening history)
    • GET /api/items/{id} - Full book details
    • GET /api/libraries - Available libraries
  • All timestamps from API are in milliseconds since epoch

Gemini API (app/recommender.py):

  • Model: models/gemini-2.5-flash
  • SDK: google.generativeai (version >=0.8.0)
  • Generates structured JSON responses for book recommendations
  • Note: Deprecated google.generativeai package - migration to google.genai may be needed in future

Configuration

Environment variables loaded via Pydantic settings (app/config.py):

Required:

  • ABS_URL - Audiobookshelf server URL
  • ABS_API_TOKEN - Audiobookshelf API token
  • GEMINI_API_KEY - Google Gemini API key

Optional (with defaults):

  • DATABASE_URL - SQLite database path (default: sqlite:///./absrecommend.db)
  • SECRET_KEY - Application secret key (default provided but should be changed)
  • HOST - Server bind address (default: 0.0.0.0)
  • PORT - Server port (default: 8000)

Important Implementation Details

Timestamp Handling: Audiobookshelf returns timestamps in milliseconds. The sync operation converts these:

datetime.fromtimestamp(timestamp_ms / 1000)

JSON Fields: genres and tags are stored as JSON strings in the database and must be serialized/deserialized:

genres=json.dumps(metadata.get("genres", []))
# Later: json.loads(book.genres)

Book Filtering: Sync only processes items where mediaItemType == "book" (excludes podcast episodes).

Session Management: Database uses async context managers. Always use:

async with async_session() as session:
    # operations

Common Development Tasks

Adding New API Endpoints

  1. Add route handler in app/main.py
  2. Use Depends(get_db) for database access
  3. Use async/await throughout
  4. Return JSONResponse for API endpoints or HTMLResponse with templates

Modifying Database Schema

  1. Update models in app/models.py
  2. Delete existing database file: rm absrecommend.db
  3. Restart application (database auto-initializes)
  4. Note: No migration system currently in place

Updating AI Prompts

Edit app/recommender.py:

  • Modify prompt in generate_recommendations() method
  • Ensure prompt requests JSON format for parsing
  • Handle JSON parse errors with fallback extraction

Frontend Changes

Templates use Jinja2 with server-side rendering:

  • HTML: app/templates/
  • CSS: app/static/css/
  • JavaScript: app/static/js/
  • Static files served at /static/ path

Git Integration

Repository is configured with Gogs at https://git.mrbamm.xyz/blance/absRecommend

Authentication uses personal access token in remote URL.

Known Limitations

  • Single-user only: No authentication or multi-user support
  • No migration system: Schema changes require manual database reset
  • Manual sync: No automatic background syncing from Audiobookshelf
  • Basic error handling: API errors may not be gracefully handled in all cases
  • Deprecated AI SDK: Using google.generativeai which is deprecated in favor of google.genai

Future Enhancement Plan

A comprehensive plan exists at /home/blance/.claude/plans/golden-snuggling-ullman.md for adding:

  • Multi-user authentication (per-user API tokens)
  • Reading log with statistics (finish dates, listening duration, ratings)
  • User management (login, registration, settings)
  • Enhanced UI with separate reading log page

When implementing these features, follow the phased approach documented in the plan file.