{"id":22370022,"url":"https://github.com/fazers/portfolio-api","last_synced_at":"2025-06-28T07:32:46.199Z","repository":{"id":61952659,"uuid":"527699260","full_name":"FaZeRs/portfolio-api","owner":"FaZeRs","description":"NestJS REST API. Monolithic Backend.","archived":false,"fork":false,"pushed_at":"2023-03-06T21:23:43.000Z","size":1425,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-31T19:42:41.320Z","etag":null,"topics":["backend","monolithic","nestjs","nodejs","portfolio","rest-api"],"latest_commit_sha":null,"homepage":"https://api.naurislinde.dev","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/FaZeRs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","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},"funding":{"custom":["https://paypal.me/naurislinde"]}},"created_at":"2022-08-22T19:09:45.000Z","updated_at":"2023-06-13T08:56:19.000Z","dependencies_parsed_at":"2024-12-08T17:31:12.829Z","dependency_job_id":null,"html_url":"https://github.com/FaZeRs/portfolio-api","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FaZeRs%2Fportfolio-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FaZeRs%2Fportfolio-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FaZeRs%2Fportfolio-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FaZeRs%2Fportfolio-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FaZeRs","download_url":"https://codeload.github.com/FaZeRs/portfolio-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245690485,"owners_count":20656594,"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":["backend","monolithic","nestjs","nodejs","portfolio","rest-api"],"created_at":"2024-12-04T19:31:44.323Z","updated_at":"2025-03-26T16:24:44.016Z","avatar_url":"https://github.com/FaZeRs.png","language":"TypeScript","funding_links":["https://paypal.me/naurislinde"],"categories":[],"sub_categories":[],"readme":"# Portfolio API\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n![Build Badge](https://github.com/FaZeRs/portfolio-api/workflows/Build/badge.svg)\n![Tests Badge](https://github.com/FaZeRs/portfolio-api/workflows/Tests/badge.svg)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=FaZeRs_portfolio-api\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=FaZeRs_portfolio-api)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=FaZeRs_portfolio-api\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=FaZeRs_portfolio-api)\n[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=FaZeRs_portfolio-api\u0026metric=code_smells)](https://sonarcloud.io/dashboard?id=FaZeRs_portfolio-api)\n\n| Repository                                                     | Info               |\n| -------------------------------------------------------------- | ------------------ |\n| [portfolio-client](https://github.com/FaZeRs/portfolio-client) | Frontend           |\n| [portfolio-api](https://github.com/FaZeRs/portfolio-api)       | Rest API           |\n| [portfolio-server](https://github.com/FaZeRs/portfolio-server) | Docker Environment |\n\n## Features\n\n| Feature                  | Info                                                            |\n| ------------------------ | --------------------------------------------------------------- |\n| Authentication           | [JWT](https://github.com/auth0/node-jsonwebtoken)               |\n| Authorization            | RBAC (Role based)                                               |\n| ORM Integration          | [TypeORM](https://github.com/typeorm/typeorm)                   |\n| DB Migrations            | [TypeORM](https://github.com/typeorm/typeorm)                   |\n| Logging                  | [winston](https://github.com/winstonjs/winston)                 |\n| Request Validation       | [class-validator](https://github.com/typestack/class-validator) |\n| Pagination               | SQL offset \u0026 limit                                              |\n| Docker Ready             | [Dockerfile](https://www.docker.com/)                           |\n| Auto-generated OpenAPI   | -                                                               |\n| Auto-generated ChangeLog | [Release Please](https://github.com/googleapis/release-please)  |\n| Queue                    | [Bull](https://github.com/OptimalBits/bull)                     |\n| File System              | [Minio](https://github.com/minio/minio)                         |\n| Mailing                  | [Nodemailer](https://github.com/nodemailer/nodemailer)          |\n\n## Installation\n\nNote: when using docker, all the `pnpm` commands can also be performed using `./scripts/pnpm` (for example `./scripts/pnpm install`).\nThis script allows you to run the same commands inside the same environment and versions than the service, without relying on what is installed on the host.\n\n```bash\n$ pnpm install\n```\n\nCreate a `.env` file from the template `.env.template` file.\n\n```bash\ncp .env.template .env\n```\n\nGenerate public and private key pair for jwt authentication:\n\n### With docker\n\nRun this command:\n\n```bash\n./scripts/generate-jwt-keys\n```\n\nIt will output something like this. You only need to add it to your `.env` file.\n\n```\nTo setup the JWT keys, please add the following values to your .env file:\nJWT_PUBLIC_KEY_BASE64=\"(long base64 content)\"\nJWT_PRIVATE_KEY_BASE64=\"(long base64 content)\"\n```\n\n### Without docker\n\n```bash\n$ ssh-keygen -t rsa -b 2048 -m PEM -f jwtRS256.key\n# Don't add passphrase\n$ openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub\n```\n\nYou may save these key files in `./local` directory as it is ignored in git.\n\nEncode keys to base64:\n\n```bash\n$ base64 -i local/jwtRS256.key\n\n$ base64 -i local/jwtRS256.key.pub\n```\n\nMust enter the base64 of the key files in `.env`:\n\n```bash\nJWT_PUBLIC_KEY_BASE64=BASE64_OF_JWT_PUBLIC_KEY\nJWT_PRIVATE_KEY_BASE64=BASE64_OF_JWT_PRIVATE_KEY\n```\n\n## Running the app\n\nWe can run the project with or without docker.\n\n### Local\n\nTo run the server without Docker we need this pre-requisite:\n\n- PostgreSQL server running\n- Redis server running\n- Minio server running\n\nCommands:\n\n```bash\n# development\n$ pnpm start\n\n# watch mode\n$ pnpm start:dev\n\n# production mode\n$ pnpm start:prod\n```\n\n### Docker\n\n```bash\n# build image\n$ docker build -t portfolio-api .\n\n# run container from image\n$ docker run -p 3000:3000 --volume 'pwd':/usr/src/app --network=\"bridge\" --env-file .env portfolio-api\n\n# run using docker compose\n$ docker compose up\n```\n\n## Test\n\n```bash\n# unit tests\n$ pnpm test\n\n# e2e tests\n$ pnpm test:e2e\n\n# test coverage\n$ pnpm test:cov\n```\n\n## Migrations\n\n```bash\n# generate migration (replace CreateUsers with name of the migration)\n$ pnpm migration:generate -- -n CreateUsers\n\n# run migration\n$ pnpm migration:run\n\n# revert migration\n$ pnpm migration:revert\n```\n\n## Architecture\n\n- [Project Structure](./docs/project-structure.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffazers%2Fportfolio-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffazers%2Fportfolio-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffazers%2Fportfolio-api/lists"}