{"id":18283814,"url":"https://github.com/fsmaiorano/dotnet-receivables-flow","last_synced_at":"2026-04-08T16:31:37.102Z","repository":{"id":242355963,"uuid":"802234709","full_name":"fsmaiorano/dotnet-receivables-flow","owner":"fsmaiorano","description":"💶 Payment processor using asynchronous queues","archived":false,"fork":false,"pushed_at":"2024-06-02T11:39:57.000Z","size":598,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-29T02:19:47.516Z","etag":null,"topics":["docker","docker-compose","dotnet8","entity-framework-core","identity","postgresql","rabbitmq"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fsmaiorano.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-17T19:41:28.000Z","updated_at":"2024-06-02T11:45:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"ef6b1b85-2157-4324-a851-6508ca5770fa","html_url":"https://github.com/fsmaiorano/dotnet-receivables-flow","commit_stats":null,"previous_names":["fsmaiorano/dotnet-receivables-flow"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fsmaiorano/dotnet-receivables-flow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsmaiorano%2Fdotnet-receivables-flow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsmaiorano%2Fdotnet-receivables-flow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsmaiorano%2Fdotnet-receivables-flow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsmaiorano%2Fdotnet-receivables-flow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fsmaiorano","download_url":"https://codeload.github.com/fsmaiorano/dotnet-receivables-flow/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsmaiorano%2Fdotnet-receivables-flow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31564850,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","dotnet8","entity-framework-core","identity","postgresql","rabbitmq"],"created_at":"2024-11-05T13:11:01.498Z","updated_at":"2026-04-08T16:31:37.086Z","avatar_url":"https://github.com/fsmaiorano.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"## 🔍 Motivation\n\nThis project was created to test the skills of a developer and I decided to use it as a way to improve my skills.\n\nThe backend was implemented at Level 8.\nThe frontend will be implemented soon.\n\nThe original challenge was created by [Aprovame](https://aprovame.com/) and ask to use Javascript, but I made it using .NET 😆\n\n## 🚀 Technologies\n\n- NET 8\n- Entity Framework Core\n- Identity\n- PostgreSQL\n- Docker / Docker Compose / Podman (I use this.)\n- RabbitMQ\n- NUnit3\n\n## 💻 The Problem\n\nA client of Bankme requested a new feature related to receivables.\n\nEvery day, this client processes multiple receivables, and our operations team was going crazy having to register all this manually!\n\nReceivables are digital representations of a document that simulates a debt to be received. For Bankme, it is important to have this information as part of the commercial flow we have with this client.\n\n### Requirements\n\n- NET 8\n- Docker / Podman\n- Python 3 (to generate batches)\n\nIn docs folder, you can find python script and the requirements.txt to generate batches.\n\n```shell\npip install --upgrade pip\n```\n\n### Structure of a Receivable\n\n| FIELD        | TYPE          | DESCRIPTION                             |\n|--------------|---------------|-----------------------------------------|\n| id           | string (UUID) | The identification of a receivable.     |\n| value        | float         | The value of the receivable.            |\n| emissionDate | date          | The emission date of the receivable.    |\n| assignor     | string (UUID) | The identification of an assignor.      |\n\n### Structure of an Assignor\n\n| FIELD    | TYPE          | DESCRIPTION                             |\n|----------|---------------|-----------------------------------------|\n| id       | string (UUID) | The identification of an assignor.      |\n| document | string(30)    | The CPF or CNPJ document of the assignor.|\n| email    | string(140)   | The email of the assignor.              |\n| phone    | string(20)    | The phone number of the assignor.       |\n| name     | string(140)   | The name or corporate name of the assignor.|\n\n## 💾 Back-end\n\n### Level 1 - Validation\n\nImplement an API using NestJS that receives data of a receivable and an assignor.\n\nThe route for this registration is:\n\n`POST /integrations/payable`\n\nThis route should receive all information. It is important to ensure the validation of this data:\n\n1. No field can be null;\n2. IDs must be of type UUID;\n3. Strings cannot have more characters than defined in their structure;\n\nIf any field is not filled out correctly, a message should be returned to the user showing which problem was found in which field.\n\nIf all data is validated, just return all the data in JSON format.\n\n### Level 2 - Persistence\n\nUse Prisma to include a new SQLite database.\n\nCreate the structure according to what was defined.\n\nIf the data is valid, register them.\n\nCreate 2 new routes:\n\n`GET /integrations/payable/:id`\n\n`GET /integrations/assignor/:id`\n\nTo make it possible to return payables and assignors independently.\n\nAlso include routes for other operations:\n\n- Edit;\n- Delete;\n- Register;\n\n### Level 3 - Tests\n\nCreate unit tests for each file of the application. For each new implementation, tests must also be created.\n\n### Level 4 - Authentication\n\nInclude an authentication system in all routes.\n\nFor this, create a new route:\n\n`POST /integrations/auth` that should receive:\n\n```json\n{\n  \"login\": \"aprovame\",\n  \"password\": \"aprovame\"\n}\n```\n\nWith these credentials, the endpoint should return a JWT with an expiration time of 1 minute.\n\nRewrite the rules of all other routes so that the JWT is sent as a parameter in the request `Header`.\n\nIf the JWT is valid, then the data should be shown; otherwise, a \"Not authorized\" message should be displayed.\n\n### Level 5 - Permission Management\n\nNow, create a permission management system.\n\nCreate a new permissions registration. This registration must store: `login` and `password`.\n\nRefactor the authentication endpoint so that JWTs are always generated if login and password are registered in the database.\n\n### Level 6 - Infra and Documentation\n\nCreate a `Dockerfile` for your API.\n\nCreate a `docker-compose.yaml` to start your project.\n\nDocument everything that has been done so far:\n\n- How to prepare the environment;\n- How to install dependencies;\n- How to run the project;\n\n### Level 7 - Batches\n\nCreate a new feature for batch processing of payables.\n\nThe idea is that the client can send a LARGE number of payables at once. This cannot be processed synchronously.\n\nCreate a new endpoint:\n\n`POST /integrations/payable/batch`\n\nIn this endpoint, it should be possible to receive batches of up to 10,000 payables.\n\nUpon receiving all payables, they should be posted to a queue.\n\nCreate a consumer for this queue that should take each payable, create its record in the database, and at the end of the batch processing, send an email of the processed batch, with the number of successes and failures.\n\n### Level 8 - Resilience\n\nIf it is not possible to process an item from the batch, put it back in the queue. This should occur up to 4 times. After that, this item should go to a \"Dead Queue\" and an email should be sent to the operations team.\n\n### Level 9 - Cloud\n\nCreate a deployment pipeline of the application in some Cloud structure (AWS, Google, Azure...).\n\n### Level 10 - Infrastructure as Code\n\nCreate a structure in Terraform that sets up the desired infrastructure.\n\n## 🖥️ Front-end\n\n### Level 1 - Registration\n\nCreate an interface where it is possible to register the payables.\n\nIt is important that your interface prevents the registration of empty fields or fields that do not follow the defined rules.\n\nDisplay the registered payable on a new screen.\n\n### Level 2 - Connecting to the API\n\nConnect your Front-end to the created API, and make the registration of a payable reflect in your API.\n\nAlso, create a screen for the registration of the assignor.\n\nChange the initial registration so that the `assignor` field is a `combobox` where it is possible to select an assignor.\n\n### Level 3 - Listing\n\nNow, create a listing system for payables, showing only: `id`, `value`, and `emissionDate`.\n\nFor each item in the list, place a link that shows the details of the payable.\n\nAdditionally, include options to edit and delete.\n\nIn this detail page, include a new link to display the assignor's data.\n\nAll data should come from the API.\n\n### Level 4 - Authentication\n\nNow implement the login and password system to access your routes in an authenticated way.\n\nStore the token in your browser's `localStorage`.\n\nIf the token expires, redirect the user to the login page.\n\n### Level 5 - Tests\n\nCreate tests for your Front-end application.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffsmaiorano%2Fdotnet-receivables-flow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffsmaiorano%2Fdotnet-receivables-flow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffsmaiorano%2Fdotnet-receivables-flow/lists"}