Invoice management system, microservice architecture.
The services implement Vertical Slice Architecture, YARP reverse proxy, RabbitMq message broker, request-response pattern, minimal api, PFD file generation, miniIO object storage, integration and unit tests.
- xUnit
- .NET 8
- ASP.NET Core 8
- Entity Framework
- PostgreSQL
- MinIO object storage
- MediatR
- Carter
- MassTransit
- RabbitMQ
- QuestPDF
- FluentValidation
- IdentityModel
- Swashbuckle
- Yarp.ReverseProxy
- Docker
-
Gateway service: Single entry point to the application.
-
Identity service: User authentication.
-
Company service: Manages interactions with companies.
-
Invoice service: Manages interaction with the invoices.
-
FileGenerator service: Generates PDF files.
-
Storage service: Stores invoices in MinIO storage.
-
gateway.api - reverse proxy gateway container.
-
rabbitmq - message broker container.
-
minio - object storage for storage service.
-
storage.api - asp.net app container for storage service.
-
file-generator.api - asp.net app container for file generator service.
-
identity.api - asp.net app container for identity service.
-
identity.api.database - postgresql database container for identity service.
-
company.api - asp.net app container for company service.
-
company.api.database - postgresql database container for company service.
-
invoice.api - asp.net app container for invoice service.
-
invoice.api.database - postgresql database container for invoice service.
Allows you to run all integration and unit tests.
> dotnet test # donet SKD is required
-
Build and start Docker images based on the configuration defined in the docker-compose.yml
> make up # docker-compose up --build
-
Stop and remove containers
> make down # docker-compose down
container | port | login | password | access |
---|---|---|---|---|
gateway.api | 5000 | - | - | http://localhost:5000 |
rabbitMQ | 5672 / 15672 | user | password | http://localhost:15672 (local access) |
minIO | 9000 / 9001 | user | password | http://localhost:9001/login (local access) |
fileGenerator.api | - | - | - | - |
identity.api | 8000 | - | - | http://localhost:8000 (local access) |
company.api | 8001 | - | - | http://localhost:8001 (local access) |
invoice.api | 8002 | - | - | http://localhost:8002 (local access) |
storage.api | 8080 | - | - | http://localhost:8080 (local access) |
identity.api.database | 5432 | user | password | http://localhost:5432 (local access) |
company.api.database | 5433 | user | password | http://localhost:5433 (local access) |
invoice.api.database | 5434 | user | password | http://localhost:5434 (local access) |
-
Identity service
http://localhost:8000/swagger/index.html
-
Company service
http://localhost:8001/swagger/index.html
-
Invoice service
http://localhost:8002/swagger/index.html
-
Storage service
http://localhost:8080/swagger/index.html
Gateway base Url: http://localhost:5000
POST
/auth/register
(allows you to register)
name type data type required string password required string
http code content-type response 201
application/json
{"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "email": "string"}
400
application/json
array
409
application/json
string
POST
/auth/login
(allows you to login, issues accessToken and refreshToken)
name type data type required string password required string
http code content-type response 200
application/json
{"accessToken": "string", "refreshToken": "string", "refreshTokenExpires": "2024-04-21T17:42:12.146Z", "accessTokenType": "string"}
400
application/json
array
404
application/json
string
POST
/auth/refresh
(allows to refresh access and refresh tokens)
name type data type "refreshToken" required string
http code content-type response 200
application/json
{"accessToken": "string", "refreshToken": "string", "refreshTokenExpires": "2024-04-21T17:43:47.494Z", "accessTokenType": "string"}
400
application/json
array
401
application/json
string
POST
/auth/logout
(allows to logout and deactivates refresh tokens)
name type data type "refreshToken" required string
http code content-type response 204
application/json
NoContent
400
application/json
array
401
application/json
string
Functionality that allows to manage and interact with companies
POST
/company
(allows to create new companies ๐๏ธ[token required])
name type data type "name" required string "taxNumber" required string "city" required string "street" required string "houseNumber" required string "postalCode" required string
http code content-type response 201
application/json
{"companyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "taxNumber": "string", "city": "string", "street": "string", "houseNumber": "string", "postalCode": "string"}
400
application/json
array
401
application/json
string
403
application/json
string
PUT
/company
(allows to update your companies ๐๏ธ[token required])
name type data type "companyId" required uuid "name" not required string "taxNumber" not required string "city" not required string "street" not required string "houseNumber" not required string "postalCode" not required string
http code content-type response 200
application/json
{"companyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "taxNumber": "string", "city": "string", "street": "string", "houseNumber": "string", "postalCode": "string"}
400
application/json
array
401
application/json
string
403
application/json
string
404
application/json
string
DELETE
/company/{ id:uuid }
(allows to delete your companies ๐๏ธ[token required])
http code content-type response 204
application/json
NoContent
401
application/json
string
403
application/json
string
404
application/json
string
GET
/company
(allows you to get all your companies ๐๏ธ[token required])
name type data type PageNumber not required int32 PageSize not required int32
http code content-type response 200
application/json
{"items": [ { "companyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "taxNumber": "string", "city": "string", "street": "string", "houseNumber": "string", "postalCode": "string" } ], "pageNumber": 0, "totalPages": 0, "totalItemsCount": 0 }
401
application/json
string
403
application/json
string
GET
/company/{ id:uuid }
(allows you to get one your company ๐๏ธ[token required])
http code content-type response 200
application/json
{"companyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "taxNumber": "string", "city": "string", "street": "string", "houseNumber": "string", "postalCode": "string"}
401
application/json
string
403
application/json
string
Functionality that allows to manage and interact with invoices
POST
/invoice
(allows to create new invoices ๐๏ธ[token required])
name type data type "sellerCompanyId" required uuid "buyerCompanyId" required uuid "termsOfPayment" required int "paymentType" required string "status" required string
http code content-type response 201
application/json
{ "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "sellerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "buyerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "number": "string", "totalNetPrice": 0, "totalGrossPrice": 0, "termsOfPayment": 0, "paymentType": "string", "status": "string", "itemsId": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"] }
400
application/json
array
401
application/json
string
403
application/json
string
404
application/json
string
PUT
/invoice
(allows to update your invoices ๐๏ธ[token required])
name type data type "invoiceId" required uuid "status" required string
http code content-type response 200
application/json
{ "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "sellerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "buyerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "number": "string", "totalNetPrice": 0, "totalGrossPrice": 0, "termsOfPayment": 0, "paymentType": "string", "status": "string", "itemsId": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"] }
400
application/json
array
401
application/json
string
403
application/json
string
404
application/json
string
DELETE
/invoice/{ id:uuid }
(allows to delete your invoices ๐๏ธ[token required])
http code content-type response 204
application/json
NoContent
401
application/json
string
403
application/json
string
404
application/json
string
PATCH
/invoice/lock/{ id:uuid }
(allows to finalize your invoices ๐๏ธ[token required])
http code content-type response 200
application/json
string
401
application/json
string
403
application/json
string
404
application/json
string
GET
/invoice
(allows you to get all your invoices ๐๏ธ[token required])
name type data type PageNumber not required int32 PageSize not required int32
http code content-type response 200
application/json
[ { "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "sellerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "buyerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "number": "string", "totalNetPrice": 0, "totalGrossPrice": 0, "termsOfPayment": 0, "paymentType": "string", "status": "string", "itemsId": [ "3fa85f64-5717-4562-b3fc-2c963f66afa6" ] } ]
401
application/json
string
403
application/json
string
GET
/invoice/{ id:uuid }
(allows you to get one your company ๐๏ธ[token required])
http code content-type response 200
application/json
[ { "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "sellerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "buyerCompanyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "number": "string", "totalNetPrice": 0, "totalGrossPrice": 0, "termsOfPayment": 0, "paymentType": "string", "status": "string", "itemsId": [ "3fa85f64-5717-4562-b3fc-2c963f66afa6" ] } ]
401
application/json
string
403
application/json
string
Functionality that allows to manage and interact with invoice items
POST
/item
(allows to create new items ๐๏ธ[token required])
name type data type "invoiceId" required uuid "name" required string "amount" required int "unit" required string "vat" required string "netPrice" required decimal
http code content-type response 201
application/json
{ "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "itemId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "amount": 0, "unit": "string", "vat": "string", "netPrice": 0, "sumNetPrice": 0, "sumGrossPrice": 0 }
400
application/json
array
401
application/json
string
403
application/json
string
404
application/json
string
PUT
/item
(allows to update your items ๐๏ธ[token required])
name type data type "itemId" required uuid "name" not required string "amount" not required int "netPrice" not required decimal
http code content-type response 200
application/json
{ "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "itemId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "amount": 0, "unit": "string", "vat": "string", "netPrice": 0, "sumNetPrice": 0, "sumGrossPrice": 0 }
400
application/json
array
401
application/json
string
403
application/json
string
404
application/json
string
DELETE
/item/{ id:uuid }
(allows to delete your items ๐๏ธ[token required])
http code content-type response 204
application/json
NoContent
401
application/json
string
403
application/json
string
404
application/json
string
GET
/item/all-by-invoice/{ id:uuid }
(allows you to get items by invoice ๐๏ธ[token required])
http code content-type response 200
application/json
[ { "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "itemId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "amount": 0, "unit": "string", "vat": "string", "netPrice": 0, "sumNetPrice": 0, "sumGrossPrice": 0 } ]
401
application/json
string
403
application/json
string
404
application/json
string
GET
/item/{ id:uuid }
(allows you to get one item ๐๏ธ[token required])
http code content-type response 200
application/json
[ { "invoiceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "itemId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "amount": 0, "unit": "string", "vat": "string", "netPrice": 0, "sumNetPrice": 0, "sumGrossPrice": 0 } ]
401
application/json
string
403
application/json
string
404
application/json
string
PDF file is created automatically when the invoice is finalized
GET
/storage
(allows to get names of all your PDF files ๐๏ธ[token required])
http code content-type response 200
application/json
[ "string", "string", ]
401
application/json
string
403
application/json
string
404
application/json
string