Files
yellowjacket/.planning/codebase/STRUCTURE.md
T
2026-02-26 16:58:25 -05:00

378 lines
18 KiB
Markdown

# Codebase Structure
**Analysis Date:** 2026-02-26
## Directory Layout
```
yellowjacket/
├── backend/ # Go backend — all application logic
│ ├── app.go # Main app struct, lifecycle hooks, dependency wiring
│ ├── assets/ # Custom HTTP asset handler for Wails webview
│ ├── config/ # Application config (TOML persistence, event emission)
│ ├── coverart/ # Cover art extraction, thumbnail generation, HTTP serving
│ ├── database/ # SQLite database layer with sqlc-generated queries
│ │ └── sql/ # SQL source files and generated code
│ │ ├── schemas/ # CREATE TABLE DDL (embedded at build time)
│ │ ├── queries/ # sqlc query definitions
│ │ └── sqlcgen/ # Auto-generated Go code (DO NOT EDIT)
│ ├── events/ # Centralized event name constants (must match frontend)
│ ├── favorites/ # Favorites config types
│ ├── ffmpeg/ # FFmpeg binary embedding (Linux/Windows)
│ │ └── bin/
│ ├── frontendutil/ # Frontend-bound utility functions (dialogs)
│ ├── library/ # Music library scanning, querying, cover art management
│ ├── logging/ # Wails logger adapter for slog
│ ├── mediacontrols/ # OS media controls (MPRIS on Linux, stub elsewhere)
│ ├── metadata/ # Audio file metadata extraction (tags, duration, decoding)
│ ├── player/ # Audio playback engine (beep library)
│ ├── playlist/ # Playlist management, M3U8 import/export, phantom resolution
│ ├── profiling/ # Dev-only pprof server and timing utilities
│ ├── queue/ # Playback queue with shuffle/repeat/persistence
│ ├── system/ # OS-specific utilities (user dirs, disk type detection)
│ ├── theme/ # Theme config types (accent color, background shade)
│ ├── tracklist/ # Track list column config types
│ └── ui/ # UI-related backend types
├── frontend/ # TypeScript/Lit frontend
│ ├── index.html # Main HTML entry point
│ ├── index.css # Global styles
│ ├── package.json # Node dependencies (Lit, Vite, WebAwesome)
│ ├── tsconfig.json # TypeScript config with path aliases
│ ├── vite.config.mts # Vite build config with alias resolution
│ ├── dist/ # Built frontend assets (gitignored)
│ ├── src/ # Source code
│ │ ├── events.ts # Event name constants (must match backend)
│ │ ├── assets/ # Static assets (fonts, images, icons)
│ │ ├── components/ # Lit Web Components (UI)
│ │ ├── store/ # Singleton stores (backend state mirrors)
│ │ │ ├── index.ts # Barrel exports for stores
│ │ │ └── controllers/ # ReactiveControllers connecting stores to components
│ │ └── utils/ # Shared frontend utilities
│ └── wailsjs/ # Auto-generated Wails bindings (DO NOT EDIT)
│ ├── go/ # Go function bindings for TypeScript
│ └── runtime/ # Wails runtime API (events, window, etc.)
├── internal/ # Internal Go packages
│ └── dev/ # Build-tag-based dev/prod detection
├── pkg/ # Shared Go packages
│ └── templcomp/ # Shared templ component utilities
├── test_data/ # Test fixtures (audio files for testing)
│ └── music_library_test/ # Mock music library directory
├── build/ # Build artifacts
│ └── bin/ # Compiled binaries
├── scripts/ # Development scripts (profiling)
├── docs/ # Documentation
│ └── dev/ # Developer docs
├── .github/ # GitHub Actions workflows
│ └── workflows/
├── main.go # Application entry point
├── go.mod # Go module definition
├── go.sum # Go dependency checksums
├── Makefile # Build commands (dev, build, test, lint, generate)
├── wails.json # Wails project config
├── .golangci.yml # golangci-lint v2 config
├── lefthook.yml # Git hooks config
├── .releaserc.yml # Semantic release config
├── renovate.json5 # Dependency update automation
└── AGENTS.md # AI coding agent guidelines
```
## Directory Purposes
**`backend/`:**
- Purpose: All Go server-side application logic
- Contains: Domain packages, infrastructure, data access
- Key files: `app.go` (main app struct and lifecycle)
**`backend/player/`:**
- Purpose: Audio playback engine using the beep library
- Contains: Player struct, volume management, state persistence/restoration, track info emission
- Key files: `player.go` (main player logic, ~1105 lines), `volume.go` (volume type conversions)
**`backend/queue/`:**
- Purpose: Playback queue management — ordering, navigation, shuffle, repeat, persistence
- Contains: Queue struct, track management, auto-advance logic, shuffle/repeat navigation, event emission, DB persistence
- Key files: `queue.go` (main queue logic), `navigation.go` (next/previous/shuffle), `handlers.go` (playback finished), `emit.go` (event emission), `persistence.go` (DB save/restore)
**`backend/library/`:**
- Purpose: Music library scanning, metadata extraction pipeline, query interface
- Contains: Library struct, concurrent scan pipeline, cover art processing, database queries for tracks/albums/artists/genres
- Key files: `library.go` (scan pipeline), `query.go` (data access methods for frontend), `rescan.go` (full rescan with clear), `coverart.go` (cover art extraction/thumbnails), `config.go` (library config types), `metrics.go` (scan metrics)
**`backend/playlist/`:**
- Purpose: Playlist CRUD, M3U8 file management, phantom track resolution
- Contains: Playlist service, M3U8 parser/writer, track matching/scoring for phantom resolution
- Key files: `playlist.go` (main service, ~1779 lines), `m3u.go` (M3U8 parsing/writing), `match.go` (phantom track scoring), `favorites.go` (default playlist management)
**`backend/database/`:**
- Purpose: SQLite database access layer
- Contains: DB wrapper, schema management, migrations, FTS5 search
- Key files: `database.go` (connection, schema, migrations), `search.go` (FTS5 full-text search queries)
**`backend/databasekom/sql/schemas/`:**
- Purpose: SQLite CREATE TABLE statements embedded at build time
- Contains: 17 `.sql` files defining all tables
- Key tables: `audio_files`, `recordings`, `artists`, `artist_credit`, `release_groups`, `cover_art`, `genres`, `playlists`, `playlist_tracks`, `queue`, `queue_tracks`, `player_state`, `search_index` (FTS5)
**`backend/database/sql/queries/`:**
- Purpose: sqlc query definitions that generate type-safe Go code
- Contains: 13 `.sql` files with named queries
- Key files: `audio_files.sql`, `recordings.sql`, `playlists.sql`, `queue.sql`, `player_state.sql`
**`backend/database/sql/sqlcgen/`:**
- Purpose: Auto-generated Go code from sqlc (DO NOT EDIT)
- Contains: Type-safe query functions, model structs
- Regenerate: `make generate` or `go generate ./...`
**`backend/events/`:**
- Purpose: Centralized event name string constants for Go side
- Contains: Single file with const groups for playback, queue, config, playlist, library events
- Key file: `events.go`
**`backend/config/`:**
- Purpose: Application configuration management
- Contains: Config struct (TOML-backed), getter/setter methods that validate + save + emit events
- Key files: `config.go` (main config), `window.go` (window size config)
- Sub-configs: Library, Theme, Window, TrackList, Favorites — each defined in their own packages
**`backend/metadata/`:**
- Purpose: Audio file metadata extraction — tags, duration, genre parsing, decoding
- Contains: Tag extraction, custom MP3/FLAC duration parsers, audio file decoder
- Key files: `metadata.go` (tag extraction), `decoder.go` (audio format decoding), `duration.go` (duration calculation), `genre.go` (genre string parsing), `mp3duration.go`, `flacduration.go`
**`backend/coverart/`:**
- Purpose: Cover art storage, thumbnail generation, HTTP serving
- Contains: Cover art handler (HTTP), file management, sized variant generation
- Key files: `coverart.go` (path/URL resolution), `handler.go` (HTTP handler)
**`backend/assets/`:**
- Purpose: Custom HTTP asset handler wrapping Wails' default handler
- Contains: ServeMux-based routing with fallback to Wails asset handler
- Key file: `handler.go`
**`backend/mediacontrols/`:**
- Purpose: OS media control integration (MPRIS2 on Linux)
- Contains: Handler interface, Linux MPRIS implementation, no-op stub for other platforms
- Key files: `mediacontrols.go` (interface), `mpris_linux.go` (Linux), `stub.go` (fallback)
**`backend/system/`:**
- Purpose: OS-specific system utilities
- Contains: User directory paths (config/data), disk type detection
- Key files: `userdata.go` (user dir paths), `disktype_linux.go` / `disktype_other.go`
**`backend/profiling/`:**
- Purpose: Dev-only profiling (pprof server, operation timing)
- Contains: Build-tagged profiling code — dev builds start pprof on :6060, prod builds are no-ops
- Key files: `profiling.go` (dev), `profiling_prod.go` (prod no-op), `timing.go` / `timing_prod.go`
**`backend/logging/`:**
- Purpose: Wails logger adapter that routes Wails log calls to slog
- Key file: `logging.go`
**`backend/frontendutil/`:**
- Purpose: Utility Go functions bound to the frontend (file/directory dialogs)
- Key file: `frontendutil.go`
**`backend/theme/`:**
- Purpose: Theme configuration types (accent color, background shade)
- Key file: `config.go`
**`backend/tracklist/`:**
- Purpose: Track list column configuration types
- Key file: `config.go`
**`backend/favorites/`:**
- Purpose: Favorites/default playlist configuration types
- Key file: `config.go`
**`frontend/src/components/`:**
- Purpose: All Lit Web Components (custom elements)
- Contains: Each component in its own subdirectory with `.ts` file(s)
- Key components:
- `audio-player/` — Player controls, seekbar, volume control
- `track-list/` — Main track listing table with column config and search ranking
- `queue-panel/` — Queue display and management
- `sidebar/` — Navigation sidebar
- `cover-grid/` — Album cover grid with virtual scrolling
- `now-playing/` — Current track info display
- `config-page/` — Settings UI
- `playlist-view/` — Playlist display and management
- `artists-view/` — Artist listing
- `genres-view/` — Genre listing
- `search-bar/` — Search input
**`frontend/src/store/`:**
- Purpose: Singleton state stores mirroring backend state
- Contains: Store classes with event bridge, state access, actions (delegated to backend), subscription system
- Key files: `player-store.ts`, `queue-store.ts`, `library-store.ts`, `playlist-store.ts`, `theme-store.ts`, `search-store.ts`, `favorites-store.ts`, `tracklist-store.ts`
- Barrel: `index.ts` re-exports stores and types
**`frontend/src/store/controllers/`:**
- Purpose: ReactiveControllers connecting Lit components to stores
- Contains: Controller classes that subscribe on `hostConnected()` and unsubscribe on `hostDisconnected()`
- Pattern: `new PlayerController(this)` in component constructor
- Key files: `player-controller.ts`, `queue-controller.ts`, `library-controller.ts`, `playlist-controller.ts`, `theme-controller.ts`, `search-controller.ts`, `favorites-controller.ts`, `tracklist-controller.ts`
**`frontend/src/utils/`:**
- Purpose: Shared frontend utility functions and controllers
- Key files: `format.ts` (display formatting), `time.ts` (time formatting), `context-menu-controller.ts`, `drag-controller.ts`, `selection-controller.ts`, `drag-image.ts`
**`frontend/src/assets/`:**
- Purpose: Static assets (fonts, images, icons)
- Contains: Font files, SVG icons organized by category (`icons/music/`, `icons/ui/`)
**`frontend/wailsjs/`:**
- Purpose: Auto-generated Wails bindings (DO NOT EDIT)
- Contains: TypeScript wrappers for Go functions and Wails runtime API
- Key directories: `go/` (bindings for each bound Go package), `runtime/` (Wails runtime API)
- Regenerated automatically by Wails on build
**`internal/dev/`:**
- Purpose: Build-tag-based dev/prod detection
- Contains: Two files with opposite build tags
- Key files: `devbuild.go` (`//go:build dev``IsDev = true`), `nondevbuild.go` (`//go:build !dev``IsDev = false`)
**`test_data/`:**
- Purpose: Test fixtures for audio file tests
- Contains: Sample audio files in `music_library_test/` directory
- Used by: `*_test.go` files that need real audio data
## Key File Locations
**Entry Points:**
- `main.go`: Application entry point — logger setup, asset handler, app creation, `wails.Run()`
- `backend/app.go`: Main app struct `YellowJacketApp`, lifecycle hooks, dependency wiring
- `frontend/index.html`: Frontend HTML entry point loaded by Wails webview
**Configuration:**
- `wails.json`: Wails project config (name, frontend commands)
- `frontend/tsconfig.json`: TypeScript config with strict mode and path aliases
- `frontend/vite.config.mts`: Vite build config with path alias resolution
- `frontend/package.json`: Node.js dependencies and scripts
- `.golangci.yml`: golangci-lint v2 configuration
- `Makefile`: Build commands (dev, build-dev, build-prod, test, lint, generate)
- `go.mod`: Go module definition and dependencies
- `lefthook.yml`: Git hook configuration
**Core Logic:**
- `backend/player/player.go`: Audio playback engine (~1105 lines)
- `backend/queue/queue.go`: Queue management (~1169 lines)
- `backend/library/library.go`: Library scan pipeline (~1329 lines)
- `backend/playlist/playlist.go`: Playlist service (~1779 lines)
- `backend/database/database.go`: Database connection and schema management
- `backend/database/search.go`: FTS5 search implementation
- `backend/config/config.go`: Application config management
**Event Contracts:**
- `backend/events/events.go`: Go event name constants
- `frontend/src/events.ts`: TypeScript event name constants (must match Go)
**Frontend State:**
- `frontend/src/store/player-store.ts`: Player state mirror
- `frontend/src/store/queue-store.ts`: Queue state mirror with delta event handling
- `frontend/src/store/index.ts`: Barrel exports for all stores
## Naming Conventions
**Files:**
- Go: `snake_case.go` — e.g., `player.go`, `queue_tracks.go`, `cover_art.go`
- Go tests: `*_test.go` co-located with source — e.g., `player_test.go`
- TypeScript: `kebab-case.ts` — e.g., `player-store.ts`, `audio-player.ts`
- SQL schemas: `snake_case.sql` — e.g., `audio_files.sql`, `player_state.sql`
**Directories:**
- Go packages: `lowercase` single word — e.g., `player`, `queue`, `library`, `metadata`
- Multi-word Go: `lowercase` concatenated — e.g., `frontendutil`, `mediacontrols`, `coverart`
- Frontend components: `kebab-case` — e.g., `audio-player/`, `track-list/`, `queue-panel/`
- Frontend stores: flat in `store/` directory
## Where to Add New Code
**New Backend Feature/Package:**
- Create directory: `backend/{feature}/`
- Add package doc comment
- Wire into `backend/app.go` — create in `NewYellowJacketApp()`, call `SetContext()` in `OnStartup()`
- If frontend-callable: add to `FEBindings` slice in `backend/app.go`
- If emitting events: add event names to `backend/events/events.go` AND `frontend/src/events.ts`
**New Frontend Component:**
- Create directory: `frontend/src/components/{component-name}/`
- Create main file: `{component-name}.ts`
- Use `@customElement('{component-name}')` decorator
- Connect to store via controller: `private player = new PlayerController(this);`
- Use path aliases for imports: `@store/*`, `@components/*`, `@go/*`, `@utils/*`
**New Frontend Store:**
- Create file: `frontend/src/store/{name}-store.ts`
- Create matching controller: `frontend/src/store/controllers/{name}-controller.ts`
- Export from `frontend/src/store/index.ts`
- Subscribe to backend events in constructor
- Delegate actions to Go via Wails bindings
**New Database Table:**
- Add schema: `backend/database/sql/schemas/{table_name}.sql`
- Add queries: `backend/database/sql/queries/{table_name}.sql`
- Run `make generate` to regenerate `backend/database/sql/sqlcgen/`
- Never edit files in `sqlcgen/` directly
**New SQL Query:**
- Add to appropriate file in `backend/database/sql/queries/`
- Run `make generate`
- Use generated methods via `db.Queries.{MethodName}()`
**New Event:**
- Add Go constant: `backend/events/events.go`
- Add TypeScript constant: `frontend/src/events.ts` (must match exactly)
- Emit in Go: `runtime.EventsEmit(ctx, events.EventName, payload)`
- Subscribe in TypeScript store: `EventsOn(Events.EventName, handler)`
**Utilities:**
- Go shared helpers: `pkg/` for cross-package utilities
- Go internal helpers: `internal/` for project-internal utilities
- Frontend shared helpers: `frontend/src/utils/`
## Special Directories
**`frontend/wailsjs/`:**
- Purpose: Auto-generated Wails TypeScript bindings for Go functions
- Generated: Yes — by Wails build tooling
- Committed: Yes
- DO NOT EDIT — regenerated on every build
**`backend/database/sql/sqlcgen/`:**
- Purpose: Auto-generated Go code from sqlc query definitions
- Generated: Yes — by `go tool sqlc generate` via `make generate`
- Committed: Yes
- DO NOT EDIT — regenerate with `make generate`
**`frontend/dist/`:**
- Purpose: Built frontend assets (Vite output)
- Generated: Yes — by `pnpm build`
- Committed: No (gitignored)
**`build/bin/`:**
- Purpose: Compiled application binaries
- Generated: Yes — by Wails build
- Committed: No
**`*_templ.go` files:**
- Purpose: Auto-generated Go code from templ templates
- Generated: Yes — by `go tool templ generate` via `make generate`
- Committed: Yes
- DO NOT EDIT — regenerate with `make generate`
**`test_data/`:**
- Purpose: Audio test fixtures for unit tests
- Generated: No — manually curated test files
- Committed: Yes
**`internal/dev/`:**
- Purpose: Build-tag-based dev/prod detection flag
- Generated: No
- Committed: Yes
- `devbuild.go` (`//go:build dev`): `IsDev = true`
- `nondevbuild.go` (`//go:build !dev`): `IsDev = false`
---
*Structure analysis: 2026-02-26*