about summary refs log tree commit diff stats
path: root/crates/rocie-client
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rocie-client')
-rw-r--r--crates/rocie-client/.openapi-generator-ignore1
-rw-r--r--crates/rocie-client/.openapi-generator/FILES65
-rw-r--r--crates/rocie-client/Cargo.toml2
-rw-r--r--crates/rocie-client/README.md63
-rw-r--r--crates/rocie-client/docs/ApiGetAuthInventoryApi.md37
-rw-r--r--crates/rocie-client/docs/ApiGetAuthProductApi.md209
-rw-r--r--crates/rocie-client/docs/ApiGetAuthProductParentApi.md89
-rw-r--r--crates/rocie-client/docs/ApiGetAuthRecipeApi.md63
-rw-r--r--crates/rocie-client/docs/ApiGetAuthUnitApi.md92
-rw-r--r--crates/rocie-client/docs/ApiGetAuthUnitPropertyApi.md63
-rw-r--r--crates/rocie-client/docs/ApiGetAuthUserApi.md63
-rw-r--r--crates/rocie-client/docs/ApiGetNoAuthUserApi.md63
-rw-r--r--crates/rocie-client/docs/ApiSetAuthBarcodeApi.md68
-rw-r--r--crates/rocie-client/docs/ApiSetAuthProductApi.md67
-rw-r--r--crates/rocie-client/docs/ApiSetAuthProductParentApi.md37
-rw-r--r--crates/rocie-client/docs/ApiSetAuthRecipeApi.md37
-rw-r--r--crates/rocie-client/docs/ApiSetAuthUnitApi.md37
-rw-r--r--crates/rocie-client/docs/ApiSetAuthUnitPropertyApi.md37
-rw-r--r--crates/rocie-client/docs/ApiSetAuthUserApi.md37
-rw-r--r--crates/rocie-client/docs/ApiSetNoAuthUserApi.md94
-rw-r--r--crates/rocie-client/docs/LoginInfo.md12
-rw-r--r--crates/rocie-client/docs/PasswordHash.md11
-rw-r--r--crates/rocie-client/docs/User.md14
-rw-r--r--crates/rocie-client/docs/UserId.md11
-rw-r--r--crates/rocie-client/docs/UserStub.md13
-rw-r--r--crates/rocie-client/src/apis/api_get_auth_inventory_api.rs64
-rw-r--r--crates/rocie-client/src/apis/api_get_auth_product_api.rs335
-rw-r--r--crates/rocie-client/src/apis/api_get_auth_product_parent_api.rs149
-rw-r--r--crates/rocie-client/src/apis/api_get_auth_recipe_api.rs107
-rw-r--r--crates/rocie-client/src/apis/api_get_auth_unit_api.rs152
-rw-r--r--crates/rocie-client/src/apis/api_get_auth_unit_property_api.rs107
-rw-r--r--crates/rocie-client/src/apis/api_get_auth_user_api.rs108
-rw-r--r--crates/rocie-client/src/apis/api_get_no_auth_user_api.rs106
-rw-r--r--crates/rocie-client/src/apis/api_set_auth_barcode_api.rs91
-rw-r--r--crates/rocie-client/src/apis/api_set_auth_product_api.rs102
-rw-r--r--crates/rocie-client/src/apis/api_set_auth_product_parent_api.rs64
-rw-r--r--crates/rocie-client/src/apis/api_set_auth_recipe_api.rs64
-rw-r--r--crates/rocie-client/src/apis/api_set_auth_unit_api.rs64
-rw-r--r--crates/rocie-client/src/apis/api_set_auth_unit_property_api.rs64
-rw-r--r--crates/rocie-client/src/apis/api_set_auth_user_api.rs64
-rw-r--r--crates/rocie-client/src/apis/api_set_no_auth_user_api.rs132
-rw-r--r--crates/rocie-client/src/apis/configuration.rs7
-rw-r--r--crates/rocie-client/src/apis/mod.rs27
-rw-r--r--crates/rocie-client/src/implies.rs9
-rw-r--r--crates/rocie-client/src/models/login_info.rs32
-rw-r--r--crates/rocie-client/src/models/mod.rs10
-rw-r--r--crates/rocie-client/src/models/password_hash.rs29
-rw-r--r--crates/rocie-client/src/models/user.rs42
-rw-r--r--crates/rocie-client/src/models/user_id.rs27
-rw-r--r--crates/rocie-client/src/models/user_stub.rs36
50 files changed, 3208 insertions, 69 deletions
diff --git a/crates/rocie-client/.openapi-generator-ignore b/crates/rocie-client/.openapi-generator-ignore
index d0e9b85..78cff62 100644
--- a/crates/rocie-client/.openapi-generator-ignore
+++ b/crates/rocie-client/.openapi-generator-ignore
@@ -8,3 +8,4 @@ Cargo.toml
 
 src/lib.rs
 src/implies.rs
+src/apis/configuration.rs
diff --git a/crates/rocie-client/.openapi-generator/FILES b/crates/rocie-client/.openapi-generator/FILES
index cf7a068..a8ce119 100644
--- a/crates/rocie-client/.openapi-generator/FILES
+++ b/crates/rocie-client/.openapi-generator/FILES
@@ -1,20 +1,25 @@
 .gitignore
 .travis.yml
 README.md
-docs/ApiGetInventoryApi.md
-docs/ApiGetProductApi.md
-docs/ApiGetProductParentApi.md
-docs/ApiGetRecipeApi.md
-docs/ApiGetUnitApi.md
-docs/ApiGetUnitPropertyApi.md
-docs/ApiSetBarcodeApi.md
-docs/ApiSetProductApi.md
-docs/ApiSetProductParentApi.md
-docs/ApiSetRecipeApi.md
-docs/ApiSetUnitApi.md
-docs/ApiSetUnitPropertyApi.md
+docs/ApiGetAuthInventoryApi.md
+docs/ApiGetAuthProductApi.md
+docs/ApiGetAuthProductParentApi.md
+docs/ApiGetAuthRecipeApi.md
+docs/ApiGetAuthUnitApi.md
+docs/ApiGetAuthUnitPropertyApi.md
+docs/ApiGetAuthUserApi.md
+docs/ApiSetAuthBarcodeApi.md
+docs/ApiSetAuthProductApi.md
+docs/ApiSetAuthProductParentApi.md
+docs/ApiSetAuthRecipeApi.md
+docs/ApiSetAuthUnitApi.md
+docs/ApiSetAuthUnitPropertyApi.md
+docs/ApiSetAuthUserApi.md
+docs/ApiSetNoAuthUserApi.md
 docs/Barcode.md
 docs/BarcodeId.md
+docs/LoginInfo.md
+docs/PasswordHash.md
 docs/Product.md
 docs/ProductAmount.md
 docs/ProductId.md
@@ -32,24 +37,31 @@ docs/UnitProperty.md
 docs/UnitPropertyId.md
 docs/UnitPropertyStub.md
 docs/UnitStub.md
+docs/User.md
+docs/UserId.md
+docs/UserStub.md
 git_push.sh
-src/apis/api_get_inventory_api.rs
-src/apis/api_get_product_api.rs
-src/apis/api_get_product_parent_api.rs
-src/apis/api_get_recipe_api.rs
-src/apis/api_get_unit_api.rs
-src/apis/api_get_unit_property_api.rs
-src/apis/api_set_barcode_api.rs
-src/apis/api_set_product_api.rs
-src/apis/api_set_product_parent_api.rs
-src/apis/api_set_recipe_api.rs
-src/apis/api_set_unit_api.rs
-src/apis/api_set_unit_property_api.rs
-src/apis/configuration.rs
+src/apis/api_get_auth_inventory_api.rs
+src/apis/api_get_auth_product_api.rs
+src/apis/api_get_auth_product_parent_api.rs
+src/apis/api_get_auth_recipe_api.rs
+src/apis/api_get_auth_unit_api.rs
+src/apis/api_get_auth_unit_property_api.rs
+src/apis/api_get_auth_user_api.rs
+src/apis/api_set_auth_barcode_api.rs
+src/apis/api_set_auth_product_api.rs
+src/apis/api_set_auth_product_parent_api.rs
+src/apis/api_set_auth_recipe_api.rs
+src/apis/api_set_auth_unit_api.rs
+src/apis/api_set_auth_unit_property_api.rs
+src/apis/api_set_auth_user_api.rs
+src/apis/api_set_no_auth_user_api.rs
 src/apis/mod.rs
 src/models/barcode.rs
 src/models/barcode_id.rs
+src/models/login_info.rs
 src/models/mod.rs
+src/models/password_hash.rs
 src/models/product.rs
 src/models/product_amount.rs
 src/models/product_id.rs
@@ -67,3 +79,6 @@ src/models/unit_property.rs
 src/models/unit_property_id.rs
 src/models/unit_property_stub.rs
 src/models/unit_stub.rs
+src/models/user.rs
+src/models/user_id.rs
+src/models/user_stub.rs
diff --git a/crates/rocie-client/Cargo.toml b/crates/rocie-client/Cargo.toml
index 96e0e24..f69441e 100644
--- a/crates/rocie-client/Cargo.toml
+++ b/crates/rocie-client/Cargo.toml
@@ -13,4 +13,4 @@ serde_json = "^1.0"
 serde_repr = "^0.1"
 url = "^2.5"
 uuid = { version = "^1.8", features = ["serde", "v4"] }
-reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart"] }
+reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart", "cookies"] }
diff --git a/crates/rocie-client/README.md b/crates/rocie-client/README.md
index e25385a..ebcdd73 100644
--- a/crates/rocie-client/README.md
+++ b/crates/rocie-client/README.md
@@ -26,38 +26,46 @@ All URIs are relative to *http://localhost*
 
 Class | Method | HTTP request | Description
 ------------ | ------------- | ------------- | -------------
-*ApiGetInventoryApi* | [**amount_by_id**](docs/ApiGetInventoryApi.md#amount_by_id) | **GET** /inventory/{id} | Get the amount of an product
-*ApiGetProductApi* | [**product_by_id**](docs/ApiGetProductApi.md#product_by_id) | **GET** /product/by-id/{id} | Get Product by id
-*ApiGetProductApi* | [**product_by_name**](docs/ApiGetProductApi.md#product_by_name) | **GET** /product/by-name/{name} | Get Product by name
-*ApiGetProductApi* | [**product_suggestion_by_name**](docs/ApiGetProductApi.md#product_suggestion_by_name) | **GET** /product/by-part-name/{name} | Get Product suggestion by name
-*ApiGetProductApi* | [**products_by_product_parent_id_direct**](docs/ApiGetProductApi.md#products_by_product_parent_id_direct) | **GET** /product/by-product-parent-id-direct/{id} | Get Products by it's product parent id
-*ApiGetProductApi* | [**products_by_product_parent_id_indirect**](docs/ApiGetProductApi.md#products_by_product_parent_id_indirect) | **GET** /product/by-product-parent-id-indirect/{id} | Get Products by it's product parent id
-*ApiGetProductApi* | [**products_in_storage**](docs/ApiGetProductApi.md#products_in_storage) | **GET** /products_in_storage/ | Return all products, which non-null amount in storage
-*ApiGetProductApi* | [**products_registered**](docs/ApiGetProductApi.md#products_registered) | **GET** /products_registered/ | Return all registered products
-*ApiGetProductParentApi* | [**product_parents**](docs/ApiGetProductParentApi.md#product_parents) | **GET** /product_parents/ | Return all registered product parents
-*ApiGetProductParentApi* | [**product_parents_toplevel**](docs/ApiGetProductParentApi.md#product_parents_toplevel) | **GET** /product_parents_toplevel/ | Return all registered product parents, that have no parents themselves
-*ApiGetProductParentApi* | [**product_parents_under**](docs/ApiGetProductParentApi.md#product_parents_under) | **GET** /product_parents_under/{id} | Return all parents, that have this parent as parent
-*ApiGetRecipeApi* | [**recipe_by_id**](docs/ApiGetRecipeApi.md#recipe_by_id) | **GET** /recipe/by-id/{id} | Get an recipe by it's id.
-*ApiGetRecipeApi* | [**recipes**](docs/ApiGetRecipeApi.md#recipes) | **GET** /recipe/all | Get all added recipes
-*ApiGetUnitApi* | [**unit_by_id**](docs/ApiGetUnitApi.md#unit_by_id) | **GET** /unit/{id} | Get Unit by id
-*ApiGetUnitApi* | [**units**](docs/ApiGetUnitApi.md#units) | **GET** /units/ | Return all registered units
-*ApiGetUnitApi* | [**units_by_property_id**](docs/ApiGetUnitApi.md#units_by_property_id) | **GET** /units-by-property/{id} | Return all registered units for a specific unit property
-*ApiGetUnitPropertyApi* | [**unit_properties**](docs/ApiGetUnitPropertyApi.md#unit_properties) | **GET** /unit-properties/ | Return all registered unit properties
-*ApiGetUnitPropertyApi* | [**unit_property_by_id**](docs/ApiGetUnitPropertyApi.md#unit_property_by_id) | **GET** /unit-property/{id} | Get Unit property by id
-*ApiSetBarcodeApi* | [**buy_barcode**](docs/ApiSetBarcodeApi.md#buy_barcode) | **POST** /barcode/{barcode_id}/buy/{times} | Buy an barcode
-*ApiSetBarcodeApi* | [**consume_barcode**](docs/ApiSetBarcodeApi.md#consume_barcode) | **POST** /barcode/{id}/consume | Consume an barcode
-*ApiSetProductApi* | [**associate_barcode**](docs/ApiSetProductApi.md#associate_barcode) | **POST** /product/{id}/associate | Associate a barcode with a product
-*ApiSetProductApi* | [**register_product**](docs/ApiSetProductApi.md#register_product) | **POST** /product/new | Register a product
-*ApiSetProductParentApi* | [**register_product_parent**](docs/ApiSetProductParentApi.md#register_product_parent) | **POST** /product_parent/new | Register a product parent
-*ApiSetRecipeApi* | [**add_recipe**](docs/ApiSetRecipeApi.md#add_recipe) | **POST** /recipe/new | Register a product parent
-*ApiSetUnitApi* | [**register_unit**](docs/ApiSetUnitApi.md#register_unit) | **POST** /unit/new | Register an Unit
-*ApiSetUnitPropertyApi* | [**register_unit_property**](docs/ApiSetUnitPropertyApi.md#register_unit_property) | **POST** /unit-property/new | Register an Unit Property
+*ApiGetAuthInventoryApi* | [**amount_by_id**](docs/ApiGetAuthInventoryApi.md#amount_by_id) | **GET** /inventory/{id} | Get the amount of an product
+*ApiGetAuthProductApi* | [**product_by_id**](docs/ApiGetAuthProductApi.md#product_by_id) | **GET** /product/by-id/{id} | Get Product by id
+*ApiGetAuthProductApi* | [**product_by_name**](docs/ApiGetAuthProductApi.md#product_by_name) | **GET** /product/by-name/{name} | Get Product by name
+*ApiGetAuthProductApi* | [**product_suggestion_by_name**](docs/ApiGetAuthProductApi.md#product_suggestion_by_name) | **GET** /product/by-part-name/{name} | Get Product suggestion by name
+*ApiGetAuthProductApi* | [**products_by_product_parent_id_direct**](docs/ApiGetAuthProductApi.md#products_by_product_parent_id_direct) | **GET** /product/by-product-parent-id-direct/{id} | Get Products by it's product parent id
+*ApiGetAuthProductApi* | [**products_by_product_parent_id_indirect**](docs/ApiGetAuthProductApi.md#products_by_product_parent_id_indirect) | **GET** /product/by-product-parent-id-indirect/{id} | Get Products by it's product parent id
+*ApiGetAuthProductApi* | [**products_in_storage**](docs/ApiGetAuthProductApi.md#products_in_storage) | **GET** /products_in_storage/ | Return all products, which non-null amount in storage
+*ApiGetAuthProductApi* | [**products_registered**](docs/ApiGetAuthProductApi.md#products_registered) | **GET** /products_registered/ | Return all registered products
+*ApiGetAuthProductParentApi* | [**product_parents**](docs/ApiGetAuthProductParentApi.md#product_parents) | **GET** /product_parents/ | Return all registered product parents
+*ApiGetAuthProductParentApi* | [**product_parents_toplevel**](docs/ApiGetAuthProductParentApi.md#product_parents_toplevel) | **GET** /product_parents_toplevel/ | Return all registered product parents, that have no parents themselves
+*ApiGetAuthProductParentApi* | [**product_parents_under**](docs/ApiGetAuthProductParentApi.md#product_parents_under) | **GET** /product_parents_under/{id} | Return all parents, that have this parent as parent
+*ApiGetAuthRecipeApi* | [**recipe_by_id**](docs/ApiGetAuthRecipeApi.md#recipe_by_id) | **GET** /recipe/by-id/{id} | Get an recipe by it's id.
+*ApiGetAuthRecipeApi* | [**recipes**](docs/ApiGetAuthRecipeApi.md#recipes) | **GET** /recipe/all | Get all added recipes
+*ApiGetAuthUnitApi* | [**unit_by_id**](docs/ApiGetAuthUnitApi.md#unit_by_id) | **GET** /unit/{id} | Get Unit by id
+*ApiGetAuthUnitApi* | [**units**](docs/ApiGetAuthUnitApi.md#units) | **GET** /units/ | Return all registered units
+*ApiGetAuthUnitApi* | [**units_by_property_id**](docs/ApiGetAuthUnitApi.md#units_by_property_id) | **GET** /units-by-property/{id} | Return all registered units for a specific unit property
+*ApiGetAuthUnitPropertyApi* | [**unit_properties**](docs/ApiGetAuthUnitPropertyApi.md#unit_properties) | **GET** /unit-properties/ | Return all registered unit properties
+*ApiGetAuthUnitPropertyApi* | [**unit_property_by_id**](docs/ApiGetAuthUnitPropertyApi.md#unit_property_by_id) | **GET** /unit-property/{id} | Get Unit property by id
+*ApiGetAuthUserApi* | [**user_by_id**](docs/ApiGetAuthUserApi.md#user_by_id) | **GET** /user/{id} | Get an specific user by id.
+*ApiGetAuthUserApi* | [**users**](docs/ApiGetAuthUserApi.md#users) | **GET** /users | Get all registered users.
+*ApiSetAuthBarcodeApi* | [**buy_barcode**](docs/ApiSetAuthBarcodeApi.md#buy_barcode) | **POST** /barcode/{barcode_id}/buy/{times} | Buy an barcode
+*ApiSetAuthBarcodeApi* | [**consume_barcode**](docs/ApiSetAuthBarcodeApi.md#consume_barcode) | **POST** /barcode/{id}/consume | Consume an barcode
+*ApiSetAuthProductApi* | [**associate_barcode**](docs/ApiSetAuthProductApi.md#associate_barcode) | **POST** /product/{id}/associate | Associate a barcode with a product
+*ApiSetAuthProductApi* | [**register_product**](docs/ApiSetAuthProductApi.md#register_product) | **POST** /product/new | Register a product
+*ApiSetAuthProductParentApi* | [**register_product_parent**](docs/ApiSetAuthProductParentApi.md#register_product_parent) | **POST** /product_parent/new | Register a product parent
+*ApiSetAuthRecipeApi* | [**add_recipe**](docs/ApiSetAuthRecipeApi.md#add_recipe) | **POST** /recipe/new | Register a product parent
+*ApiSetAuthUnitApi* | [**register_unit**](docs/ApiSetAuthUnitApi.md#register_unit) | **POST** /unit/new | Register an Unit
+*ApiSetAuthUnitPropertyApi* | [**register_unit_property**](docs/ApiSetAuthUnitPropertyApi.md#register_unit_property) | **POST** /unit-property/new | Register an Unit Property
+*ApiSetAuthUserApi* | [**register_user**](docs/ApiSetAuthUserApi.md#register_user) | **POST** /user/new | Register an new User
+*ApiSetNoAuthUserApi* | [**login**](docs/ApiSetNoAuthUserApi.md#login) | **POST** /login | Log in as a specific user
+*ApiSetNoAuthUserApi* | [**logout**](docs/ApiSetNoAuthUserApi.md#logout) | **POST** /logout | Log the current user out
+*ApiSetNoAuthUserApi* | [**provision**](docs/ApiSetNoAuthUserApi.md#provision) | **POST** /provision | Provision this instance.
 
 
 ## Documentation For Models
 
  - [Barcode](docs/Barcode.md)
  - [BarcodeId](docs/BarcodeId.md)
+ - [LoginInfo](docs/LoginInfo.md)
+ - [PasswordHash](docs/PasswordHash.md)
  - [Product](docs/Product.md)
  - [ProductAmount](docs/ProductAmount.md)
  - [ProductId](docs/ProductId.md)
@@ -75,6 +83,9 @@ Class | Method | HTTP request | Description
  - [UnitPropertyId](docs/UnitPropertyId.md)
  - [UnitPropertyStub](docs/UnitPropertyStub.md)
  - [UnitStub](docs/UnitStub.md)
+ - [User](docs/User.md)
+ - [UserId](docs/UserId.md)
+ - [UserStub](docs/UserStub.md)
 
 
 To get access to the crate's generated documentation, use:
diff --git a/crates/rocie-client/docs/ApiGetAuthInventoryApi.md b/crates/rocie-client/docs/ApiGetAuthInventoryApi.md
new file mode 100644
index 0000000..ece4d4b
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetAuthInventoryApi.md
@@ -0,0 +1,37 @@
+# \ApiGetAuthInventoryApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**amount_by_id**](ApiGetAuthInventoryApi.md#amount_by_id) | **GET** /inventory/{id} | Get the amount of an product
+
+
+
+## amount_by_id
+
+> models::ProductAmount amount_by_id(id)
+Get the amount of an product
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**ProductId**](.md) | Product id | [required] |
+
+### Return type
+
+[**models::ProductAmount**](ProductAmount.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiGetAuthProductApi.md b/crates/rocie-client/docs/ApiGetAuthProductApi.md
new file mode 100644
index 0000000..8af92f3
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetAuthProductApi.md
@@ -0,0 +1,209 @@
+# \ApiGetAuthProductApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**product_by_id**](ApiGetAuthProductApi.md#product_by_id) | **GET** /product/by-id/{id} | Get Product by id
+[**product_by_name**](ApiGetAuthProductApi.md#product_by_name) | **GET** /product/by-name/{name} | Get Product by name
+[**product_suggestion_by_name**](ApiGetAuthProductApi.md#product_suggestion_by_name) | **GET** /product/by-part-name/{name} | Get Product suggestion by name
+[**products_by_product_parent_id_direct**](ApiGetAuthProductApi.md#products_by_product_parent_id_direct) | **GET** /product/by-product-parent-id-direct/{id} | Get Products by it's product parent id
+[**products_by_product_parent_id_indirect**](ApiGetAuthProductApi.md#products_by_product_parent_id_indirect) | **GET** /product/by-product-parent-id-indirect/{id} | Get Products by it's product parent id
+[**products_in_storage**](ApiGetAuthProductApi.md#products_in_storage) | **GET** /products_in_storage/ | Return all products, which non-null amount in storage
+[**products_registered**](ApiGetAuthProductApi.md#products_registered) | **GET** /products_registered/ | Return all registered products
+
+
+
+## product_by_id
+
+> models::Product product_by_id(id)
+Get Product by id
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**ProductId**](.md) | Product id | [required] |
+
+### Return type
+
+[**models::Product**](Product.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## product_by_name
+
+> models::Product product_by_name(name)
+Get Product by name
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**name** | **String** | Name of the product | [required] |
+
+### Return type
+
+[**models::Product**](Product.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## product_suggestion_by_name
+
+> Vec<models::Product> product_suggestion_by_name(name)
+Get Product suggestion by name
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**name** | **String** | Partial name of a product | [required] |
+
+### Return type
+
+[**Vec<models::Product>**](Product.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## products_by_product_parent_id_direct
+
+> Vec<models::Product> products_by_product_parent_id_direct(id)
+Get Products by it's product parent id
+
+This will only return products directly associated with this product parent id
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**ProductParentId**](.md) | Product parent id | [required] |
+
+### Return type
+
+[**Vec<models::Product>**](Product.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## products_by_product_parent_id_indirect
+
+> Vec<models::Product> products_by_product_parent_id_indirect(id)
+Get Products by it's product parent id
+
+This will also return all products below this product parent id
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**ProductParentId**](.md) | Product parent id | [required] |
+
+### Return type
+
+[**Vec<models::Product>**](Product.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## products_in_storage
+
+> Vec<models::Product> products_in_storage()
+Return all products, which non-null amount in storage
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::Product>**](Product.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## products_registered
+
+> Vec<models::Product> products_registered()
+Return all registered products
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::Product>**](Product.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiGetAuthProductParentApi.md b/crates/rocie-client/docs/ApiGetAuthProductParentApi.md
new file mode 100644
index 0000000..fbdc3b1
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetAuthProductParentApi.md
@@ -0,0 +1,89 @@
+# \ApiGetAuthProductParentApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**product_parents**](ApiGetAuthProductParentApi.md#product_parents) | **GET** /product_parents/ | Return all registered product parents
+[**product_parents_toplevel**](ApiGetAuthProductParentApi.md#product_parents_toplevel) | **GET** /product_parents_toplevel/ | Return all registered product parents, that have no parents themselves
+[**product_parents_under**](ApiGetAuthProductParentApi.md#product_parents_under) | **GET** /product_parents_under/{id} | Return all parents, that have this parent as parent
+
+
+
+## product_parents
+
+> Vec<models::ProductParent> product_parents()
+Return all registered product parents
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::ProductParent>**](ProductParent.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## product_parents_toplevel
+
+> Vec<models::ProductParent> product_parents_toplevel()
+Return all registered product parents, that have no parents themselves
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::ProductParent>**](ProductParent.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## product_parents_under
+
+> Vec<models::ProductParent> product_parents_under(id)
+Return all parents, that have this parent as parent
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**ProductParentId**](.md) | Product parent id | [required] |
+
+### Return type
+
+[**Vec<models::ProductParent>**](ProductParent.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiGetAuthRecipeApi.md b/crates/rocie-client/docs/ApiGetAuthRecipeApi.md
new file mode 100644
index 0000000..96d5a77
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetAuthRecipeApi.md
@@ -0,0 +1,63 @@
+# \ApiGetAuthRecipeApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**recipe_by_id**](ApiGetAuthRecipeApi.md#recipe_by_id) | **GET** /recipe/by-id/{id} | Get an recipe by it's id.
+[**recipes**](ApiGetAuthRecipeApi.md#recipes) | **GET** /recipe/all | Get all added recipes
+
+
+
+## recipe_by_id
+
+> models::Recipe recipe_by_id(id)
+Get an recipe by it's id.
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**RecipeId**](.md) | Recipe id | [required] |
+
+### Return type
+
+[**models::Recipe**](Recipe.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## recipes
+
+> models::Recipe recipes()
+Get all added recipes
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**models::Recipe**](Recipe.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiGetAuthUnitApi.md b/crates/rocie-client/docs/ApiGetAuthUnitApi.md
new file mode 100644
index 0000000..3f2b02f
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetAuthUnitApi.md
@@ -0,0 +1,92 @@
+# \ApiGetAuthUnitApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**unit_by_id**](ApiGetAuthUnitApi.md#unit_by_id) | **GET** /unit/{id} | Get Unit by id
+[**units**](ApiGetAuthUnitApi.md#units) | **GET** /units/ | Return all registered units
+[**units_by_property_id**](ApiGetAuthUnitApi.md#units_by_property_id) | **GET** /units-by-property/{id} | Return all registered units for a specific unit property
+
+
+
+## unit_by_id
+
+> models::Unit unit_by_id(id)
+Get Unit by id
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**UnitId**](.md) | Unit id | [required] |
+
+### Return type
+
+[**models::Unit**](Unit.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## units
+
+> Vec<models::Unit> units()
+Return all registered units
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::Unit>**](Unit.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## units_by_property_id
+
+> Vec<models::Unit> units_by_property_id(id)
+Return all registered units for a specific unit property
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**UnitPropertyId**](.md) | Unit property id | [required] |
+
+### Return type
+
+[**Vec<models::Unit>**](Unit.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiGetAuthUnitPropertyApi.md b/crates/rocie-client/docs/ApiGetAuthUnitPropertyApi.md
new file mode 100644
index 0000000..d88249a
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetAuthUnitPropertyApi.md
@@ -0,0 +1,63 @@
+# \ApiGetAuthUnitPropertyApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**unit_properties**](ApiGetAuthUnitPropertyApi.md#unit_properties) | **GET** /unit-properties/ | Return all registered unit properties
+[**unit_property_by_id**](ApiGetAuthUnitPropertyApi.md#unit_property_by_id) | **GET** /unit-property/{id} | Get Unit property by id
+
+
+
+## unit_properties
+
+> Vec<models::UnitProperty> unit_properties()
+Return all registered unit properties
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::UnitProperty>**](UnitProperty.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## unit_property_by_id
+
+> models::UnitProperty unit_property_by_id(id)
+Get Unit property by id
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**UnitPropertyId**](.md) | Unit Property id | [required] |
+
+### Return type
+
+[**models::UnitProperty**](UnitProperty.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiGetAuthUserApi.md b/crates/rocie-client/docs/ApiGetAuthUserApi.md
new file mode 100644
index 0000000..653e82a
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetAuthUserApi.md
@@ -0,0 +1,63 @@
+# \ApiGetAuthUserApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**user_by_id**](ApiGetAuthUserApi.md#user_by_id) | **GET** /user/{id} | Get an specific user by id.
+[**users**](ApiGetAuthUserApi.md#users) | **GET** /users | Get all registered users.
+
+
+
+## user_by_id
+
+> models::User user_by_id(id)
+Get an specific user by id.
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**UserId**](.md) | User id | [required] |
+
+### Return type
+
+[**models::User**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## users
+
+> Vec<models::User> users()
+Get all registered users.
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::User>**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiGetNoAuthUserApi.md b/crates/rocie-client/docs/ApiGetNoAuthUserApi.md
new file mode 100644
index 0000000..7923a1a
--- /dev/null
+++ b/crates/rocie-client/docs/ApiGetNoAuthUserApi.md
@@ -0,0 +1,63 @@
+# \ApiGetNoAuthUserApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**user_by_id**](ApiGetNoAuthUserApi.md#user_by_id) | **GET** /user/{id} | Get an specific user by id.
+[**users**](ApiGetNoAuthUserApi.md#users) | **GET** /users | Get all registered users.
+
+
+
+## user_by_id
+
+> models::User user_by_id(id)
+Get an specific user by id.
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**UserId**](.md) | User id | [required] |
+
+### Return type
+
+[**models::User**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## users
+
+> Vec<models::User> users()
+Get all registered users.
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**Vec<models::User>**](User.md)
+
+### Authorization
+
+[apiKeyAuth](../README.md#apiKeyAuth)
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetAuthBarcodeApi.md b/crates/rocie-client/docs/ApiSetAuthBarcodeApi.md
new file mode 100644
index 0000000..535643b
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetAuthBarcodeApi.md
@@ -0,0 +1,68 @@
+# \ApiSetAuthBarcodeApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**buy_barcode**](ApiSetAuthBarcodeApi.md#buy_barcode) | **POST** /barcode/{barcode_id}/buy/{times} | Buy an barcode
+[**consume_barcode**](ApiSetAuthBarcodeApi.md#consume_barcode) | **POST** /barcode/{id}/consume | Consume an barcode
+
+
+
+## buy_barcode
+
+> buy_barcode(barcode_id, times)
+Buy an barcode
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**barcode_id** | [**BarcodeId**](.md) | The numeric value of the barcode | [required] |
+**times** | **u32** | How often to buy the barcode | [required] |
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## consume_barcode
+
+> consume_barcode(id, unit_amount)
+Consume an barcode
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**BarcodeId**](.md) | The numeric value of the barcode | [required] |
+**unit_amount** | [**UnitAmount**](UnitAmount.md) |  | [required] |
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetAuthProductApi.md b/crates/rocie-client/docs/ApiSetAuthProductApi.md
new file mode 100644
index 0000000..eb52b59
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetAuthProductApi.md
@@ -0,0 +1,67 @@
+# \ApiSetAuthProductApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**associate_barcode**](ApiSetAuthProductApi.md#associate_barcode) | **POST** /product/{id}/associate | Associate a barcode with a product
+[**register_product**](ApiSetAuthProductApi.md#register_product) | **POST** /product/new | Register a product
+
+
+
+## associate_barcode
+
+> associate_barcode(id, barcode)
+Associate a barcode with a product
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**id** | [**ProductId**](.md) | The id of the product to associated the barcode with | [required] |
+**barcode** | [**Barcode**](Barcode.md) |  | [required] |
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## register_product
+
+> models::ProductId register_product(product_stub)
+Register a product
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**product_stub** | [**ProductStub**](ProductStub.md) |  | [required] |
+
+### Return type
+
+[**models::ProductId**](ProductId.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetAuthProductParentApi.md b/crates/rocie-client/docs/ApiSetAuthProductParentApi.md
new file mode 100644
index 0000000..e48c269
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetAuthProductParentApi.md
@@ -0,0 +1,37 @@
+# \ApiSetAuthProductParentApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**register_product_parent**](ApiSetAuthProductParentApi.md#register_product_parent) | **POST** /product_parent/new | Register a product parent
+
+
+
+## register_product_parent
+
+> models::ProductParentId register_product_parent(product_parent_stub)
+Register a product parent
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**product_parent_stub** | [**ProductParentStub**](ProductParentStub.md) |  | [required] |
+
+### Return type
+
+[**models::ProductParentId**](ProductParentId.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetAuthRecipeApi.md b/crates/rocie-client/docs/ApiSetAuthRecipeApi.md
new file mode 100644
index 0000000..0ec118b
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetAuthRecipeApi.md
@@ -0,0 +1,37 @@
+# \ApiSetAuthRecipeApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**add_recipe**](ApiSetAuthRecipeApi.md#add_recipe) | **POST** /recipe/new | Register a product parent
+
+
+
+## add_recipe
+
+> models::RecipeId add_recipe(recipe_stub)
+Register a product parent
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**recipe_stub** | [**RecipeStub**](RecipeStub.md) |  | [required] |
+
+### Return type
+
+[**models::RecipeId**](RecipeId.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetAuthUnitApi.md b/crates/rocie-client/docs/ApiSetAuthUnitApi.md
new file mode 100644
index 0000000..d5927f8
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetAuthUnitApi.md
@@ -0,0 +1,37 @@
+# \ApiSetAuthUnitApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**register_unit**](ApiSetAuthUnitApi.md#register_unit) | **POST** /unit/new | Register an Unit
+
+
+
+## register_unit
+
+> models::UnitId register_unit(unit_stub)
+Register an Unit
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**unit_stub** | [**UnitStub**](UnitStub.md) |  | [required] |
+
+### Return type
+
+[**models::UnitId**](UnitId.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetAuthUnitPropertyApi.md b/crates/rocie-client/docs/ApiSetAuthUnitPropertyApi.md
new file mode 100644
index 0000000..855065c
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetAuthUnitPropertyApi.md
@@ -0,0 +1,37 @@
+# \ApiSetAuthUnitPropertyApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**register_unit_property**](ApiSetAuthUnitPropertyApi.md#register_unit_property) | **POST** /unit-property/new | Register an Unit Property
+
+
+
+## register_unit_property
+
+> models::UnitPropertyId register_unit_property(unit_property_stub)
+Register an Unit Property
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**unit_property_stub** | [**UnitPropertyStub**](UnitPropertyStub.md) |  | [required] |
+
+### Return type
+
+[**models::UnitPropertyId**](UnitPropertyId.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetAuthUserApi.md b/crates/rocie-client/docs/ApiSetAuthUserApi.md
new file mode 100644
index 0000000..7409a8a
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetAuthUserApi.md
@@ -0,0 +1,37 @@
+# \ApiSetAuthUserApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**register_user**](ApiSetAuthUserApi.md#register_user) | **POST** /user/new | Register an new User
+
+
+
+## register_user
+
+> models::UserId register_user(user_stub)
+Register an new User
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**user_stub** | [**UserStub**](UserStub.md) |  | [required] |
+
+### Return type
+
+[**models::UserId**](UserId.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/ApiSetNoAuthUserApi.md b/crates/rocie-client/docs/ApiSetNoAuthUserApi.md
new file mode 100644
index 0000000..f532533
--- /dev/null
+++ b/crates/rocie-client/docs/ApiSetNoAuthUserApi.md
@@ -0,0 +1,94 @@
+# \ApiSetNoAuthUserApi
+
+All URIs are relative to *http://localhost*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**login**](ApiSetNoAuthUserApi.md#login) | **POST** /login | Log in as a specific user
+[**logout**](ApiSetNoAuthUserApi.md#logout) | **POST** /logout | Log the current user out
+[**provision**](ApiSetNoAuthUserApi.md#provision) | **POST** /provision | Provision this instance.
+
+
+
+## login
+
+> login(login_info)
+Log in as a specific user
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**login_info** | [**LoginInfo**](LoginInfo.md) |  | [required] |
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## logout
+
+> logout()
+Log the current user out
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+ (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not defined
+- **Accept**: text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## provision
+
+> models::UserId provision(user_stub)
+Provision this instance.
+
+This only works, if no users exist yet.
+
+### Parameters
+
+
+Name | Type | Description  | Required | Notes
+------------- | ------------- | ------------- | ------------- | -------------
+**user_stub** | [**UserStub**](UserStub.md) |  | [required] |
+
+### Return type
+
+[**models::UserId**](UserId.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: application/json, text/plain
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/crates/rocie-client/docs/LoginInfo.md b/crates/rocie-client/docs/LoginInfo.md
new file mode 100644
index 0000000..699a685
--- /dev/null
+++ b/crates/rocie-client/docs/LoginInfo.md
@@ -0,0 +1,12 @@
+# LoginInfo
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | [**models::UserId**](UserId.md) | The id of the user. | 
+**password** | **String** | The password of the user. | 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/crates/rocie-client/docs/PasswordHash.md b/crates/rocie-client/docs/PasswordHash.md
new file mode 100644
index 0000000..ac022d2
--- /dev/null
+++ b/crates/rocie-client/docs/PasswordHash.md
@@ -0,0 +1,11 @@
+# PasswordHash
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**value** | **String** |  | 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/crates/rocie-client/docs/User.md b/crates/rocie-client/docs/User.md
new file mode 100644
index 0000000..d0f2a81
--- /dev/null
+++ b/crates/rocie-client/docs/User.md
@@ -0,0 +1,14 @@
+# User
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**description** | Option<**String**> | An description of this user. | [optional]
+**id** | [**models::UserId**](UserId.md) | The unique ID for this user. | 
+**name** | **String** | The user-displayed name of this user. | 
+**password_hash** | [**models::PasswordHash**](PasswordHash.md) | The hash of the user's password. | 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/crates/rocie-client/docs/UserId.md b/crates/rocie-client/docs/UserId.md
new file mode 100644
index 0000000..f183106
--- /dev/null
+++ b/crates/rocie-client/docs/UserId.md
@@ -0,0 +1,11 @@
+# UserId
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**value** | [**uuid::Uuid**](uuid::Uuid.md) |  | 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/crates/rocie-client/docs/UserStub.md b/crates/rocie-client/docs/UserStub.md
new file mode 100644
index 0000000..60bd072
--- /dev/null
+++ b/crates/rocie-client/docs/UserStub.md
@@ -0,0 +1,13 @@
+# UserStub
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**description** | Option<**String**> | An optional description of the new user. | [optional]
+**name** | **String** | The name of the new user. | 
+**password** | **String** | The password of the new user. | 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/crates/rocie-client/src/apis/api_get_auth_inventory_api.rs b/crates/rocie-client/src/apis/api_get_auth_inventory_api.rs
new file mode 100644
index 0000000..6249b62
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_auth_inventory_api.rs
@@ -0,0 +1,64 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`amount_by_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum AmountByIdError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn amount_by_id(configuration: &configuration::Configuration, id: models::ProductId) -> Result<models::ProductAmount, Error<AmountByIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/inventory/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ProductAmount`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ProductAmount`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<AmountByIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_get_auth_product_api.rs b/crates/rocie-client/src/apis/api_get_auth_product_api.rs
new file mode 100644
index 0000000..dcc35a7
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_auth_product_api.rs
@@ -0,0 +1,335 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`product_by_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductByIdError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`product_by_name`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductByNameError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`product_suggestion_by_name`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductSuggestionByNameError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`products_by_product_parent_id_direct`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductsByProductParentIdDirectError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`products_by_product_parent_id_indirect`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductsByProductParentIdIndirectError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`products_in_storage`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductsInStorageError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`products_registered`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductsRegisteredError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn product_by_id(configuration: &configuration::Configuration, id: models::ProductId) -> Result<models::Product, Error<ProductByIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/product/by-id/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Product`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Product`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductByIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn product_by_name(configuration: &configuration::Configuration, name: &str) -> Result<models::Product, Error<ProductByNameError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_name = name;
+
+    let uri_str = format!("{}/product/by-name/{name}", configuration.base_path, name=crate::apis::urlencode(p_name));
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Product`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Product`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductByNameError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn product_suggestion_by_name(configuration: &configuration::Configuration, name: &str) -> Result<Vec<models::Product>, Error<ProductSuggestionByNameError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_name = name;
+
+    let uri_str = format!("{}/product/by-part-name/{name}", configuration.base_path, name=crate::apis::urlencode(p_name));
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Product&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Product&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductSuggestionByNameError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+/// This will only return products directly associated with this product parent id
+pub async fn products_by_product_parent_id_direct(configuration: &configuration::Configuration, id: models::ProductParentId) -> Result<Vec<models::Product>, Error<ProductsByProductParentIdDirectError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/product/by-product-parent-id-direct/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Product&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Product&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductsByProductParentIdDirectError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+/// This will also return all products below this product parent id
+pub async fn products_by_product_parent_id_indirect(configuration: &configuration::Configuration, id: models::ProductParentId) -> Result<Vec<models::Product>, Error<ProductsByProductParentIdIndirectError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/product/by-product-parent-id-indirect/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Product&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Product&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductsByProductParentIdIndirectError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn products_in_storage(configuration: &configuration::Configuration, ) -> Result<Vec<models::Product>, Error<ProductsInStorageError>> {
+
+    let uri_str = format!("{}/products_in_storage/", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Product&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Product&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductsInStorageError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn products_registered(configuration: &configuration::Configuration, ) -> Result<Vec<models::Product>, Error<ProductsRegisteredError>> {
+
+    let uri_str = format!("{}/products_registered/", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Product&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Product&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductsRegisteredError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_get_auth_product_parent_api.rs b/crates/rocie-client/src/apis/api_get_auth_product_parent_api.rs
new file mode 100644
index 0000000..68b17d7
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_auth_product_parent_api.rs
@@ -0,0 +1,149 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`product_parents`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductParentsError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`product_parents_toplevel`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductParentsToplevelError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`product_parents_under`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProductParentsUnderError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn product_parents(configuration: &configuration::Configuration, ) -> Result<Vec<models::ProductParent>, Error<ProductParentsError>> {
+
+    let uri_str = format!("{}/product_parents/", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::ProductParent&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::ProductParent&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductParentsError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn product_parents_toplevel(configuration: &configuration::Configuration, ) -> Result<Vec<models::ProductParent>, Error<ProductParentsToplevelError>> {
+
+    let uri_str = format!("{}/product_parents_toplevel/", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::ProductParent&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::ProductParent&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductParentsToplevelError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn product_parents_under(configuration: &configuration::Configuration, id: models::ProductParentId) -> Result<Vec<models::ProductParent>, Error<ProductParentsUnderError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/product_parents_under/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::ProductParent&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::ProductParent&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProductParentsUnderError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_get_auth_recipe_api.rs b/crates/rocie-client/src/apis/api_get_auth_recipe_api.rs
new file mode 100644
index 0000000..4eddb2f
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_auth_recipe_api.rs
@@ -0,0 +1,107 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`recipe_by_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum RecipeByIdError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`recipes`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum RecipesError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn recipe_by_id(configuration: &configuration::Configuration, id: models::RecipeId) -> Result<models::Recipe, Error<RecipeByIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/recipe/by-id/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Recipe`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Recipe`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<RecipeByIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn recipes(configuration: &configuration::Configuration, ) -> Result<models::Recipe, Error<RecipesError>> {
+
+    let uri_str = format!("{}/recipe/all", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Recipe`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Recipe`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<RecipesError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_get_auth_unit_api.rs b/crates/rocie-client/src/apis/api_get_auth_unit_api.rs
new file mode 100644
index 0000000..c1f7e97
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_auth_unit_api.rs
@@ -0,0 +1,152 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`unit_by_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UnitByIdError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`units`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UnitsError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`units_by_property_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UnitsByPropertyIdError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn unit_by_id(configuration: &configuration::Configuration, id: models::UnitId) -> Result<models::Unit, Error<UnitByIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/unit/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Unit`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Unit`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UnitByIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn units(configuration: &configuration::Configuration, ) -> Result<Vec<models::Unit>, Error<UnitsError>> {
+
+    let uri_str = format!("{}/units/", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Unit&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Unit&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UnitsError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn units_by_property_id(configuration: &configuration::Configuration, id: models::UnitPropertyId) -> Result<Vec<models::Unit>, Error<UnitsByPropertyIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/units-by-property/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Unit&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::Unit&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UnitsByPropertyIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_get_auth_unit_property_api.rs b/crates/rocie-client/src/apis/api_get_auth_unit_property_api.rs
new file mode 100644
index 0000000..1359f40
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_auth_unit_property_api.rs
@@ -0,0 +1,107 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`unit_properties`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UnitPropertiesError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`unit_property_by_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UnitPropertyByIdError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn unit_properties(configuration: &configuration::Configuration, ) -> Result<Vec<models::UnitProperty>, Error<UnitPropertiesError>> {
+
+    let uri_str = format!("{}/unit-properties/", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::UnitProperty&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::UnitProperty&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UnitPropertiesError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn unit_property_by_id(configuration: &configuration::Configuration, id: models::UnitPropertyId) -> Result<models::UnitProperty, Error<UnitPropertyByIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/unit-property/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnitProperty`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnitProperty`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UnitPropertyByIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_get_auth_user_api.rs b/crates/rocie-client/src/apis/api_get_auth_user_api.rs
new file mode 100644
index 0000000..61e3935
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_auth_user_api.rs
@@ -0,0 +1,108 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`user_by_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UserByIdError {
+    Status401(),
+    Status403(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`users`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UsersError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn user_by_id(configuration: &configuration::Configuration, id: models::UserId) -> Result<models::User, Error<UserByIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/user/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::User`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::User`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UserByIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn users(configuration: &configuration::Configuration, ) -> Result<Vec<models::User>, Error<UsersError>> {
+
+    let uri_str = format!("{}/users", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::User&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::User&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UsersError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_get_no_auth_user_api.rs b/crates/rocie-client/src/apis/api_get_no_auth_user_api.rs
new file mode 100644
index 0000000..1a5e91d
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_get_no_auth_user_api.rs
@@ -0,0 +1,106 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`user_by_id`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UserByIdError {
+    Status403(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`users`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum UsersError {
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn user_by_id(configuration: &configuration::Configuration, id: models::UserId) -> Result<models::User, Error<UserByIdError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+
+    let uri_str = format!("{}/user/{id}", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::User`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::User`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UserByIdError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn users(configuration: &configuration::Configuration, ) -> Result<Vec<models::User>, Error<UsersError>> {
+
+    let uri_str = format!("{}/users", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::User&gt;`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::User&gt;`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<UsersError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_auth_barcode_api.rs b/crates/rocie-client/src/apis/api_set_auth_barcode_api.rs
new file mode 100644
index 0000000..494694d
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_auth_barcode_api.rs
@@ -0,0 +1,91 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`buy_barcode`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum BuyBarcodeError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`consume_barcode`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ConsumeBarcodeError {
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn buy_barcode(configuration: &configuration::Configuration, barcode_id: models::BarcodeId, times: u32) -> Result<(), Error<BuyBarcodeError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_barcode_id = barcode_id;
+    let p_times = times;
+
+    let uri_str = format!("{}/barcode/{barcode_id}/buy/{times}", configuration.base_path, barcode_id=p_barcode_id.to_string(), times=p_times);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+
+    if !status.is_client_error() && !status.is_server_error() {
+        Ok(())
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<BuyBarcodeError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn consume_barcode(configuration: &configuration::Configuration, id: models::BarcodeId, unit_amount: models::UnitAmount) -> Result<(), Error<ConsumeBarcodeError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+    let p_unit_amount = unit_amount;
+
+    let uri_str = format!("{}/barcode/{id}/consume", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_unit_amount);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+
+    if !status.is_client_error() && !status.is_server_error() {
+        Ok(())
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ConsumeBarcodeError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_auth_product_api.rs b/crates/rocie-client/src/apis/api_set_auth_product_api.rs
new file mode 100644
index 0000000..fd1cd23
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_auth_product_api.rs
@@ -0,0 +1,102 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`associate_barcode`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum AssociateBarcodeError {
+    Status400(String),
+    Status401(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`register_product`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum RegisterProductError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn associate_barcode(configuration: &configuration::Configuration, id: models::ProductId, barcode: models::Barcode) -> Result<(), Error<AssociateBarcodeError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_id = id;
+    let p_barcode = barcode;
+
+    let uri_str = format!("{}/product/{id}/associate", configuration.base_path, id=p_id.to_string());
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_barcode);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+
+    if !status.is_client_error() && !status.is_server_error() {
+        Ok(())
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<AssociateBarcodeError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn register_product(configuration: &configuration::Configuration, product_stub: models::ProductStub) -> Result<models::ProductId, Error<RegisterProductError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_product_stub = product_stub;
+
+    let uri_str = format!("{}/product/new", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_product_stub);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ProductId`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ProductId`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<RegisterProductError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_auth_product_parent_api.rs b/crates/rocie-client/src/apis/api_set_auth_product_parent_api.rs
new file mode 100644
index 0000000..6ec3a17
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_auth_product_parent_api.rs
@@ -0,0 +1,64 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`register_product_parent`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum RegisterProductParentError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn register_product_parent(configuration: &configuration::Configuration, product_parent_stub: models::ProductParentStub) -> Result<models::ProductParentId, Error<RegisterProductParentError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_product_parent_stub = product_parent_stub;
+
+    let uri_str = format!("{}/product_parent/new", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_product_parent_stub);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ProductParentId`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ProductParentId`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<RegisterProductParentError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_auth_recipe_api.rs b/crates/rocie-client/src/apis/api_set_auth_recipe_api.rs
new file mode 100644
index 0000000..52eb874
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_auth_recipe_api.rs
@@ -0,0 +1,64 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`add_recipe`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum AddRecipeError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn add_recipe(configuration: &configuration::Configuration, recipe_stub: models::RecipeStub) -> Result<models::RecipeId, Error<AddRecipeError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_recipe_stub = recipe_stub;
+
+    let uri_str = format!("{}/recipe/new", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_recipe_stub);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::RecipeId`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::RecipeId`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<AddRecipeError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_auth_unit_api.rs b/crates/rocie-client/src/apis/api_set_auth_unit_api.rs
new file mode 100644
index 0000000..0f96f98
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_auth_unit_api.rs
@@ -0,0 +1,64 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`register_unit`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum RegisterUnitError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn register_unit(configuration: &configuration::Configuration, unit_stub: models::UnitStub) -> Result<models::UnitId, Error<RegisterUnitError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_unit_stub = unit_stub;
+
+    let uri_str = format!("{}/unit/new", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_unit_stub);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnitId`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnitId`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<RegisterUnitError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_auth_unit_property_api.rs b/crates/rocie-client/src/apis/api_set_auth_unit_property_api.rs
new file mode 100644
index 0000000..bfb8a4d
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_auth_unit_property_api.rs
@@ -0,0 +1,64 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`register_unit_property`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum RegisterUnitPropertyError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn register_unit_property(configuration: &configuration::Configuration, unit_property_stub: models::UnitPropertyStub) -> Result<models::UnitPropertyId, Error<RegisterUnitPropertyError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_unit_property_stub = unit_property_stub;
+
+    let uri_str = format!("{}/unit-property/new", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_unit_property_stub);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnitPropertyId`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnitPropertyId`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<RegisterUnitPropertyError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_auth_user_api.rs b/crates/rocie-client/src/apis/api_set_auth_user_api.rs
new file mode 100644
index 0000000..4f43bbe
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_auth_user_api.rs
@@ -0,0 +1,64 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`register_user`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum RegisterUserError {
+    Status401(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn register_user(configuration: &configuration::Configuration, user_stub: models::UserStub) -> Result<models::UserId, Error<RegisterUserError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_user_stub = user_stub;
+
+    let uri_str = format!("{}/user/new", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_user_stub);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UserId`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UserId`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<RegisterUserError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/api_set_no_auth_user_api.rs b/crates/rocie-client/src/apis/api_set_no_auth_user_api.rs
new file mode 100644
index 0000000..6a59d1f
--- /dev/null
+++ b/crates/rocie-client/src/apis/api_set_no_auth_user_api.rs
@@ -0,0 +1,132 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+
+use reqwest;
+use serde::{Deserialize, Serialize, de::Error as _};
+use crate::{apis::ResponseContent, models};
+use super::{Error, configuration, ContentType};
+
+
+/// struct for typed errors of method [`login`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum LoginError {
+    Status403(),
+    Status404(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`logout`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum LogoutError {
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+/// struct for typed errors of method [`provision`]
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum ProvisionError {
+    Status403(),
+    Status500(String),
+    UnknownValue(serde_json::Value),
+}
+
+
+pub async fn login(configuration: &configuration::Configuration, login_info: models::LoginInfo) -> Result<(), Error<LoginError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_login_info = login_info;
+
+    let uri_str = format!("{}/login", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_login_info);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+
+    if !status.is_client_error() && !status.is_server_error() {
+        Ok(())
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<LoginError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+pub async fn logout(configuration: &configuration::Configuration, ) -> Result<(), Error<LogoutError>> {
+
+    let uri_str = format!("{}/logout", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+
+    if !status.is_client_error() && !status.is_server_error() {
+        Ok(())
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<LogoutError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
+/// This only works, if no users exist yet.
+pub async fn provision(configuration: &configuration::Configuration, user_stub: models::UserStub) -> Result<models::UserId, Error<ProvisionError>> {
+    // add a prefix to parameters to efficiently prevent name collisions
+    let p_user_stub = user_stub;
+
+    let uri_str = format!("{}/provision", configuration.base_path);
+    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
+
+    if let Some(ref user_agent) = configuration.user_agent {
+        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
+    }
+    req_builder = req_builder.json(&p_user_stub);
+
+    let req = req_builder.build()?;
+    let resp = configuration.client.execute(req).await?;
+
+    let status = resp.status();
+    let content_type = resp
+        .headers()
+        .get("content-type")
+        .and_then(|v| v.to_str().ok())
+        .unwrap_or("application/octet-stream");
+    let content_type = super::ContentType::from(content_type);
+
+    if !status.is_client_error() && !status.is_server_error() {
+        let content = resp.text().await?;
+        match content_type {
+            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
+            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UserId`"))),
+            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UserId`")))),
+        }
+    } else {
+        let content = resp.text().await?;
+        let entity: Option<ProvisionError> = serde_json::from_str(&content).ok();
+        Err(Error::ResponseError(ResponseContent { status, content, entity }))
+    }
+}
+
diff --git a/crates/rocie-client/src/apis/configuration.rs b/crates/rocie-client/src/apis/configuration.rs
index 590f233..c143926 100644
--- a/crates/rocie-client/src/apis/configuration.rs
+++ b/crates/rocie-client/src/apis/configuration.rs
@@ -8,8 +8,6 @@
  * Generated by: https://openapi-generator.tech
  */
 
-
-
 #[derive(Debug, Clone)]
 pub struct Configuration {
     pub base_path: String,
@@ -29,7 +27,6 @@ pub struct ApiKey {
     pub key: String,
 }
 
-
 impl Configuration {
     pub fn new() -> Configuration {
         Configuration::default()
@@ -38,10 +35,12 @@ impl Configuration {
 
 impl Default for Configuration {
     fn default() -> Self {
+        let client = reqwest::Client::builder().cookie_store(true).build().expect("to be not missconfigured");
+
         Configuration {
             base_path: "http://localhost".to_owned(),
             user_agent: Some("OpenAPI-Generator/0.1.0/rust".to_owned()),
-            client: reqwest::Client::new(),
+            client,
             basic_auth: None,
             oauth_access_token: None,
             bearer_access_token: None,
diff --git a/crates/rocie-client/src/apis/mod.rs b/crates/rocie-client/src/apis/mod.rs
index 13e70ba..e1b12e3 100644
--- a/crates/rocie-client/src/apis/mod.rs
+++ b/crates/rocie-client/src/apis/mod.rs
@@ -111,17 +111,20 @@ impl From<&str> for ContentType {
     }
 }
 
-pub mod api_get_inventory_api;
-pub mod api_get_product_api;
-pub mod api_get_product_parent_api;
-pub mod api_get_recipe_api;
-pub mod api_get_unit_api;
-pub mod api_get_unit_property_api;
-pub mod api_set_barcode_api;
-pub mod api_set_product_api;
-pub mod api_set_product_parent_api;
-pub mod api_set_recipe_api;
-pub mod api_set_unit_api;
-pub mod api_set_unit_property_api;
+pub mod api_get_auth_inventory_api;
+pub mod api_get_auth_product_api;
+pub mod api_get_auth_product_parent_api;
+pub mod api_get_auth_recipe_api;
+pub mod api_get_auth_unit_api;
+pub mod api_get_auth_unit_property_api;
+pub mod api_get_auth_user_api;
+pub mod api_set_auth_barcode_api;
+pub mod api_set_auth_product_api;
+pub mod api_set_auth_product_parent_api;
+pub mod api_set_auth_recipe_api;
+pub mod api_set_auth_unit_api;
+pub mod api_set_auth_unit_property_api;
+pub mod api_set_auth_user_api;
+pub mod api_set_no_auth_user_api;
 
 pub mod configuration;
diff --git a/crates/rocie-client/src/implies.rs b/crates/rocie-client/src/implies.rs
index e9de0ea..4b4091c 100644
--- a/crates/rocie-client/src/implies.rs
+++ b/crates/rocie-client/src/implies.rs
@@ -1,6 +1,6 @@
 use std::fmt::Display;
 
-use crate::models::{BarcodeId, ProductId, ProductParentId, RecipeId, UnitId, UnitPropertyId};
+use crate::models::{BarcodeId, ProductId, ProductParentId, RecipeId, UnitId, UnitPropertyId, UserId};
 
 // TODO(@bpeetz): The client generator should just do this. <2025-09-23>
 
@@ -45,3 +45,10 @@ impl Display for RecipeId {
     }
 }
 impl Copy for RecipeId {}
+
+impl Display for UserId {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.value.fmt(f)
+    }
+}
+impl Copy for UserId {}
diff --git a/crates/rocie-client/src/models/login_info.rs b/crates/rocie-client/src/models/login_info.rs
new file mode 100644
index 0000000..5aef74e
--- /dev/null
+++ b/crates/rocie-client/src/models/login_info.rs
@@ -0,0 +1,32 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+use crate::models;
+use serde::{Deserialize, Serialize};
+
+#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
+pub struct LoginInfo {
+    /// The id of the user.
+    #[serde(rename = "id")]
+    pub id: models::UserId,
+    /// The password of the user.
+    #[serde(rename = "password")]
+    pub password: String,
+}
+
+impl LoginInfo {
+    pub fn new(id: models::UserId, password: String) -> LoginInfo {
+        LoginInfo {
+            id,
+            password,
+        }
+    }
+}
+
diff --git a/crates/rocie-client/src/models/mod.rs b/crates/rocie-client/src/models/mod.rs
index e053411..135d612 100644
--- a/crates/rocie-client/src/models/mod.rs
+++ b/crates/rocie-client/src/models/mod.rs
@@ -2,6 +2,10 @@ pub mod barcode;
 pub use self::barcode::Barcode;
 pub mod barcode_id;
 pub use self::barcode_id::BarcodeId;
+pub mod login_info;
+pub use self::login_info::LoginInfo;
+pub mod password_hash;
+pub use self::password_hash::PasswordHash;
 pub mod product;
 pub use self::product::Product;
 pub mod product_amount;
@@ -36,3 +40,9 @@ pub mod unit_property_stub;
 pub use self::unit_property_stub::UnitPropertyStub;
 pub mod unit_stub;
 pub use self::unit_stub::UnitStub;
+pub mod user;
+pub use self::user::User;
+pub mod user_id;
+pub use self::user_id::UserId;
+pub mod user_stub;
+pub use self::user_stub::UserStub;
diff --git a/crates/rocie-client/src/models/password_hash.rs b/crates/rocie-client/src/models/password_hash.rs
new file mode 100644
index 0000000..31413bf
--- /dev/null
+++ b/crates/rocie-client/src/models/password_hash.rs
@@ -0,0 +1,29 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+use crate::models;
+use serde::{Deserialize, Serialize};
+
+/// PasswordHash : This is stored as an PHC password string.  This type corresponds to the string representation of a PHC string as described in the [PHC string format specification][1].  PHC strings have the following format:  ```text $<id>[$v=<version>][$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]] ```
+#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
+pub struct PasswordHash {
+    #[serde(rename = "value")]
+    pub value: String,
+}
+
+impl PasswordHash {
+    /// This is stored as an PHC password string.  This type corresponds to the string representation of a PHC string as described in the [PHC string format specification][1].  PHC strings have the following format:  ```text $<id>[$v=<version>][$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]] ```
+    pub fn new(value: String) -> PasswordHash {
+        PasswordHash {
+            value,
+        }
+    }
+}
+
diff --git a/crates/rocie-client/src/models/user.rs b/crates/rocie-client/src/models/user.rs
new file mode 100644
index 0000000..7397275
--- /dev/null
+++ b/crates/rocie-client/src/models/user.rs
@@ -0,0 +1,42 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+use crate::models;
+use serde::{Deserialize, Serialize};
+
+/// User : The definition of an rocie user.
+#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
+pub struct User {
+    /// An description of this user.
+    #[serde(rename = "description", skip_serializing_if = "Option::is_none")]
+    pub description: Option<String>,
+    /// The unique ID for this user.
+    #[serde(rename = "id")]
+    pub id: models::UserId,
+    /// The user-displayed name of this user.
+    #[serde(rename = "name")]
+    pub name: String,
+    /// The hash of the user's password.
+    #[serde(rename = "password_hash")]
+    pub password_hash: models::PasswordHash,
+}
+
+impl User {
+    /// The definition of an rocie user.
+    pub fn new(id: models::UserId, name: String, password_hash: models::PasswordHash) -> User {
+        User {
+            description: None,
+            id,
+            name,
+            password_hash,
+        }
+    }
+}
+
diff --git a/crates/rocie-client/src/models/user_id.rs b/crates/rocie-client/src/models/user_id.rs
new file mode 100644
index 0000000..3a67fd6
--- /dev/null
+++ b/crates/rocie-client/src/models/user_id.rs
@@ -0,0 +1,27 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+use crate::models;
+use serde::{Deserialize, Serialize};
+
+#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
+pub struct UserId {
+    #[serde(rename = "value")]
+    pub value: uuid::Uuid,
+}
+
+impl UserId {
+    pub fn new(value: uuid::Uuid) -> UserId {
+        UserId {
+            value,
+        }
+    }
+}
+
diff --git a/crates/rocie-client/src/models/user_stub.rs b/crates/rocie-client/src/models/user_stub.rs
new file mode 100644
index 0000000..8f620db
--- /dev/null
+++ b/crates/rocie-client/src/models/user_stub.rs
@@ -0,0 +1,36 @@
+/*
+ * rocie-server
+ *
+ * An enterprise grocery management system - server
+ *
+ * The version of the OpenAPI document: 0.1.0
+ * Contact: benedikt.peetz@b-peetz.de
+ * Generated by: https://openapi-generator.tech
+ */
+
+use crate::models;
+use serde::{Deserialize, Serialize};
+
+#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
+pub struct UserStub {
+    /// An optional description of the new user.
+    #[serde(rename = "description", skip_serializing_if = "Option::is_none")]
+    pub description: Option<String>,
+    /// The name of the new user.
+    #[serde(rename = "name")]
+    pub name: String,
+    /// The password of the new user.
+    #[serde(rename = "password")]
+    pub password: String,
+}
+
+impl UserStub {
+    pub fn new(name: String, password: String) -> UserStub {
+        UserStub {
+            description: None,
+            name,
+            password,
+        }
+    }
+}
+