# CLAUDE.md

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

## Project Overview

**LanSpread2** is a peer-to-peer (P2P) game distribution system with a Tauri desktop application frontend. It enables users to share games over local networks using mDNS discovery and QUIC protocol for peer communication.

## Common Development Commands

### Build

```bash
# Development (opens UI, needs user interaction)
cargo tauri dev

# Debug build for very quick testing (without bundle)
cargo tauri build --debug --no-bundle

# Release build for testing (without bundling)
cargo tauri build --no-bundle

# Production (with bundling)
cargo tauri build -- --profile release-lto
```

### Build Profiles

- `release`: Default release profile with debug info, assertions enabled, overflow checks on, for testing
- `release-lto`: Optimized for distribution with LTO enabled, debug symbols stripped, smaller binary, only for production

### Code Quality

```bash
# Lint all code
cargo clippy

# Format code (nightly Rust)
cargo +nightly fmt
```

### Testing

```bash
# Run all tests
cargo test --workspace

# Run tests for a specific crate
cargo test -p lanspread-peer

# Run a specific test
cargo test -p lanspread-peer test_name

# Run tests with output
cargo test -- --nocapture
```

### Dependencies

```bash
# Update frontend dependencies (Deno)
deno outdated --update --latest
```

### Wayland Users

```bash
# Set this environment variable if running on Wayland
WEBKIT_DISABLE_DMABUF_RENDERER=1
```

## Architecture

LanSpread follows a layered, modular architecture with clear separation of concerns:

### Crate Structure

The project is organized as a Cargo workspace with 7 crates:

**Foundation Layer:**

- **lanspread-utils**: Utility macros and helpers used across all crates
- **lanspread-db**: Core data structures (`Game`, `GameFileDescription`, game metadata)

**Protocol & Communication:**

- **lanspread-proto**: P2P communication protocol definitions
  - Message types: `Request` (Ping, ListGames, GetGame, etc.), `Response`, `Message` trait
  - Serialization: JSON with `serde`

**Network Discovery & Compatibility:**

- **lanspread-mdns**: mDNS service discovery and advertisement
  - Advertises and discovers "_lanspread._udp.local." services on LAN
  - Uses `mdns-sd` crate

- **lanspread-compat**: Compatibility layer for legacy ETI game database format
  - Reads legacy `game.db` SQLite databases
  - Converts `EtiGame` structs to modern `Game` struct

**Core P2P Engine:**

- **lanspread-peer**: Central orchestration for all P2P functionality
  - Entry point: `start_peer()` in `lib.rs`
  - Communicates via unbounded channels (`PeerEvent`, `PeerCommand`)
  - Key modules:
    - `services.rs`: Background tasks (server, discovery, ping, local game monitor)
    - `handlers.rs`: Command handlers for UI requests
    - `network.rs`: QUIC connection management with length-delimited frames
    - `download.rs`: Chunked file transfer logic
    - `peer_db.rs`: Peer tracking and game availability
    - `path_validation.rs`: Security for file operations

**Application Layer:**

- **lanspread-tauri-deno-ts**: Tauri desktop application
  - Binary + Library crate for the UI layer
  - IPC commands: `request_games`, `install_game`, etc.
  - Manages `LanSpreadState` for peer controller, game DB, and downloads
  - Uses Tauri plugins: logging, shell, dialogs, persistent storage
  - Allocates MiMalloc for memory efficiency

### Data Flow

```
User (Tauri UI)
    ↓ IPC Commands (request_games, install_game)
    ↓
lanspread-tauri-deno-ts (app layer)
    ↓
lanspread-peer (P2P engine)
    ├─ lanspread-mdns (discovers peers via mDNS)
    ├─ lanspread-proto (constructs P2P messages)
    ├─ lanspread-compat (reads legacy game databases)
    └─ QUIC Network ↔ Other Peers
    ↓
lanspread-db (game data structures)
    ↓
Result → Back to UI
```

### Key Architectural Details

1. **Async/Await**: Tokio runtime throughout for non-blocking I/O
2. **Message Passing**: Unbounded channels for inter-component communication (events and commands)
3. **Protocol**: Length-delimited QUIC frames with JSON serialization
4. **Service Discovery**: Automatic mDNS announcement and discovery of peers
5. **File Streaming**: Chunked transfer with path validation for security
6. **Legacy Support**: Backwards compatibility with ETI game database format
7. **Error Handling**: Custom error types via `eyre` crate

## Development Practices

### From AGENTS.md

- Always check code with `cargo clippy` and fix any issues
- Always format with `cargo +nightly fmt` after completing changes
- Use appropriate Rust log levels when debugging:
  - `RUST_LOG=lanspread=debug` for module-specific debugging
  - `RUST_LOG=info,lanspread=debug` for general info + module debug

### Performance Considerations

- Use `release-lto` profile for final builds to enable Link-Time Optimization
- MiMalloc is used for the Tauri app to reduce memory overhead
- QUIC protocol chosen for efficient P2P communication
- Length-delimited framing reduces message parsing overhead

## Important Implementation Notes

### Logging

The codebase uses `tracing` and `log` crates. Note: There's documented uncertainty about their exact relationship (see LESSONS_LEARNED.md). The client app uses `log` crate; be consistent with whichever is used in the component you're modifying.

### Legacy Database Support

Some users may have old ETI format game databases. The `lanspread-compat` crate handles reading these. When querying games, both modern and legacy formats are considered.

### Path Validation

File transfers validate paths to prevent directory traversal attacks. All file operations use validated paths from `lanspread-peer`.

### Retry Logic

`lanspread-peer` includes retry logic for requesting games from peers. This handles transient network failures in P2P discovery.

## Known Design Decisions

**Why not Tauri + Leptos?** Leptos adds unnecessary complexity. Tauri is designed to transfer backend Rust to frontend JavaScript world, but with Leptos the frontend becomes Rust, creating a double translation. The current Tauri + Deno/TypeScript approach is cleaner.

**Why Tauri?** Simple setup, easy development with `cargo tauri dev`, easy testing and bundling with installers, small final binary (~13MB).
