Files
NaviWatcher/CLAUDE.md
Vladimir Zagainov 0065057514 feat: add Navidrome client with Subsonic API sync
Add the Navidrome client module that connects to a Navidrome server via
the Subsonic API, fetches artist and album data, and syncs it into the
local SQLite database.

- Add go-subsonic dependency for Subsonic API communication
- Create internal/navidrome/client.go with NavidromeClient wrapper
  - NewClient constructor with token-based auth
  - Ping health check with HTTP status validation
  - GetArtists fetches all artists via getArtists endpoint
  - GetArtistAlbums fetches albums per artist via getArtist endpoint
- Create internal/navidrome/sync.go with sync orchestration
  - SyncArtists upserts artists into artist_settings table
  - SyncAlbums fetches and stores albums for monitored artists
- Add local_albums table (migration 003) with FK to artist_settings
- Add LocalAlbum CRUD operations in internal/database/local_albums.go
- Full test coverage: 19 tests across client and sync packages
- All tests pass, go vet and go fmt clean
2026-05-21 09:45:27 +03:00

5.0 KiB

CLAUDE.md

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

Development Commands

Building

# Build the application
go build -o naviwatcher

# Build with race detector
go build -race -o naviwatcher

# Cross-platform build examples
GOOS=linux GOARCH=amd64 go build -o naviwatcher-linux
GOOS=darwin GOARCH=amd64 go build -o naviwatcher-mac
GOOS=windows GOARCH=amd64 go build -o naviwatcher.exe

Running

# Run the application
./naviwatcher

# Run with specific config file
./naviwatcher -config=/path/to/config.yaml

# Run in development mode (if implemented)
go run main.go

Testing

# Run all tests
go test ./...

# Run tests with coverage
go test ./... -cover

# Run a specific test package
go test ./internal/scanner

# Run tests verbose
go test ./... -v

Dependency Management

# Add a new dependency
go get github.com/example/package@v1.2.3

# Update dependencies
go get -u ./...

# Tidy up dependencies
go mod tidy

# Vendor dependencies (if needed)
go mod vendor

Linting and Formatting

# Format code
go fmt ./...

# Vet for potential issues
go vet ./...

# Static analysis (if golangci-lint is installed)
golangci-lint run

Docker

# Build Docker image
docker build -t naviwatcher .

# Run with docker compose
docker compose up

# Run in background
docker compose up -d

# View logs
docker compose logs -f

Code Architecture

Based on the specification (docs/Specification.md), the application follows a modular architecture:

Core Modules

  1. Navidrome Client (internal/navidrome/ or similar)

    • Handles Subsonic API communication
    • Fetches artist and album data from Navidrome instance
    • Implements authentication and error handling
  2. MusicBrainz Provider (internal/musicbrainz/ or similar)

    • Interfaces with MusicBrainz API
    • Implements rate limiting (1 request/second)
    • Manages caching of artist discographies (24-hour TTL)
    • Works with Release Group (RG) entities to minimize duplicates
  3. Scanner Engine (internal/scanner/ or similar)

    • Normalizes string comparisons for fuzzy matching
    • Implements the comparison algorithm (0.85 similarity threshold)
    • Handles removal of special characters, years, and bracketed keywords
    • Compares local albums vs. external discographies
  4. Database Layer (internal/database/ or similar)

    • SQLite 3 integration via github.com/mattn/go-sqlite3
    • Subsonic API client via github.com/delucks/go-subsonic
    • Manages schema migrations
    • Handles tables:
      • artist_settings: Artist monitoring configuration
      • local_albums: Navidrome albums synced via Subsonic API (id, artist_id, title)
      • external_releases: Cached MusicBrainz data
      • notifications_sent: Sent notification tracking
  5. Notifier (internal/notifier/ or similar)

    • Telegram bot integration
    • Scheduled task execution (cron-based)
    • Batch notification sending
    • Message formatting with Web UI links
  6. Web UI (internal/web/ or similar)

    • Go standard library net/http + html/template
    • Embedded templates using //go:embed
    • Basic authentication protection
    • Dashboard for viewing missing albums
    • Artist detail views with ignore functionality
    • Archive view for previously ignored releases

Key Technical Requirements

  • Concurrency: Separate goroutines for external API calls to keep web UI responsive
  • Rate Limiting: Strict adherence to MusicBrainz 1 request/second limit
  • Graceful Shutdown: Proper SIGTERM handling to close database connections
  • Configuration: YAML-based config (config.yaml) with environment-specific overrides
  • Static Assets: HTML templates embedded via //go:embed for single-binary deployment
  • Data Modeling: Focus on Release Group entities rather than specific releases

Common Development Patterns

  • Use context.Context for cancellation and timeouts
  • Implement proper error handling with logging
  • Follow Go idioms and conventions
  • Write table-driven tests for complex logic
  • Use dependency injection for testability
  • Apply the specified fuzzy matching algorithm consistently

Configuration Reference

See docs/Specification.md Section 7 for full config.yaml structure including:

  • Server settings (host, port, basic auth)
  • Navidrome connection details
  • MusicBrainz API configuration
  • Telegram notification settings
  • Scanner parameters (fuzzy threshold, filters)

Database Schema

See docs/Specification.md Section 5 for complete SQLite schema including:

  • artist_settings table columns and defaults
  • external_releases table structure
  • notifications_sent table for tracking

Getting Started

  1. Copy config.yaml.example to config.yaml and fill in your values
  2. Ensure Navidrome instance is running and accessible
  3. Set up Telegram bot and obtain token/chat ID
  4. Initialize database: ./naviwatcher (will create tables on first run)
  5. Start the service: ./naviwatcher
  6. Access Web UI at http://localhost:8080 (or configured host/port)