Files
invoiceninja-sdk/CLAUDE.md
T
awkawbandClaude Opus 5 ff9a859d0b
CI / test (push) Canceled after 0s
Initial commit: async Rust client for the Invoice Ninja v5 API
Covers Clients, Invoices, Quotes, Credits, Payments, Products, Expenses,
Projects, Tasks, and Vendors, each with list, list_all, get, create,
update, and delete, generated by the resource_methods! macro.

Every model carries a #[serde(flatten)] extra map so fields the API
returns but the crate does not model survive a get/update round-trip
instead of being silently dropped.

Includes a Nix dev shell (Rust via rust-overlay), a GitHub Actions CI
workflow running build/test/fmt/clippy, and round-trip tests for the
extra-preservation invariant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-23 14:30:01 -04:00

3.0 KiB

CLAUDE.md

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

What this is

An async Rust client for the Invoice Ninja v5 API.

Development environment

This project uses Nix for toolchain management (Rust via rust-overlay):

nix develop

Common commands

cargo build
cargo test
cargo test <test_name>       # run a single test
cargo check
cargo clippy
cargo fmt

# Run the example (requires IN_API_TOKEN, optionally IN_BASE_URL)
IN_API_TOKEN=... cargo run --example list_clients

Tests live in tests/ (integration-style, no network access required); src/ has no #[test] modules.

Architecture

  • src/client.rs — InvoiceNinjaClient holds a reqwest::Client (with the X-Api-Token auth header baked in) and a base_url. Low-level helpers (get_list, get_one, post_one, put_one, delete_one) handle request dispatch and decode ListResponse<T> / ItemResponse<T> envelopes, mapping non-2xx responses through api_error into Error::Api.
  • Per-resource methods (list_clients, get_invoice, create_product, etc.) are generated by the resource_methods! macro at the bottom of client.rs, which expands to list/list_all/get/create/update/delete for a given REST path and model type. To add a new resource: add a model under src/models/, re-export it from src/models/mod.rs, and add one resource_methods! invocation in client.rs. Note the macro takes six method names before the path and model — adding a resource means passing all six.
  • list_* returns one page; list_all_* goes through get_all_pages, which follows page/per_page until a page returns fewer rows than requested.
  • src/models/ — one file per resource (client.rs, invoice.rs, payment.rs, product.rs, expense.rs, project.rs, task.rs, vendor.rs), plus common.rs for shared envelope/pagination types (ListParams, ListResponse, ItemResponse, Meta, Pagination). Invoice Ninja stores quotes and credits in the same table as invoices (an entity_type field distinguishes them), so Quote and Credit are type aliases for Invoice (src/models/invoice.rs) and share the /quotes, /credits, and /invoices paths via the macro.
  • Every model struct has a #[serde(flatten)] pub extra: Map<String, Value> field. This preserves any API fields not explicitly modeled, so a get followed by an update round-trips without silently dropping data. Keep this pattern when adding fields or new models.
  • src/error.rs — Error enum (thiserror) covering transport, JSON decode, API error responses (with per-field validation errors map), and client construction errors. ApiErrorBody mirrors Invoice Ninja's error JSON shape.

Coverage

Clients, Invoices, Quotes, Credits, Payments, Products, Expenses, Projects, Tasks, and Vendors, each with list, list_all, get, create, update, and delete.