{"id":18884739,"url":"https://github.com/leandroppf/gostack-desafio-typeorm-upload","last_synced_at":"2025-06-18T13:35:55.158Z","repository":{"id":42875408,"uuid":"257218712","full_name":"leandroppf/gostack-desafio-typeorm-upload","owner":"leandroppf","description":null,"archived":false,"fork":false,"pushed_at":"2023-01-24T02:12:29.000Z","size":1776,"stargazers_count":0,"open_issues_count":16,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-31T04:25:41.558Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/leandroppf.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}},"created_at":"2020-04-20T08:30:54.000Z","updated_at":"2020-08-24T01:45:13.000Z","dependencies_parsed_at":"2023-02-13T11:30:27.664Z","dependency_job_id":null,"html_url":"https://github.com/leandroppf/gostack-desafio-typeorm-upload","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"rocketseat-education/gostack-template-typeorm-upload","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandroppf%2Fgostack-desafio-typeorm-upload","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandroppf%2Fgostack-desafio-typeorm-upload/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandroppf%2Fgostack-desafio-typeorm-upload/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandroppf%2Fgostack-desafio-typeorm-upload/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leandroppf","download_url":"https://codeload.github.com/leandroppf/gostack-desafio-typeorm-upload/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239857396,"owners_count":19708686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-08T07:14:04.008Z","updated_at":"2025-02-20T14:37:28.763Z","avatar_url":"https://github.com/leandroppf.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg alt=\"GoStack\" src=\"https://storage.googleapis.com/golden-wind/bootcamp-gostack/header-desafios.png\" /\u003e\n\n\u003ch3 align=\"center\"\u003e\n  Desafio 06: Banco de dados e upload de arquivos no Node.js\n\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e“Só deseje as coisas as quais você está disposto a lutar”!\u003c/blockquote\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"GitHub language count\" src=\"https://img.shields.io/github/languages/count/leandroppf/gostack-desafio-conceitos-react-native?color=%2304D361\"\u003e\n\n  \u003ca href=\"https://rocketseat.com.br\"\u003e\n    \u003cimg alt=\"Made by Leandro Pedroso\" src=\"https://img.shields.io/badge/made%20by-Leandroppf-%2304D361\"\u003e\n  \u003c/a\u003e\n\n  \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-%2304D361\"\u003e\n\n  \u003ca href=\"https://github.com/leandroppf/gostack-desafio-typeorm-upload/stargazers\"\u003e\n    \u003cimg alt=\"Stargazers\" src=\"https://img.shields.io/github/stars/leandroppf/gostack-desafio-typeorm-upload?style=social\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## :rocket: Sobre o desafio\n\nNesse desafio, o objetivo era continuar desenvolvendo a aplicação de gestão de transações, treinando o que aprendi até agora no Node.js junto ao TypeScript, utilizando o conceito de models, repositories e services, mas dessa vez incluindo o uso de banco de dados com o TypeORM e envio de arquivos com o Multer!\n\nEssa será uma aplicação que deve armazenar transações financeiras de entrada e saída e permitir o cadastro e a listagem dessas transações, além de permitir a criação de novos registros no banco de dados a partir do envio de um arquivo csv.\n\n### Rotas da aplicação\n\nPara esse desafio eu recebi um template de exemplo com rotas pré definidas, porém sem código de execução, meu objetivo era desenvolver o código para atingir os objetivos de cada rota, utilizando o conceito de models, repositories e services!\n\n- **`POST /transactions`**: A rota deve receber `title`, `value`, `type`, e `category` dentro do corpo da requisição, sendo o `type` o tipo da transação, que deve ser `income` para entradas (depósitos) e `outcome` para saídas (retiradas). Ao cadastrar uma nova transação, ela deve ser armazenada dentro do seu banco de dados, possuindo os campos `id`, `title`, `value`, `type`, `category_id`, `created_at`, `updated_at`. A rota deve retornar um objeto com o seguinte formato:\n\n```json\n{\n  \"id\": \"uuid\",\n  \"title\": \"Salário\",\n  \"value\": 3000,\n  \"type\": \"income\"\n}\n```\n\n- **`GET /transactions`**: Essa rota deve retornar uma listagem com todas as transações que você cadastrou até agora, junto com o valor da soma de entradas, retiradas e total de crédito. Essa rota deve retornar um objeto com o seguinte formato:\n\n```json\n{\n  \"transactions\": [\n    {\n      \"id\": \"uuid\",\n      \"title\": \"Salário\",\n      \"value\": 4000,\n      \"type\": \"income\"\n    },\n    {\n      \"id\": \"uuid\",\n      \"title\": \"Freela\",\n      \"value\": 2000,\n      \"type\": \"income\"\n    },\n    {\n      \"id\": \"uuid\",\n      \"title\": \"Pagamento da fatura\",\n      \"value\": 4000,\n      \"type\": \"outcome\"\n    },\n    {\n      \"id\": \"uuid\",\n      \"title\": \"Cadeira Gamer\",\n      \"value\": 1200,\n      \"type\": \"outcome\"\n    }\n  ],\n  \"balance\": {\n    \"income\": 6000,\n    \"outcome\": 5200,\n    \"total\": 800\n  }\n}\n```\n\n- **`DELETE /transactions/:id`**: A rota deve deletar uma transação com o `id` presente nos parâmetros da rota;\n\n* **`POST /transactions/import`**: A rota deve permitir a importação de um arquivo com formato `.csv` contendo as mesmas informações necessárias para criação de uma transação `id`, `title`, `value`, `type`, `category_id`, `created_at`, `updated_at`, onde cada linha do arquivo CSV deve ser um novo registro para o banco de dados, e por fim retorne todas as `transactions` que foram importadas para seu banco de dados.\n\n### Especificação dos testes\n\nO template também possui testes automatizados e um dos objetivos é que o código criado passe em todos os testes listados abaixo:\n\n\u003ch4 align=\"center\"\u003e\n  ⚠️ Antes de rodar os testes, foi necessário criar um banco de dados com o nome \"gostack_desafio06_tests\" para que todos os testes pudessem executar corretamente ⚠️\n\u003c/h4\u003e\n\n- **`should be able to create a new transaction`**: Para que esse teste passe, sua aplicação deve permitir que uma transação seja criada, e retorne um json com a transação criado.\n\n* **`should create tags when inserting new transactions`**: Para que esse teste passe, sua aplicação deve permitir que ao criar uma nova transação com uma categoria que não existe, essa seja criada e inserida no campo category_id da transação com o `id` que acabou de ser criado.\n\n- **`should not create tags when they already exists`**: Para que esse teste passe, sua aplicação deve permitir que ao criar uma nova transação com uma categoria que já existe, seja atribuído ao campo category_id da transação com o `id` dessa categoria existente, não permitindo a criação de categorias com o mesmo `title`.\n\n* **`should be able to list the transactions`**: Para que esse teste passe, sua aplicação deve permitir que seja retornado um array de objetos contendo todas as transações junto ao balanço de income, outcome e total das transações que foram criadas até o momento.\n\n- **`should not be able to create outcome transaction without a valid balance`**: Para que esse teste passe, sua aplicação não deve permitir que uma transação do tipo `outcome` extrapole o valor total que o usuário tem em caixa (total de income), retornando uma resposta com código HTTP 400 e uma mensagem de erro no seguinte formato: `{ error: string }`.\n\n* **`should be able to delete a transaction`**: Para que esse teste passe, você deve permitir que a sua rota de delete exclua uma transação, e ao fazer a exclusão, ele retorne uma resposta vazia, com status 204.\n\n- **`should be able to import transactions`**: Para que esse teste passe, sua aplicação deve permitir que seja importado um arquivo csv, contendo o seguinte [modelo](./assets/file.csv). Com o arquivo importado, você deve permitir que seja criado no banco de dados todos os registros e categorias que estavam presentes nesse arquivo, e retornar todas as transactions que foram importadas.\n\n---\n\nDesafio concluído no dia 21/04/2020 por Leandro Pinto Pedroso Filho\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandroppf%2Fgostack-desafio-typeorm-upload","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleandroppf%2Fgostack-desafio-typeorm-upload","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandroppf%2Fgostack-desafio-typeorm-upload/lists"}