174 lines
5.3 KiB
Markdown
174 lines
5.3 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Development Commands
|
|
|
|
### Building
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# Format code
|
|
go fmt ./...
|
|
|
|
# Vet for potential issues
|
|
go vet ./...
|
|
|
|
# Static analysis (if golangci-lint is installed)
|
|
golangci-lint run
|
|
```
|
|
|
|
### Docker
|
|
```bash
|
|
# 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
|
|
|
|
Shared normalization lives in `internal/normalize` (`NormalizeString`, `NormalizeArtistName`) — this is the single source of truth for string normalization, reused by both `internal/musicbrainz` and `internal/scanner`. Do NOT add local copies of normalization logic elsewhere.
|
|
|
|
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) |