# device-inventory A lightweight hardware inventory tracker built in C++17. Uses a **client/server** model: the server owns the file-backed database and exposes a TCP interface on localhost; the CLI client connects to it to run commands. --- ## Architecture ``` ┌──────────────┐ TCP (localhost:9876) ┌─────────────────────┐ │ inventory-cli│ ─────────────────────► │ inventory-server │ │ (CLI client)│ ◄───────────────────── │ database ► file.db │ └──────────────┘ └─────────────────────┘ ``` * **inventory-server** – loads the inventory file on start, accepts one command per connection, and flushes changes to disk after every mutation. * **inventory-cli** – a thin CLI that translates subcommands into protocol messages, connects to the server, and pretty-prints the response. --- ## Build Requires CMake ≥ 3.16 and a C++17-capable compiler. ```bash cd device-inventory cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build ``` Binaries end up in `build/inventory-server` and `build/inventory-cli`. --- ## Running ### Start the server ```bash ./build/inventory-server # uses inventory.db in CWD ./build/inventory-server --port 9876 --db /var/lib/inventory/data.db ``` The server reloads the file every time it restarts. On the very first run the file is created automatically. ### Use the CLI ```bash # Shorthand for the examples below cli="./build/inventory-cli" ``` --- ## Commands ### Servers ```bash # Add a server $cli add-server "web01" "192.168.1.10" "Rack A" "Primary web server" # List all servers $cli list-servers # Edit a field (fields: name | hostname | location | description) $cli edit-server 1 hostname "10.0.0.1" $cli edit-server 1 description "Retired – do not use" ``` ### Part types ```bash # Add a part type $cli add-part-type "RAM" "Memory modules" $cli add-part-type "SSD" "Solid-state storage" # List all part types $cli list-part-types # Edit a field (fields: name | description) $cli edit-part-type 1 description "DDR4/DDR5 memory" ``` ### Parts ```bash # Add a part to a server # add-part $cli add-part 1 1 "16 GB DDR4" "SN-MEM-001" "DIMM slot A1" $cli add-part 1 2 "Samsung 870 EVO 1 TB" "SN-SSD-004" "Primary OS drive" # List parts of a server $cli list-parts 1 # Edit a field (fields: name | serial | description | server_id | part_type_id) $cli edit-part 2 serial "SN-SSD-005" $cli edit-part 2 server_id 3 ``` --- ## Database file format Plain text, one record per line – safe to inspect or diff with standard tools. ``` # device-inventory database META||| S||||| PT||| P|||||| ``` Pipe characters and backslashes inside field values are escaped with `\|` and `\\` respectively. --- ## Wire protocol Commands are newline-terminated lines; fields are separated by ASCII SOH (`0x01`). Each connection carries exactly one request/response pair. ``` Client → Server: COMMAND\x01arg1\x01arg2\n Server → Client: OK\n field1\x01field2\x01...\n ← 0 or more data rows END\n -- or -- ERR \n ```