{"id":50695760,"url":"https://github.com/hngprojects/energy-iq-be","last_synced_at":"2026-06-09T06:08:40.091Z","repository":{"id":355582594,"uuid":"1227462348","full_name":"hngprojects/energy-iq-be","owner":"hngprojects","description":"AI-Powered Energy Management Platform for Nigerian SMEs \u0026 African Businesses","archived":false,"fork":false,"pushed_at":"2026-05-11T11:34:05.000Z","size":473,"stargazers_count":0,"open_issues_count":6,"forks_count":2,"subscribers_count":0,"default_branch":"dev","last_synced_at":"2026-05-11T11:38:05.640Z","etag":null,"topics":["nestjs-backend","postgressql","typescript"],"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/hngprojects.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2026-05-02T18:06:06.000Z","updated_at":"2026-05-11T09:58:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hngprojects/energy-iq-be","commit_stats":null,"previous_names":["hngprojects/energy-iq-be"],"tags_count":0,"template":false,"template_full_name":"hngprojects/nestjs-starter","purl":"pkg:github/hngprojects/energy-iq-be","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fenergy-iq-be","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fenergy-iq-be/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fenergy-iq-be/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fenergy-iq-be/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hngprojects","download_url":"https://codeload.github.com/hngprojects/energy-iq-be/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hngprojects%2Fenergy-iq-be/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34093841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["nestjs-backend","postgressql","typescript"],"created_at":"2026-06-09T06:08:39.270Z","updated_at":"2026-06-09T06:08:40.081Z","avatar_url":"https://github.com/hngprojects.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EnergyIQ Backend\n\nEnergyIQ is an AI-powered energy management platform for Nigerian SMEs and African businesses. This repository contains the NestJS API that powers authentication, user management, health checks, and the backend foundation for energy intelligence features.\n\n## What this service provides\n\n- JWT authentication with access and refresh token flows.\n- User lifecycle APIs for creating, listing, updating, and deleting users.\n- A public health endpoint for uptime and deployment checks.\n- Strict validation, global error handling, and consistent response envelopes.\n- PostgreSQL persistence with TypeORM migrations and seeders.\n- Swagger API documentation for local development and integration work.\n\n## Tech Stack\n\n- NestJS 11 and TypeScript\n- PostgreSQL and TypeORM\n- JWT authentication with Passport guards\n- `class-validator`, `class-transformer`, and a global `ValidationPipe`\n- Environment validation with `@t3-oss/env-core` and Zod\n- Helmet, compression, structured logging, and a global exception filter\n\n## Quick Start\n\n### Prerequisites\n\n- Node.js 20 or newer\n- pnpm 9 or newer\n- PostgreSQL 14 or newer\n\n### Local setup\n\n```bash\npnpm install\ncp .env.example .env\n\n# update .env with your database credentials and JWT secrets\n\npnpm migration:run\npnpm seed # optional\npnpm start:dev\n```\n\nIf Swagger is enabled, open `http://localhost:3000/docs`. The public health check is available at `http://localhost:3000/health`.\n\n## Environment\n\nThe application validates configuration at startup and fails fast on missing or invalid values. Start from `.env.example` and adjust it for your environment.\n\n| Variable | Purpose |\n|---|---|\n| `NODE_ENV` | Application mode |\n| `PORT` | HTTP port |\n| `HOST` | HTTP hostname (default: `localhost`) |\n| `DATABASE_HOST`, `DATABASE_PORT`, `DATABASE_USER`, `DATABASE_PASSWORD`, `DATABASE_NAME` | PostgreSQL connection settings |\n| `DATABASE_SYNC` | Keep `false` outside local experimentation; use migrations instead |\n| `DATABASE_SSL` | Enable for managed PostgreSQL providers |\n| `DATABASE_LOGGING` | Toggle TypeORM logging |\n| `JWT_ACCESS_SECRET` | Access token signing secret |\n| `JWT_ACCESS_EXPIRES_IN` | Access token lifetime |\n| `JWT_REFRESH_SECRET` | Refresh token signing secret |\n| `JWT_REFRESH_EXPIRES_IN` | Refresh token lifetime |\n| `CORS_ORIGIN` | Comma-separated allowed origins or `*` |\n| `SWAGGER_ENABLED` | Enable or disable Swagger |\n\n## Scripts\n\n### Application\n| Script | Purpose |\n|---|---|\n| `pnpm start:dev` | Run the API in watch mode |\n| `pnpm start:debug` | Run the API with the debugger attached |\n| `pnpm start:prod` | Run the compiled application from `dist/` |\n| `pnpm build` | Compile the project |\n| `pnpm lint` | Lint and auto-fix supported issues |\n| `pnpm format` | Format source and test files |\n\n### Cleanup\n| Script | Purpose |\n|---|---|\n| `pnpm clean` | Remove `node_modules`, `pnpm-lock.yaml`, `dist`, and build metadata |\n| `pnpm rebuild` | Clean install dependencies and rebuild the project |\n| `pnpm clean:rebuild` | Full cleanup and rebuild (clean + rebuild) |\n\n### Quality gates\n| Script | Purpose |\n|---|---|\n| `pnpm test` | Run unit tests |\n| `pnpm test:watch` | Run unit tests in watch mode |\n| `pnpm test:cov` | Generate coverage report |\n| `pnpm test:debug` | Run tests with debugger attached |\n| `pnpm test:e2e` | Run end-to-end tests |\n| `pnpm validate` | Run lint, tests, and build in one command |\n\n## Git Hooks\n\nThis repository uses Husky to run checks automatically at the Git stage level:\n\n- `pre-commit` runs `lint-staged` on staged `*.ts` files so formatting and lint fixes happen before the commit is created.\n- `commit-msg` runs `commitlint` to enforce conventional commit messages.\n- `pre-push` runs `pnpm validate` to block pushes when lint, tests, e2e, or build fail.\n\nAfter cloning the repository, run `pnpm install` once. The `prepare` script in `package.json` installs the hooks automatically during dependency installation, so you do not need to set Husky up manually in each clone unless install scripts are skipped.\n\n### Database\n| Script | Purpose |\n|---|---|\n| `pnpm migration:run` | Apply pending migrations |\n| `pnpm migration:revert` | Revert the latest migration |\n| `pnpm migration:show` | Show migration status |\n| `pnpm migration:generate \u003cName\u003e` | Generate a migration in `src/database/migrations` from entity changes |\n| `pnpm migration:create` | Create an empty migration |\n| `pnpm schema:drop` | Drop the current database schema (use with caution) |\n| `pnpm seed` | Run seeders |\n| `pnpm db:reset` | Drop, migrate, and seed the database |\n\nUse the short wrapper when creating a migration:\n\n```bash\npnpm migration:generate CreateUserTable\n```\n\nThe generated file is written to `src/database/migrations` automatically.\n\n## API Surface\n\nAll application routes are prefixed with `/api/v1` except the health check. API versioning uses URI-based versioning; future versions will be available at `/api/v2`, `/api/v3`, etc. The health check remains at `/health` (no version prefix) for compatibility with load balancers and orchestration platforms.\n\n### Health\n\n| Endpoint | Method | Auth | Purpose |\n|---|---|---|---|\n| `/health` | GET | Public | Liveness probe |\n\n### Authentication\n\n| Endpoint | Method | Auth | Purpose |\n|---|---|---|---|\n| `/api/v1/auth/register` | POST | Public | Create a new account |\n| `/api/v1/auth/login` | POST | Public | Authenticate and issue tokens |\n| `/api/v1/auth/refresh` | POST | Public | Exchange a refresh token for a new access token |\n| `/api/v1/auth/logout` | POST | Bearer token | Revoke the current refresh token |\n| `/api/v1/auth/me` | GET | Bearer token | Return the current authenticated user |\n\n### Users\n\n| Endpoint | Method | Auth | Purpose |\n|---|---|---|---|\n| `/api/v1/users` | POST | Bearer token | Create a user |\n| `/api/v1/users` | GET | Bearer token | List users with pagination |\n| `/api/v1/users/:id` | GET | Bearer token | Fetch a user by ID |\n| `/api/v1/users/:id` | PATCH | Bearer token | Update a user |\n| `/api/v1/users/:id` | DELETE | Bearer token | Delete a user |\n\nThe global JWT guard protects the API by default. Use the `@Public()` decorator for endpoints that should remain open.\n\n## Response Format\n\nAll responses follow a standardized envelope for consistency. Success and error responses are handled by a global interceptor and exception filter.\n\n### Success Response\n\n```json\n{\n  \"success\": true,\n  \"message\": \"Resource retrieved successfully\",\n  \"data\": { },\n  \"meta\": {\n    \"timestamp\": \"2026-05-03T12:34:56.000Z\",\n    \"version\": \"1.0.0\",\n    \"requestId\": \"550e8400-e29b-41d4-a716-446655440000\",\n    \"pagination\": {\n      \"total\": 100,\n      \"page\": 1,\n      \"limit\": 20,\n      \"hasNext\": true,\n      \"hasPrev\": false\n    }\n  }\n}\n```\n\nMessages are drawn from the `SYS_MSG` constants (`src/common/constants/sys-msg.ts`) and selected automatically based on HTTP method and status code.\n\n### Error Response\n\n```json\n{\n  \"success\": false,\n  \"message\": \"The request could not be processed because it is invalid\",\n  \"error\": \"BadRequestException\",\n  \"statusCode\": 400,\n  \"meta\": {\n    \"timestamp\": \"2026-05-03T12:34:56.000Z\",\n    \"version\": \"1.0.0\",\n    \"requestId\": \"550e8400-e29b-41d4-a716-446655440000\"\n  }\n}\n```\n\nErrors are normalized by the global exception filter and include the HTTP status, error name, message, and request metadata.\n\n## Deployment Notes\n\n- Keep `DATABASE_SYNC=false` in production and rely on migrations.\n- Use strong, unique JWT secrets for access and refresh tokens.\n- Set `SWAGGER_ENABLED=false` if public API documentation is not required in production.\n- Configure `CORS_ORIGIN` explicitly for production clients.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the codebase map, testing expectations, review checklist, and required `pnpm validate` workflow before push.\n\n## License\n\nUNLICENSED\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhngprojects%2Fenergy-iq-be","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhngprojects%2Fenergy-iq-be","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhngprojects%2Fenergy-iq-be/lists"}