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
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