{"id":15173989,"url":"https://github.com/pedrohenrikle/crud-tasks","last_synced_at":"2026-03-05T22:36:07.660Z","repository":{"id":254733020,"uuid":"845059689","full_name":"pedrohenrikle/crud-tasks","owner":"pedrohenrikle","description":"A Node.js \u0026 Typescript based API, developed with fastify, using JWT token authantication. Uses SQLite as a local database. ","archived":false,"fork":false,"pushed_at":"2024-08-28T02:27:48.000Z","size":287,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-26T06:31:27.071Z","etag":null,"topics":["api","crud","fastify","jwt","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pedrohenrikle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-08-20T13:58:00.000Z","updated_at":"2024-08-28T02:27:51.000Z","dependencies_parsed_at":"2024-08-28T03:28:48.956Z","dependency_job_id":null,"html_url":"https://github.com/pedrohenrikle/crud-tasks","commit_stats":null,"previous_names":["pedrohenrikle/crud-tasks"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pedrohenrikle/crud-tasks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrohenrikle%2Fcrud-tasks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrohenrikle%2Fcrud-tasks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrohenrikle%2Fcrud-tasks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrohenrikle%2Fcrud-tasks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedrohenrikle","download_url":"https://codeload.github.com/pedrohenrikle/crud-tasks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrohenrikle%2Fcrud-tasks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30153002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T21:15:50.531Z","status":"ssl_error","status_checked_at":"2026-03-05T21:15:11.173Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["api","crud","fastify","jwt","nodejs","typescript"],"created_at":"2024-09-27T11:22:40.563Z","updated_at":"2026-03-05T22:36:07.632Z","avatar_url":"https://github.com/pedrohenrikle.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# **OpenCRUD API**\n\n✨ A Node.js \u0026 Typescript based API, developed with [fastify](https://fastify.dev/) and uses JWT Token. Uses SQLite as database. ✨\n\n[![GitHub Repo stars](https://img.shields.io/github/stars/pedrohenrikle/crud-tasks)](https://github.com/pedrohenrikle/crud-tasks)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n\n\u003c/div\u003e\n\n## Table of contents\n\n- [Getting Started](#getting-started)\n- [Features](#🛠️-features)\n  - [Functional requirements](#frs-functional-requirements)\n  - [Business rules](#brs-business-rules)\n  - [Non-functional requirements](#nfrs-non-functional-requirements)\n- [Endpoints](#🛑-endpoints)\n  - [Users](#users)\n  - [Tasks](#tasks)\n- [Technologies](#🚀-technologies)\n- [License](#📝-license)\n- [Author](#✍-author)\n\n\n## Getting Started\n\nTo get started with OpenCRUD API, follow these simple steps:\n\n### 1. Installation\n\nFirst of all, clone the repository and install de dependencies.\n\n```shell\npnpm install\n```\n\n### 2. Setting up your environment\n\nNow we must setup our environment variables. Create a file on root as ***.env***. Inside, put all data like is here in: [.env.example](https://github.com/pedrohenrikle/crud-tasks/blob/main/.env.example)\n\n```shell\nNODE_ENV=dev\n\n# Auth\nJWT_SECRET=YOUR_SECRET_HERE\n\n# Database\nDATABASE_URL=\"path_from_your_database\"\n```\n\n### 3. Setting up database\n\nNow we must setup our database. We're going to apply the migrations executing the following command:\n\n```shell\nnpx prisma migrate deploy\n```\n\n### 4. Run\n\nNow, you can run the API with \n\n```shell\npnpm run dev\n```\n\n## 🛠️ Features\n\n### FRs (Functional requirements)\n\n- [x] It must be possible to register;\n- [x] It must be possible to authenticate;\n- [x] It must be possible to obtain the profile of a user;\n- [x] It must be possible to edit a user;\n- [x] It must be possible to delete a user;\n- [x] It must be possible to create a new task;\n- [x] It must be possible to edit a task;\n- [x] It must be possible to list all tasks from a user;\n- [x] It must be possible to delete a task\n\n\n### BRs (Business Rules)\n\n- [x] The user must not be able to register with a duplicate e-mail address;\n- [x] All routes besides the user register and user log-in need to be logged-in;\n\n### NFRs (Non-functional requirements)\n\n- [x] The user's password must be encrypted;\n- [x] The application data must be persisted in a SQLite database;\n- [x] The user must be identified by a JWT (JSON Web Token);\n\n## 🛑 Endpoints\n\nHere you can see all the endpoints of the application. You'll need to use the prefix \"/api\", so to example: If you want to register a user, use: `[protocol]://[url]/api/users`.\n\n### Users\n\n- ```POST - '/users'```\n  - This is the user's entry route, where the user will register with in the application. You must send the request with a ***data*** equal a some user's informations on the body of the requisition. \"***name***\" is optional.\n  \u003cbr\u003e\u003cbr\u003e\n\n    | Params       | Type       | Default  | Optional |\n    | :---         | :---       | :---     | :---     |\n    | `name`       | **string** | -        | true     |\n    | `email`      | **string** | -        | false     |\n    | `password`   | **string** | -        | false     |\n\n\n\u003cbr\u003e\u003cbr\u003e\n\n- `POST - '/users/login'`\n  - This is the authenticate route. Here, the user can log-in on our application. Send the data as the body of the request as a JSON. After that, we will generate a access token that contains the **userId** and his **email**.\n  \u003cbr\u003e\u003cbr\u003e\n\n    | Params       | Type       | Default  | Optional |\n    | :---         | :---       | :---     | :---     |\n    | `email`      | **string** | -        | false    |\n    | `password`   | **string** | -        | false    |\n\n\u003cbr\u003e\u003cbr\u003e\n\n- ```GET - '/users'```\n  - This is the route to get all data about the user logged-in. Need to pass the JWT Token as Authorization Bearer to identify himself.\n  \u003cbr\u003e\u003cbr\u003e\n\n    | Header           | Type       | \n    | :---             | :---       | \n    | `Authorization`  | **Bearer** |\n\n\u003cbr\u003e\u003cbr\u003e\n\n- ```PUT - '/users/edit'```\n  - This is the route dedicated to edit user's profile. First, the user need to pass his JWT Token as Authorization Bearer to identify himself. Also need to send the data as the body of the request as a JSON. \n  \u003cbr\u003e\u003cbr\u003e\n\n    | Header           | Type       | \n    | :---             | :---       | \n    | `Authorization`  | **Bearer** |\n\n    ---\n\n    | Params       | Type       | Default  | Optional |\n    | :---         | :---       | :---     | :---     |\n    | `name`       | **string** | -        | true     |\n    | `email`      | **string** | -        | true     |\n    | `password`   | **string** | -        | true     |\n\n\u003cbr\u003e\u003cbr\u003e\n\n- ```DELETE - '/users/delete'```\n  - This is the delete route for users. Here, the user can delete his own account, just passing the JWT Token as Authorization Bearer to identify himself.\n  \u003cbr\u003e\u003cbr\u003e\n\n    | Header           | Type       | \n    | :---             | :---       | \n    | `Authorization`  | **Bearer** |\n\n\u003cbr\u003e\u003cbr\u003e\n\n### Tasks\n\nOn ***Tasks***, every route needs to be authenticated, that means every request must have the following header with the JWT Token: `Authorization Bearer ${token}`.\n\n- ```POST - '/tasks'```\n  - This route is dedicated to create a new task. The data of the task shall be passed on the requisition's body. The new task is going to be assigned to the logged-in user.\n  \u003cbr\u003e\u003cbr\u003e\n\n    | Params       | Type       | Default  | Optional |\n    | :---         | :---       | :---     | :---     |\n    | `title`      | **string** | -        | false    |\n    | `description`| **string** | -        | true     |\n\n\u003cbr\u003e\u003cbr\u003e\n\n- ```GET - '/tasks/user'```\n  - This route is going to return all tasks that belong to the user logged-in.\n\n\u003cbr\u003e\u003cbr\u003e\n\n- ```GET - '/tasks/:taskId'```\n  - This route is going to return all data of a specific task. Need to pass the **task's ID** as a param on *url*.\n  \u003cbr\u003e\u003cbr\u003e\n    | Params       | Type       | Default  | Optional |\n    | :---         | :---       | :---     | :---     |\n    | `taskId`     | **string** | -        | false    |\n\n\u003cbr\u003e\u003cbr\u003e\n\n- ```PUT - '/tasks/:taskId'```\n  - This is the route dedicated to edit a specific task. First, the user need to provide de taskId on the *url*. Also need to send the data that want to change as the body of the request as a JSON. \n  \u003cbr\u003e\u003cbr\u003e\n\n    | Params       | Type        | Default  | Optional |\n    | :---         | :---        | :---     | :---     |\n    | `title`      | **string**  | -        | true     |\n    | `description`| **string**  | -        | true     |\n    | `isFinished` | **boolean** | *false*  | true     |\n\n\u003cbr\u003e\u003cbr\u003e\n\n- ```DELETE - '/tasks/:taskId'```\n  - This route is going to delete a specific task. Need to pass the **task's ID** as a param on *url*. A user can only delete a task that is assigned to him.\n  \u003cbr\u003e\u003cbr\u003e\n    | Params       | Type       | Default  | Optional |\n    | :---         | :---       | :---     | :---     |\n    | `taskId`     | **string** | -        | false    |\n\n\u003cbr\u003e\u003cbr\u003e\n\n## 🚀 Technologies\n  The technologies used to develop this application was:\n  - [nodejs](https://nodejs.org/en)\n  - [typescript](https://www.typescriptlang.org/)\n  - [fastify](https://fastify.dev/)\n  - [@fastify/cookie](https://github.com/fastify/fastify-cookie)\n  - [@fastify/jwt](https://github.com/fastify/fastify-jwt)\n  - [prisma](https://www.prisma.io/)\n  - [bcryptjs](https://github.com/dcodeIO/bcrypt.js)\n  - [eslint](https://eslint.org/)\n  - [tsx](https://github.com/privatenumber/tsx)\n\n## 📝 License\nOpenCRUD API is released under the MIT License.\n\n\n## ✍ Author\n\u003cbr\u003e\n\n\u003cdiv style=\"display: flex; flex-direction: column; gap: 0.5rem\"\u003e\n  \u003cimg alt=\"Pedro Henrique Klein\" title=\"Pedro Henrique Klein\" src=\"https://github.com/pedrohenrikle.png\" width=\"150\"\u003e\n  \u003cp\u003e\n      Made with 💜 by Pedro Henrique Klein\n  \u003c/p\u003e\n  \u003cdiv style=\"display: flex; align-item: center; gap: 1rem\"\u003e\n      \u003ca href=\"https://www.linkedin.com/in/pedro-klein/\" target=\"_blank\"\u003e\n          \u003cimg align=\"center\" src=\"https://img.shields.io/badge/LinkedIn-%230077B5?style=for-the-badge\u0026logo=linkedin\u0026logoColor=white\" alt=\"LinkedIn: pedro-klein\" /\u003e\n      \u003c/a\u003e\n      \u003ca href=\"mailto:pedro.klein.sl@gmail.com\" target=\"_blank\"\u003e\n          \u003cimg align=\"center\" src=\"https://img.shields.io/badge/Gmail-FF0000?style=for-the-badge\u0026logo=gmail\u0026logoColor=white\" alt=\"pedro.klein.sl@gmail.com\" /\u003e\n      \u003c/a\u003e\n  \u003c/div\u003e\n\u003c/div\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrohenrikle%2Fcrud-tasks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedrohenrikle%2Fcrud-tasks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrohenrikle%2Fcrud-tasks/lists"}