{"id":32446321,"url":"https://github.com/angel-iscoding/ecommerce-api","last_synced_at":"2026-05-06T03:35:21.281Z","repository":{"id":261503389,"uuid":"884454440","full_name":"angel-iscoding/Ecommerce-API","owner":"angel-iscoding","description":"Ecommerce API developed with Nest.js.","archived":false,"fork":false,"pushed_at":"2025-10-30T11:46:48.000Z","size":1366,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-13T21:39:18.138Z","etag":null,"topics":["backend","nestjs","postgresql","redis"],"latest_commit_sha":null,"homepage":"","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/angel-iscoding.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-06T19:28:19.000Z","updated_at":"2025-10-16T18:19:14.000Z","dependencies_parsed_at":"2024-11-06T22:37:00.206Z","dependency_job_id":"dbc42b09-391d-4315-9b4b-532820e0ba91","html_url":"https://github.com/angel-iscoding/Ecommerce-API","commit_stats":null,"previous_names":["angel-iscoding/e-commerce-api","angel-iscoding/ecommerce-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/angel-iscoding/Ecommerce-API","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angel-iscoding%2FEcommerce-API","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angel-iscoding%2FEcommerce-API/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angel-iscoding%2FEcommerce-API/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angel-iscoding%2FEcommerce-API/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/angel-iscoding","download_url":"https://codeload.github.com/angel-iscoding/Ecommerce-API/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angel-iscoding%2FEcommerce-API/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32677932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"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":["backend","nestjs","postgresql","redis"],"created_at":"2025-10-26T04:52:53.062Z","updated_at":"2026-05-06T03:35:21.272Z","avatar_url":"https://github.com/angel-iscoding.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ecommerce API (NestJS)\n\nThis repository contains an ecommerce backend built with NestJS. It uses PostgreSQL for persistent storage, Redis for caching/session/cart storage, Cloudinary for media, and TypeORM as the ORM.\n\nThis README documents the project's features, how to run it with Docker, environment variables, DB initialization, and common troubleshooting steps.\n\n## Tech stack\n\n- Node.js (NestJS)\n- TypeScript\n- TypeORM\n- PostgreSQL\n- Redis\n- Cloudinary (file uploads)\n- Jest (tests)\n\n## Project features (high level)\n\n- Inventory management (products, stock)\n- Persistent shopping cart (backed by Redis)\n- Authentication \u0026 Authorization (JWT + roles)\n- Orders and order details\n- Payments integration (PayPal)\n- File uploads to Cloudinary\n- Seeders / preloaders for categories and products\n\nEach feature is organized in modules inside `src/` (for example `store-management`, `user-management`, `auth`, etc.).\n\n## Docker (recommended)\n\nThe repository includes `docker-compose.yml` and a `Dockerfile` to run the whole stack (Postgres, Redis, API).\n\nQuick start (development):\n\n```bash\n# Build images and start containers\ndocker compose up --build\n\n# Tail logs\ndocker compose logs -f\n```\n\nNotes:\n- The app exposes port `3000` inside the container and `docker-compose.yml` maps host `3000` to container `3000` by default.\n- If this is the first time running, the Postgres container will create the database and user only if the data directory is empty. See \"Database initialization\" below for an idempotent setup.\n\n## Environment variables\n\n`docker-compose.yml` in this repository uses a small indirection: Docker-specific variables with the `DOCKER_` prefix are used to configure services, and the `app` service picks up translated variables for runtime. The compose file expects an `.env` with the following variables (examples):\n\nDocker / Compose variables (put these in `.env`):\n\n- DOCKER_POSTGRES_USER — Postgres initialization user (example: `ecommerce_user`)\n- DOCKER_POSTGRES_PASSWORD — Postgres initialization password\n- DOCKER_POSTGRES_DB — Postgres database name\n- DOCKER_DB_HOST — host value injected into the app (typically `db`)\n- DOCKER_DB_PORT — DB port (typically `5432`)\n- DOCKER_REDIS_HOST — Redis host value injected into the app (typically `redis`)\n\nThe `db` service maps these Compose variables into Postgres environment variables:\n- `POSTGRES_USER: ${DOCKER_POSTGRES_USER}`\n- `POSTGRES_PASSWORD: ${DOCKER_POSTGRES_PASSWORD}`\n- `POSTGRES_DB: ${DOCKER_POSTGRES_DB}`\n\nThe `app` service receives runtime variables from the same `.env` file (via `env_file`) and the compose file maps Docker variables into the app runtime variables. The app expects the following runtime variables (examples):\n\n- DB_HOST — hostname used by TypeORM (set by compose to `${DOCKER_DB_HOST}`)\n- DB_PORT — database port (set by compose to `${DOCKER_DB_PORT}`)\n- POSTGRES_DB — database name (set by compose to `${DOCKER_POSTGRES_DB}`)\n- POSTGRES_PASSWORD — DB password (set by compose to `${DOCKER_POSTGRES_PASSWORD}`)\n- REDIS_HOST — Redis host (set by compose to `${DOCKER_REDIS_HOST}`)\n- NODE_ENV — `development` or `production`\n- APP_PORT — application port (3000)\n- JWT_SECRET — secret used for signing JWT tokens (use a long random secret)\n\nExample `.env` (update the values before running in production):\n\n```ini\n# Docker / compose variables (used to configure the db \u0026 redis services)\nDOCKER_POSTGRES_USER=ecommerce_user\nDOCKER_POSTGRES_PASSWORD=your_secure_password_here_change_this\nDOCKER_POSTGRES_DB=ecommerce_db\nDOCKER_DB_HOST=db\nDOCKER_DB_PORT=5432\nDOCKER_REDIS_HOST=redis\n\n# Application runtime variables (the compose maps DOCKER_* -\u003e app variables)\nNODE_ENV=production\nAPP_PORT=3000\nJWT_SECRET=replace_this_with_a_real_secret_min_32_chars\n\n# If you need Redis auth\nREDIS_PASSWORD=your_redis_password_here_change_this\n```\n\nSecurity: never commit real secrets; use Docker secrets, environment injection on CI, or a vault in production.\n\n## Database initialization (idempotent)\n\nThis repository ships with a `src/config/typeorm.ts` that reads DB credentials from environment variables. To make DB initialization automatic and idempotent when using Docker Compose, there are two approaches:\n\n1. Use Postgres' `/docker-entrypoint-initdb.d` mechanism:\n   - Create a directory `docker/init/` in the repo and place an SQL file such as `init.sql` with statements guarded by `DO $$ BEGIN ... EXCEPTION WHEN OTHERS THEN END $$;` or use `CREATE ROLE IF NOT EXISTS` / `CREATE DATABASE IF NOT EXISTS` patterns.\n   - Mount the folder into the `db` service in `docker-compose.yml` as `/docker-entrypoint-initdb.d`. Postgres will execute those scripts only when the data directory is empty (first-run).\n\n2. Use a short `db-init` helper service that waits for Postgres and runs idempotent SQL (helps when you keep the data volume):\n   - Create a script like `docker/init/db-init.sh` which connects as `postgres` and runs `CREATE ROLE IF NOT EXISTS ...`, `ALTER DATABASE ... OWNER TO ...` and `CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";`.\n   - Have the `app` service depend on this `db-init` service or run the script as an init container.\n\nImportant: If a Postgres volume already exists, `/docker-entrypoint-initdb.d` scripts will NOT run. In that case either:\n- Run the idempotent SQL script manually once (connect to the DB and run it), or\n- Remove the volume to reinitialize the DB (data will be lost):\n\n```bash\ndocker compose down\ndocker volume rm ecommerce-api_postgres-data\ndocker compose up --build\n```\n\nI included an example script and/or suggested steps in the project's root to help automate this (see `docker/init/` if added).\n\n## Common troubleshooting\n\n- \"password authentication failed / role does not exist\":\n  - Reason: the DB user in `.env` wasn't created because Postgres already had an initialized data directory.\n  - Fix: create the role manually in the Postgres container or use an idempotent init script (see above).\n\n- `function uuid_generate_v4() does not exist`:\n  - Fix: create the `uuid-ossp` extension in the target database:\n    ```bash\n    docker compose exec db psql -U postgres -d \u003cyour_db\u003e -c \"CREATE EXTENSION IF NOT EXISTS \\\"uuid-ossp\\\";\"\n    ```\n\n- ESLint warnings about TypeScript version: the project uses TypeScript 5.9.x which may not be supported by the installed `@typescript-eslint` parser. If you see parser warnings, consider pinning a supported TS version, updating `@typescript-eslint` to a newer compatible version, or ignore the warning.\n\n## Development\n\nRun locally without Docker (requires Node and Postgres locally):\n\n```bash\nnpm install\ncp .env.example .env   # edit .env\nnpm run start:dev\n```\n\nNotes on path aliases: the project uses `@` as a TypeScript path alias mapping to `src/`. This is configured in `tsconfig.json` and the Jest mapping is set in `package.json` so imports like `@/store-management/products/product.service` work.\n\n## Seeds and preloaders\n\nThe project contains preloaders for categories and products (`src/utils/helpers/preload*`). These may throw errors if run multiple times against the same DB because they might not be fully idempotent. Consider modifying seeders to upsert or to skip existing entries.\n\n## Next improvements (suggested)\n\n- Add `docker/init/init.sql` or `docker/init/db-init.sh` with idempotent SQL to ensure DB users, DB and extensions exist on first-run without manual steps.\n- Add `package-lock.json` to enable `npm ci` inside Docker and increase build reproducibility.\n- Make seeders idempotent (use upsert or pre-checks).\n- Add docker secrets or environment config for production.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangel-iscoding%2Fecommerce-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangel-iscoding%2Fecommerce-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangel-iscoding%2Fecommerce-api/lists"}