# Changelog
All notable changes to this project will be documented in this file.
## [0.5.0] - 2025-11-11
### 🧪 Added
- Introduced a **complete automated test suite** covering both database and CLI layers.
- Implemented `setup_temp_db()` utility for creating **temporary SQLite databases** in the system temp directory:
- Windows → `%TEMP%\librius_test_*.db`
- macOS / Linux → `/tmp/librius_test_*.db`
- Added **unit tests** for database insert and search operations.
- Added **integration tests** for:
- CLI commands (`--help`, `search`, etc.) using `assert_cmd` and `predicates`.
- Database schema and consistency validation.
- ISBN normalization and formatting.
- All tests now use the **real production schema** for reliable, cross-platform testing.
---
### 🔧 Changed
- Performed a **modular refactor of the CLI** (`cli.rs` → `cli/` directory):
- Split the monolithic `cli.rs` into three logical units:
- `args.rs` — defines the full command tree and global flags.
- `dispatch.rs` — routes parsed commands to their handlers.
- `mod.rs` — re-exports and integrates the CLI components.
- Improved code readability, testability, and long-term maintainability.
- Prepared CLI for future integration with the `librius_core` crate and the GUI frontend.
- Simplified the internal command dispatch logic and aligned display order for consistent help output.
---
### 🧱 Internal
- Removed obsolete in-source test modules (`#[cfg(test)]`) from production files.
- Eliminated build and Clippy warnings by conditionally compiling test-only code.
- Verified complete cross-platform compatibility (Windows, macOS, Linux).
- Established the foundation for **multi-platform CI testing** planned for `v0.5.1`.
---
## [0.4.6] - 2025-11-11
### 🔧 Changed
- **Reorganized command index** in the CLI help output for better logical grouping and readability.
Commands are now displayed in a clearer order, following a structured hierarchy (Book commands, App commands, etc.).
- **Localized help section titles (`help_heading`)** across the entire CLI, including:
- “Global options”
- “List-specific options”
- “Import-specific options”
- “Export-specific options”
- and other command-related help blocks
- Improved overall **consistency and clarity** of command descriptions and section headings in both English and Italian.
### 🧩 Internal
- Updated `display_order` values to reflect the new command hierarchy.
- Refined `cli.rs` layout for easier maintenance of localized help headings.
---
## [0.4.5] - 2025-11-11
### Added
- **🔍 New `search` command**
- Allows searching books by title, author, editor, genre, or language.
- Usage:
```bash
librius search "dune"
librius search "frank herbert" --short
```
- Supports both full (`BookFull`) and compact (`BookShort`) table views.
- Integrated with i18n for localized output messages and help text.
### Changed
- Unified search output with `print_info`, `print_ok`, and `print_warn` for consistent message style.
- Renamed `commands/search.rs` → `commands/search_book.rs` to avoid ambiguous glob re-exports.
- Refactored `search_books()` in `db/search.rs` to remove redundant closure for Clippy compliance.
---
## [0.4.1] - 2025-10-22
### Added
- **New `del` command**
- Allows deletion of books by **ID or ISBN** with hybrid detection.
- Added **interactive confirmation prompt** to prevent accidental deletions.
- Introduced **`--force`** flag to skip confirmation in automated workflows.
- Integrated with **`write_log()`** to record all deletions (forced or confirmed).
- Localized all messages and help text for English and Italian.
- Updated CLI documentation and help output to include the new command.
### Example usage
```bash
# Interactive mode
$ librius del 129
Sei sicuro di voler eliminare il libro 129? [y/N]: y
✅ Libro 129 eliminato correttamente.
# Forced mode
$ librius del 9788820382698 --force
✅ Book 9788820382698 deleted successfully.
```
### Changed
- Minor cleanup in CLI argument ordering and localized help strings.
- Improved developer workflow consistency in the tools/ directory.
### Internal
- All deletions are now logged via write_log() for audit and traceability.
- Added developer scripts in /tools for build and submodule checks.
- Updated private submodule tools_private to latest revision.
---
## [0.4.0] - 2025-10-18
### Added
- New command `add book`:
- Fetches book information automatically from the Google Books API using ISBN.
- Populates title, author, editor, year, language, genre, and summary automatically.
- Fallback to interactive mode (planned) for books not found.
- New command `edit book`:
- Allows updating any existing book record by ID or ISBN.
- Supports all editable fields (`title`, `author`, `editor`, `year`, `language`, `pages`,
`genre`, `summary`, `room`, `shelf`, `row`, `position`), excluding ID and ISBN.
- Automatically converts language codes (e.g., `"en" → "English"`) using `lang_code_to_name()`.
- Dynamically generates CLI arguments for each editable field via a centralized
`EDITABLE_FIELDS` definition in `fields.rs`.
- Grouped and ordered help output using `display_order()` and `next_help_heading()`:
- Global options appear first.
- Book-specific options are clearly grouped under titled sections.
- Field updates now display **localized detailed messages**:
- e.g. `✅ Field "year" updated successfully (2018 → 2020).`
- Shows both the previous and new values for each modified field.
- Final update summary message supports **language-aware pluralization**:
- English: `"✅ Book 9788820382698 successfully updated (2 fields modified)."`
- Italian: `"✅ Libro 9788820382698 aggiornato correttamente (2 campi modificati)."`
- Integrated dynamic i18n support for all CLI help messages (`add`, `edit`, `book`, `isbn`).
- Added automatic language name resolution (e.g., `"it"` → `"Italian"`).
- New utility module `utils/lang.rs` for ISO 639-1 to language name conversion.
- **New utility module `utils/isbn.rs`:**
- Introduced the `normalize_isbn()` helper for validation and bidirectional formatting.
- Supports both ISBN-10 and ISBN-13 with hyphenation handling.
- Returns localized error messages for invalid, undefined, or malformed ISBNs.
- Includes comprehensive unit tests and doctests.
- Localized console messages for book lookup, edition, and insertion results.
### Changed
- Modularized command structure: added `add.rs`, `add_book.rs`, and `edit_book.rs` under `src/commands/`.
- Unified language handling logic between `add` and `edit` commands.
- Improved error handling for Google Books API responses and JSON decoding.
- Replaced manual `impl Default` blocks with idiomatic `#[derive(Default)]`.
- Enhanced ISBN display formatting in the `list` command using `normalize_isbn()` for readable hyphenated output.
- Refactored CLI (`cli.rs`) with ordered, grouped, and localized help output for all commands.
- Localized final book update message with plural-sensitive translation keys:
- `"edit.book.updated.one"` and `"edit.book.updated.many"` in `en.json` / `it.json`.
### Fixed
- Deserialization issues with Google Books API fields (`volumeInfo`, `publishedDate`, `pageCount`).
- Empty fields on insertion caused by incorrect field mapping.
- Prevented duplicate ISBN insertion with user-friendly message (`"Book already present in your library"`).
### Example usage
```bash
# ➕ Add a new book automatically using its ISBN
$ librius add book --isbn 9788820382698
🔍 Searching for book with ISBN: 9788820382698
📘 Found: “La lingua dell'antico Egitto” — Emanuele M. Ciampini (2018)
✅ Book “La lingua dell'antico Egitto” successfully added to your library.
# 📚 List all books (compact view)
$ librius list --short
📚 Your Library
┌─────┬──────────────────────────────┬──────────────────────┬──────────────────────────────────────────────────────┬──────┬───────────────────┐
│ ID │ Title │ Author │ Editor │ Year │ ISBN │
├─────┼──────────────────────────────┼──────────────────────┼──────────────────────────────────────────────────────┼──────┼───────────────────┤
│ 91 │ The Hobbit │ J.R.R. Tolkien │ Allen & Unwin │ 1937 │ 978-0-345-33968-3 │
│ 92 │ Foundation │ Isaac Asimov │ Gnome Press │ 1951 │ 978-0-553-80371-0 │
│128 │ La lingua dell'antico Egitto │ Emanuele M. Ciampini │ Lingue antiche del Vicino Oriente e del Mediterraneo │ 2018 │ 978-88-203-8269-8 │
└─────┴──────────────────────────────┴──────────────────────┴──────────────────────────────────────────────────────┴──────┴───────────────────┘
# ✏️ Edit an existing record (by ISBN or ID)
$ librius edit book 9788820382698 --year 2020
📝 Updating book with ISBN 9788820382698...
✅ Field “year” updated successfully (2018 → 2020)
# 🌍 Update language using ISO code (automatically converted)
$ librius edit book 9788820382698 --lang_book en
📝 Updating book language...
✅ Field “language” updated successfully (“Italian” → “English”)
# 📖 Display detailed information
$ librius list --id 128 --details
📘 Book Details (ID 128)
────────────────────────────────────────────────────────────────────────────
Title: La lingua dell'antico Egitto
Author: Emanuele M. Ciampini
Editor: Lingue antiche del Vicino Oriente e del Mediterraneo
Year: 2020
Language: English
Genre: Linguistics
Pages: 432
Room: B
Shelf: 4
Row: 2
Position: 5
ISBN: 978-88-203-8269-8
────────────────────────────────────────────────────────────────────────────
```
---
## [0.3.5] - 2025-10-17
### Added
- Introduced official **Librius icon and branding assets**
- Added `librius.svg`, `librius.png`, and `librius.ico` in `res/`
- Included build integration for Windows executables
- Prepared cross-platform structure for future GUI integration
### Changed
- Updated documentation and README with new logo and asset references
---
## [0.3.0] - 2025-10-16
### Added
- Introduced the `tabled` crate (`v0.20.0`) for tabular output.
- New `--short` flag for `librius list` showing only key columns (ID, Title, Author, Editor, Year).
- New utility `build_table()` in `utils/table.rs` to render tables with consistent style and alignment.
- CLI option `--delimiter` / `-d` for `import` command.
Allows specifying a custom CSV field separator (default: `,`).
### Changed
- Refactored `list` command to use `BookFull` and `BookShort` wrappers implementing `Tabled`.
- Standardized module structure across the project:
- Each main directory (`commands`, `db`, `config`, `i18n`, `models`, `utils`) now includes a `mod.rs`.
- Unified import/export logic in `lib.rs` for cleaner module access.
- Improved code readability, organization, and adherence to Rust idioms.
### Refactored
- Extracted duplicated import logic into reusable helper functions:
- `utils::open_import_file()` now handles file opening with localized error reporting.
- `utils::handle_import_result()` manages database insert results and counters.
- Unified behavior between `handle_import_csv()` and `handle_import_json()`.
- Simplified error handling and improved localization consistency across import operations.
- Reduced code duplication and improved maintainability throughout the import module.
### Fixed
- **CSV/JSON import deserialization error**:
The `id` field in the `Book` struct is now optional (`Option<i32>`),
preventing missing-field errors during import when the ID column is not present.
### Removed
- Legacy manual `println!` formatting for book listings.
---
## [0.2.5] - 2025-10-15
### Added
- **Backup command** (`librius backup`)
- Creates plain `.sqlite` backups in the `backups/` directory
- Optional `--compress` flag for compressed backups
- `.zip` format on Windows
- `.tar.gz` format on macOS and Linux
- Localized help and messages via i18n (English and Italian)
- Timestamp-based file naming for safe sequential backups
- Fixed backup compression error on macOS/Linux (`paths in archives must be relative`).
- **Export command** (`librius export`)
- Added support for exporting library data in multiple formats:
- `--csv` (default): plain text export with semicolon delimiter
- `--json`: structured JSON array output
- `--xlsx`: formatted Excel file using umya-spreadsheet
- Localized CLI help and status messages (English/Italian)
- Automatic export directory and timestamped filenames
- Uses `dirs` crate for cross-platform export path handling
- **Import command** (`librius import`)
- Supports importing book data from external sources
- Available formats:
- `--csv` (default): semicolon-delimited CSV
- `--json`: JSON array of objects
- Unified parsing via `serde` and shared `BookRecord` struct
- Duplicate detection through unique index on `isbn`
- Uses `INSERT OR IGNORE` for idempotent imports (no duplication)
- Verbose mode logs skipped records (e.g., “Skipped duplicate ISBN: …”)
- Non-blocking import completion logging
### Database
- Added migration `PATCH_004_ISBN_INDEX`:
- Creates unique index on `books.isbn` to prevent duplicates
- Automatically applied during startup migrations
### Technical
- Added dependency: `csv = "1.3"` for CSV import with serde
- Unified SQL insert logic via `insert_book_record()` helper
- Improved transaction safety and i18n message consistency
---
## [0.2.4] - 2025-10-15
### Added
- Full internationalization (i18n) for CLI help, subcommands, and arguments.
- Embedded JSON language files (`en.json`, `it.json`) — no external dependencies required.
- Dynamic language selection via `--lang <code>` or the `language` key in `librius.conf` (YAML).
### Fixed
- Resolved duplicated `--help` and `--version` flag conflicts in Clap.
- Restored proper `--help` propagation for subcommands (`list`, `config`).
- Ensured fallback to English if an unknown language code is provided.
### Changed
- Pre-language bootstrap messages (e.g., “Load configuration...”) remain in English for clarity.
- Improved initialization order: configuration and DB migrations now run after language setup.
### Notes
- Default language remains English unless overridden by `--lang` or the `language` field in `librius.conf` (YAML).
- This version finalizes the transition to a fully localized CLI core.
---
## [v0.2.3] - 2025-10-14
### Added
- **Multilanguage support (i18n)**:
- Added `i18n` module with `load_language()` and `tr()` functions.
- Introduced translation files under `src/i18n/locales/` (`en.json`, `it.json`).
- Added `src/i18n/locales/README.md` with key naming conventions.
- CLI option `--lang` (or `-l`) allows overriding the language from configuration.
- Config file can define a `language:` field for persistent preference.
- Added `tr_with()` utility for runtime placeholder substitution (e.g., `{path}`, `{title}`).
- **Fallback system**: if a translation key is missing or the language file is unavailable, English (`en.json`) is used
automatically.
- **Python helper script** (`scripts/extract_translations.py`):
- Scans Rust source files for user-facing strings.
- Updates `en.json` with any missing entries without overwriting existing ones.
### Changed
- All user-facing messages (`print_info`, `print_ok`, `print_err`, `println!`, etc.) are now translatable.
- Main startup sequence (`main.rs`) loads the selected language before configuration and database initialization.
### Improved
- Added helper in `config.rs` to read language preference directly from `librius.conf`.
- Enhanced verbosity filtering to respect localized messages.
- Clearer structure for future locale additions (fr, es, de, ...).
---
## [v0.2.2] - 2025-10-14
### Added
- **Structured database migration system**
- Introduced `MigrationResult` enum replacing the previous boolean return value.
- `run_migrations()` now returns explicit results (`Applied([...])` or `None`).
- Each applied patch is now logged in the database with detailed information.
- **Patch safety improvements**
- `PATCH_002` now checks for the existence of columns (`language`, `pages`, `genre`, `summary`) before adding them.
- Prevents duplicate column errors on repeated runs.
- **Enhanced migration logging**
- Migrations now record results under `DB_MIGRATION_OK`, `DB_MIGRATION_FAIL`, and `MIGRATIONS_COMPLETED` events in
the `log` table.
- Clear distinction between actual migrations and up-to-date states.
### Changed
- Refactored `run_migrations()` logic for clarity and maintainability.
- Updated database initialization flow (`start_db()`) to react dynamically to migration results.
- Improved internal output messages for migrations and startup consistency.
### Fixed
- Ensured safe re-execution of migration patches on existing databases.
- Removed redundant success messages when no migrations were needed.
- Unified patch logging behavior across all modules.
---
## [v0.2.1] - 2025-10-13
### Added
- **Database migrations**: introduced `db/migrate.rs` with incremental patch system and automatic execution at startup.
- **Configuration migrations**: added `config/migrate.rs` to automatically upgrade YAML configuration files.
- **Logging system**: new `utils::write_log()` function records database and migration events into the `log` table.
- **Verbose mode**: added global `--verbose` flag for diagnostic and debug output.
- Normal mode: silent operation, only command results shown.
- Verbose mode: shows configuration loading, database opening, and migration messages.
- **`db::start_db()`**: unified entry point that handles opening, creating, and migrating the database automatically.
- **Timestamp utility**: new `utils::now_str()` returns ISO 8601 formatted timestamps (`%+`).
### Changed
- Initialization messages are now hidden in normal mode.
- `main.rs` simplified: initialization logic moved into `db::start_db()`.
- `print_info()` and `print_ok()` now depend on verbose mode.
### Fixed
- Prevented redundant database initialization messages on repeated launches.
- Ensured migrations and configuration updates are idempotent and silent if up-to-date.
---
## [v0.2.0] - 2025-10-13
- feat(cli): add `config` command with `--print`, `--init`, `--edit`, and `--editor` options
- fix(windows): correctly handle editors with spaces in their path using `Path::new(&editor_to_use)`
- refactor(cli): move command and subcommand definitions into dedicated `cli.rs` module
- feat(utils): introduce `utils.rs` module with standard CLI icons and colored output helpers
- docs(readme): update structure and configuration examples
- style: minor formatting and consistency improvements across CLI output
---
## [v0.1.1] - 2025-10-12
- feat(models): add location fields to `Book` and `books` table schema (room, shelf, row, position)
## [v0.1.0] - 2025-10-12
- docs: add crate, module and item-level documentation for docs.rs
- feat(models): update `Book` struct to match `books` table schema (editor, language, pages, genre, summary, added_at)
- feat(models): change `added_at` type to `chrono::DateTime<Utc>` and enable `chrono` `serde` feature in `cargo.toml`
- feat(cli): make `list` handler return `Result` and handle errors in `main`
- feat(list): parse `added_at` from DB (RFC3339 / SQLite formats) and display `added_at` in the list as `YYYY-MM-DD`
- feat(crate): add `src/lib.rs` to expose crate API and improve docs generation on docs.rs
- docs: add docs.rs badge and local documentation instructions to `README.md`
- style: run `rustfmt` and fix Clippy warnings (code style and minor refactors)