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.
๐ท Frameworks, Libraries and Technologies
๐๏ธ List of microservices
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.
๐๏ธ Microservices diagram
๐ณ List of docker containers
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
๐ How to run the server
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
๐จ๏ธ Swagger UI documentation (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
๐ง Implementation features
POST /auth/register (allows you to register)
name
type
data type
email
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
email
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
Create new companies (๐Token required )
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
Update your companies (๐Token required )
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 your companies (๐Token required )
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 all your companies (๐Token required )
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 one your company (๐Token required )
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
Create invoices (๐Token required )
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
Update your unfinished invoices (๐Token required )
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 your unfinished invoices (๐Token required )
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
Finalize your unfinished invoices (๐Token required )
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 all your invoices (๐Token required )
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 one your invoice (๐Token required )
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
Create new items on your unfinished invoice (๐Token required )
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
Update items on your unfinished invoice (๐Token required )
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 items on your unfinished invoice (๐Token required )
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 all items by invoice (๐Token required )
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 one item by id (๐Token required )
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 names of all your PDF files (๐Token required )
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
Download your PDF file by name (๐Token required )
GET /storage/{ fileName:string } (allows to download your PDF file ๐๏ธ[token required])
http code
content-type
response
200
application/pdf
PDFfile
401
application/json
string
403
application/json
string
404
application/json
string