Badges
CI / check (push) Successful in 1m9s
CI / docker (push) Successful in 1m34s

This commit is contained in:
Connor Johnstone
2026-03-23 17:02:11 -04:00
parent 6821427471
commit 3708829c3b
2 changed files with 64 additions and 5 deletions
+59 -5
View File
@@ -1,11 +1,57 @@
# CLAUDE.md -- Shanty Architecture Reference
# CLAUDE.md
This document is the authoritative reference for any LLM working on the Shanty codebase. Read this before making changes.
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What Is Shanty?
Shanty is a self-hosted music management application ("better Lidarr"). It searches MusicBrainz for music metadata, downloads from YouTube via yt-dlp, tags and organizes files, and serves the library over the Subsonic protocol. It is a Cargo workspace where each component is both a standalone CLI tool and a library consumed by the web app.
## Development Commands
A `justfile` provides common workflows. Run `just` to see all targets.
```sh
just check # fmt + lint + test (full pre-commit check)
just dev # build frontend + run server
just build # cargo build --workspace
just test # cargo test --workspace
just lint # cargo clippy --workspace -- -D warnings
just fmt # cargo fmt
just frontend # cd shanty-web/frontend && trunk build
just run # cargo run --bin shanty
```
**Running single crate tests:**
```sh
cargo test --package shanty-db
cargo test --package shanty-tag
```
**Running a single test by name:**
```sh
cargo test --package shanty-tag test_tag_with_match
```
**Frontend build (Yew/Trunk → WASM):**
```sh
cd shanty-web/frontend && trunk build # dev
cd shanty-web/frontend && trunk build --release # optimized
```
**Running the server with verbose logging:**
```sh
cargo run --bin shanty -- -v # info
cargo run --bin shanty -- -vv # debug
cargo run --bin shanty -- -vvv # trace
```
**MusicBrainz dump import subcommand:**
```sh
cargo run --bin shanty -- mb-import --download --data-dir /path/to/dumps
```
**Prerequisites:** Rust (stable, edition 2024), yt-dlp, ffmpeg, Python 3, ytmusicapi, Trunk. The `rust-toolchain.toml` pins stable and adds the `wasm32-unknown-unknown` target.
## Design Philosophy
1. **Modular crates.** Each crate is a library and a CLI binary. The web app imports the library side; the CLI binary is for standalone use. Crates are git submodules hosted at `ssh://connor@git.rcjohnstone.com:2222/Shanty/{name}.git`. The exceptions are `shanty-config` and `shanty-data`, which are local workspace crates (not submodules).
@@ -20,7 +66,7 @@ Shanty is a self-hosted music management application ("better Lidarr"). It searc
## Workspace Structure
All crates live in the workspace root `/home/connor/docs/projects/shanty/`.
All crates live in the workspace root.
| Crate | Purpose |
|-------|---------|
@@ -137,10 +183,18 @@ The config is loaded once at startup and held in `Arc<RwLock<AppConfig>>`. It ca
## Testing
```sh
cargo test --workspace
cargo test --workspace # all tests
cargo test --package shanty-db # single crate
```
Integration tests per crate. Mock providers exist for MusicBrainz in tests. The frontend is excluded from workspace tests (it has its own build process via Trunk).
The frontend is excluded from workspace tests (it has its own build process via Trunk).
**Test patterns used across crates:**
- **In-memory SQLite:** Integration tests create `Database::new("sqlite::memory:")` for fast, isolated DB testing. No fixtures directory -- data is inserted programmatically.
- **Mock providers:** Each crate that depends on external APIs defines its own mock trait implementations (e.g., `MockProvider` for `MetadataProvider`, `MockBackend` for `DownloadBackend`). Mocks are self-contained per crate.
- **Temp files:** `tempfile::TempDir` + `lofty` to create real MP3 files with valid ID3 tags for index/org/tag tests.
- **Integration tests:** `{crate}/tests/integration.rs` (async via `#[tokio::test]`)
- **Unit tests:** `#[cfg(test)]` modules inline in source files for pure functions (sanitization, parsing, normalization, template rendering).
## Important Constraints