{"id":13902775,"url":"https://github.com/podkrepi-bg/api","last_synced_at":"2026-04-15T16:10:31.352Z","repository":{"id":36957766,"uuid":"405699739","full_name":"podkrepi-bg/api","owner":"podkrepi-bg","description":"Nest.js REST backend for charity platform Podkrepi.bg https://podkrepi.bg/swagger","archived":false,"fork":false,"pushed_at":"2024-07-24T10:54:39.000Z","size":12411,"stargazers_count":81,"open_issues_count":37,"forks_count":43,"subscribers_count":30,"default_branch":"master","last_synced_at":"2024-07-25T10:19:13.559Z","etag":null,"topics":["charity-platform","hacktoberfest","hacktoberfest2022","nestjs","prisma","typescript"],"latest_commit_sha":null,"homepage":"https://podkrepi.bg","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/podkrepi-bg.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-12T16:52:32.000Z","updated_at":"2024-07-24T10:54:43.000Z","dependencies_parsed_at":"2024-05-22T08:27:57.235Z","dependency_job_id":"76201e57-d8b1-48e9-b35c-c7524c385bd8","html_url":"https://github.com/podkrepi-bg/api","commit_stats":null,"previous_names":[],"tags_count":80,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podkrepi-bg%2Fapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podkrepi-bg%2Fapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podkrepi-bg%2Fapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/podkrepi-bg%2Fapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/podkrepi-bg","download_url":"https://codeload.github.com/podkrepi-bg/api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":214260278,"owners_count":15707073,"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":["charity-platform","hacktoberfest","hacktoberfest2022","nestjs","prisma","typescript"],"created_at":"2024-08-06T22:01:23.702Z","updated_at":"2026-04-15T16:10:31.328Z","avatar_url":"https://github.com/podkrepi-bg.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003ch1\u003e\u003cp align=\"center\"\u003e\n  Дарителска Платформа Подкрепи.бг \u003cbr/\u003e\n  REST API\n\u003c/p\u003e\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://podkrepi.bg/\" target=\"blank\"\u003e\u003cimg src=\"https://podkrepi.bg/podkrepi-bg-logo-en.svg\" width=\"320\" alt=\"Podkrepi.bg logo\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/podkrepi-bg/api/actions/workflows/tests.yml\"\u003e\u003cimg src=\"https://github.com/podkrepi-bg/api/actions/workflows/tests.yml/badge.svg\" alt=\"API tests\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/podkrepi-bg/api/actions/workflows/release.yml\"\u003e\u003cimg src=\"https://github.com/podkrepi-bg/api/actions/workflows/release.yml/badge.svg\" alt=\"Deployment\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Links\n\n| Service  | Development                      | Staging                           | Production                    |\n| -------- | -------------------------------- | --------------------------------- | ----------------------------- |\n| Website  | \u003chttps://localhost:3040\u003e         | \u003chttps://dev.podkrepi.bg\u003e         | \u003chttps://podkrepi.bg\u003e         |\n| Rest API | \u003chttps://localhost:5010/api/v1\u003e  | \u003chttps://dev.podkrepi.bg/api/v1\u003e  | \u003chttps://podkrepi.bg/api/v1\u003e  |\n| Swagger  | \u003chttps://localhost:5010/swagger\u003e | \u003chttps://dev.podkrepi.bg/swagger\u003e | \u003chttps://podkrepi.bg/swagger\u003e |\n\n## Dependencies and References\n\n- API\n  - \u003chttps://nestjs.com/\u003e\n  - \u003chttps://www.prisma.io/nestjs\u003e\n  - \u003chttps://docs.nestjs.com/recipes/prisma\u003e\n  - \u003chttps://github.com/juliandavidmr/awesome-nestjs#awesome-nest\u003e\n- Database\n  - \u003chttps://www.postgresql.org/\u003e\n  - \u003chttps://hub.docker.com/r/bitnami/postgresql/\u003e\n  - \u003chttps://prisma.io/\u003e\n  - [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate)\n  - \u003chttps://github.com/catalinmiron/awesome-prisma\u003e\n- Workspace\n  - \u003chttps://nx.dev/\u003e\n\n# Setup Development Environment (recommended)\n\nTo run and develop the module NodeJS 20 is required. In this section 2 ways of configuring a development environment are described.\n\n## Installing the prerequisites\n\nThe following prerequisites are required in order to be able to run the project:\n\n- [Node.js v20](https://nodejs.org/en/download/)\n- [Yarn v3.x](https://yarnpkg.com/getting-started/install)\n- [Docker](https://www.docker.com/get-started) with [Docker Compose](https://docs.docker.com/compose/) (to easily run a local database instance)\n\n## Development container\n\nIf you wish to keep your host clean, it is also possible to develop the module in a Docker container. You can do that by using the [Visual Studio Code](https://code.visualstudio.com/download)'s [Remote Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) and read [how to initialize your dev container](https://code.visualstudio.com/docs/remote/containers).\n\n- Make sure you have the extension installed\n- Open the folder of the module in VS Code\n- Hit `Ctrl`/`Cmd` + `Shift` + `P` -\u003e Remote-Containers: Reopen Folder in Container\n\n## Clone the code and install dependencies\n\n```shell\ngit clone git@github.com:podkrepi-bg/api.git\ncd api\n\nyarn set version berry\nyarn\n```\n\n## Create Docker containers for the Dev Database(postgres) and the Identity Server(Keycloak)\n\nRun the below command in your terminal:\n\n```shell\ndocker compose up -d pg-db keycloak\n```\n\nThis will start the following services in your local docker:\n\n- Local Postgres DB on default port 5432 for your personal development\n- Local Keycloak Identity server Admin UI on \u003chttp://localhost:8180\u003e with config coming from `./manifests/keycloak/config`:\n  - Keycloak Local Admin User: `admin` with pass: `admin`\n  - Podkrepi Local Admin users:\n    - coordinator@podkrepi.bg, reviewer@podkrepi.bg, admin@podkrepi.bg,\n    - all with pass: `$ecurePa33`\n\n## Initialize the Database with Prisma Migration scripts\n\nThis is needed first time only. We use [Prisma](https://www.prisma.io/) as Database management and versioning tool the following migration command will init the database from the schema.prisma file. See Database Development Guidelines below for further details.\n\n```shell\n# Create db schema\nyarn prisma migrate deploy\n\n# Generate the prisma clients\nyarn prisma generate\n\n# Seed initial test data\nyarn prisma db seed\n```\n\n## Setup local environment\n\nCopy the provided `.env.example` to `.env`\n\n```shell\ncp .env.example .env\n```\n\n**Note:** _To avoid modifying the original file, you can create `.env.local` and add overrides for the variables that are specific to your local environment. This approach allows you to keep your customizations separate from the default values._\n\n### Configure Stripe (optional)\n\nIf you'll be working on payment-related features, follow the\n[Stripe setup guide in TESTING.md](TESTING.md#stripe--first-time-setup) to\nconfigure your Stripe keys and webhook listener.\n\n### Run the tests\n\nTesting the initialization is done correctly.\n\n```shell\nyarn test\n```\n\n### Run the Local API Server in Development Mode\n\n```shell\nyarn dev\n```\n\nand the backend API server will listen on \u003chttp://localhost:5010/api/v1\u003e\n\n## (Alternative) Development Environment To Run Inside Docker\n\nFirst build the images locally and start the containers. Then iterate on the code and changes will be picked up through the mounted folders.\n\n```shell\ndocker-compose up --build -d\n```\n\nAfter starting your dev server visit:\n\n- \u003chttp://localhost:5010/api/v1\u003e (API)\n\nTo shut down the dev server use:\n\n```shell\ndocker-compose down\n```\n\n# Development Guidelines\n\n## API Docs via Swagger\n\nAvailable at \u003chttp://localhost:5010/swagger/\u003e\n\n## Understand your workspace\n\nRun `nx dep-graph` to see a diagram of the dependencies of your projects.\n\n## NestJS Code Generaators\n\nWe recommend using [Nestjs generators](https://docs.nestjs.com/cli/usages#nest-generate) to create different nestsj components in generic way.\n\n```shell\nyarn nest # will print all generators\n```\n\nUse the [Nest resource generator](https://docs.nestjs.com/recipes/crud-generator) to create all interfaces for CRUD operations around a new entity/resource\n\n```shell\nyarn nest generate resource [name]\n```\n\n## Building\n\nRun `yarn build-all` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.\n\n## Formatting\n\nMake sure you run auto-formatting before you commit your changes.\n\n```shell\nyarn format\n```\n\n# Database Guidelines\n\nFor the database layer we're using [Prisma](https://prisma.io). In order to get familiar with the concept please read [What is Prisma?](https://www.prisma.io/docs/concepts/overview/what-is-prisma) and watch some intro videos on [YouTube](https://www.youtube.com/watch?v=EEDGwLB55bI\u0026ab_channel=Prisma).\n\n## Database Development Workflow\n\nThe project already contains the database shema in shema.prisma file and initialization \"seed\" scripts for inital data are in db/seed folder.\n\n## On an empty database\n\nInitialize the database using these commands. It will initialize the database using the schema.prisma, the migration scripts and the db/seed scripts to insert data records for the API to work.\n\n```shell\nyarn prisma migrate deploy\nyarn prisma seed\n```\n\nPrisma offers a nice Web Client to review and edit the database:\n\n```shell\nyarn prisma studio\n```\n\n## Making DB Schema Changes\n\nThere are two ways to work with the database:\n\n- schema first - make changes in schema.prisma and update the database\n- db first - make changes directly in the database and introspect to update the schema.prisma\n\n### 1. Workflow for Schema First approach (recommended)\n\nAfter initializing the database, feel free to edit the schema.prisma file in the main folder. When done with changes execute to update the database:\n\n```shell\nyarn prisma migrate dev\n```\n\nThe command will ask you to name your changes and will generate a migration script that will be saved in ./migrations folder.\n\nRun the tests again `yarn test` to ensure all ok.\n\nIf you don't want to generate small migrations for every change, after finishing the work on your branch, delete the migration files manually and run again `yarn prisma migrate dev` to create one single feature level migration.\n\nRead more about [Team development with Prisma Migrate here.](https://www.prisma.io/docs/guides/database/developing-with-prisma-migrate/team-development/)\n\n### 2. Workflow for Databased First approach\n\nAfter initializing the database, open prisma stidio or your favorite DB Management IDE and feel free to make db changes. When done with changes, execute:\n\n```shell\nyarn prisma db pull\n```\n\nThis will read all changed from you db instance and will update the schema.prisma file with nessary translations.\n\nNow that the schema file is updated, we need to update the prismajs client which is used by our app by running:\n\n```shell\nyarn prisma generate\n```\n\nThis process is called [Prisma DB Introspection](https://www.prisma.io/docs/concepts/components/introspection).\n\n## Resetting to master\n\nIf things go bad, there is a way to reset your database to the original state. This will delete the database and will create it from the schema, executing also the seeding.\n\n```shell\nyarn prisma migrate reset\n```\n\n# File Upload to S3\n\nWe use S3 for storing the uploaded files in buckets. The code expects the buckets to be created on prod or dev environment. We are hosting S3 ourselves using ceph https://ceph.io/en/discover/technology/.\n\nThe creation of the buckets can happen using s3cmd client https://s3tools.org/s3cmd or any other S3 client and using the S3 secrets for the respective environment.\n\nTo configure S3cmd run \n```shell\ns3cmd --configure\n```\n\nAll settings are self descriptive, however pay attention to these:\n- The default region is not a Country code but \"object-store-dev\" for development and \"object-store\" for prod\n- S3 endpoint: cdn-dev.podkrepi.bg\n- When asked for DNS-style bucket use: cdn-dev.podkrepi.bg\n- When asked for encryption password just press 'Enter' for leaving it empty\n\nThen bucket creation is like this:\n\n```shell\ns3cmd ls\ns3cmd mb s3://bucket-name\ns3cmd ls\n```\n\n# Configuring Google Sign-in with Keycloak\n\nFor enabling sign-in with existing gmail account we use the token-exchange feature of Keycloak as per the great description in: https://medium.com/@souringhosh/keycloak-token-exchange-usage-with-google-sign-in-cd9127ebc96d\n\nThe logic is the following:\n\n1. The frontend acquires a token from Google Sign-in\n2. The frontend sends the token to the backend API requesting a login with external provider (see: auth.service.ts issueTokenFromProvider)\n3. The backend sends the token-exchange request to Keycloak passing the Google Token for Permission to Login\n4. Keycloak server grants permission and returns the access token\n5. Backend creates the new user in the database and returns the access token for use from Frontend\n\n# Production environment\n\n## Environment variables\n\n| Setting                   | Description                                           | Default value                                                               |\n| ------------------------- | ----------------------------------------------------- | --------------------------------------------------------------------------- |\n| `PORT`                    | The address on which the module binds.                | 5010                                                                        |\n| `GLOBAL_PREFIX`           | Registers a prefix for every HTTP route path          | api/v1                                                                      |\n| `APP_VERSION`             | The version of the application                        | \"unknown\"                                                                   |\n| `APP_ENV`                 | Application runtime environment                       | development                                                                 |\n| `NODE_ENV`                | Node build environment                                | development                                                                 |\n| `TARGET_ENV`              | Docker multi-stage target                             | development                                                                 |\n| `TARGET_APP`              | Run specific application from the image.              | api                                                                         |\n| `DATABASE_URL`            | Database connection string.                           | postgres://postgres:postgrespass@localhost:5432/postgres?schema=api         |\n| `S3_ENDPOINT`             | Endpoint for S3 interface.                            | \u003chttps://cdn-dev.podkrepi.bg\u003e                                               |\n| `S3_REGION`               | The S3 region                                         | us-east-1                                                                   |\n| `S3_ACCESS_KEY`           | The S3 access key.                                    | \\*\\*\\*\\*\\*\\*                                                                |\n| `S3_SECRET_ACCESS_KEY`    | The S3 secret access key.                             | \\*\\*\\*\\*\\*\\*                                                                |\n| `KEYCLOAK_URL`            | Keycloak authentication url                           | \u003chttp://localhost:8180\u003e                                                     |\n| `KEYCLOAK_REALM`          | Keycloak Realm name                                   | webapp                                                                      |\n| `KEYCLOAK_CLIENT_ID`      | Keycloak Client name                                  | jwt-headless                                                                |\n| `KEYCLOAK_SECRET`         | Secret to reach Keycloak in headless mode             | DEV-KEYCLOAK-SECRET                                                         |\n| `KEYCLOAK_USER`           | Master user for Keycloak Server                       | admin                                                                       |\n| `KEYCLOAK_PASSWORD`       | Master user's password for Keycloak Server            | admin                                                                       |\n| `STRIPE_SECRET_KEY`       | Stripe secret key                                     | \\*\\*\\*\\*\\*\\*                                                                |\n| `STRIPE_WEBHOOK_SECRET`   | Stripe webhook secret key                             | \\*\\*\\*\\*\\*\\*                                                                |\n| `SENTRY_DSN`              | Sentry Data Source Name                               | \u003chttps://58b71cdea21f45c0bcbe5c1b49317973@o540074.ingest.sentry.io/5707518\u003e |\n| `SENTRY_ORG`              | Sentry organization                                   | podkrepibg                                                                  |\n| `SENTRY_PROJECT`          | Sentry project                                        | rest-api                                                                    |\n| `SENTRY_AUTH_TOKEN`       | Sentry build auth token                               | \\*\\*\\*\\*\\*\\*                                                                |\n| `SENTRY_SERVER_ROOT_DIR`  | App directory inside the docker image                 | /app                                                                        |\n| `SENDGRID_API_KEY`        | SendGrid API key                                      | `\"\"` - emails disabled if not set                                           |\n| `SENDGRID_SENDER_EMAIL`   | SendGrid sender email                                 | info@podkrepi.bg                                                            |\n| `SENDGRID_INTERNAL_EMAIL` | Internal notification email from contact form request | info@podkrepi.bg (Prod), qa@podkrepi.bg (Dev), dev@podkrepi.bg (localhost)  |\n| `SENDGRID_CONTACTS_URL`   | Endpoint to receive newsletter subscriptions          | /v3/marketing/contacts                                                      |\n\n## Deployment\n\n```sql\nCREATE SCHEMA api;\nCREATE USER postgres WITH ENCRYPTED PASSWORD 'postgrespass';\nGRANT ALL PRIVILEGES ON SCHEMA api TO postgres;\n```\n\n## Migrations deployment\n\n```shell\ndocker build -f Dockerfile.migrations .\ndocker run  --env-file .env --network host \u003cimage-id\u003e\n```\n\n## Manual resolution of failed db migrations\n\nOverall procedure:\n\n1. Ensure a local connection to the k8s cluster\n2. Start a new `migrate-database` container manually in the proper namespace (`podkrepibg-dev` or `podkrepibg`).\n\n```shell\nkubectl run manual-migrate-db \\\n    -it --rm \\\n    -n podkrepibg-dev \\\n    --image=ghcr.io/podkrepi-bg/api/migrations:master \\\n    -- /bin/sh\n```\n\n3. Check migration status with `yarn prisma migrate status`\n\n```shell\nFollowing migration have failed: 20220605165716_rename_bank_hash_to_payment_reference\n```\n\n4. Rollback or apply migrations (suggested commands are printed from the status)\n\n```shell\nThe failed migration(s) can be marked as rolled back or applied:\n\n- If you rolled back the migration(s) manually:\nyarn prisma migrate resolve --rolled-back \"20220605165716_rename_bank_hash_to_payment_reference\"\n\n- If you fixed the database manually (hotfix):\nyarn prisma migrate resolve --applied \"20220605165716_rename_bank_hash_to_payment_reference\"\n```\n\n5. Run migration deployment\n\n```shell\nyarn prisma migrate deploy\n```\n\n6. At this point you can re-deploy the `api-headless` deployment to trigger the standard flow of operation\n\n## Postman\n\nIf you'd like to use Postman to query the API - see [postman doc](./tools/postman/readme.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodkrepi-bg%2Fapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpodkrepi-bg%2Fapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpodkrepi-bg%2Fapi/lists"}