From b7688f3f82cadb474ffd3644b6786af8ff3ffc21 Mon Sep 17 00:00:00 2001
From: Bruno Fernandes <brunofvn6@gmail.com.com>
Date: Fri, 21 Jun 2024 21:00:33 -0300
Subject: [PATCH] infra: all routes coded, tests must be made to verify

---
 client.http                                   | 272 ++++++++++++++++++
 keys/private_key.pem                          |  28 ++
 keys/private_key_base64.pem                   |   1 +
 keys/public_key.pem                           |   9 +
 keys/public_key_base64.pem                    |   1 +
 package-lock.json                             | 149 ++++++++--
 package.json                                  |   9 +-
 src/core/entities/unique-entity-id.ts         |   7 +
 .../courier/delete-courier-use-case.ts        |   3 +
 .../order/collect-order-use-case.spec.ts      |  16 +-
 .../use-cases/order/delete-order-use-case.ts  |   3 +
 .../order/deliver-order-use-case.spec.ts      |  24 +-
 .../fetch-nearby-orders-use-case.spec.ts      |   2 +-
 ...er-as-awaiting-for-pickup-use-case.spec.ts |  16 +-
 .../order/return-order-use-case.spec.ts       |  20 +-
 .../recipient/delete-recipient-use-case.ts    |   3 +
 .../update-recipient-use-case.spec.ts         |   6 +-
 .../recipient/update-recipient-use-case.ts    |   8 +-
 .../enterprise/entities/abstract/user.ts      |   4 +-
 .../enterprise/entities/order-attachment.ts   |   7 +
 .../enterprise/entities/order.ts              | 101 ++++---
 .../entities/value-objects/address.ts         |  67 +++--
 .../enterprise/entities/value-objects/cep.ts  |   7 +
 .../entities/value-objects/coordinates.ts     |  31 +-
 .../enterprise/entities/value-objects/cpf.ts  |   7 +
 .../entities/value-objects/state.ts           | 126 ++++----
 .../subscribers/on-order-delivered.ts         |  37 ---
 src/infra/app.module.ts                       |   2 +
 src/infra/auth/auth.module.ts                 |  29 ++
 src/infra/auth/current-user-decorator.ts      |  10 +
 src/infra/auth/jwt-auth.guard.ts              |  22 ++
 src/infra/auth/jwt.strategy.ts                |  29 ++
 src/infra/auth/public.ts                      |   4 +
 src/infra/cryptography/bcrypt-encrypter.ts    |  14 +
 src/infra/cryptography/cryptography.module.ts |  14 +
 src/infra/cryptography/jwt-encoder.ts         |  13 +
 .../mappers/prisma-update-order-mapper.ts     |   7 +-
 .../@exports/controllers.exports.ts           |  48 ++++
 .../authenticate.controller.ts                |  75 +++++
 .../register.controller.ts                    |  79 +++++
 .../collect-order.controller.e2e-spec.ts      | 120 ++++++++
 .../collect-order.controller.ts               |  85 ++++++
 .../create-order.controller.e2e-spec.ts       |   0
 .../create-order.controller.ts                |  87 ++++++
 .../delete-order.controller.e2e-spec.ts       |   0
 .../delete-order.controller.ts                |  68 +++++
 .../deliver-order.controller.e2e-spec.ts      |   0
 .../deliver-order.controller.ts               |  77 +++++
 ...fetch-nearby-orders.controller.e2e-spec.ts |   0
 .../fetch-nearby-orders.controller.ts         |  89 ++++++
 .../fetch-orders.controller.e2e-spec.ts       |   0
 .../fetch-orders.controller.ts                | 110 +++++++
 .../find-order.controller.e2e-spec.ts         |   0
 .../find-order.controller.ts                  |  78 +++++
 ...awaiting-for-pickup.controller.e2e-spec.ts |   0
 ...order-as-awaiting-for-pickup.controller.ts |  79 +++++
 .../return-order.controller.e2e-spec.ts       |   0
 .../return-order.controller.ts                |  78 +++++
 .../delete-user.controller.ts                 |  78 +++++
 .../fetch-users.controller.ts                 |  84 ++++++
 .../user-controllers/find-user.controller.ts  |  87 ++++++
 .../update-user-password.controller.ts        |  88 ++++++
 .../update-user.controller.ts                 |  90 ++++++
 .../make-authenticate-request.ts              |  20 ++
 .../make-register-request.ts                  |  24 ++
 .../make-collect-order-request.ts             |  18 ++
 .../make-create-order-request.ts              |  24 ++
 .../make-delete-order-request.ts              |  18 ++
 .../make-deliver-order-request.ts             |  19 ++
 .../make-fetch-nearby-orders-request.ts       |  26 ++
 .../make-fetch-orders-request.ts              |  20 ++
 .../make-find-order-request.ts                |  18 ++
 ...rk-order-as-awaiting-for-pickup-request.ts |  18 ++
 .../return-order-request copy.ts              |  18 ++
 .../user-factories/delete-user-request.ts     |  20 ++
 .../user-factories/fetch-users-request.ts     |  19 ++
 .../user-factories/find-user-request.ts       |  20 ++
 .../update-user-password-request.ts           |  24 ++
 .../user-factories/update-user-request.ts     |  25 ++
 src/infra/http/http.module.ts                 |   8 +-
 src/infra/http/utils/isCPF.ts                 |  61 ++++
 src/infra/pipes/zod-validation-pipe.ts        |  23 ++
 test/factories/entities/makeOrder.ts          |  10 +-
 utils/generate-async-crypto-keys.ts           | 243 ++++++++++++++++
 utils/generate-env-file-with-env-example.ts   |   8 +
 85 files changed, 3055 insertions(+), 237 deletions(-)
 create mode 100644 client.http
 create mode 100644 keys/private_key.pem
 create mode 100644 keys/private_key_base64.pem
 create mode 100644 keys/public_key.pem
 create mode 100644 keys/public_key_base64.pem
 delete mode 100644 src/domain/generic/notification/application/subscribers/on-order-delivered.ts
 create mode 100644 src/infra/auth/auth.module.ts
 create mode 100644 src/infra/auth/current-user-decorator.ts
 create mode 100644 src/infra/auth/jwt-auth.guard.ts
 create mode 100644 src/infra/auth/jwt.strategy.ts
 create mode 100644 src/infra/auth/public.ts
 create mode 100644 src/infra/cryptography/bcrypt-encrypter.ts
 create mode 100644 src/infra/cryptography/cryptography.module.ts
 create mode 100644 src/infra/cryptography/jwt-encoder.ts
 create mode 100644 src/infra/http/controllers/auth-and-register-controllers/authenticate.controller.ts
 create mode 100644 src/infra/http/controllers/auth-and-register-controllers/register.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/collect-order.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/collect-order.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/create-order.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/create-order.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/delete-order.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/delete-order.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/deliver-order.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/deliver-order.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/fetch-nearby-orders.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/fetch-nearby-orders.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/fetch-orders.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/fetch-orders.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/find-order.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/find-order.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/mark-order-as-awaiting-for-pickup.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/mark-order-as-awaiting-for-pickup.controller.ts
 create mode 100644 src/infra/http/controllers/order-controllers/return-order.controller.e2e-spec.ts
 create mode 100644 src/infra/http/controllers/order-controllers/return-order.controller.ts
 create mode 100644 src/infra/http/controllers/user-controllers/delete-user.controller.ts
 create mode 100644 src/infra/http/controllers/user-controllers/fetch-users.controller.ts
 create mode 100644 src/infra/http/controllers/user-controllers/find-user.controller.ts
 create mode 100644 src/infra/http/controllers/user-controllers/update-user-password.controller.ts
 create mode 100644 src/infra/http/controllers/user-controllers/update-user.controller.ts
 create mode 100644 src/infra/http/factories/requests/auth-and-register-factories/make-authenticate-request.ts
 create mode 100644 src/infra/http/factories/requests/auth-and-register-factories/make-register-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-collect-order-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-create-order-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-delete-order-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-deliver-order-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-fetch-nearby-orders-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-fetch-orders-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-find-order-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/make-mark-order-as-awaiting-for-pickup-request.ts
 create mode 100644 src/infra/http/factories/requests/order-request-factories/return-order-request copy.ts
 create mode 100644 src/infra/http/factories/requests/user-factories/delete-user-request.ts
 create mode 100644 src/infra/http/factories/requests/user-factories/fetch-users-request.ts
 create mode 100644 src/infra/http/factories/requests/user-factories/find-user-request.ts
 create mode 100644 src/infra/http/factories/requests/user-factories/update-user-password-request.ts
 create mode 100644 src/infra/http/factories/requests/user-factories/update-user-request.ts
 create mode 100644 src/infra/http/utils/isCPF.ts
 create mode 100644 src/infra/pipes/zod-validation-pipe.ts
 create mode 100644 utils/generate-async-crypto-keys.ts
 create mode 100644 utils/generate-env-file-with-env-example.ts

diff --git a/client.http b/client.http
new file mode 100644
index 0000000..621ebb4
--- /dev/null
+++ b/client.http
@@ -0,0 +1,272 @@
+@baseUrl = http://localhost:3000
+@authToken = {{authenticate.response.body.token}}
+
+
+@firstCourierId = {{fetchCourier.response.body.couriers[0]._id._value}}
+@firstRecipientId = {{fetchRecipient.response.body.recipients[0]._id._value}}
+
+@firstOrderId = {{fetchAllOrders.response.body.orders[0]._id._value}}
+
+@currentLatitude = -23.3963853
+@currentLongitude = -46.3086881
+
+@nearbyLatitude = -23.3798813
+@nearbyLongitude = -46.2576877
+
+@farAwayLatitude = -23.3571925
+@farAwayLongitude = -46.2076257
+
+
+###
+
+
+# @name authenticate
+POST {{baseUrl}}/sessions
+Content-Type: application/json
+
+{
+    "cpf": "45618677830",
+    "password": "123",
+    "role": "adm"
+}
+
+
+###
+
+# @name registerCourier
+POST {{baseUrl}}/register
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+{
+    "cpf": "24247258028",
+    "name": "courier teste",
+    "password": "123",
+    "requestResponsibleId": "02e3db39-2855-4d57-86bf-8a10364d9804",
+    "role": "courier"
+}
+
+###
+
+# @name registerRecipient
+POST {{baseUrl}}/register
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+{
+    "cpf": "67131743020",
+    "name": "courier teste",
+    "password": "123",
+    "requestResponsibleId": "02e3db39-2855-4d57-86bf-8a10364d9804",
+    "role": "recipient"
+}
+
+
+###
+
+# @name deleteUser
+DELETE  {{baseUrl}}/users/courier/a95c748a-dbbb-456f-9d6c-a91a584d2ca9
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name fetchCourier
+GET {{baseUrl}}/users/courier
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name fetchRecipient
+GET {{baseUrl}}/users/recipient
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name findCourier
+GET {{baseUrl}}/users/courier/{{firstCourierId}}
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name findRecipient
+GET {{baseUrl}}/users/recipient/{{firstRecipientId}}
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name updateCourierPassword
+PATCH  {{baseUrl}}/users/courier/{{firstCourierId}}/update-password
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+{
+  "password": "Courier pass",
+}
+
+
+###
+
+# @name updateRecipientPassword
+PATCH  {{baseUrl}}/users/recipient/{{firstRecipientId}}/update-password
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+{
+  "password": "Recipient pass",
+}
+
+
+
+###
+
+# @name updateUser
+PUT   {{baseUrl}}/users/courier/6726449a-790d-40e9-a5fe-6d725066c335
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+{
+    "cpf": "48995844078",
+    "name": "otavio 2"
+}
+
+
+###
+
+# @name collectOrder
+PATCH  {{baseUrl}}/orders/{{firstOrderId}}/collect
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name createNearbyOrder
+POST  {{baseUrl}}/orders
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+{
+    "courierId": "{{firstCourierId}}",
+    "recipientId": "{{firstRecipientId}}",
+    "address": {
+        "coordinates": {
+            "latitude": "{{nearbyLatitude}}",
+            "longitude": "{{nearbyLongitude}}"
+        },
+        "cep": "77777-888",
+        "number": "Rua dos bobos",
+        "street": "número zero",
+        "neighborhood": "Não tinha bairro",
+        "city": "Não tinha cidade",
+        "state": "SP"
+    }
+}
+
+
+###
+
+# @name createFarAwayOrder
+POST  {{baseUrl}}/orders
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+{
+    "courierId": "{{firstCourierId}}",
+    "recipientId": "{{firstRecipientId}}",
+    "address": {
+        "coordinates": {
+            "latitude": "{{farAwayLatitude}}",
+            "longitude": "{{farAwayLongitude}}"
+        },
+        "cep": "77777-888",
+        "number": "Rua dos bobos",
+        "street": "número zero",
+        "neighborhood": "Não tinha bairro",
+        "city": "Não tinha cidade",
+        "state": "SP"
+    }
+}
+
+
+###
+
+# @name deleteOrder
+DELETE  {{baseUrl}}/orders/{{firstOrderId}}
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name deliverOrder
+PATCH  {{baseUrl}}/orders/{{firstOrderId}}/deliver
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name fetchNearbyOrders
+GET {{baseUrl}}/orders/:{{firstCourierId}}/nearby?latitude={{currentLatitude}}&longitude={{currentLongitude}}
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name fetchAllOrders
+GET {{baseUrl}}/orders/all
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name fetchCourierOrders
+GET {{baseUrl}}/orders/courier?userId={{firstCourierId}}
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name fetchRecipientOrders
+GET {{baseUrl}}/orders/recipent?userId={{firstRecipientId}}
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name findOrder
+GET {{baseUrl}}/orders/{{firstOrderId}}/find
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name markOrderAsAwaitingForPickup
+PATCH  {{baseUrl}}/orders/{{firstOrderId}}/awaiting
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
+###
+
+# @name returnOrder
+PATCH  {{baseUrl}}/orders/{{firstOrderId}}/return?returnCause=porque sim
+Content-Type: application/json
+Authorization: Bearer {{authToken}}
+
+
diff --git a/keys/private_key.pem b/keys/private_key.pem
new file mode 100644
index 0000000..fc5328f
--- /dev/null
+++ b/keys/private_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCb2arF98U+xNCi
+Tid9aYct7r9IbTCYA2xj2f+evcIywms5agMSSYHH/rHSMi/IK+pHCxuEbPb2kH3Q
+rg67QrrqP7YP/ZfIrZP9mh3QzxTanckFyAfvmVPlSXCH4wz4FTcXHk+k3wa0k3/5
+/tt1uZlJ21+WzxD+qROkm1ONNCMdwCQXPXw9065fRZJTFuGZ9VcLESup7ZxEYidu
+MnCDmShQ3xwiwGpnw7hOo+5aZYP62h4ZTrZVi76iNz8mAYG1k43PjLxIFwqb77Ad
+fOSXkHeu314E2WZN5nJfO3qjFE8w5olEMF04jH+sikKA8FyMnsrVb9Dco71cRE9i
+i5/Y25hNAgMBAAECggEAHygYA505tcd3dSceLmyBHY3n+DT5/L3cdqbPez7w2qBy
++qamqAqBc0fH6V9mnYQoAR1nmiUFhzvSJzyQzd90ih2ECnTWWgRXfGDJ2qN3hg/6
+rtjzOzNiKgmxQT1DK7pkCc9huTJr/wAo2sPYQFQDINiGJtpNCbgn6OWzgZxdc9YU
+ktemF6iT3S1Ggr+S60o4kHJIlKogMpOp/wnXMxuBTYlDA2my5TEYmTA8aXIc3fJU
+UxrY2xtAbjH1vaR5dFD2lK5yrBXcOy5DxEdzm9ETlNgfJo4HRkrxwCzeSo01EzJm
+zvTsP3FkiMuHUaSldG+kIp3A0wzSHBArEf63XntXWQKBgQDJme0Snp+Z1CJAp/8R
+D45O27Q3cAo2R1BoZ8mMqEsMkxKmm43O8a07BPKy1qHezCDiCPpx9HxUsI+PdLVo
+WHaaclzaoZLbV8WA0KMRhgP6/DY9/qb8FsKEh9CTxIWOyHXJZjLW0YjEbe6Ne1E/
+no2Vr5OBlEGIjKlnopWbX/oGxQKBgQDF52JXWzj+dEOv7QHoXx65d6Wo1F9PXiYF
+kWgAUlhBhR0aHVgHZ1/3aITXibanvHLWtt6izdf0my5HlvQ4BmxilY182J6a/u1V
+1fvUf9wNrT1IUhqZiJJAniF1eCMbURihtf0cVeU0291hsWSSNWORzu/daT76gzri
+3J/iu8yj6QKBgFOLhXJ859kgzx0KQaq5TpkhdTqwJJs/zHOn5x9yMr/ARy9iMU88
+WjSmJUm1ppkk8M+bNuZ4kfmqvaOOkwrt9iClGhPEd46Mfh2W2K0PY6DkWjowyNSZ
+Pf0cJ3TFMS/tpNpUjub1KH92qzBYlWAO/c+1ViSR4uKKoD2BZAxipsOdAoGANA3W
+ag/Of+9o1l9Kvyo11KbJ5gxmPWQQMCq85kjCeglfTD0nqFrifRr6xg6tApWoxx02
+li/6e5ZNp/rmpc3auFuJ6aq4nSAsoQU1xgETim1kzx75bCTmAyUUu+crpMXB6tcJ
+imh1b1/dbRLR1zs/w1xg7yX9sLrPxFgvnd2zx/ECgYBkI7tpq1NVnWDGtt/JDHrR
+Ukiuk7rJ8yCdxBLGFsDhF7QXIoSSPW5AATptEs3TVVNiRXmOHjzSiKVvp7h+zXe/
+eb10OkfEuQYnZidPr1HyD3tqtcko3XK3fPGruXwX4SnM20Eh5JUJv+fQzzTZ136W
+huL3jGmD0p3naEeDL6HZIA==
+-----END PRIVATE KEY-----
diff --git a/keys/private_key_base64.pem b/keys/private_key_base64.pem
new file mode 100644
index 0000000..6584c7e
--- /dev/null
+++ b/keys/private_key_base64.pem
@@ -0,0 +1 @@
+LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tDQpNSUlFdkFJQkFEQU5CZ2txaGtpRzl3MEJBUUVGQUFTQ0JLWXdnZ1NpQWdFQUFvSUJBUUNiMmFyRjk4VSt4TkNpDQpUaWQ5YVljdDdyOUliVENZQTJ4ajJmK2V2Y0l5d21zNWFnTVNTWUhIL3JIU01pL0lLK3BIQ3h1RWJQYjJrSDNRDQpyZzY3UXJycVA3WVAvWmZJclpQOW1oM1F6eFRhbmNrRnlBZnZtVlBsU1hDSDR3ejRGVGNYSGsrazN3YTBrMy81DQovdHQxdVpsSjIxK1d6eEQrcVJPa20xT05OQ01kd0NRWFBYdzkwNjVmUlpKVEZ1R1o5VmNMRVN1cDdaeEVZaWR1DQpNbkNEbVNoUTN4d2l3R3BudzdoT28rNWFaWVA2Mmg0WlRyWlZpNzZpTno4bUFZRzFrNDNQakx4SUZ3cWI3N0FkDQpmT1NYa0hldTMxNEUyV1pONW5KZk8zcWpGRTh3NW9sRU1GMDRqSCtzaWtLQThGeU1uc3JWYjlEY283MWNSRTlpDQppNS9ZMjVoTkFnTUJBQUVDZ2dFQUh5Z1lBNTA1dGNkM2RTY2VMbXlCSFkzbitEVDUvTDNjZHFiUGV6N3cycUJ5DQorcWFtcUFxQmMwZkg2VjltbllRb0FSMW5taVVGaHp2U0p6eVF6ZDkwaWgyRUNuVFdXZ1JYZkdESjJxTjNoZy82DQpydGp6T3pOaUtnbXhRVDFESzdwa0NjOWh1VEpyL3dBbzJzUFlRRlFESU5pR0p0cE5DYmduNk9XemdaeGRjOVlVDQprdGVtRjZpVDNTMUdncitTNjBvNGtISklsS29nTXBPcC93blhNeHVCVFlsREEybXk1VEVZbVRBOGFYSWMzZkpVDQpVeHJZMnh0QWJqSDF2YVI1ZEZEMmxLNXlyQlhjT3k1RHhFZHptOUVUbE5nZkpvNEhSa3J4d0N6ZVNvMDFFekptDQp6dlRzUDNGa2lNdUhVYVNsZEcra0lwM0Ewd3pTSEJBckVmNjNYbnRYV1FLQmdRREptZTBTbnArWjFDSkFwLzhSDQpENDVPMjdRM2NBbzJSMUJvWjhtTXFFc01reEttbTQzTzhhMDdCUEt5MXFIZXpDRGlDUHB4OUh4VXNJK1BkTFZvDQpXSGFhY2x6YW9aTGJWOFdBMEtNUmhnUDYvRFk5L3FiOEZzS0VoOUNUeElXT3lIWEpaakxXMFlqRWJlNk5lMUUvDQpubzJWcjVPQmxFR0lqS2xub3BXYlgvb0d4UUtCZ1FERjUySlhXemorZEVPdjdRSG9YeDY1ZDZXbzFGOVBYaVlGDQprV2dBVWxoQmhSMGFIVmdIWjEvM2FJVFhpYmFudkhMV3R0Nml6ZGYwbXk1SGx2UTRCbXhpbFkxODJKNmEvdTFWDQoxZnZVZjl3TnJUMUlVaHFaaUpKQW5pRjFlQ01iVVJpaHRmMGNWZVUwMjkxaHNXU1NOV09SenUvZGFUNzZnenJpDQozSi9pdTh5ajZRS0JnRk9MaFhKODU5a2d6eDBLUWFxNVRwa2hkVHF3SkpzL3pIT241eDl5TXIvQVJ5OWlNVTg4DQpXalNtSlVtMXBwa2s4TStiTnVaNGtmbXF2YU9Pa3dydDlpQ2xHaFBFZDQ2TWZoMlcySzBQWTZEa1dqb3d5TlNaDQpQZjBjSjNURk1TL3RwTnBVanViMUtIOTJxekJZbFdBTy9jKzFWaVNSNHVLS29EMkJaQXhpcHNPZEFvR0FOQTNXDQphZy9PZis5bzFsOUt2eW8xMUtiSjVneG1QV1FRTUNxODVrakNlZ2xmVEQwbnFGcmlmUnI2eGc2dEFwV294eDAyDQpsaS82ZTVaTnAvcm1wYzNhdUZ1SjZhcTRuU0Fzb1FVMXhnRVRpbTFreng3NWJDVG1BeVVVdStjcnBNWEI2dGNKDQppbWgxYjEvZGJSTFIxenMvdzF4Zzd5WDlzTHJQeEZndm5kMnp4L0VDZ1lCa0k3dHBxMU5WbldER3R0L0pESHJSDQpVa2l1azdySjh5Q2R4QkxHRnNEaEY3UVhJb1NTUFc1QUFUcHRFczNUVlZOaVJYbU9IanpTaUtWdnA3aCt6WGUvDQplYjEwT2tmRXVRWW5aaWRQcjFIeUQzdHF0Y2tvM1hLM2ZQR3J1WHdYNFNuTTIwRWg1SlVKditmUXp6VFoxMzZXDQpodUwzakdtRDBwM25hRWVETDZIWklBPT0NCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0NCg==
\ No newline at end of file
diff --git a/keys/public_key.pem b/keys/public_key.pem
new file mode 100644
index 0000000..384bcaa
--- /dev/null
+++ b/keys/public_key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm9mqxffFPsTQok4nfWmH
+Le6/SG0wmANsY9n/nr3CMsJrOWoDEkmBx/6x0jIvyCvqRwsbhGz29pB90K4Ou0K6
+6j+2D/2XyK2T/Zod0M8U2p3JBcgH75lT5Ulwh+MM+BU3Fx5PpN8GtJN/+f7bdbmZ
+Sdtfls8Q/qkTpJtTjTQjHcAkFz18PdOuX0WSUxbhmfVXCxErqe2cRGInbjJwg5ko
+UN8cIsBqZ8O4TqPuWmWD+toeGU62VYu+ojc/JgGBtZONz4y8SBcKm++wHXzkl5B3
+rt9eBNlmTeZyXzt6oxRPMOaJRDBdOIx/rIpCgPBcjJ7K1W/Q3KO9XERPYouf2NuY
+TQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/keys/public_key_base64.pem b/keys/public_key_base64.pem
new file mode 100644
index 0000000..8acefb0
--- /dev/null
+++ b/keys/public_key_base64.pem
@@ -0,0 +1 @@
+LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBbTltcXhmZkZQc1RRb2s0bmZXbUgNCkxlNi9TRzB3bUFOc1k5bi9ucjNDTXNKck9Xb0RFa21CeC82eDBqSXZ5Q3ZxUndzYmhHejI5cEI5MEs0T3UwSzYNCjZqKzJELzJYeUsyVC9ab2QwTThVMnAzSkJjZ0g3NWxUNVVsd2grTU0rQlUzRng1UHBOOEd0Sk4vK2Y3YmRibVoNClNkdGZsczhRL3FrVHBKdFRqVFFqSGNBa0Z6MThQZE91WDBXU1V4YmhtZlZYQ3hFcnFlMmNSR0luYmpKd2c1a28NClVOOGNJc0JxWjhPNFRxUHVXbVdEK3RvZUdVNjJWWXUrb2pjL0pnR0J0Wk9OejR5OFNCY0ttKyt3SFh6a2w1QjMNCnJ0OWVCTmxtVGVaeVh6dDZveFJQTU9hSlJEQmRPSXgvcklwQ2dQQmNqSjdLMVcvUTNLTzlYRVJQWW91ZjJOdVkNClRRSURBUUFCDQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0NCg==
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index f41b442..b1beda5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,8 @@
         "@nestjs/common": "10.3.9",
         "@nestjs/config": "3.2.2",
         "@nestjs/core": "10.3.9",
+        "@nestjs/jwt": "10.2.0",
+        "@nestjs/passport": "10.0.3",
         "@nestjs/platform-express": "10.3.9",
         "@prisma/client": "5.15.0",
         "bcryptjs": "2.4.3",
@@ -20,7 +22,9 @@
         "reflect-metadata": "0.2.2",
         "remask": "1.2.2",
         "rxjs": "7.8.1",
-        "zod": "3.23.8"
+        "tsx": "4.15.6",
+        "zod": "3.23.8",
+        "zod-validation-error": "3.3.0"
       },
       "devDependencies": {
         "@faker-js/faker": "8.4.1",
@@ -32,6 +36,7 @@
         "@types/express": "4.17.21",
         "@types/multer": "1.4.11",
         "@types/node": "20.14.2",
+        "@types/passport-jwt": "4.0.1",
         "@types/supertest": "6.0.2",
         "@typescript-eslint/eslint-plugin": "7.13.0",
         "@typescript-eslint/parser": "7.13.0",
@@ -382,7 +387,6 @@
       "cpu": [
         "ppc64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "aix"
@@ -398,7 +402,6 @@
       "cpu": [
         "arm"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "android"
@@ -414,7 +417,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "android"
@@ -430,7 +432,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "android"
@@ -446,7 +447,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "darwin"
@@ -462,7 +462,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "darwin"
@@ -478,7 +477,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "freebsd"
@@ -494,7 +492,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "freebsd"
@@ -510,7 +507,6 @@
       "cpu": [
         "arm"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -526,7 +522,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -542,7 +537,6 @@
       "cpu": [
         "ia32"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -558,7 +552,6 @@
       "cpu": [
         "loong64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -574,7 +567,6 @@
       "cpu": [
         "mips64el"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -590,7 +582,6 @@
       "cpu": [
         "ppc64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -606,7 +597,6 @@
       "cpu": [
         "riscv64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -622,7 +612,6 @@
       "cpu": [
         "s390x"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -638,7 +627,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "linux"
@@ -654,7 +642,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "netbsd"
@@ -670,7 +657,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "openbsd"
@@ -686,7 +672,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "sunos"
@@ -702,7 +687,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "win32"
@@ -718,7 +702,6 @@
       "cpu": [
         "ia32"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "win32"
@@ -734,7 +717,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "optional": true,
       "os": [
         "win32"
@@ -1312,6 +1294,27 @@
         }
       }
     },
+    "node_modules/@nestjs/jwt": {
+      "version": "10.2.0",
+      "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-10.2.0.tgz",
+      "integrity": "sha512-x8cG90SURkEiLOehNaN2aRlotxT0KZESUliOPKKnjWiyJOcWurkF3w345WOX0P4MgFzUjGoZ1Sy0aZnxeihT0g==",
+      "dependencies": {
+        "@types/jsonwebtoken": "9.0.5",
+        "jsonwebtoken": "9.0.2"
+      },
+      "peerDependencies": {
+        "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0"
+      }
+    },
+    "node_modules/@nestjs/passport": {
+      "version": "10.0.3",
+      "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-10.0.3.tgz",
+      "integrity": "sha512-znJ9Y4S8ZDVY+j4doWAJ8EuuVO7SkQN3yOBmzxbGaXbvcSwFDAdGJ+OMCg52NdzIO4tQoN4pYKx8W6M0ArfFRQ==",
+      "peerDependencies": {
+        "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
+        "passport": "^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0"
+      }
+    },
     "node_modules/@nestjs/platform-express": {
       "version": "10.3.9",
       "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.9.tgz",
@@ -2354,6 +2357,14 @@
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
       "dev": true
     },
+    "node_modules/@types/jsonwebtoken": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz",
+      "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/methods": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
@@ -2379,11 +2390,39 @@
       "version": "20.14.2",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
       "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
-      "dev": true,
       "dependencies": {
         "undici-types": "~5.26.4"
       }
     },
+    "node_modules/@types/passport": {
+      "version": "1.0.16",
+      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz",
+      "integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/passport-jwt": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@types/passport-jwt/-/passport-jwt-4.0.1.tgz",
+      "integrity": "sha512-Y0Ykz6nWP4jpxgEUYq8NoVZeCQPo1ZndJLfapI249g1jHChvRfZRO/LS3tqu26YgAS/laI1qx98sYGz0IalRXQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/jsonwebtoken": "*",
+        "@types/passport-strategy": "*"
+      }
+    },
+    "node_modules/@types/passport-strategy": {
+      "version": "0.2.38",
+      "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
+      "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*",
+        "@types/passport": "*"
+      }
+    },
     "node_modules/@types/qs": {
       "version": "6.9.15",
       "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
@@ -4453,7 +4492,6 @@
       "version": "0.21.5",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
       "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
-      "dev": true,
       "hasInstallScript": true,
       "bin": {
         "esbuild": "bin/esbuild"
@@ -5698,7 +5736,6 @@
       "version": "2.3.3",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
       "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "dev": true,
       "hasInstallScript": true,
       "optional": true,
       "os": [
@@ -5791,7 +5828,6 @@
       "version": "4.7.5",
       "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz",
       "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==",
-      "dev": true,
       "dependencies": {
         "resolve-pkg-maps": "^1.0.0"
       },
@@ -7505,6 +7541,24 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/passport": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz",
+      "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==",
+      "peer": true,
+      "dependencies": {
+        "passport-strategy": "1.x.x",
+        "pause": "0.0.1",
+        "utils-merge": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/jaredhanson"
+      }
+    },
     "node_modules/passport-jwt": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.1.tgz",
@@ -7609,6 +7663,12 @@
         "node": "*"
       }
     },
+    "node_modules/pause": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
+      "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==",
+      "peer": true
+    },
     "node_modules/picocolors": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
@@ -8037,7 +8097,6 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
       "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
-      "dev": true,
       "funding": {
         "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
       }
@@ -9201,6 +9260,24 @@
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
       "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
     },
+    "node_modules/tsx": {
+      "version": "4.15.6",
+      "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.15.6.tgz",
+      "integrity": "sha512-is0VQQlfNZRHEuSSTKA6m4xw74IU4AizmuB6lAYLRt9XtuyeQnyJYexhNZOPCB59SqC4JzmSzPnHGBXxf3k0hA==",
+      "dependencies": {
+        "esbuild": "~0.21.4",
+        "get-tsconfig": "^4.7.5"
+      },
+      "bin": {
+        "tsx": "dist/cli.mjs"
+      },
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      }
+    },
     "node_modules/type-check": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -9398,8 +9475,7 @@
     "node_modules/undici-types": {
       "version": "5.26.5",
       "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
-      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
-      "dev": true
+      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
     },
     "node_modules/universalify": {
       "version": "2.0.1",
@@ -10148,6 +10224,17 @@
       "funding": {
         "url": "https://github.com/sponsors/colinhacks"
       }
+    },
+    "node_modules/zod-validation-error": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.3.0.tgz",
+      "integrity": "sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw==",
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "peerDependencies": {
+        "zod": "^3.18.0"
+      }
     }
   }
 }
diff --git a/package.json b/package.json
index 3ec1cd6..09cb5ab 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,8 @@
     "build": "nest build",
     "start": "nest start",
     "dev": "nest start --watch",
+    "dev:gen-env": "tsx ./utils/generate-env-file-with-env-example.ts",
+    "ci:gen-jwt-keys": "tsx ./utils/generate-async-crypto-keys.ts",
     "start:debug": "nest start --debug --watch",
     "start:prod": "node dist/main",
     "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
@@ -28,6 +30,7 @@
     "@types/express": "4.17.21",
     "@types/multer": "1.4.11",
     "@types/node": "20.14.2",
+    "@types/passport-jwt": "4.0.1",
     "@types/supertest": "6.0.2",
     "@typescript-eslint/eslint-plugin": "7.13.0",
     "@typescript-eslint/parser": "7.13.0",
@@ -50,6 +53,8 @@
     "@nestjs/common": "10.3.9",
     "@nestjs/config": "3.2.2",
     "@nestjs/core": "10.3.9",
+    "@nestjs/jwt": "10.2.0",
+    "@nestjs/passport": "10.0.3",
     "@nestjs/platform-express": "10.3.9",
     "@prisma/client": "5.15.0",
     "bcryptjs": "2.4.3",
@@ -58,6 +63,8 @@
     "reflect-metadata": "0.2.2",
     "remask": "1.2.2",
     "rxjs": "7.8.1",
-    "zod": "3.23.8"
+    "tsx": "4.15.6",
+    "zod": "3.23.8",
+    "zod-validation-error": "3.3.0"
   }
 }
diff --git a/src/core/entities/unique-entity-id.ts b/src/core/entities/unique-entity-id.ts
index 8e95b06..813c07e 100644
--- a/src/core/entities/unique-entity-id.ts
+++ b/src/core/entities/unique-entity-id.ts
@@ -1,4 +1,11 @@
 import { randomUUID } from 'node:crypto'
+import z from 'zod'
+
+// eslint-disable-next-line
+export const uniqueEntityIdInstanceSchema = z.custom<UniqueEntityId>(
+  (data) => data instanceof UniqueEntityId,
+  'must be an UniqueEntityId',
+)
 
 export default class UniqueEntityId {
   private _value: string
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/courier/delete-courier-use-case.ts b/src/domain/core/deliveries-and-orders/application/use-cases/courier/delete-courier-use-case.ts
index 5f9a263..a716f81 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/courier/delete-courier-use-case.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/courier/delete-courier-use-case.ts
@@ -33,6 +33,9 @@ export class DeleteCourierUseCase {
     const hasPermission = Permissions.hasPermission('read_courier', adm.role)
     if (!hasPermission) return left(new UnauthorizedError())
 
+    const courier = await this.couriersRepository.findById(courierId)
+    if (!courier) return left(new ResourceNotFoundError())
+
     await this.couriersRepository.delete(courierId)
 
     return right(null)
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/order/collect-order-use-case.spec.ts b/src/domain/core/deliveries-and-orders/application/use-cases/order/collect-order-use-case.spec.ts
index ff06fee..c9c46ca 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/order/collect-order-use-case.spec.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/order/collect-order-use-case.spec.ts
@@ -40,7 +40,7 @@ describe('collect order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
@@ -113,11 +113,11 @@ describe('collect order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
 
@@ -157,13 +157,13 @@ describe('collect order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
     // fake return
-    order.actions.adm.admReturned()
+    order.actions.adm.admReturned('sei la', adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/order/delete-order-use-case.ts b/src/domain/core/deliveries-and-orders/application/use-cases/order/delete-order-use-case.ts
index ffe6ae8..179d399 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/order/delete-order-use-case.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/order/delete-order-use-case.ts
@@ -33,6 +33,9 @@ export class DeleteOrderUseCase {
     const hasPermission = Permissions.hasPermission('read_order', adm.role)
     if (!hasPermission) return left(new UnauthorizedError())
 
+    const order = await this.ordersRepository.findById(orderId)
+    if (!order) return left(new ResourceNotFoundError())
+
     await this.ordersRepository.delete(orderId)
 
     return right(null)
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/order/deliver-order-use-case.spec.ts b/src/domain/core/deliveries-and-orders/application/use-cases/order/deliver-order-use-case.spec.ts
index 76c718d..60ab9a6 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/order/deliver-order-use-case.spec.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/order/deliver-order-use-case.spec.ts
@@ -44,10 +44,10 @@ describe('deliver order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
 
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
@@ -94,10 +94,10 @@ describe('deliver order use case', () => {
     const order = (await sut.dependencies.ordersRepository.findMany())[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
 
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
@@ -145,7 +145,7 @@ describe('deliver order use case', () => {
     const order = (await sut.dependencies.ordersRepository.findMany())[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
@@ -195,13 +195,13 @@ describe('deliver order use case', () => {
     const order = (await sut.dependencies.ordersRepository.findMany())[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
     // fake return
-    order.actions.adm.admReturned()
+    order.actions.adm.admReturned('sei la', adm.id)
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
 
@@ -252,11 +252,11 @@ describe('deliver order use case', () => {
     const order = (await sut.dependencies.ordersRepository.findMany())[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/order/fetch-nearby-orders-use-case.spec.ts b/src/domain/core/deliveries-and-orders/application/use-cases/order/fetch-nearby-orders-use-case.spec.ts
index 4944c72..35589e8 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/order/fetch-nearby-orders-use-case.spec.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/order/fetch-nearby-orders-use-case.spec.ts
@@ -127,7 +127,7 @@ describe('fetch nearby orders use case', () => {
         longitude: -46.3086881,
       },
     })
-    // courier ccordinates
+    // courier coordinates
     // -23.3963853,-46.3086881
 
     expect(sutResp.isRight()).toBeTruthy()
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/order/mark-order-as-awaiting-for-pickup-use-case.spec.ts b/src/domain/core/deliveries-and-orders/application/use-cases/order/mark-order-as-awaiting-for-pickup-use-case.spec.ts
index ab89061..ccb666f 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/order/mark-order-as-awaiting-for-pickup-use-case.spec.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/order/mark-order-as-awaiting-for-pickup-use-case.spec.ts
@@ -105,7 +105,7 @@ describe('mark order as awaiting for pickup use case', () => {
     const order = (await sut.dependencies.ordersRepository.findMany())[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
@@ -145,13 +145,13 @@ describe('mark order as awaiting for pickup use case', () => {
     const order = (await sut.dependencies.ordersRepository.findMany())[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
     // fake return
-    order.actions.adm.admReturned()
+    order.actions.adm.admReturned('sei la', adm.id)
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
 
@@ -190,11 +190,11 @@ describe('mark order as awaiting for pickup use case', () => {
     const order = (await sut.dependencies.ordersRepository.findMany())[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/order/return-order-use-case.spec.ts b/src/domain/core/deliveries-and-orders/application/use-cases/order/return-order-use-case.spec.ts
index 30bc8eb..08d9121 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/order/return-order-use-case.spec.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/order/return-order-use-case.spec.ts
@@ -41,11 +41,11 @@ describe('return order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
 
@@ -121,9 +121,9 @@ describe('return order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
 
     const sutResp = await sut.useCase.execute({
       orderId: order.id.value,
@@ -163,13 +163,13 @@ describe('return order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
     // fake collected
-    order.actions.adm.admCollected()
+    order.actions.adm.admCollected(adm.id)
     // fake delivery
-    order.actions.courier.courierDeliver()
+    order.actions.courier.courierDeliver(order.courierId!)
     // fake return
-    order.actions.adm.admReturned()
+    order.actions.adm.admReturned('sei la', adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
@@ -212,7 +212,7 @@ describe('return order use case', () => {
     )[0]
 
     // fake awaiting for pickup
-    order.actions.adm.admSetAwaitingPickup()
+    order.actions.adm.admSetAwaitingPickup(adm.id)
 
     // update changes
     createOrder.dependencies.ordersRepository.update(order)
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/recipient/delete-recipient-use-case.ts b/src/domain/core/deliveries-and-orders/application/use-cases/recipient/delete-recipient-use-case.ts
index 0d9ee99..0e7b294 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/recipient/delete-recipient-use-case.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/recipient/delete-recipient-use-case.ts
@@ -33,6 +33,9 @@ export class DeleteRecipientUseCase {
     const hasPermission = Permissions.hasPermission('read_recipient', adm.role)
     if (!hasPermission) return left(new UnauthorizedError())
 
+    const recipient = await this.recipientsRepository.findById(recipientId)
+    if (!recipient) return left(new ResourceNotFoundError())
+
     await this.recipientsRepository.delete(recipientId)
 
     return right(null)
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.spec.ts b/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.spec.ts
index 253397f..6f7dc29 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.spec.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.spec.ts
@@ -39,7 +39,7 @@ describe('update recipient use case', () => {
       recipientId: recipient.id.value,
       cpf: '44411132112',
       name: 'bruno-2',
-      admId: adm.id.value,
+      requestResponsibleId: adm.id.value,
     })
 
     const recipients = await sut.dependencies.recipientsRepository.findMany()
@@ -74,7 +74,7 @@ describe('update recipient use case', () => {
       recipientId: recipient.id.value,
       cpf: '44411132112',
       name: 'bruno-2',
-      admId: adm.id.value,
+      requestResponsibleId: adm.id.value,
     })
 
     const updates = await sut.dependencies.recipientUpdatesRepository.findMany()
@@ -104,7 +104,7 @@ describe('update recipient use case', () => {
       recipientId: recipient.id.value,
       cpf: '44411132112',
       name: 'bruno-2',
-      admId: 'any Id',
+      requestResponsibleId: 'any Id',
     })
 
     const recipients = await sut.dependencies.recipientsRepository.findMany()
diff --git a/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.ts b/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.ts
index f172080..6e728d5 100644
--- a/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.ts
+++ b/src/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case.ts
@@ -12,7 +12,7 @@ export interface UpdateRecipientUseCaseRequest {
   recipientId: string
   name: string
   cpf: string
-  admId: string
+  requestResponsibleId: string
 }
 
 export type UpdateRecipientUseCaseResponse = Either<
@@ -32,9 +32,9 @@ export class UpdateRecipientUseCase {
     recipientId,
     cpf,
     name,
-    admId,
+    requestResponsibleId,
   }: UpdateRecipientUseCaseRequest): Promise<UpdateRecipientUseCaseResponse> {
-    const adm = await this.admsRepository.findById(admId)
+    const adm = await this.admsRepository.findById(requestResponsibleId)
     if (!adm) return left(new ResourceNotFoundError())
 
     const hasPermission = Permissions.hasPermission(
@@ -48,7 +48,7 @@ export class UpdateRecipientUseCase {
 
     const { data: update } = recipient.changeData(
       { cpf, name },
-      new UniqueEntityId(admId),
+      new UniqueEntityId(requestResponsibleId),
     )
     await this.recipientsRepository.update(recipient)
     await this.recipientUpdatesRepository.create(update)
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/abstract/user.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/abstract/user.ts
index 6ee3ec6..6caf89e 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/abstract/user.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/abstract/user.ts
@@ -2,8 +2,10 @@ import Entity from '@/core/entities/entity'
 import { Cpf } from '../value-objects/cpf'
 import { Coordinates } from '../value-objects/coordinates'
 import UniqueEntityId from '@/core/entities/unique-entity-id'
+import z from 'zod'
 
-export type UserRoles = 'recipient' | 'adm' | 'courier'
+export const userRoleSchema = z.enum(['recipient', 'adm', 'courier'])
+export type UserRoles = z.infer<typeof userRoleSchema>
 
 export interface UserProps {
   name: string
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/order-attachment.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/order-attachment.ts
index 21d3525..5cf42f5 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/order-attachment.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/order-attachment.ts
@@ -1,5 +1,12 @@
 import UniqueEntityId from '@/core/entities/unique-entity-id'
 import Entity from '@/core/entities/entity'
+import z from 'zod'
+
+// eslint-disable-next-line
+export const orderAttachmentInstanceSchema = z.custom<OrderAttachment>(
+  (data) => data instanceof OrderAttachment,
+  'must be a valide OrderAttachment',
+)
 
 export interface OrderAttachmentProps {
   orderId: UniqueEntityId
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/order.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/order.ts
index 24f3596..62db02c 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/order.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/order.ts
@@ -1,6 +1,7 @@
-import UniqueEntityId from '@/core/entities/unique-entity-id'
-import { Address } from './value-objects/address'
-import { Optional } from '@/core/types/optional'
+import UniqueEntityId, {
+  uniqueEntityIdInstanceSchema,
+} from '@/core/entities/unique-entity-id'
+import { Address, addressInstanceSchema } from './value-objects/address'
 import { AggregateRoot } from '@/core/entities/aggregate-root'
 import { OrderAlreadyAcceptedError } from '@/core/errors/errors/order-errors/order-already-accepted-error'
 import { OrderIsClosedError } from '@/core/errors/errors/order-errors/order-is-closed-error'
@@ -13,39 +14,75 @@ import { OrderAwaitingForPickupEvent } from '../events/order-awaiting-for-pickup
 import { OrderNotDeliveredError } from '@/core/errors/errors/order-errors/order-not-delivered-error'
 import { OrderCourierReturnedEvent } from '../events/order-courier-returned-event'
 import { UpdateOrder } from './update-order'
-import { OrderAttachment } from './order-attachment'
+import {
+  OrderAttachment,
+  orderAttachmentInstanceSchema,
+} from './order-attachment'
 import { OrderAlreadyReturnedError } from '@/core/errors/errors/order-errors/order-already-returned-error copy'
 import { OrderNotAwaitingPickupError } from '@/core/errors/errors/order-errors/order-not-awaiting-for-pickup-error'
 import { OrderWasNotCollectedError } from '@/core/errors/errors/order-errors/order-was-not-collected-error'
 import { OrderCourierCollectedEvent } from '../events/order-courier-collected-event'
-
-export interface OrderProps {
-  recipientId: UniqueEntityId
-  courierId: UniqueEntityId | null
-  address: Address
-  delivered: Date | null
-  deliveredPhoto: OrderAttachment | null
-  awaitingPickup: Date | null
-  collected: Date | null
-  returned: Date | null
-  returnCause: string | null
-  createdAt: Date
-  updatedAt: Date | null
-}
-
-export type OrderCreateProps = Omit<
-  Optional<
-    OrderProps,
-    | 'awaitingPickup'
-    | 'collected'
-    | 'returned'
-    | 'returnCause'
-    | 'delivered'
-    | 'createdAt'
-    | 'updatedAt'
-  >,
-  'deliveredPhoto'
-> & { deliveredPhoto?: string | null }
+import z from 'zod'
+
+export const orderPropsSchema = z.object({
+  recipientId: uniqueEntityIdInstanceSchema,
+  courierId: uniqueEntityIdInstanceSchema.nullable(),
+  address: addressInstanceSchema,
+  delivered: z.date().nullable(),
+  deliveredPhoto: orderAttachmentInstanceSchema.nullable(),
+  awaitingPickup: z.date().nullable(),
+  collected: z.date().nullable(),
+  returned: z.date().nullable(),
+  returnCause: z.string().nullable(),
+  createdAt: z.date(),
+  updatedAt: z.date().nullable(),
+})
+
+export type OrderProps = z.infer<typeof orderPropsSchema>
+
+// export interface OrderProps {
+//   recipientId: UniqueEntityId
+//   courierId: UniqueEntityId | null
+//   address: Address
+//   delivered: Date | null
+//   deliveredPhoto: OrderAttachment | null
+//   awaitingPickup: Date | null
+//   collected: Date | null
+//   returned: Date | null
+//   returnCause: string | null
+//   createdAt: Date
+//   updatedAt: Date | null
+// }
+
+export const orderCreatePropsSchema = z.object({
+  recipientId: uniqueEntityIdInstanceSchema,
+  courierId: uniqueEntityIdInstanceSchema.nullable(),
+  address: addressInstanceSchema,
+  delivered: z.date().nullable().optional(),
+  deliveredPhoto: z.string().nullable().optional(),
+  awaitingPickup: z.date().nullable().optional(),
+  collected: z.date().nullable().optional(),
+  returned: z.date().nullable().optional(),
+  returnCause: z.string().nullable().optional(),
+  createdAt: z.date().optional(),
+  updatedAt: z.date().nullable().optional(),
+})
+
+export type OrderCreateProps = z.infer<typeof orderCreatePropsSchema>
+
+// export type OrderCreateProps = Omit<
+//   Optional<
+//     OrderProps,
+//     | 'awaitingPickup'
+//     | 'collected'
+//     | 'returned'
+//     | 'returnCause'
+//     | 'delivered'
+//     | 'createdAt'
+//     | 'updatedAt'
+//   >,
+//   'deliveredPhoto'
+// > & { deliveredPhoto?: string | null }
 
 export type UpdateOrderReturn<errors> = { data?: UpdateOrder; error?: errors }
 
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/address.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/address.ts
index c64d97e..71be4a0 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/address.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/address.ts
@@ -1,21 +1,56 @@
 import { ValueObject } from '@/core/entities/value-objects'
 import { Cep } from './cep'
-import { Coordinates } from './coordinates'
-import { State, StatesShort } from './state'
-
-export interface AddressProps {
-  coordinates: Coordinates
-  cep: string
-  number: string
-  street: string
-  neighborhood: string
-  city: string
-  state: StatesShort
-}
-
-export type AddressCreationProps = Omit<AddressProps, 'coordinates'> & {
-  coordinates: Coordinates['raw']
-}
+import {
+  Coordinates,
+  coordinatesInstanceSchema,
+  coordinatesSchema,
+} from './coordinates'
+import { State, StatesShort, statesShortSchema } from './state'
+import z from 'zod'
+
+// eslint-disable-next-line
+export const addressInstanceSchema = z.custom<Address>(
+  (data) => data instanceof Address,
+  'must be a valide Address',
+)
+
+export const addressPropsSchema = z.object({
+  coordinates: coordinatesInstanceSchema,
+  cep: z.string(),
+  number: z.string(),
+  street: z.string(),
+  neighborhood: z.string(),
+  city: z.string(),
+  state: statesShortSchema,
+})
+
+export type AddressProps = z.infer<typeof addressPropsSchema>
+
+// export interface AddressProps {
+//   coordinates: Coordinates
+//   cep: string
+//   number: string
+//   street: string
+//   neighborhood: string
+//   city: string
+//   state: StatesShort
+// }
+
+export const addressCreationPropsSchema = z.object({
+  coordinates: coordinatesSchema,
+  cep: z.string(),
+  number: z.string(),
+  street: z.string(),
+  neighborhood: z.string(),
+  city: z.string(),
+  state: statesShortSchema,
+})
+
+export type AddressCreationProps = z.infer<typeof addressCreationPropsSchema>
+
+// export type AddressCreationProps = Omit<AddressProps, 'coordinates'> & {
+//   coordinates: Coordinates['raw']
+// }
 
 export type AddressRaw = {
   coordinates: Coordinates['raw']
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cep.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cep.ts
index 242c6f8..a09dd32 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cep.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cep.ts
@@ -1,5 +1,12 @@
 import { DataValidationError } from '@/core/errors/errors/data-validation-error'
 import { mask } from 'remask'
+import z from 'zod'
+
+// eslint-disable-next-line
+export const cepInstanceSchema = z.custom<Cep>(
+  (data) => data instanceof Cep,
+  'must be a valide Cep',
+)
 
 export class Cep {
   private cep: string
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/coordinates.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/coordinates.ts
index c8e9199..2a14f39 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/coordinates.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/coordinates.ts
@@ -1,19 +1,26 @@
 import { ValueObject } from '@/core/entities/value-objects'
 import z from 'zod'
 
+// eslint-disable-next-line
+export const coordinatesInstanceSchema = z.custom<Coordinates>(
+  (data) => data instanceof Coordinates,
+  'must be a valide Coordinates',
+)
+
+export const latitudeSchema = z.coerce
+  .number()
+  .refine((lat) => Math.abs(lat) <= 90, 'latitude must be between -90 and 90')
+
+export const longitudeSchema = z.coerce
+  .number()
+  .refine(
+    (lat) => Math.abs(lat) <= 180,
+    'longitude must be between -180 and 180',
+  )
+
 export const coordinatesSchema = z.object({
-  latitude: z.coerce
-    .number()
-    .refine(
-      (lat) => Math.abs(lat) <= 90,
-      'latitude must be between -90 and 90',
-    ),
-  longitude: z.coerce
-    .number()
-    .refine(
-      (lat) => Math.abs(lat) <= 180,
-      'longitude must be between -180 and 180',
-    ),
+  latitude: latitudeSchema,
+  longitude: longitudeSchema,
 })
 
 export type CoordinatesProps = z.infer<typeof coordinatesSchema>
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cpf.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cpf.ts
index 9af026a..afcbcff 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cpf.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cpf.ts
@@ -1,5 +1,12 @@
 import { DataValidationError } from '@/core/errors/errors/data-validation-error'
 import { mask } from 'remask'
+import z from 'zod'
+
+// eslint-disable-next-line
+export const cpfInstanceSchema = z.custom<Cpf>(
+  (data) => data instanceof Cpf,
+  'must be a valide Cpf',
+)
 
 export class Cpf {
   private cpf: string
diff --git a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/state.ts b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/state.ts
index 8a38219..d9ee8bf 100644
--- a/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/state.ts
+++ b/src/domain/core/deliveries-and-orders/enterprise/entities/value-objects/state.ts
@@ -1,59 +1,73 @@
-export type StatesShort =
-  | 'AM'
-  | 'PA'
-  | 'RR'
-  | 'AP'
-  | 'AC'
-  | 'RO'
-  | 'TO'
-  | 'MA'
-  | 'PI'
-  | 'CE'
-  | 'RN'
-  | 'PB'
-  | 'PE'
-  | 'AL'
-  | 'SE'
-  | 'BA'
-  | 'MG'
-  | 'ES'
-  | 'RJ'
-  | 'SP'
-  | 'PR'
-  | 'SC'
-  | 'RS'
-  | 'MS'
-  | 'MT'
-  | 'GO'
-  | 'DF'
-type StatesVerbose =
-  | 'Amazonas'
-  | 'Pará'
-  | 'Roraima'
-  | 'Amapá'
-  | 'Acre'
-  | 'Rondônia'
-  | 'Tocantins'
-  | 'Maranhão'
-  | 'Piauí'
-  | 'Ceará'
-  | 'Rio Grande do Norte'
-  | 'Paraíba'
-  | 'Pernambuco'
-  | 'Alagoas'
-  | 'Sergipe'
-  | 'Bahia'
-  | 'Minas Gerais'
-  | 'Espírito Santo'
-  | 'Rio de Janeiro'
-  | 'São Paulo'
-  | 'Paraná'
-  | 'Santa Catarina'
-  | 'Rio Grande do Sul'
-  | 'Mato Grosso do Sul'
-  | 'Mato Grosso'
-  | 'Goiás'
-  | 'Distrito Federal'
+import z from 'zod'
+
+export const statesShortSchema = z.enum([
+  'AM',
+  'PA',
+  'RR',
+  'AP',
+  'AC',
+  'RO',
+  'TO',
+  'MA',
+  'PI',
+  'CE',
+  'RN',
+  'PB',
+  'PE',
+  'AL',
+  'SE',
+  'BA',
+  'MG',
+  'ES',
+  'RJ',
+  'SP',
+  'PR',
+  'SC',
+  'RS',
+  'MS',
+  'MT',
+  'GO',
+  'DF',
+])
+export type StatesShort = z.infer<typeof statesShortSchema>
+
+export const statesStatesVerboseSchema = z.enum([
+  'Amazonas',
+  'Pará',
+  'Roraima',
+  'Amapá',
+  'Acre',
+  'Rondônia',
+  'Tocantins',
+  'Maranhão',
+  'Piauí',
+  'Ceará',
+  'Rio Grande do Norte',
+  'Paraíba',
+  'Pernambuco',
+  'Alagoas',
+  'Sergipe',
+  'Bahia',
+  'Minas Gerais',
+  'Espírito Santo',
+  'Rio de Janeiro',
+  'São Paulo',
+  'Paraná',
+  'Santa Catarina',
+  'Rio Grande do Sul',
+  'Mato Grosso do Sul',
+  'Mato Grosso',
+  'Goiás',
+  'Distrito Federal',
+])
+
+type StatesVerbose = z.infer<typeof statesStatesVerboseSchema>
+
+// eslint-disable-next-line
+export const stateInstanceSchema = z.custom<State>(
+  (data) => data instanceof State,
+  'must be a valide State',
+)
 
 export class State {
   private state: StatesShort
diff --git a/src/domain/generic/notification/application/subscribers/on-order-delivered.ts b/src/domain/generic/notification/application/subscribers/on-order-delivered.ts
deleted file mode 100644
index 25d8ab7..0000000
--- a/src/domain/generic/notification/application/subscribers/on-order-delivered.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { DomainEvents } from '@/core/events/domain-events'
-import { EventHandler } from '@/core/events/event-handler'
-import SendNotificationUseCase from '../use-cases/send-notification'
-import { left } from '@/core/either'
-import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
-import { Injectable } from '@nestjs/common'
-import { OrdersRepository } from '@/domain/core/deliveries-and-orders/application/repositories/order-repositories/orders-repository'
-import { OrderDeliveredEvent } from '@/domain/core/deliveries-and-orders/enterprise/events/order-delivered-event'
-
-@Injectable()
-export class OnOrderDelivered implements EventHandler {
-  constructor(
-    private ordersRepository: OrdersRepository,
-    private sendNotificationUseCase: SendNotificationUseCase,
-  ) {
-    this.setupSubscriptions()
-  }
-
-  setupSubscriptions(): void {
-    DomainEvents.register(
-      this.sendNewAnswerNotification.bind(this),
-      OrderDeliveredEvent.name,
-    )
-  }
-
-  private async sendNewAnswerNotification({ order }: OrderDeliveredEvent) {
-    const currentOrder = await this.ordersRepository.findById(order.id.value)
-
-    if (!currentOrder) return left(new ResourceNotFoundError())
-
-    await this.sendNotificationUseCase.execute({
-      recipientId: currentOrder.recipientId.value,
-      title: `Um entregador aceitou realizar seu pedido ${currentOrder.id.value}`,
-      content: `Em breve o entregador irá retirar seu pedido`,
-    })
-  }
-}
diff --git a/src/infra/app.module.ts b/src/infra/app.module.ts
index 5da5ac0..e6227c8 100644
--- a/src/infra/app.module.ts
+++ b/src/infra/app.module.ts
@@ -3,6 +3,7 @@ import { EnvModule } from './env/env.module'
 import { ConfigModule } from '@nestjs/config'
 import { envSchema } from './env/env'
 import { HttpModule } from './http/http.module'
+import { AuthModule } from './auth/auth.module'
 
 @Module({
   imports: [
@@ -12,6 +13,7 @@ import { HttpModule } from './http/http.module'
     }),
     EnvModule,
     HttpModule,
+    AuthModule,
   ],
   controllers: [],
   providers: [],
diff --git a/src/infra/auth/auth.module.ts b/src/infra/auth/auth.module.ts
new file mode 100644
index 0000000..af1567a
--- /dev/null
+++ b/src/infra/auth/auth.module.ts
@@ -0,0 +1,29 @@
+import { Module } from '@nestjs/common'
+import { JwtModule } from '@nestjs/jwt'
+import { readFileSync } from 'node:fs'
+import { resolve } from 'node:path'
+import { JwtStrategy } from './jwt.strategy'
+import { PassportModule } from '@nestjs/passport'
+import { APP_GUARD } from '@nestjs/core'
+import { JwtAuthGuard } from './jwt-auth.guard'
+
+@Module({
+  imports: [
+    JwtModule.registerAsync({
+      global: true,
+      useFactory() {
+        const pathToKeys = './keys'
+        const pathToPrivateKey = resolve(pathToKeys, 'private_key.pem')
+        const pathToPublicKey = resolve(pathToKeys, 'public_key.pem')
+        return {
+          signOptions: { algorithm: 'RS256' },
+          privateKey: readFileSync(pathToPrivateKey, 'utf8'),
+          publicKey: readFileSync(pathToPublicKey, 'utf8'),
+        }
+      },
+    }),
+    PassportModule,
+  ],
+  providers: [JwtStrategy, { provide: APP_GUARD, useClass: JwtAuthGuard }],
+})
+export class AuthModule {}
diff --git a/src/infra/auth/current-user-decorator.ts b/src/infra/auth/current-user-decorator.ts
new file mode 100644
index 0000000..3198435
--- /dev/null
+++ b/src/infra/auth/current-user-decorator.ts
@@ -0,0 +1,10 @@
+import { ExecutionContext, createParamDecorator } from '@nestjs/common'
+import { TokenPayload } from './jwt.strategy'
+
+export const CurrentUser = createParamDecorator(
+  (_: never, context: ExecutionContext) => {
+    const request = context.switchToHttp().getRequest()
+
+    return request.user as TokenPayload
+  },
+)
diff --git a/src/infra/auth/jwt-auth.guard.ts b/src/infra/auth/jwt-auth.guard.ts
new file mode 100644
index 0000000..fedb164
--- /dev/null
+++ b/src/infra/auth/jwt-auth.guard.ts
@@ -0,0 +1,22 @@
+import { ExecutionContext, Injectable } from '@nestjs/common'
+import { Reflector } from '@nestjs/core'
+import { AuthGuard } from '@nestjs/passport'
+import { IS_PUBLIC_KEY } from './public'
+
+@Injectable()
+export class JwtAuthGuard extends AuthGuard('jwt') {
+  constructor(private reflector: Reflector) {
+    super()
+  }
+
+  canActivate(context: ExecutionContext) {
+    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
+      context.getHandler(),
+      context.getClass(),
+    ])
+    if (isPublic) {
+      return true
+    }
+    return super.canActivate(context)
+  }
+}
diff --git a/src/infra/auth/jwt.strategy.ts b/src/infra/auth/jwt.strategy.ts
new file mode 100644
index 0000000..7b8d22c
--- /dev/null
+++ b/src/infra/auth/jwt.strategy.ts
@@ -0,0 +1,29 @@
+import { Injectable } from '@nestjs/common'
+import { PassportStrategy } from '@nestjs/passport'
+import { readFileSync } from 'node:fs'
+import { ExtractJwt, Strategy } from 'passport-jwt'
+import { z } from 'zod'
+
+const tokenSchema = z.object({
+  sub: z.string().uuid(),
+  role: z.enum(['recipient', 'adm', 'courier']),
+})
+
+export type TokenPayload = z.infer<typeof tokenSchema>
+
+@Injectable()
+export class JwtStrategy extends PassportStrategy(Strategy) {
+  constructor() {
+    const publicKey = readFileSync('./keys/public_key.pem')
+
+    super({
+      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
+      secretOrKey: publicKey,
+      algorithms: ['RS256'],
+    })
+  }
+
+  async validate(payload: TokenPayload) {
+    return tokenSchema.parse(payload)
+  }
+}
diff --git a/src/infra/auth/public.ts b/src/infra/auth/public.ts
new file mode 100644
index 0000000..91c2399
--- /dev/null
+++ b/src/infra/auth/public.ts
@@ -0,0 +1,4 @@
+import { SetMetadata } from '@nestjs/common'
+
+export const IS_PUBLIC_KEY = 'isPublic'
+export const Public = () => SetMetadata(IS_PUBLIC_KEY, true)
diff --git a/src/infra/cryptography/bcrypt-encrypter.ts b/src/infra/cryptography/bcrypt-encrypter.ts
new file mode 100644
index 0000000..43ecea8
--- /dev/null
+++ b/src/infra/cryptography/bcrypt-encrypter.ts
@@ -0,0 +1,14 @@
+import { Encrypter } from '@/domain/core/deliveries-and-orders/application/cryptography/encrypter'
+import { Injectable } from '@nestjs/common'
+import { hash, compare } from 'bcryptjs'
+
+@Injectable()
+export class BcryptEncrypter implements Encrypter {
+  hash(painText: string): Promise<string> {
+    return hash(painText, 8)
+  }
+
+  compare(painText: string, hash: string): Promise<boolean> {
+    return compare(painText, hash)
+  }
+}
diff --git a/src/infra/cryptography/cryptography.module.ts b/src/infra/cryptography/cryptography.module.ts
new file mode 100644
index 0000000..dd58299
--- /dev/null
+++ b/src/infra/cryptography/cryptography.module.ts
@@ -0,0 +1,14 @@
+import { Module } from '@nestjs/common'
+import { BcryptEncrypter } from './bcrypt-encrypter'
+import { JwtEncoder } from './jwt-encoder'
+import { Encrypter } from '@/domain/core/deliveries-and-orders/application/cryptography/encrypter'
+import { Encoder } from '@/domain/core/deliveries-and-orders/application/cryptography/encoder'
+
+@Module({
+  providers: [
+    { provide: Encrypter, useClass: BcryptEncrypter },
+    { provide: Encoder, useClass: JwtEncoder },
+  ],
+  exports: [Encrypter, Encoder],
+})
+export class CryptographyModule {}
diff --git a/src/infra/cryptography/jwt-encoder.ts b/src/infra/cryptography/jwt-encoder.ts
new file mode 100644
index 0000000..b696ed4
--- /dev/null
+++ b/src/infra/cryptography/jwt-encoder.ts
@@ -0,0 +1,13 @@
+import { Encoder } from '@/domain/core/deliveries-and-orders/application/cryptography/encoder'
+import { JwtService } from '@nestjs/jwt'
+import { TokenPayload } from '../auth/jwt.strategy'
+import { Injectable } from '@nestjs/common'
+
+@Injectable()
+export class JwtEncoder implements Encoder {
+  constructor(private jwt: JwtService) {}
+
+  async encode(payload: TokenPayload): Promise<string> {
+    return this.jwt.sign(payload)
+  }
+}
diff --git a/src/infra/database/prisma/mappers/prisma-update-order-mapper.ts b/src/infra/database/prisma/mappers/prisma-update-order-mapper.ts
index a7f76ec..f3acac4 100644
--- a/src/infra/database/prisma/mappers/prisma-update-order-mapper.ts
+++ b/src/infra/database/prisma/mappers/prisma-update-order-mapper.ts
@@ -38,7 +38,12 @@ export class PrismaUpdateOrderMapper {
   }
 
   static domainToPrisma(update: UpdateOrder): PrismaUpdates {
-    const changes = JSON.stringify(update.changes)
+    console.log('before changes')
+    const changes = JSON.stringify({
+      before: update.changes.before.toJson(),
+      after: update.changes.after.toJson(),
+    })
+    console.log('afetr changes', changes)
 
     const prismaUpdate: PrismaUpdates = {
       changes,
diff --git a/src/infra/http/controllers/@exports/controllers.exports.ts b/src/infra/http/controllers/@exports/controllers.exports.ts
index e69de29..85001d1 100644
--- a/src/infra/http/controllers/@exports/controllers.exports.ts
+++ b/src/infra/http/controllers/@exports/controllers.exports.ts
@@ -0,0 +1,48 @@
+import { ModuleMetadata } from '@nestjs/common'
+import { AuthenticateController } from '../auth-and-register-controllers/authenticate.controller'
+import { RegisterController } from '../auth-and-register-controllers/register.controller'
+import { DeleteUserController } from '../user-controllers/delete-user.controller'
+import { FetchUsersController } from '../user-controllers/fetch-users.controller'
+import { FindUserController } from '../user-controllers/find-user.controller'
+import { UpdateUserPasswordController } from '../user-controllers/update-user-password.controller'
+import { UpdateUserController } from '../user-controllers/update-user.controller'
+import { CollectOrderController } from '../order-controllers/collect-order.controller'
+import { CreateOrderController } from '../order-controllers/create-order.controller'
+import { DeleteOrderController } from '../order-controllers/delete-order.controller'
+import { DeliverOrderController } from '../order-controllers/deliver-order.controller'
+import { FetchNearbyOrdersController } from '../order-controllers/fetch-nearby-orders.controller'
+import { FetchOrdersController } from '../order-controllers/fetch-orders.controller'
+import { FindOrderController } from '../order-controllers/find-order.controller'
+import { MarkOrderAsAwaitingForPickupController } from '../order-controllers/mark-order-as-awaiting-for-pickup.controller'
+import { ReturnOrderController } from '../order-controllers/return-order.controller'
+
+const authAndRegisterControllers: NonNullable<ModuleMetadata['controllers']> = [
+  AuthenticateController,
+  RegisterController,
+]
+
+const userControllers: NonNullable<ModuleMetadata['controllers']> = [
+  DeleteUserController,
+  FetchUsersController,
+  FindUserController,
+  UpdateUserPasswordController,
+  UpdateUserController,
+]
+
+const orderControllers: NonNullable<ModuleMetadata['controllers']> = [
+  CollectOrderController,
+  CreateOrderController,
+  DeleteOrderController,
+  DeliverOrderController,
+  FetchNearbyOrdersController,
+  FetchOrdersController,
+  FindOrderController,
+  MarkOrderAsAwaitingForPickupController,
+  ReturnOrderController,
+]
+
+export const controllers: NonNullable<ModuleMetadata['controllers']> = [
+  ...authAndRegisterControllers,
+  ...userControllers,
+  ...orderControllers,
+]
diff --git a/src/infra/http/controllers/auth-and-register-controllers/authenticate.controller.ts b/src/infra/http/controllers/auth-and-register-controllers/authenticate.controller.ts
new file mode 100644
index 0000000..a6392c1
--- /dev/null
+++ b/src/infra/http/controllers/auth-and-register-controllers/authenticate.controller.ts
@@ -0,0 +1,75 @@
+import {
+  BadRequestException,
+  Body,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Post,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { validaCPF } from '../../utils/isCPF'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+import { Public } from '@/infra/auth/public'
+import { Either } from '@/core/either'
+import { AuthenticateAdmUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/auth-and-register/adm/authenticate-adm-use-case'
+import { AuthenticateRecipientUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/auth-and-register/recipient/authenticate-recipient-use-case'
+import { AuthenticateCourierUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/auth-and-register/courier/authenticate-courier-use-case'
+
+const bodySchema = z.object({
+  cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+  password: z.string(),
+  role: z.enum(['recipient', 'adm', 'courier']),
+})
+
+type BodySchema = z.infer<typeof bodySchema>
+
+const pipe = new ZodValidationPipe(bodySchema)
+
+@Controller('/sessions')
+@Public()
+export class AuthenticateController {
+  constructor(
+    private authenticateCourier: AuthenticateCourierUseCase,
+    private authenticateRecipient: AuthenticateRecipientUseCase,
+    private authenticateAdm: AuthenticateAdmUseCase,
+  ) {}
+
+  @Post()
+  @HttpCode(200)
+  async handle(@Body(pipe) { role, ...body }: BodySchema) {
+    let resp: Either<
+      ResourceNotFoundError | UnauthorizedError,
+      {
+        token: string
+      }
+    >
+    if (role === 'courier') {
+      resp = await this.authenticateCourier.execute(body)
+    } else if (role === 'recipient') {
+      resp = await this.authenticateRecipient.execute(body)
+    } else {
+      resp = await this.authenticateAdm.execute(body)
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      const token = resp.value.token
+
+      return { token }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/auth-and-register-controllers/register.controller.ts b/src/infra/http/controllers/auth-and-register-controllers/register.controller.ts
new file mode 100644
index 0000000..6f13c91
--- /dev/null
+++ b/src/infra/http/controllers/auth-and-register-controllers/register.controller.ts
@@ -0,0 +1,79 @@
+import { RegisterCourierUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/auth-and-register/courier/register-courier-use-case'
+import {
+  BadRequestException,
+  Body,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Post,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { validaCPF } from '../../utils/isCPF'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { RegisterRecipientUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/auth-and-register/recipient/register-recipient-use-case'
+import { Either } from '@/core/either'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+
+const bodySchema = z.object({
+  cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+  name: z.string(),
+  password: z.string(),
+  role: z.enum(['recipient', 'adm', 'courier']),
+})
+
+type BodySchema = z.infer<typeof bodySchema>
+
+const pipe = new ZodValidationPipe(bodySchema)
+
+@Controller('/register')
+// @Public()
+export class RegisterController {
+  constructor(
+    private registerCourier: RegisterCourierUseCase,
+    private registerRecipient: RegisterRecipientUseCase,
+  ) {}
+
+  @Post()
+  @HttpCode(201)
+  async handle(
+    @Body(pipe) { role, ...body }: BodySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+    let resp: Either<ResourceNotFoundError | UnauthorizedError, null>
+    if (role === 'courier') {
+      resp = await this.registerCourier.execute({
+        ...body,
+        requestResponsibleId,
+      })
+    } else if (role === 'recipient') {
+      resp = await this.registerRecipient.execute({
+        ...body,
+        requestResponsibleId,
+      })
+    } else {
+      throw new BadRequestException(`cannot register an admin`)
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/collect-order.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/collect-order.controller.e2e-spec.ts
new file mode 100644
index 0000000..fc79e5c
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/collect-order.controller.e2e-spec.ts
@@ -0,0 +1,120 @@
+import { AppModule } from '@/infra/app.module'
+import { PrismaAdmMapper } from '@/infra/database/prisma/mappers/prisma-adm-mapper'
+import { PrismaService } from '@/infra/database/prisma/prisma.service'
+import { INestApplication } from '@nestjs/common'
+import { Test } from '@nestjs/testing'
+import { makeAdm } from 'test/factories/entities/makeAdm'
+import { makeAuthenticateRequest } from '../../factories/requests/auth-and-register-factories/make-authenticate-request'
+import { Cpf } from '@/domain/core/deliveries-and-orders/enterprise/entities/value-objects/cpf'
+import { makeRegisterRequest } from '../../factories/requests/auth-and-register-factories/make-register-request'
+import { makeCreateOrderRequest } from '../../factories/requests/order-request-factories/make-create-order-request'
+import { makeCollectOrderRequest } from '../../factories/requests/order-request-factories/make-collect-order-request'
+
+describe('collect order controller', () => {
+  let app: INestApplication
+  let prisma: PrismaService
+
+  beforeAll(async () => {
+    const moduleRef = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile()
+
+    app = moduleRef.createNestApplication()
+    prisma = moduleRef.get(PrismaService)
+
+    await app.init()
+  })
+
+  test('PATCH /orders/:id/collect', async () => {
+    await prisma.prismaUser.create({
+      data: PrismaAdmMapper.domainToPrisma(
+        makeAdm({
+          cpf: new Cpf('20635940078'),
+          password: '123',
+        }),
+      ),
+    })
+
+    const authAdmResp = await makeAuthenticateRequest(app, {
+      body: {
+        cpf: '20635940078',
+        password: '123',
+        role: 'adm',
+      },
+    })
+
+    const token = authAdmResp.body.token
+
+    const createRecipientResp = await makeRegisterRequest(app, {
+      token,
+      body: {
+        cpf: '66967772023',
+        name: 'recipient teste',
+        password: '123',
+        role: 'recipient',
+      },
+    })
+
+    const createCourierResp = await makeRegisterRequest(app, {
+      token,
+      body: {
+        cpf: '29241359072',
+        name: 'courier teste',
+        password: '123',
+        role: 'courier',
+      },
+    })
+
+    const recipient = (
+      await prisma.prismaUser.findMany({
+        where: {
+          role: 'recipient',
+        },
+      })
+    )[0]
+
+    const courier = (
+      await prisma.prismaUser.findMany({
+        where: {
+          role: 'courier',
+        },
+      })
+    )[0]
+
+    const createOrderResp = await makeCreateOrderRequest(app, {
+      token,
+      body: {
+        address: {
+          cep: '004475900',
+          street: 'rua dos bobos',
+          number: 'numero zero',
+          city: 'nao tinha cidade',
+          neighborhood: 'nao tinha bairro',
+          state: 'SP',
+          coordinates: {
+            latitude: 1,
+            longitude: 1,
+          },
+        },
+        courierId: courier.id,
+        recipientId: recipient.id,
+      },
+    })
+
+    const order = (await prisma.prismaOrder.findMany())[0]
+
+    const collectOrderResp = await makeCollectOrderRequest(app, {
+      orderId: order.id,
+      token,
+    })
+
+    const orderUpdated = (await prisma.prismaOrder.findMany())[0]
+
+    expect(authAdmResp.statusCode).toEqual(200)
+    expect(createRecipientResp.statusCode).toEqual(201)
+    expect(createCourierResp.statusCode).toEqual(201)
+    expect(createOrderResp.statusCode).toEqual(201)
+    expect(collectOrderResp.statusCode).toEqual(204)
+    expect(orderUpdated.collected).toEqual(expect.any(Date))
+  })
+})
diff --git a/src/infra/http/controllers/order-controllers/collect-order.controller.ts b/src/infra/http/controllers/order-controllers/collect-order.controller.ts
new file mode 100644
index 0000000..903ee34
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/collect-order.controller.ts
@@ -0,0 +1,85 @@
+import {
+  BadRequestException,
+  Controller,
+  HttpCode,
+  InternalServerErrorException,
+  NotFoundException,
+  Param,
+  Patch,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { CollectOrderUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/collect-order-use-case'
+import { OrderAwaitingPickupError } from '@/core/errors/errors/order-errors/order-awaiting-for-pickup-error'
+import { OrderIsClosedError } from '@/core/errors/errors/order-errors/order-is-closed-error'
+import { InternalServerError } from '@/core/errors/errors/internal-server-error'
+
+const paramsSchema = z.object({
+  id: z.string().uuid(),
+})
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:id/collect')
+// @Public()
+export class CollectOrderController {
+  constructor(private collectOrder: CollectOrderUseCase) {}
+
+  @Patch()
+  @HttpCode(204)
+  async handle(
+    @Param(pipeParams) { id }: ParamsSchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.collectOrder.execute({
+      requestResponsibleId,
+      orderId: id,
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      const isAwaitingError = value instanceof OrderAwaitingPickupError
+      const isClosedError = value instanceof OrderIsClosedError
+
+      const isOrderError = isAwaitingError || isClosedError
+
+      if (isOrderError) {
+        throw new BadRequestException({ message: value.message })
+      }
+
+      if (value instanceof InternalServerError) {
+        throw new InternalServerErrorException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/create-order.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/create-order.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/create-order.controller.ts b/src/infra/http/controllers/order-controllers/create-order.controller.ts
new file mode 100644
index 0000000..5095036
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/create-order.controller.ts
@@ -0,0 +1,87 @@
+import {
+  BadRequestException,
+  Body,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Post,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { CreateOrderUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/create-order-use-case'
+
+import {
+  Address,
+  addressCreationPropsSchema,
+} from '@/domain/core/deliveries-and-orders/enterprise/entities/value-objects/address'
+import UniqueEntityId from '@/core/entities/unique-entity-id'
+
+// const paramsSchema = z.object({
+//   id: z.string().uuid(),
+// })
+
+/* 
+  bodySchema example
+
+  address: makeAddress(),
+  courierId: new UniqueEntityId('123'),
+  recipientId: new UniqueEntityId('1188'),
+*/
+
+const bodySchema = z.object({
+  address: addressCreationPropsSchema,
+  courierId: z.string(),
+  recipientId: z.string(),
+})
+
+// type ParamsSchema = z.infer<typeof paramsSchema>
+type BodySchema = z.infer<typeof bodySchema>
+
+// const pipeParams = new ZodValidationPipe(paramsSchema)
+const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders')
+// @Public()
+export class CreateOrderController {
+  constructor(private createOrder: CreateOrderUseCase) {}
+
+  @Post()
+  @HttpCode(201)
+  async handle(
+    @Body(pipeBody) body: BodySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.createOrder.execute({
+      requestResponsibleId,
+      creationProps: {
+        address: new Address(body.address),
+        courierId: new UniqueEntityId(body.courierId),
+        recipientId: new UniqueEntityId(body.recipientId),
+      },
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/delete-order.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/delete-order.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/delete-order.controller.ts b/src/infra/http/controllers/order-controllers/delete-order.controller.ts
new file mode 100644
index 0000000..39b8484
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/delete-order.controller.ts
@@ -0,0 +1,68 @@
+import {
+  BadRequestException,
+  Controller,
+  Delete,
+  HttpCode,
+  NotFoundException,
+  Param,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { DeleteOrderUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/delete-order-use-case'
+
+const paramsSchema = z.object({
+  id: z.string().uuid(),
+})
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:id')
+// @Public()
+export class DeleteOrderController {
+  constructor(private deleteOrder: DeleteOrderUseCase) {}
+
+  @Delete()
+  @HttpCode(204)
+  async handle(
+    @Param(pipeParams) { id }: ParamsSchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.deleteOrder.execute({
+      requestResponsibleId,
+      orderId: id,
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/deliver-order.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/deliver-order.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/deliver-order.controller.ts b/src/infra/http/controllers/order-controllers/deliver-order.controller.ts
new file mode 100644
index 0000000..20c1134
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/deliver-order.controller.ts
@@ -0,0 +1,77 @@
+import {
+  BadRequestException,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Param,
+  Patch,
+  Query,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { DeliverOrderUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/deliver-order-use-case'
+
+const paramsSchema = z.object({
+  id: z.string().uuid(),
+})
+
+const querySchema = z.object({
+  attachmentId: z.string().uuid(),
+})
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+type QuerySchema = z.infer<typeof querySchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+const pipeQuery = new ZodValidationPipe(querySchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:id/deliver')
+// @Public()
+export class DeliverOrderController {
+  constructor(private deliverOrder: DeliverOrderUseCase) {}
+
+  @Patch()
+  @HttpCode(204)
+  async handle(
+    @Param(pipeParams) { id }: ParamsSchema,
+    @Query(pipeQuery) { attachmentId }: QuerySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.deliverOrder.execute({
+      requestResponsibleId,
+      orderId: id,
+      attachmentId,
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/fetch-nearby-orders.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/fetch-nearby-orders.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/fetch-nearby-orders.controller.ts b/src/infra/http/controllers/order-controllers/fetch-nearby-orders.controller.ts
new file mode 100644
index 0000000..ab1cb32
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/fetch-nearby-orders.controller.ts
@@ -0,0 +1,89 @@
+import {
+  BadRequestException,
+  Controller,
+  Get,
+  HttpCode,
+  NotFoundException,
+  Param,
+  Query,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+
+import { FetchNearbyOrdersUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/fetch-nearby-orders-use-case'
+import {
+  latitudeSchema,
+  longitudeSchema,
+} from '@/domain/core/deliveries-and-orders/enterprise/entities/value-objects/coordinates'
+
+const paramsSchema = z.object({
+  courierId: z.string().uuid(),
+})
+
+const querySchema = z.object({
+  latitude: latitudeSchema,
+  longitude: longitudeSchema,
+})
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+type QuerySchema = z.infer<typeof querySchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+const pipeQuery = new ZodValidationPipe(querySchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:courierId/nearby')
+// @Public()
+export class FetchNearbyOrdersController {
+  constructor(private fetchNearbyOrders: FetchNearbyOrdersUseCase) {}
+
+  @Get()
+  @HttpCode(200)
+  async handle(
+    @Param(pipeParams) { courierId }: ParamsSchema,
+    @Query(pipeQuery) { latitude, longitude }: QuerySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.fetchNearbyOrders.execute({
+      requestResponsibleId,
+      coordinates: {
+        latitude,
+        longitude,
+      },
+      courierId,
+      requestResponsibleRole: user.role,
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      const value = resp.value
+
+      return { orders: value.orders }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/fetch-orders.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/fetch-orders.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/fetch-orders.controller.ts b/src/infra/http/controllers/order-controllers/fetch-orders.controller.ts
new file mode 100644
index 0000000..956c069
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/fetch-orders.controller.ts
@@ -0,0 +1,110 @@
+import {
+  BadRequestException,
+  Controller,
+  Get,
+  HttpCode,
+  NotFoundException,
+  Param,
+  Query,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { FetchCourierOrdersUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/fetch-courier-orders-use-case'
+import { FetchRecipientOrdersUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/fetch-recipient-orders-use-case'
+import { FetchOrdersUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/fetch-orders-use-case'
+import { userRoleSchema } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { Either } from '@/core/either'
+import { Order } from '@/domain/core/deliveries-and-orders/enterprise/entities/order'
+
+const paramsSchema = z.object({
+  role: z.union([userRoleSchema, z.enum(['all'])]),
+})
+
+const querySchema = z.object({
+  userId: z.string().uuid().optional(),
+})
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+type QuerySchema = z.infer<typeof querySchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+const pipeQuery = new ZodValidationPipe(querySchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:role')
+// @Public()
+export class FetchOrdersController {
+  constructor(
+    private fetchOrders: FetchOrdersUseCase,
+    private fetchCourierOrders: FetchCourierOrdersUseCase,
+    private fetchRecipientOrders: FetchRecipientOrdersUseCase,
+  ) {}
+
+  @Get()
+  @HttpCode(200)
+  async handle(
+    @Param(pipeParams) { role }: ParamsSchema,
+    @Query(pipeQuery) { userId }: QuerySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+    console.log('requestResponsibleId', requestResponsibleId)
+
+    let resp: Either<
+      ResourceNotFoundError | UnauthorizedError,
+      { orders: Order[] }
+    >
+
+    if (role === 'all') {
+      resp = await this.fetchOrders.execute({
+        requestResponsibleId,
+      })
+    } else if (role === 'courier') {
+      if (!userId) throw new BadRequestException('param id was not passed')
+      resp = await this.fetchCourierOrders.execute({
+        requestResponsibleId,
+        courierId: userId,
+        requestResponsibleRole: user.role,
+      })
+    } else if (role === 'recipient') {
+      if (!userId) throw new BadRequestException('param id was not passed')
+      resp = await this.fetchRecipientOrders.execute({
+        requestResponsibleId,
+        recipientId: userId,
+        requestResponsibleRole: user.role,
+      })
+    } else {
+      throw new BadRequestException('admins have not orders linked to them')
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      const value = resp.value
+
+      return { orders: value.orders }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/find-order.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/find-order.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/find-order.controller.ts b/src/infra/http/controllers/order-controllers/find-order.controller.ts
new file mode 100644
index 0000000..1d6be76
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/find-order.controller.ts
@@ -0,0 +1,78 @@
+import {
+  BadRequestException,
+  Controller,
+  Get,
+  HttpCode,
+  NotFoundException,
+  Param,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { FindOrderUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/find-order-use-case'
+
+const paramsSchema = z.object({
+  id: z.string().uuid(),
+})
+
+// const querySchema = z.object({
+//   latitude: latitudeSchema,
+//   longitude: longitudeSchema,
+// })
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+// type QuerySchema = z.infer<typeof querySchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+// const pipeQuery = new ZodValidationPipe(querySchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:id/find')
+// @Public()
+export class FindOrderController {
+  constructor(private findOrder: FindOrderUseCase) {}
+
+  @Get()
+  @HttpCode(200)
+  async handle(
+    @Param(pipeParams) { id }: ParamsSchema,
+    // @Query(pipeQuery) { latitude, longitude }: QuerySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.findOrder.execute({
+      requestResponsibleId,
+      orderId: id,
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      const value = resp.value
+
+      return { order: value.order }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/mark-order-as-awaiting-for-pickup.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/mark-order-as-awaiting-for-pickup.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/mark-order-as-awaiting-for-pickup.controller.ts b/src/infra/http/controllers/order-controllers/mark-order-as-awaiting-for-pickup.controller.ts
new file mode 100644
index 0000000..ea3cd4e
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/mark-order-as-awaiting-for-pickup.controller.ts
@@ -0,0 +1,79 @@
+import {
+  BadRequestException,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Param,
+  Patch,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { MarkOrderAsAwaitingForPickupUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/mark-order-as-awaiting-for-pickup-use-case'
+
+const paramsSchema = z.object({
+  id: z.string().uuid(),
+})
+
+// const querySchema = z.object({
+//   latitude: latitudeSchema,
+//   longitude: longitudeSchema,
+// })
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+// type QuerySchema = z.infer<typeof querySchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+// const pipeQuery = new ZodValidationPipe(querySchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:id/awaiting')
+// @Public()
+export class MarkOrderAsAwaitingForPickupController {
+  constructor(
+    private markOrderAsAwaitingForPickup: MarkOrderAsAwaitingForPickupUseCase,
+  ) {}
+
+  @Patch()
+  @HttpCode(204)
+  async handle(
+    @Param(pipeParams) { id }: ParamsSchema,
+    // @Query(pipeQuery) { latitude, longitude }: QuerySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.markOrderAsAwaitingForPickup.execute({
+      requestResponsibleId,
+      orderId: id,
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+      // return { order: value.order }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/order-controllers/return-order.controller.e2e-spec.ts b/src/infra/http/controllers/order-controllers/return-order.controller.e2e-spec.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/infra/http/controllers/order-controllers/return-order.controller.ts b/src/infra/http/controllers/order-controllers/return-order.controller.ts
new file mode 100644
index 0000000..d50ef54
--- /dev/null
+++ b/src/infra/http/controllers/order-controllers/return-order.controller.ts
@@ -0,0 +1,78 @@
+import {
+  BadRequestException,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Param,
+  Patch,
+  Query,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { ReturnOrderUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/order/return-order-use-case'
+
+const paramsSchema = z.object({
+  id: z.string().uuid(),
+})
+
+const querySchema = z.object({
+  returnCause: z.string().min(10),
+})
+
+// const bodySchema = z.object({
+//   cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+//   name: z.string(),
+// })
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+type QuerySchema = z.infer<typeof querySchema>
+// type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+const pipeQuery = new ZodValidationPipe(querySchema)
+// const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/orders/:id/return')
+// @Public()
+export class ReturnOrderController {
+  constructor(private returnOrder: ReturnOrderUseCase) {}
+
+  @Patch()
+  @HttpCode(204)
+  async handle(
+    @Param(pipeParams) { id }: ParamsSchema,
+    @Query(pipeQuery) { returnCause }: QuerySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    const resp = await this.returnOrder.execute({
+      requestResponsibleId,
+      orderId: id,
+      returnCause,
+    })
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+      // return { order: value.order }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/user-controllers/delete-user.controller.ts b/src/infra/http/controllers/user-controllers/delete-user.controller.ts
new file mode 100644
index 0000000..dc64775
--- /dev/null
+++ b/src/infra/http/controllers/user-controllers/delete-user.controller.ts
@@ -0,0 +1,78 @@
+import {
+  BadRequestException,
+  Controller,
+  Delete,
+  HttpCode,
+  NotFoundException,
+  Param,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { DeleteCourierUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/courier/delete-courier-use-case'
+import { Either } from '@/core/either'
+import { DeleteRecipientUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/recipient/delete-recipient-use-case'
+
+const paramsSchema = z.object({
+  role: z.enum(['recipient', 'adm', 'courier']),
+  id: z.string().uuid(),
+})
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+
+const pipe = new ZodValidationPipe(paramsSchema)
+
+@Controller('/users/:role/:id')
+// @Public()
+export class DeleteUserController {
+  constructor(
+    private deleteCourier: DeleteCourierUseCase,
+    private deleteRecipient: DeleteRecipientUseCase,
+  ) {}
+
+  @Delete()
+  @HttpCode(204)
+  async handle(
+    @Param(pipe) { id, role }: ParamsSchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    let resp: Either<ResourceNotFoundError | UnauthorizedError, null>
+
+    if (role === 'courier') {
+      resp = await this.deleteCourier.execute({
+        requestResponsibleId,
+        courierId: id,
+      })
+    } else if (role === 'recipient') {
+      resp = await this.deleteRecipient.execute({
+        requestResponsibleId,
+        recipientId: id,
+      })
+    } else {
+      throw new BadRequestException(`cannot delete an admin`)
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/controllers/user-controllers/fetch-users.controller.ts b/src/infra/http/controllers/user-controllers/fetch-users.controller.ts
new file mode 100644
index 0000000..90c1c9d
--- /dev/null
+++ b/src/infra/http/controllers/user-controllers/fetch-users.controller.ts
@@ -0,0 +1,84 @@
+import {
+  BadRequestException,
+  Controller,
+  Get,
+  HttpCode,
+  NotFoundException,
+  Param,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { Either } from '@/core/either'
+import { FetchCouriersUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/courier/fetch-couriers-use-case'
+import { FetchRecipientsUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/recipient/fetch-recipients-use-case'
+import { Courier } from '@/domain/core/deliveries-and-orders/enterprise/entities/courier'
+import { Recipient } from '@/domain/core/deliveries-and-orders/enterprise/entities/recipient'
+
+const paramsSchema = z.object({
+  role: z.enum(['recipient', 'adm', 'courier']),
+})
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+
+const pipe = new ZodValidationPipe(paramsSchema)
+
+@Controller('/users/:role')
+// @Public()
+export class FetchUsersController {
+  constructor(
+    private fetchCouriers: FetchCouriersUseCase,
+    private fetchRecipients: FetchRecipientsUseCase,
+  ) {}
+
+  @Get()
+  @HttpCode(200)
+  async handle(
+    @Param(pipe) { role }: ParamsSchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    let resp: Either<
+      ResourceNotFoundError | UnauthorizedError,
+      { couriers: Courier[] } | { recipients: Recipient[] }
+    >
+
+    if (role === 'courier') {
+      resp = await this.fetchCouriers.execute({
+        requestResponsibleId,
+      })
+    } else if (role === 'recipient') {
+      resp = await this.fetchRecipients.execute({
+        requestResponsibleId,
+      })
+    } else {
+      throw new BadRequestException(`cannot fetch admins`)
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      const value = resp.value[role + 's']
+
+      return {
+        [role + 's']: value,
+      }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/user-controllers/find-user.controller.ts b/src/infra/http/controllers/user-controllers/find-user.controller.ts
new file mode 100644
index 0000000..bac508d
--- /dev/null
+++ b/src/infra/http/controllers/user-controllers/find-user.controller.ts
@@ -0,0 +1,87 @@
+import {
+  BadRequestException,
+  Controller,
+  Get,
+  HttpCode,
+  NotFoundException,
+  Param,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { Either } from '@/core/either'
+import { Courier } from '@/domain/core/deliveries-and-orders/enterprise/entities/courier'
+import { Recipient } from '@/domain/core/deliveries-and-orders/enterprise/entities/recipient'
+import { FindCourierUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/courier/find-courier-use-case'
+import { FindRecipientUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/recipient/find-recipient-use-case'
+
+const paramsSchema = z.object({
+  role: z.enum(['recipient', 'adm', 'courier']),
+  id: z.string().uuid(),
+})
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+
+const pipe = new ZodValidationPipe(paramsSchema)
+
+@Controller('/users/:role/:id')
+// @Public()
+export class FindUserController {
+  constructor(
+    private findCourier: FindCourierUseCase,
+    private findRecipient: FindRecipientUseCase,
+  ) {}
+
+  @Get()
+  @HttpCode(200)
+  async handle(
+    @Param(pipe) { role, id }: ParamsSchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    let resp: Either<
+      ResourceNotFoundError | UnauthorizedError,
+      { courier: Courier } | { recipient: Recipient }
+    >
+
+    if (role === 'courier') {
+      resp = await this.findCourier.execute({
+        requestResponsibleId,
+        courierId: id,
+      })
+    } else if (role === 'recipient') {
+      resp = await this.findRecipient.execute({
+        requestResponsibleId,
+        recipientId: id,
+      })
+    } else {
+      throw new BadRequestException(`cannot find an admin`)
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      const value = resp.value[role]
+
+      return {
+        [role]: value,
+      }
+    }
+  }
+}
diff --git a/src/infra/http/controllers/user-controllers/update-user-password.controller.ts b/src/infra/http/controllers/user-controllers/update-user-password.controller.ts
new file mode 100644
index 0000000..b07b459
--- /dev/null
+++ b/src/infra/http/controllers/user-controllers/update-user-password.controller.ts
@@ -0,0 +1,88 @@
+import {
+  BadRequestException,
+  Body,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Param,
+  Patch,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { Either } from '@/core/either'
+import { UpdateCourierPasswordUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/courier/update-courier-password-use-case'
+import { UpdateRecipientPasswordUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-password-use-case'
+
+const paramsSchema = z.object({
+  role: z.enum(['recipient', 'adm', 'courier']),
+  id: z.string().uuid(),
+})
+
+const bodySchema = z.object({
+  password: z.string(),
+})
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/users/:role/:id/update-password')
+// @Public()
+export class UpdateUserPasswordController {
+  constructor(
+    private updateCourierPassword: UpdateCourierPasswordUseCase,
+    private updateRecipientPassword: UpdateRecipientPasswordUseCase,
+  ) {}
+
+  @Patch()
+  @HttpCode(204)
+  async handle(
+    @Param(pipeParams) { role, id }: ParamsSchema,
+    @Body(pipeBody) body: BodySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    let resp: Either<ResourceNotFoundError | UnauthorizedError, null>
+
+    if (role === 'courier') {
+      resp = await this.updateCourierPassword.execute({
+        requestResponsibleId,
+        courierId: id,
+        ...body,
+      })
+    } else if (role === 'recipient') {
+      resp = await this.updateRecipientPassword.execute({
+        requestResponsibleId,
+        recipientId: id,
+        ...body,
+      })
+    } else {
+      throw new BadRequestException(`cannot update an admin password`)
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/controllers/user-controllers/update-user.controller.ts b/src/infra/http/controllers/user-controllers/update-user.controller.ts
new file mode 100644
index 0000000..ff41bb6
--- /dev/null
+++ b/src/infra/http/controllers/user-controllers/update-user.controller.ts
@@ -0,0 +1,90 @@
+import {
+  BadRequestException,
+  Body,
+  Controller,
+  HttpCode,
+  NotFoundException,
+  Param,
+  Put,
+  UnauthorizedException,
+} from '@nestjs/common'
+import z from 'zod'
+import { ZodValidationPipe } from '@/infra/pipes/zod-validation-pipe'
+import { UnauthorizedError } from '@/core/errors/errors/unauthorized-error'
+import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
+// import { Public } from '@/infra/auth/public'
+import { CurrentUser } from '@/infra/auth/current-user-decorator'
+import { TokenPayload } from '@/infra/auth/jwt.strategy'
+import { Either } from '@/core/either'
+import { UpdateCourierUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/courier/update-courier-use-case'
+import { UpdateRecipientUseCase } from '@/domain/core/deliveries-and-orders/application/use-cases/recipient/update-recipient-use-case'
+import { validaCPF } from '../../utils/isCPF'
+
+const paramsSchema = z.object({
+  role: z.enum(['recipient', 'adm', 'courier']),
+  id: z.string().uuid(),
+})
+
+const bodySchema = z.object({
+  cpf: z.string().refine((cpf) => validaCPF(cpf), 'must be a valid cpf'),
+  name: z.string(),
+})
+
+type ParamsSchema = z.infer<typeof paramsSchema>
+type BodySchema = z.infer<typeof bodySchema>
+
+const pipeParams = new ZodValidationPipe(paramsSchema)
+const pipeBody = new ZodValidationPipe(bodySchema)
+
+@Controller('/users/:role/:id')
+// @Public()
+export class UpdateUserController {
+  constructor(
+    private updateCourier: UpdateCourierUseCase,
+    private updateRecipient: UpdateRecipientUseCase,
+  ) {}
+
+  @Put()
+  @HttpCode(204)
+  async handle(
+    @Param(pipeParams) { role, id }: ParamsSchema,
+    @Body(pipeBody) body: BodySchema,
+    @CurrentUser() user: TokenPayload,
+  ) {
+    const requestResponsibleId = user.sub
+
+    let resp: Either<ResourceNotFoundError | UnauthorizedError, null>
+
+    if (role === 'courier') {
+      resp = await this.updateCourier.execute({
+        requestResponsibleId,
+        courierId: id,
+        ...body,
+      })
+    } else if (role === 'recipient') {
+      resp = await this.updateRecipient.execute({
+        requestResponsibleId,
+        recipientId: id,
+        ...body,
+      })
+    } else {
+      throw new BadRequestException(`cannot update an admin`)
+    }
+
+    if (resp.isLeft()) {
+      const value = resp.value
+      if (value instanceof ResourceNotFoundError) {
+        throw new NotFoundException({ message: value.message })
+      }
+      if (value instanceof UnauthorizedError) {
+        throw new UnauthorizedException({ message: value.message })
+      }
+
+      throw new BadRequestException()
+    }
+
+    if (resp.isRight()) {
+      // const value = resp.value
+    }
+  }
+}
diff --git a/src/infra/http/factories/requests/auth-and-register-factories/make-authenticate-request.ts b/src/infra/http/factories/requests/auth-and-register-factories/make-authenticate-request.ts
new file mode 100644
index 0000000..8e6c949
--- /dev/null
+++ b/src/infra/http/factories/requests/auth-and-register-factories/make-authenticate-request.ts
@@ -0,0 +1,20 @@
+import { UserRoles } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeAuthenticateRequestProps {
+  body: {
+    cpf: string
+    password: string
+    role: UserRoles
+  }
+}
+
+export async function makeAuthenticateRequest(
+  app: INestApplication,
+  { body }: MakeAuthenticateRequestProps,
+) {
+  const resp = await request(app.getHttpServer()).post(`/sessions`).send(body)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/auth-and-register-factories/make-register-request.ts b/src/infra/http/factories/requests/auth-and-register-factories/make-register-request.ts
new file mode 100644
index 0000000..536f684
--- /dev/null
+++ b/src/infra/http/factories/requests/auth-and-register-factories/make-register-request.ts
@@ -0,0 +1,24 @@
+import { INestApplication } from '@nestjs/common'
+import { UserRoles } from '@prisma/client'
+import request from 'supertest'
+
+export interface MakeRegisterRequestProps {
+  body: {
+    cpf: string
+    name: string
+    password: string
+    role: UserRoles
+  }
+  token: string
+}
+
+export async function makeRegisterRequest(
+  app: INestApplication,
+  { token }: MakeRegisterRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .patch(`/register`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-collect-order-request.ts b/src/infra/http/factories/requests/order-request-factories/make-collect-order-request.ts
new file mode 100644
index 0000000..02b781d
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-collect-order-request.ts
@@ -0,0 +1,18 @@
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeCollectOrderRequestProps {
+  orderId: string
+  token: string
+}
+
+export async function makeCollectOrderRequest(
+  app: INestApplication,
+  { orderId, token }: MakeCollectOrderRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .patch(`/orders/${orderId}/collect`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-create-order-request.ts b/src/infra/http/factories/requests/order-request-factories/make-create-order-request.ts
new file mode 100644
index 0000000..0bb6403
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-create-order-request.ts
@@ -0,0 +1,24 @@
+import { AddressCreationProps } from '@/domain/core/deliveries-and-orders/enterprise/entities/value-objects/address'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeCreateOrderRequestProps {
+  body: {
+    address: AddressCreationProps
+    courierId: string
+    recipientId: string
+  }
+  token: string
+}
+
+export async function makeCreateOrderRequest(
+  app: INestApplication,
+  { body, token }: MakeCreateOrderRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .post(`/orders/`)
+    .set('Authorization', `Bearer ${token}`)
+    .send(body)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-delete-order-request.ts b/src/infra/http/factories/requests/order-request-factories/make-delete-order-request.ts
new file mode 100644
index 0000000..0ea551b
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-delete-order-request.ts
@@ -0,0 +1,18 @@
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeDeleteOrderRequestProps {
+  orderId: string
+  token: string
+}
+
+export async function makeDeleteOrderRequest(
+  app: INestApplication,
+  { orderId, token }: MakeDeleteOrderRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .delete(`/orders/${orderId}`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-deliver-order-request.ts b/src/infra/http/factories/requests/order-request-factories/make-deliver-order-request.ts
new file mode 100644
index 0000000..ca25e61
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-deliver-order-request.ts
@@ -0,0 +1,19 @@
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeDeliverOrderRequestProps {
+  orderId: string
+  attachmentId: string
+  token: string
+}
+
+export async function makeDeliverOrderRequest(
+  app: INestApplication,
+  { orderId, attachmentId, token }: MakeDeliverOrderRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .patch(`/orders/${orderId}/deliver?attachmentId=${attachmentId}`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-fetch-nearby-orders-request.ts b/src/infra/http/factories/requests/order-request-factories/make-fetch-nearby-orders-request.ts
new file mode 100644
index 0000000..3c6daa0
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-fetch-nearby-orders-request.ts
@@ -0,0 +1,26 @@
+import { Coordinates } from '@/domain/core/deliveries-and-orders/enterprise/entities/value-objects/coordinates'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeFetchNearbyOrdersRequestProps {
+  courierId: string
+  coordinates: Coordinates['raw']
+  token: string
+}
+
+export async function makeFetchNearbyOrdersRequest(
+  app: INestApplication,
+  {
+    courierId,
+    token,
+    coordinates: { latitude, longitude },
+  }: MakeFetchNearbyOrdersRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .get(
+      `/orders/${courierId}/nearby?latitude=${latitude}&longitude=${longitude}`,
+    )
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-fetch-orders-request.ts b/src/infra/http/factories/requests/order-request-factories/make-fetch-orders-request.ts
new file mode 100644
index 0000000..e9c764d
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-fetch-orders-request.ts
@@ -0,0 +1,20 @@
+import { UserRoles } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeFetchOrdersRequestProps {
+  role: UserRoles | 'all'
+  userId?: string
+  token: string
+}
+
+export async function makeFetchOrdersRequest(
+  app: INestApplication,
+  { role, token, userId }: MakeFetchOrdersRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .get(`/orders/${role}/${userId ? '?userId=' + userId : ''}`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-find-order-request.ts b/src/infra/http/factories/requests/order-request-factories/make-find-order-request.ts
new file mode 100644
index 0000000..eaabda1
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-find-order-request.ts
@@ -0,0 +1,18 @@
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeFindOrdersRequestProps {
+  orderId: string
+  token: string
+}
+
+export async function makeFindOrdersRequest(
+  app: INestApplication,
+  { token, orderId }: MakeFindOrdersRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .get(`/orders/${orderId}/find`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/make-mark-order-as-awaiting-for-pickup-request.ts b/src/infra/http/factories/requests/order-request-factories/make-mark-order-as-awaiting-for-pickup-request.ts
new file mode 100644
index 0000000..3713e37
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/make-mark-order-as-awaiting-for-pickup-request.ts
@@ -0,0 +1,18 @@
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeMarkOrderAsAwaitingForPickupRequestProps {
+  orderId: string
+  token: string
+}
+
+export async function makeMarkOrderAsAwaitingForPickupRequest(
+  app: INestApplication,
+  { token, orderId }: MakeMarkOrderAsAwaitingForPickupRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .patch(`/orders/${orderId}/awaiting`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/order-request-factories/return-order-request copy.ts b/src/infra/http/factories/requests/order-request-factories/return-order-request copy.ts
new file mode 100644
index 0000000..6242ea6
--- /dev/null
+++ b/src/infra/http/factories/requests/order-request-factories/return-order-request copy.ts	
@@ -0,0 +1,18 @@
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeReturnOrderRequestProps {
+  orderId: string
+  token: string
+}
+
+export async function makeReturnOrderRequest(
+  app: INestApplication,
+  { token, orderId }: MakeReturnOrderRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .patch(`/orders/${orderId}/return`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/user-factories/delete-user-request.ts b/src/infra/http/factories/requests/user-factories/delete-user-request.ts
new file mode 100644
index 0000000..4b2cbee
--- /dev/null
+++ b/src/infra/http/factories/requests/user-factories/delete-user-request.ts
@@ -0,0 +1,20 @@
+import { UserRoles } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeDeleteUserRequestProps {
+  role: UserRoles
+  userId: string
+  token: string
+}
+
+export async function makeDeleteUserRequest(
+  app: INestApplication,
+  { role, userId, token }: MakeDeleteUserRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .delete(`/users/${role}/${userId}`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/user-factories/fetch-users-request.ts b/src/infra/http/factories/requests/user-factories/fetch-users-request.ts
new file mode 100644
index 0000000..d18450b
--- /dev/null
+++ b/src/infra/http/factories/requests/user-factories/fetch-users-request.ts
@@ -0,0 +1,19 @@
+import { UserRoles } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeFetchUsersRequestProps {
+  role: UserRoles
+  token: string
+}
+
+export async function makeFetchUsersRequest(
+  app: INestApplication,
+  { role, token }: MakeFetchUsersRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .get(`/users/${role}`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/user-factories/find-user-request.ts b/src/infra/http/factories/requests/user-factories/find-user-request.ts
new file mode 100644
index 0000000..65a5a5d
--- /dev/null
+++ b/src/infra/http/factories/requests/user-factories/find-user-request.ts
@@ -0,0 +1,20 @@
+import { UserRoles } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeFindUserRequestProps {
+  role: UserRoles
+  userId: string
+  token: string
+}
+
+export async function makeFindUserRequest(
+  app: INestApplication,
+  { role, userId, token }: MakeFindUserRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .get(`/user/${role}/${userId}`)
+    .set('Authorization', `Bearer ${token}`)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/user-factories/update-user-password-request.ts b/src/infra/http/factories/requests/user-factories/update-user-password-request.ts
new file mode 100644
index 0000000..a96ce22
--- /dev/null
+++ b/src/infra/http/factories/requests/user-factories/update-user-password-request.ts
@@ -0,0 +1,24 @@
+import { UserRoles } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeUpdateUserPasswordRequestProps {
+  role: UserRoles
+  userId: string
+  body: {
+    password: string
+  }
+  token: string
+}
+
+export async function makeUpdateUserPasswordRequest(
+  app: INestApplication,
+  { role, userId, token, body }: MakeUpdateUserPasswordRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .patch(`/users/${role}/${userId}/update-password`)
+    .set('Authorization', `Bearer ${token}`)
+    .send(body)
+
+  return resp
+}
diff --git a/src/infra/http/factories/requests/user-factories/update-user-request.ts b/src/infra/http/factories/requests/user-factories/update-user-request.ts
new file mode 100644
index 0000000..53c1ae0
--- /dev/null
+++ b/src/infra/http/factories/requests/user-factories/update-user-request.ts
@@ -0,0 +1,25 @@
+import { UserRoles } from '@/domain/core/deliveries-and-orders/enterprise/entities/abstract/user'
+import { INestApplication } from '@nestjs/common'
+import request from 'supertest'
+
+export interface MakeUpdateUserRequestProps {
+  role: UserRoles
+  userId: string
+  body: {
+    cpf: string
+    name: string
+  }
+  token: string
+}
+
+export async function makeUpdateUserRequest(
+  app: INestApplication,
+  { role, userId, token, body }: MakeUpdateUserRequestProps,
+) {
+  const resp = await request(app.getHttpServer())
+    .patch(`/users/${role}/${userId}`)
+    .set('Authorization', `Bearer ${token}`)
+    .send(body)
+
+  return resp
+}
diff --git a/src/infra/http/http.module.ts b/src/infra/http/http.module.ts
index c17fda2..c373867 100644
--- a/src/infra/http/http.module.ts
+++ b/src/infra/http/http.module.ts
@@ -1,9 +1,13 @@
 import { Module } from '@nestjs/common'
 import { DatabaseModule } from '../database/database.module'
-import { useCases } from './controllers/use-cases.exports'
+import { useCases } from './controllers/@exports/use-cases.exports'
+import { AuthModule } from '../auth/auth.module'
+import { controllers } from './controllers/@exports/controllers.exports'
+import { CryptographyModule } from '../cryptography/cryptography.module'
 
 @Module({
-  imports: [DatabaseModule],
+  imports: [DatabaseModule, AuthModule, CryptographyModule],
   providers: [...useCases],
+  controllers: [...controllers],
 })
 export class HttpModule {}
diff --git a/src/infra/http/utils/isCPF.ts b/src/infra/http/utils/isCPF.ts
new file mode 100644
index 0000000..4455948
--- /dev/null
+++ b/src/infra/http/utils/isCPF.ts
@@ -0,0 +1,61 @@
+// import { randint } from './numbers'
+
+export const criaDigitos: (num: string) => string = (num: string) => {
+  const arrNum = num.split('')
+  const length = arrNum.length
+
+  const digito = arrNum
+    .map((letter, index) => {
+      const number = Number(letter)
+      return number * (length + 1 - index)
+    })
+    .reduce((acc, num) => acc + num, 0)
+
+  const digitoCalc1 = 11 - (digito % 11)
+  const digitoCalc2 = digitoCalc1 > 9 ? '0' : String(digitoCalc1)
+
+  if (arrNum.length === 11) {
+    const result = arrNum.join('')
+    return result
+  }
+  const arrNum2 = [...arrNum, digitoCalc2]
+  const result = arrNum2.join('')
+
+  return criaDigitos(result)
+}
+
+export const formataCPF = (cpf: string) => {
+  cpf = String(cpf)
+  const parte1 = cpf.slice(0, 3)
+  const parte2 = cpf.slice(3, 6)
+  const parte3 = cpf.slice(6, 9)
+  const digitos = cpf.slice(-2)
+
+  cpf = `${parte1}.${parte2}.${parte3}-${digitos}`
+  return cpf
+}
+
+export const validaCPF = (text: string) => {
+  if (!text) return false
+  const cpfClear = text.replaceAll(/\D+/g, '')
+  if (cpfClear.length !== 11) return false
+  if (cpfClear[0].repeat(cpfClear.length) === cpfClear) return false
+
+  const cpfArray = cpfClear.split('') as string[]
+  const cpfFiltered = cpfArray
+    .filter((n) => {
+      if (!/\W/g.exec(n)) return n
+      return false
+    })
+    .filter((n) => {
+      if (Number.isInteger(Number(n))) return n
+      return false
+    })
+
+  const cpfJoined = cpfFiltered.join('')
+  const parte1 = cpfJoined.slice(0, -2)
+  const cpfValido = criaDigitos(parte1)
+
+  const cpf = cpfJoined
+  return cpf === cpfValido
+}
diff --git a/src/infra/pipes/zod-validation-pipe.ts b/src/infra/pipes/zod-validation-pipe.ts
new file mode 100644
index 0000000..94cb43d
--- /dev/null
+++ b/src/infra/pipes/zod-validation-pipe.ts
@@ -0,0 +1,23 @@
+import { BadRequestException, PipeTransform } from '@nestjs/common'
+import { ZodError, ZodSchema } from 'zod'
+import { fromZodError } from 'zod-validation-error'
+
+export class ZodValidationPipe implements PipeTransform {
+  constructor(private schema: ZodSchema) {}
+
+  transform(value: unknown) {
+    try {
+      this.schema.parse(value)
+    } catch (error) {
+      if (error instanceof ZodError) {
+        throw new BadRequestException({
+          errors: fromZodError(error),
+          message: 'validation failed',
+          statusCode: 400,
+        })
+      }
+      throw new BadRequestException('validation failed')
+    }
+    return value
+  }
+}
diff --git a/test/factories/entities/makeOrder.ts b/test/factories/entities/makeOrder.ts
index ee7d620..d673695 100644
--- a/test/factories/entities/makeOrder.ts
+++ b/test/factories/entities/makeOrder.ts
@@ -1,8 +1,14 @@
 import UniqueEntityId from '@/core/entities/unique-entity-id'
-import { Order } from '@/domain/core/deliveries-and-orders/enterprise/entities/order'
+import {
+  Order,
+  OrderCreateProps,
+} from '@/domain/core/deliveries-and-orders/enterprise/entities/order'
 import { makeAddress } from './value-objects/makeAddress'
 
-export function makeOrder(override?: Partial<Order>, id?: UniqueEntityId) {
+export function makeOrder(
+  override?: Partial<OrderCreateProps>,
+  id?: UniqueEntityId,
+) {
   const result = Order.create(
     {
       address: makeAddress(override?.address),
diff --git a/utils/generate-async-crypto-keys.ts b/utils/generate-async-crypto-keys.ts
new file mode 100644
index 0000000..c98e1b3
--- /dev/null
+++ b/utils/generate-async-crypto-keys.ts
@@ -0,0 +1,243 @@
+import { exec } from 'child_process'
+import path from 'node:path'
+import fs from 'node:fs'
+
+class AsyncCryptoKeys {
+  private _publicKey: string | null = null
+  private _privateKey: string | null = null
+
+  private _publicKeyBase64: string | null = null
+  private _privateKeyBase64: string | null = null
+
+  get publicKey() {
+    return this._publicKey
+  }
+
+  get privateKey() {
+    return this._privateKey
+  }
+
+  get publicKeyBase64() {
+    return this._publicKeyBase64
+  }
+
+  get privateKeyBase64() {
+    return this._privateKeyBase64
+  }
+
+  // Função para executar os comandos
+  async generate() {
+    const baseDir = path.resolve(__dirname, '..')
+    const keysDir = path.resolve(baseDir, 'keys')
+
+    const privateKeyPath = path.resolve(keysDir, 'private_key.pem')
+    const publicKeyPath = path.resolve(keysDir, 'public_key.pem')
+
+    if (!this.fileExists(keysDir)) {
+      fs.mkdir(keysDir, { recursive: true }, (err) =>
+        console.log('erro ao criar o arquivo', err?.message),
+      )
+    }
+
+    // const password = randomUUID()
+
+    // const privateKeyCommand = `openssl genpkey -algorithm RSA -out ${privateKeyPath} -aes256 -pass pass:${password}`
+    const privateKeyCommand = `openssl genpkey -algorithm RSA -out ${privateKeyPath} -pkeyopt rsa_keygen_bits:2048`
+    // const publicKeyCommand = `openssl rsa -pubout -in ${privateKeyPath} -out ${publicKeyPath} -passin pass:${password}`
+    const publicKeyCommand = `openssl rsa -pubout -in ${privateKeyPath} -out ${publicKeyPath}`
+
+    this.execute(
+      privateKeyCommand,
+      'private',
+      async () =>
+        await this.waitFor(() => this.fileExists(privateKeyPath, true)),
+      () => this.execute(publicKeyCommand, 'public'),
+    )
+
+    const privatePathExists = await this.waitFor(() =>
+      this.fileExists(privateKeyPath, true),
+    )
+    const publicPathExists = await this.waitFor(() =>
+      this.fileExists(publicKeyPath, true),
+    )
+
+    const isCreated = privatePathExists && publicPathExists
+
+    console.log('isCreated - openssl', isCreated)
+    if (isCreated) {
+      const { privateKeyContent, publicKeyContent } = await this.getKeys({
+        privateKeyPath,
+        publicKeyPath,
+      })
+
+      this._privateKey = privateKeyContent
+      this._publicKey = publicKeyContent
+
+      console.log('generating base64')
+      const privateKeyBse64Path = path.resolve(
+        keysDir,
+        'private_key_base64.pem',
+      )
+      const publicKeyBse64Path = path.resolve(keysDir, 'public_key_base64.pem')
+
+      const privateKeyContentBase64 = Buffer.from(
+        privateKeyContent ?? '',
+      )?.toString('base64')
+      const publicKeyContentBase64 = Buffer.from(
+        publicKeyContent ?? '',
+      )?.toString('base64')
+
+      fs.writeFileSync(privateKeyBse64Path, privateKeyContentBase64)
+      fs.writeFileSync(publicKeyBse64Path, publicKeyContentBase64)
+
+      this._privateKeyBase64 = privateKeyContentBase64
+      this._publicKeyBase64 = publicKeyContentBase64
+
+      // const privateKeyBase64Command = `openssl base64 -in ${privateKeyPath} -out ${privateKeyBse64Path} -pass pass:${password}`
+      // const publicKeyBase64Command = `openssl base64 -in ${publicKeyPath} -out ${publicKeyBse64Path} -pass pass:${password}`
+
+      // this.execute(privateKeyBase64Command, 'private')
+      // this.execute(publicKeyBase64Command, 'public')
+
+      // const privatePathExists = await this.waitFor(() =>
+      //   this.fileExists(privateKeyBse64Path, true),
+      // )
+      // const publicPathExists = await this.waitFor(() =>
+      //   this.fileExists(publicKeyBse64Path, true),
+      // )
+
+      // const isCreated = privatePathExists && publicPathExists
+
+      // if (isCreated) {
+      //   const keys = await this.getKeys({
+      //     privateKeyPath: privateKeyBse64Path,
+      //     publicKeyPath: publicKeyBse64Path,
+      //   })
+
+      //   this._privateKeyBase64 = keys.privateKeyContent
+      //   this._publicKey = keys.publicKeyContent
+      // }
+    }
+  }
+
+  fileExists(path: string, throwError?: boolean) {
+    const info = fs.existsSync(path)
+
+    if (!info && throwError) throw new Error('file does not exist')
+    return info
+  }
+
+  /**
+   * This function loops through a function rerunning all assertions
+   * inside of it until it gets a truthy result.
+   *
+   * If the maximum duration is reached, it then rejects.
+   *
+   * @param expectations A function containing all tests assertions
+   * @param maxDuration Maximum wait time before rejecting
+   */
+  async waitFor(assertions: () => void, maxDuration = 1000): Promise<boolean> {
+    return new Promise((resolve) => {
+      let elapsedTime = 0
+
+      const interval = setInterval(() => {
+        elapsedTime += 10
+
+        try {
+          assertions()
+          clearInterval(interval)
+          resolve(true)
+        } catch (err) {
+          if (elapsedTime >= maxDuration) {
+            resolve(false)
+          }
+        }
+      }, 10)
+    })
+  }
+
+  private execute(
+    command: string,
+    key: 'public' | 'private',
+    fileCreation?: () => Promise<boolean>,
+    callback?: () => { execOperation: boolean; callbackOperation: boolean },
+  ) {
+    let execOperation: boolean = false
+    let callbackOperation: boolean = false
+
+    console.log('\nexecuting', command)
+    exec(command, async (error) => {
+      if (error) {
+        console.error(
+          `Erro ao extrair chave ${key === 'public' ? 'pública' : 'privada'}: ${error.message}`,
+        )
+        return
+      }
+
+      console.log(
+        '- ',
+        `Chave ${key === 'public' ? 'pública' : 'privada'} gerada com sucesso.`,
+      )
+      execOperation = true
+
+      const isCreated = fileCreation ? await fileCreation() : false
+
+      if (callback && isCreated) {
+        const { execOperation } = callback()
+        callbackOperation = execOperation
+      }
+    })
+
+    return { execOperation, callbackOperation }
+  }
+
+  private readKeyFile(filePath: string) {
+    try {
+      const content = fs.readFileSync(filePath, 'utf8')
+      return content
+    } catch (error: any) { //eslint-disable-line
+      console.error(`Erro ao ler o arquivo ${filePath}: ${error.message}`)
+      return null
+    }
+  }
+
+  private async getKeys({
+    privateKeyPath,
+    publicKeyPath,
+  }: {
+    privateKeyPath: string
+    publicKeyPath: string
+  }) {
+    const privatePathExists = await this.waitFor(() =>
+      this.fileExists(privateKeyPath, true),
+    )
+    const publicPathExists = await this.waitFor(() =>
+      this.fileExists(publicKeyPath, true),
+    )
+
+    if (!privatePathExists || !publicPathExists)
+      throw new Error('files dont exist')
+
+    // Leitura da chave privada
+    const privateKeyContent = this.readKeyFile(privateKeyPath)
+
+    // if (privateKeyContent) {
+    //   console.log('Conteúdo da chave privada:')
+    //   console.log(privateKeyContent)
+    // }
+
+    // Leitura da chave pública
+    const publicKeyContent = this.readKeyFile(publicKeyPath)
+
+    // if (publicKeyContent) {
+    //   console.log('Conteúdo da chave pública:')
+    //   console.log(publicKeyContent)
+    // }
+
+    return { privateKeyContent, publicKeyContent }
+  }
+}
+
+const keys = new AsyncCryptoKeys()
+
+keys.generate()
diff --git a/utils/generate-env-file-with-env-example.ts b/utils/generate-env-file-with-env-example.ts
new file mode 100644
index 0000000..8412140
--- /dev/null
+++ b/utils/generate-env-file-with-env-example.ts
@@ -0,0 +1,8 @@
+import { readFileSync, writeFileSync } from 'node:fs'
+import { resolve } from 'node:path'
+
+const envExamplePath = resolve(__dirname, '..', '.env.example')
+const envContent = readFileSync(envExamplePath)
+
+const envPath = resolve(__dirname, '..', '.env')
+writeFileSync(envPath, envContent)