nestforge-generator 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +371 -0
- package/README.pt-BR.md +370 -0
- package/dist/features/auth-strategy.js +19 -0
- package/dist/features/auth-strategy.js.map +1 -0
- package/dist/features/database.js +59 -0
- package/dist/features/database.js.map +1 -0
- package/dist/features/dependencies.js +57 -0
- package/dist/features/dependencies.js.map +1 -0
- package/dist/features/language.js +172 -0
- package/dist/features/language.js.map +1 -0
- package/dist/features/markers.js +116 -0
- package/dist/features/markers.js.map +1 -0
- package/dist/generator.js +120 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.js +137 -0
- package/dist/prompts.js.map +1 -0
- package/package.json +76 -0
- package/templates/drizzle/.env.example +45 -0
- package/templates/drizzle/.env.test +38 -0
- package/templates/drizzle/.github/workflows/ci.yml +119 -0
- package/templates/drizzle/ARCHITECTURE.md +227 -0
- package/templates/drizzle/ARCHITECTURE.pt-BR.md +225 -0
- package/templates/drizzle/CODE_OF_CONDUCT.md +29 -0
- package/templates/drizzle/CODE_OF_CONDUCT.pt-BR.md +27 -0
- package/templates/drizzle/CONTRIBUTING.md +57 -0
- package/templates/drizzle/CONTRIBUTING.pt-BR.md +54 -0
- package/templates/drizzle/Dockerfile +43 -0
- package/templates/drizzle/LICENSE +21 -0
- package/templates/drizzle/README.md +257 -0
- package/templates/drizzle/README.pt-BR.md +257 -0
- package/templates/drizzle/ROADMAP.md +143 -0
- package/templates/drizzle/ROADMAP.pt-BR.md +143 -0
- package/templates/drizzle/TESTING.md +136 -0
- package/templates/drizzle/TESTING.pt-BR.md +136 -0
- package/templates/drizzle/docker-compose.yml +82 -0
- package/templates/drizzle/docs/adding-a-module.md +585 -0
- package/templates/drizzle/docs/features-markers.md +457 -0
- package/templates/drizzle/drizzle.config.ts +49 -0
- package/templates/drizzle/nest-cli.json +8 -0
- package/templates/drizzle/package.json +96 -0
- package/templates/drizzle/src/app.module.ts +72 -0
- package/templates/drizzle/src/auth/auth.controller.ts +283 -0
- package/templates/drizzle/src/auth/auth.module.ts +81 -0
- package/templates/drizzle/src/auth/auth.service.spec.ts +111 -0
- package/templates/drizzle/src/auth/auth.service.ts +631 -0
- package/templates/drizzle/src/auth/drizzle-session.store.ts +263 -0
- package/templates/drizzle/src/auth/dto/forgot-password.dto.ts +9 -0
- package/templates/drizzle/src/auth/dto/login.dto.ts +10 -0
- package/templates/drizzle/src/auth/dto/refresh-token.dto.ts +9 -0
- package/templates/drizzle/src/auth/dto/register.dto.ts +11 -0
- package/templates/drizzle/src/auth/dto/reset-password.dto.ts +10 -0
- package/templates/drizzle/src/auth/guards/github-auth.guard.ts +10 -0
- package/templates/drizzle/src/auth/guards/google-auth.guard.ts +10 -0
- package/templates/drizzle/src/auth/guards/jwt-auth.guard.ts +25 -0
- package/templates/drizzle/src/auth/guards/session-auth.guard.spec.ts +77 -0
- package/templates/drizzle/src/auth/guards/session-auth.guard.ts +37 -0
- package/templates/drizzle/src/auth/session.service.spec.ts +74 -0
- package/templates/drizzle/src/auth/session.service.ts +96 -0
- package/templates/drizzle/src/auth/strategies/github.strategy.ts +41 -0
- package/templates/drizzle/src/auth/strategies/google.strategy.ts +43 -0
- package/templates/drizzle/src/auth/strategies/jwt.strategy.ts +25 -0
- package/templates/drizzle/src/auth/token.service.ts +175 -0
- package/templates/drizzle/src/common/constants/permissions.ts +8 -0
- package/templates/drizzle/src/common/constants/role-permissions.ts +9 -0
- package/templates/drizzle/src/common/constants/role.enum.ts +5 -0
- package/templates/drizzle/src/common/decorators/current-user.decorator.ts +8 -0
- package/templates/drizzle/src/common/decorators/permissions.decorator.ts +7 -0
- package/templates/drizzle/src/common/decorators/public.decorator.ts +4 -0
- package/templates/drizzle/src/common/decorators/roles.decorator.ts +6 -0
- package/templates/drizzle/src/common/filters/http-exception.filter.ts +34 -0
- package/templates/drizzle/src/common/guards/permissions.guard.spec.ts +54 -0
- package/templates/drizzle/src/common/guards/permissions.guard.ts +28 -0
- package/templates/drizzle/src/common/guards/roles.guard.spec.ts +37 -0
- package/templates/drizzle/src/common/guards/roles.guard.ts +24 -0
- package/templates/drizzle/src/common/interceptors/logging.interceptor.ts +23 -0
- package/templates/drizzle/src/common/middleware/csrf.middleware.spec.ts +97 -0
- package/templates/drizzle/src/common/middleware/csrf.middleware.ts +46 -0
- package/templates/drizzle/src/common/utils/avatar-storage.util.ts +32 -0
- package/templates/drizzle/src/common/utils/hash.util.ts +5 -0
- package/templates/drizzle/src/config/env.validation.ts +50 -0
- package/templates/drizzle/src/database/database-lifecycle.service.ts +30 -0
- package/templates/drizzle/src/database/database.constants.ts +2 -0
- package/templates/drizzle/src/database/database.decorators.ts +5 -0
- package/templates/drizzle/src/database/database.module.ts +96 -0
- package/templates/drizzle/src/database/database.types.ts +28 -0
- package/templates/drizzle/src/database/schema/index.ts +11 -0
- package/templates/drizzle/src/database/schema/mysql.schema.ts +215 -0
- package/templates/drizzle/src/database/schema/postgres.schema.ts +218 -0
- package/templates/drizzle/src/database/schema/sqlite.schema.ts +190 -0
- package/templates/drizzle/src/database/seed.ts +152 -0
- package/templates/drizzle/src/health/health.controller.ts +49 -0
- package/templates/drizzle/src/health/health.module.ts +19 -0
- package/templates/drizzle/src/health/indicators/drizzle-health.indicator.spec.ts +71 -0
- package/templates/drizzle/src/health/indicators/drizzle-health.indicator.ts +52 -0
- package/templates/drizzle/src/health/indicators/redis-health.indicator.spec.ts +54 -0
- package/templates/drizzle/src/health/indicators/redis-health.indicator.ts +33 -0
- package/templates/drizzle/src/mail/mail.module.ts +12 -0
- package/templates/drizzle/src/mail/mail.processor.ts +48 -0
- package/templates/drizzle/src/mail/mail.service.ts +24 -0
- package/templates/drizzle/src/mail/templates/email-templates.ts +28 -0
- package/templates/drizzle/src/main.ts +145 -0
- package/templates/drizzle/src/metrics/metrics.controller.ts +22 -0
- package/templates/drizzle/src/metrics/metrics.interceptor.ts +30 -0
- package/templates/drizzle/src/metrics/metrics.module.ts +12 -0
- package/templates/drizzle/src/metrics/metrics.service.ts +34 -0
- package/templates/drizzle/src/types/express-session.d.ts +13 -0
- package/templates/drizzle/src/users/dto/create-user.dto.ts +12 -0
- package/templates/drizzle/src/users/dto/find-users-query.dto.ts +12 -0
- package/templates/drizzle/src/users/dto/update-user.dto.ts +6 -0
- package/templates/drizzle/src/users/entities/user.entity.ts +23 -0
- package/templates/drizzle/src/users/users.controller.ts +165 -0
- package/templates/drizzle/src/users/users.module.ts +10 -0
- package/templates/drizzle/src/users/users.service.spec.ts +301 -0
- package/templates/drizzle/src/users/users.service.ts +213 -0
- package/templates/drizzle/test/auth.e2e-spec.ts +114 -0
- package/templates/drizzle/test/session-auth.e2e-spec.ts +163 -0
- package/templates/drizzle/test/users.e2e-spec.ts +212 -0
- package/templates/drizzle/test/utils/clean-database.ts +104 -0
- package/templates/drizzle/test/utils/e2e-setup.ts +77 -0
- package/templates/drizzle/tsconfig.build.json +4 -0
- package/templates/drizzle/tsconfig.json +25 -0
- package/templates/drizzle/vitest.config.ts +20 -0
- package/templates/drizzle/vitest.e2e.config.ts +19 -0
- package/templates/prisma/.env.example +44 -0
- package/templates/prisma/.env.test +37 -0
- package/templates/prisma/.github/workflows/ci.yml +109 -0
- package/templates/prisma/ARCHITECTURE.md +70 -0
- package/templates/prisma/ARCHITECTURE.pt-BR.md +63 -0
- package/templates/prisma/CODE_OF_CONDUCT.md +29 -0
- package/templates/prisma/CODE_OF_CONDUCT.pt-BR.md +27 -0
- package/templates/prisma/CONTRIBUTING.md +57 -0
- package/templates/prisma/CONTRIBUTING.pt-BR.md +54 -0
- package/templates/prisma/Dockerfile +33 -0
- package/templates/prisma/LICENSE +21 -0
- package/templates/prisma/README.md +267 -0
- package/templates/prisma/README.pt-BR.md +267 -0
- package/templates/prisma/ROADMAP.md +75 -0
- package/templates/prisma/ROADMAP.pt-BR.md +65 -0
- package/templates/prisma/TESTING.md +123 -0
- package/templates/prisma/TESTING.pt-BR.md +123 -0
- package/templates/prisma/docker-compose.yml +78 -0
- package/templates/prisma/docs/adding-a-module.md +230 -0
- package/templates/prisma/docs/features-markers.md +50 -0
- package/templates/prisma/nest-cli.json +8 -0
- package/templates/prisma/package.json +95 -0
- package/templates/prisma/prisma/schema.prisma +105 -0
- package/templates/prisma/prisma/seed.ts +46 -0
- package/templates/prisma/src/app.module.ts +72 -0
- package/templates/prisma/src/auth/auth.controller.ts +283 -0
- package/templates/prisma/src/auth/auth.module.ts +59 -0
- package/templates/prisma/src/auth/auth.service.spec.ts +53 -0
- package/templates/prisma/src/auth/auth.service.ts +224 -0
- package/templates/prisma/src/auth/dto/forgot-password.dto.ts +9 -0
- package/templates/prisma/src/auth/dto/login.dto.ts +10 -0
- package/templates/prisma/src/auth/dto/refresh-token.dto.ts +9 -0
- package/templates/prisma/src/auth/dto/register.dto.ts +11 -0
- package/templates/prisma/src/auth/dto/reset-password.dto.ts +10 -0
- package/templates/prisma/src/auth/guards/github-auth.guard.ts +10 -0
- package/templates/prisma/src/auth/guards/google-auth.guard.ts +10 -0
- package/templates/prisma/src/auth/guards/jwt-auth.guard.ts +25 -0
- package/templates/prisma/src/auth/guards/session-auth.guard.spec.ts +77 -0
- package/templates/prisma/src/auth/guards/session-auth.guard.ts +37 -0
- package/templates/prisma/src/auth/session.service.spec.ts +74 -0
- package/templates/prisma/src/auth/session.service.ts +96 -0
- package/templates/prisma/src/auth/strategies/github.strategy.ts +41 -0
- package/templates/prisma/src/auth/strategies/google.strategy.ts +43 -0
- package/templates/prisma/src/auth/strategies/jwt.strategy.ts +25 -0
- package/templates/prisma/src/auth/token.service.ts +84 -0
- package/templates/prisma/src/common/constants/permissions.ts +8 -0
- package/templates/prisma/src/common/constants/role-permissions.ts +9 -0
- package/templates/prisma/src/common/decorators/current-user.decorator.ts +8 -0
- package/templates/prisma/src/common/decorators/permissions.decorator.ts +7 -0
- package/templates/prisma/src/common/decorators/public.decorator.ts +4 -0
- package/templates/prisma/src/common/decorators/roles.decorator.ts +6 -0
- package/templates/prisma/src/common/filters/http-exception.filter.ts +34 -0
- package/templates/prisma/src/common/guards/permissions.guard.spec.ts +54 -0
- package/templates/prisma/src/common/guards/permissions.guard.ts +28 -0
- package/templates/prisma/src/common/guards/roles.guard.spec.ts +37 -0
- package/templates/prisma/src/common/guards/roles.guard.ts +24 -0
- package/templates/prisma/src/common/interceptors/logging.interceptor.ts +23 -0
- package/templates/prisma/src/common/middleware/csrf.middleware.spec.ts +97 -0
- package/templates/prisma/src/common/middleware/csrf.middleware.ts +46 -0
- package/templates/prisma/src/common/utils/avatar-storage.util.ts +32 -0
- package/templates/prisma/src/common/utils/hash.util.ts +5 -0
- package/templates/prisma/src/config/env.validation.ts +49 -0
- package/templates/prisma/src/database/prisma.module.ts +9 -0
- package/templates/prisma/src/database/prisma.service.ts +13 -0
- package/templates/prisma/src/health/health.controller.ts +49 -0
- package/templates/prisma/src/health/health.module.ts +19 -0
- package/templates/prisma/src/health/indicators/prisma-health.indicator.spec.ts +22 -0
- package/templates/prisma/src/health/indicators/prisma-health.indicator.ts +19 -0
- package/templates/prisma/src/health/indicators/redis-health.indicator.spec.ts +54 -0
- package/templates/prisma/src/health/indicators/redis-health.indicator.ts +33 -0
- package/templates/prisma/src/mail/mail.module.ts +12 -0
- package/templates/prisma/src/mail/mail.processor.ts +48 -0
- package/templates/prisma/src/mail/mail.service.ts +24 -0
- package/templates/prisma/src/mail/templates/email-templates.ts +28 -0
- package/templates/prisma/src/main.ts +92 -0
- package/templates/prisma/src/metrics/metrics.controller.ts +22 -0
- package/templates/prisma/src/metrics/metrics.interceptor.ts +30 -0
- package/templates/prisma/src/metrics/metrics.module.ts +12 -0
- package/templates/prisma/src/metrics/metrics.service.ts +34 -0
- package/templates/prisma/src/types/express-session.d.ts +13 -0
- package/templates/prisma/src/users/dto/create-user.dto.ts +12 -0
- package/templates/prisma/src/users/dto/find-users-query.dto.ts +12 -0
- package/templates/prisma/src/users/dto/update-user.dto.ts +6 -0
- package/templates/prisma/src/users/entities/user.entity.ts +20 -0
- package/templates/prisma/src/users/users.controller.ts +165 -0
- package/templates/prisma/src/users/users.module.ts +10 -0
- package/templates/prisma/src/users/users.service.spec.ts +104 -0
- package/templates/prisma/src/users/users.service.ts +114 -0
- package/templates/prisma/test/auth.e2e-spec.ts +75 -0
- package/templates/prisma/test/session-auth.e2e-spec.ts +163 -0
- package/templates/prisma/test/users.e2e-spec.ts +106 -0
- package/templates/prisma/test/utils/clean-database.ts +14 -0
- package/templates/prisma/test/utils/e2e-setup.ts +58 -0
- package/templates/prisma/tsconfig.build.json +4 -0
- package/templates/prisma/tsconfig.json +25 -0
- package/templates/prisma/vitest.config.ts +20 -0
- package/templates/prisma/vitest.e2e.config.ts +19 -0
- package/templates/typeorm/.env.example +45 -0
- package/templates/typeorm/.env.test +38 -0
- package/templates/typeorm/.github/workflows/ci.yml +116 -0
- package/templates/typeorm/ARCHITECTURE.md +158 -0
- package/templates/typeorm/ARCHITECTURE.pt-BR.md +156 -0
- package/templates/typeorm/CODE_OF_CONDUCT.md +29 -0
- package/templates/typeorm/CODE_OF_CONDUCT.pt-BR.md +27 -0
- package/templates/typeorm/CONTRIBUTING.md +57 -0
- package/templates/typeorm/CONTRIBUTING.pt-BR.md +54 -0
- package/templates/typeorm/Dockerfile +43 -0
- package/templates/typeorm/LICENSE +21 -0
- package/templates/typeorm/README.md +266 -0
- package/templates/typeorm/README.pt-BR.md +266 -0
- package/templates/typeorm/ROADMAP.md +79 -0
- package/templates/typeorm/ROADMAP.pt-BR.md +67 -0
- package/templates/typeorm/TESTING.md +114 -0
- package/templates/typeorm/TESTING.pt-BR.md +114 -0
- package/templates/typeorm/docker-compose.yml +78 -0
- package/templates/typeorm/docs/adding-a-module.md +369 -0
- package/templates/typeorm/docs/features-markers.md +50 -0
- package/templates/typeorm/nest-cli.json +8 -0
- package/templates/typeorm/package.json +98 -0
- package/templates/typeorm/src/app.module.ts +72 -0
- package/templates/typeorm/src/auth/auth.controller.ts +283 -0
- package/templates/typeorm/src/auth/auth.module.ts +86 -0
- package/templates/typeorm/src/auth/auth.service.spec.ts +111 -0
- package/templates/typeorm/src/auth/auth.service.ts +346 -0
- package/templates/typeorm/src/auth/dto/forgot-password.dto.ts +9 -0
- package/templates/typeorm/src/auth/dto/login.dto.ts +10 -0
- package/templates/typeorm/src/auth/dto/refresh-token.dto.ts +9 -0
- package/templates/typeorm/src/auth/dto/register.dto.ts +11 -0
- package/templates/typeorm/src/auth/dto/reset-password.dto.ts +10 -0
- package/templates/typeorm/src/auth/entities/email-verification-token.entity.ts +69 -0
- package/templates/typeorm/src/auth/entities/oauth-account.entity.ts +50 -0
- package/templates/typeorm/src/auth/entities/password-reset-token.entity.ts +69 -0
- package/templates/typeorm/src/auth/entities/refresh-token.entity.ts +69 -0
- package/templates/typeorm/src/auth/entities/session.entity.ts +50 -0
- package/templates/typeorm/src/auth/guards/github-auth.guard.ts +10 -0
- package/templates/typeorm/src/auth/guards/google-auth.guard.ts +10 -0
- package/templates/typeorm/src/auth/guards/jwt-auth.guard.ts +25 -0
- package/templates/typeorm/src/auth/guards/session-auth.guard.spec.ts +77 -0
- package/templates/typeorm/src/auth/guards/session-auth.guard.ts +37 -0
- package/templates/typeorm/src/auth/session.service.spec.ts +74 -0
- package/templates/typeorm/src/auth/session.service.ts +96 -0
- package/templates/typeorm/src/auth/strategies/github.strategy.ts +41 -0
- package/templates/typeorm/src/auth/strategies/google.strategy.ts +43 -0
- package/templates/typeorm/src/auth/strategies/jwt.strategy.ts +25 -0
- package/templates/typeorm/src/auth/token.service.ts +115 -0
- package/templates/typeorm/src/common/constants/permissions.ts +8 -0
- package/templates/typeorm/src/common/constants/role-permissions.ts +9 -0
- package/templates/typeorm/src/common/constants/role.enum.ts +5 -0
- package/templates/typeorm/src/common/decorators/current-user.decorator.ts +8 -0
- package/templates/typeorm/src/common/decorators/permissions.decorator.ts +7 -0
- package/templates/typeorm/src/common/decorators/public.decorator.ts +4 -0
- package/templates/typeorm/src/common/decorators/roles.decorator.ts +6 -0
- package/templates/typeorm/src/common/filters/http-exception.filter.ts +34 -0
- package/templates/typeorm/src/common/guards/permissions.guard.spec.ts +54 -0
- package/templates/typeorm/src/common/guards/permissions.guard.ts +28 -0
- package/templates/typeorm/src/common/guards/roles.guard.spec.ts +37 -0
- package/templates/typeorm/src/common/guards/roles.guard.ts +24 -0
- package/templates/typeorm/src/common/interceptors/logging.interceptor.ts +23 -0
- package/templates/typeorm/src/common/middleware/csrf.middleware.spec.ts +97 -0
- package/templates/typeorm/src/common/middleware/csrf.middleware.ts +46 -0
- package/templates/typeorm/src/common/utils/avatar-storage.util.ts +32 -0
- package/templates/typeorm/src/common/utils/hash.util.ts +5 -0
- package/templates/typeorm/src/config/env.validation.ts +50 -0
- package/templates/typeorm/src/database/data-source.ts +20 -0
- package/templates/typeorm/src/database/database.module.ts +39 -0
- package/templates/typeorm/src/database/seed.ts +81 -0
- package/templates/typeorm/src/database/typeorm-options.ts +49 -0
- package/templates/typeorm/src/health/health.controller.ts +49 -0
- package/templates/typeorm/src/health/health.module.ts +19 -0
- package/templates/typeorm/src/health/indicators/redis-health.indicator.spec.ts +54 -0
- package/templates/typeorm/src/health/indicators/redis-health.indicator.ts +33 -0
- package/templates/typeorm/src/health/indicators/typeorm-health.indicator.spec.ts +49 -0
- package/templates/typeorm/src/health/indicators/typeorm-health.indicator.ts +37 -0
- package/templates/typeorm/src/mail/mail.module.ts +12 -0
- package/templates/typeorm/src/mail/mail.processor.ts +48 -0
- package/templates/typeorm/src/mail/mail.service.ts +24 -0
- package/templates/typeorm/src/mail/templates/email-templates.ts +28 -0
- package/templates/typeorm/src/main.ts +107 -0
- package/templates/typeorm/src/metrics/metrics.controller.ts +22 -0
- package/templates/typeorm/src/metrics/metrics.interceptor.ts +30 -0
- package/templates/typeorm/src/metrics/metrics.module.ts +12 -0
- package/templates/typeorm/src/metrics/metrics.service.ts +34 -0
- package/templates/typeorm/src/types/express-session.d.ts +13 -0
- package/templates/typeorm/src/users/dto/create-user.dto.ts +12 -0
- package/templates/typeorm/src/users/dto/find-users-query.dto.ts +12 -0
- package/templates/typeorm/src/users/dto/update-user.dto.ts +6 -0
- package/templates/typeorm/src/users/entities/user.entity.ts +113 -0
- package/templates/typeorm/src/users/users.controller.ts +165 -0
- package/templates/typeorm/src/users/users.module.ts +13 -0
- package/templates/typeorm/src/users/users.service.spec.ts +183 -0
- package/templates/typeorm/src/users/users.service.ts +124 -0
- package/templates/typeorm/test/auth.e2e-spec.ts +111 -0
- package/templates/typeorm/test/session-auth.e2e-spec.ts +159 -0
- package/templates/typeorm/test/users.e2e-spec.ts +183 -0
- package/templates/typeorm/test/utils/clean-database.ts +65 -0
- package/templates/typeorm/test/utils/e2e-setup.ts +77 -0
- package/templates/typeorm/tsconfig.build.json +4 -0
- package/templates/typeorm/tsconfig.json +25 -0
- package/templates/typeorm/vitest.config.ts +20 -0
- package/templates/typeorm/vitest.e2e.config.ts +19 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Contribuindo com o NestForge
|
|
2
|
+
|
|
3
|
+
[English](CONTRIBUTING.md) | **Português**
|
|
4
|
+
|
|
5
|
+
Obrigado por considerar contribuir! 🎉
|
|
6
|
+
|
|
7
|
+
## Como começar
|
|
8
|
+
|
|
9
|
+
1. Faça um fork do repositório
|
|
10
|
+
2. Clone o seu fork: `git clone https://github.com/SEU_USUARIO/nestforge.git`
|
|
11
|
+
3. Crie uma branch: `git checkout -b feat/nome-da-feature`
|
|
12
|
+
4. Suba o ambiente: `docker compose up` (ou `npm install` + `npm run start:dev`)
|
|
13
|
+
5. Faça suas alterações
|
|
14
|
+
6. Rode os testes e o lint antes de commitar: `npm run test && npm run lint`
|
|
15
|
+
7. Commit seguindo o padrão abaixo
|
|
16
|
+
8. Abra um Pull Request descrevendo o que foi feito e por quê
|
|
17
|
+
|
|
18
|
+
## Padrão de commits
|
|
19
|
+
|
|
20
|
+
Usamos commits em português, seguindo [Conventional Commits](https://www.conventionalcommits.org/):
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
feat: adiciona autenticação via Google OAuth
|
|
24
|
+
fix: corrige validação do refresh token
|
|
25
|
+
docs: atualiza guia de instalação
|
|
26
|
+
test: adiciona testes de integração para users
|
|
27
|
+
refactor: extrai lógica de hash para utils
|
|
28
|
+
chore: atualiza dependências
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Padrões de código
|
|
32
|
+
|
|
33
|
+
- Se o seu código for ligado a um recurso opcional da CLI (Swagger, Redis, RBAC, etc.), marque ele seguindo [`docs/feature-markers.md`](docs/feature-markers.md) — sem isso, a CLI não consegue remover o trecho quando alguém desliga o recurso.
|
|
34
|
+
- TypeScript estrito (sem `any` sem justificativa)
|
|
35
|
+
- Validação de entrada sempre via Zod (DTOs)
|
|
36
|
+
- Nada de lógica de negócio no controller — controller só orquestra, service resolve
|
|
37
|
+
- Toda rota nova precisa de decorators de Swagger (`@ApiTags`, `@ApiOperation`, etc)
|
|
38
|
+
- Toda feature nova precisa de teste (unitário no mínimo)
|
|
39
|
+
|
|
40
|
+
## Reportando bugs
|
|
41
|
+
|
|
42
|
+
Abra uma issue com:
|
|
43
|
+
- Descrição do problema
|
|
44
|
+
- Passos para reproduzir
|
|
45
|
+
- Comportamento esperado vs. atual
|
|
46
|
+
- Versão do Node / ambiente (Docker ou local)
|
|
47
|
+
|
|
48
|
+
## Sugerindo features
|
|
49
|
+
|
|
50
|
+
Abra uma issue com a tag `enhancement` descrevendo o problema que a feature resolve antes de sair implementando — isso evita retrabalho caso a abordagem precise ser discutida.
|
|
51
|
+
|
|
52
|
+
## Código de conduta
|
|
53
|
+
|
|
54
|
+
Ao contribuir, você concorda em seguir o [Código de Conduta](CODE_OF_CONDUCT.pt-BR.md) do projeto.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# --- Base ---
|
|
2
|
+
FROM node:20-alpine AS base
|
|
3
|
+
|
|
4
|
+
WORKDIR /app
|
|
5
|
+
|
|
6
|
+
COPY package*.json ./
|
|
7
|
+
|
|
8
|
+
# --- Dependencies ---
|
|
9
|
+
FROM base AS deps
|
|
10
|
+
|
|
11
|
+
RUN npm ci
|
|
12
|
+
|
|
13
|
+
# --- Development ---
|
|
14
|
+
FROM deps AS development
|
|
15
|
+
|
|
16
|
+
COPY . .
|
|
17
|
+
|
|
18
|
+
EXPOSE 3000
|
|
19
|
+
|
|
20
|
+
CMD ["npm", "run", "start:dev"]
|
|
21
|
+
|
|
22
|
+
# --- Build ---
|
|
23
|
+
FROM deps AS build
|
|
24
|
+
|
|
25
|
+
COPY . .
|
|
26
|
+
|
|
27
|
+
RUN npm run build
|
|
28
|
+
RUN npm prune --omit=dev
|
|
29
|
+
|
|
30
|
+
# --- Production ---
|
|
31
|
+
FROM node:20-alpine AS production
|
|
32
|
+
|
|
33
|
+
WORKDIR /app
|
|
34
|
+
|
|
35
|
+
ENV NODE_ENV=production
|
|
36
|
+
|
|
37
|
+
COPY --from=build /app/node_modules ./node_modules
|
|
38
|
+
COPY --from=build /app/dist ./dist
|
|
39
|
+
COPY --from=build /app/package.json ./package.json
|
|
40
|
+
|
|
41
|
+
EXPOSE 3000
|
|
42
|
+
|
|
43
|
+
CMD ["node", "dist/main.js"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jeiel Jedson Leão Alves
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# NestForge
|
|
2
|
+
|
|
3
|
+
**English** | [Português](README.pt-BR.md)
|
|
4
|
+
|
|
5
|
+
> Production-ready NestJS starter with Drizzle ORM, Authentication, Docker, Testing, CI/CD and Clean Architecture.
|
|
6
|
+
|
|
7
|
+
[](https://github.com/jeiel2013/nestforge/actions/workflows/ci.yml)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
[](https://nestjs.com)
|
|
11
|
+
|
|
12
|
+
NestForge is a NestJS starter designed to accelerate the beginning of serious backend projects, with complete authentication, clean architecture, security, and observability already configured. The idea is to clone it, run `docker compose up`, and have an API ready to evolve.
|
|
13
|
+
|
|
14
|
+
## ✨ Features
|
|
15
|
+
|
|
16
|
+
- 🔐 **Configurable authentication** — JWT with access/refresh tokens, Drizzle-backed Session/Cookies, OAuth-only, or no authentication
|
|
17
|
+
- 🌐 **OAuth** — Google and GitHub, integrated with the selected token or session strategy
|
|
18
|
+
- 👥 **RBAC** — Roles (Admin, Manager, User) and granular Permissions
|
|
19
|
+
- 🛡️ **Security** — Helmet, CORS, Rate Limiting, validation, and serialization with Zod
|
|
20
|
+
- 🗄️ **Database** — Drizzle ORM with PostgreSQL, MySQL, or SQLite
|
|
21
|
+
- 📨 **Email** — queues with BullMQ + Redis, locally tested with Mailpit
|
|
22
|
+
- 📄 **Automatic documentation** — Swagger
|
|
23
|
+
- 🪵 **Structured logs** — Pino
|
|
24
|
+
- ✅ **Tests** — unit and integration tests with Vitest
|
|
25
|
+
- 🐳 **Docker** — complete environment with a single command
|
|
26
|
+
- ⚙️ **CI/CD** — GitHub Actions (build, lint, test)
|
|
27
|
+
|
|
28
|
+
## 🧱 Stack
|
|
29
|
+
|
|
30
|
+
| Layer | Technology |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Framework | NestJS + TypeScript |
|
|
33
|
+
| ORM / Query Builder | Drizzle ORM |
|
|
34
|
+
| Database | PostgreSQL, MySQL, or SQLite |
|
|
35
|
+
| Cache / Queues | Redis + BullMQ |
|
|
36
|
+
| Authentication | JWT, Session/Cookies, or OAuth with Passport |
|
|
37
|
+
| Validation | Zod + nestjs-zod (schemas automatically become DTOs + Swagger) |
|
|
38
|
+
| Docs | Swagger |
|
|
39
|
+
| Email (dev) | Mailpit |
|
|
40
|
+
| Tests | Vitest |
|
|
41
|
+
| CI | GitHub Actions |
|
|
42
|
+
|
|
43
|
+
## 📁 Folder structure
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
src/
|
|
47
|
+
│
|
|
48
|
+
├── auth/ # login, sessions/tokens, OAuth, guards, and strategies
|
|
49
|
+
├── users/ # user CRUD
|
|
50
|
+
├── common/ # decorators, filters, guards, interceptors, pipes, utilities
|
|
51
|
+
├── config/ # typed and validated configuration (env)
|
|
52
|
+
├── database/ # Drizzle connection, schemas, configuration, migrations, and seed
|
|
53
|
+
├── modules/ # additional domain modules
|
|
54
|
+
├── shared/ # code shared between modules
|
|
55
|
+
├── jobs/ # queues and workers (BullMQ)
|
|
56
|
+
├── mail/ # email templates and delivery
|
|
57
|
+
└── main.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 🚀 Getting started
|
|
61
|
+
|
|
62
|
+
### Prerequisites
|
|
63
|
+
|
|
64
|
+
- Node.js 20+
|
|
65
|
+
- Docker and Docker Compose
|
|
66
|
+
|
|
67
|
+
### Running with Docker (recommended)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone https://github.com/jeiel2013/nestforge.git
|
|
71
|
+
cd nestforge
|
|
72
|
+
cp .env.example .env
|
|
73
|
+
docker compose up
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This starts the API and the services selected during generation, such as PostgreSQL or MySQL, Redis, and Mailpit. SQLite projects do not require a database container.
|
|
77
|
+
|
|
78
|
+
### Running locally
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install
|
|
82
|
+
cp .env.example .env
|
|
83
|
+
npm run migration:generate
|
|
84
|
+
npm run migration:migrate
|
|
85
|
+
npm run seed
|
|
86
|
+
npm run start:dev
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Drizzle Kit reads `drizzle.config.ts`, generates SQL migrations in `drizzle/`, and uses only the schema for the database selected during project generation.
|
|
90
|
+
|
|
91
|
+
Swagger documentation is available at `http://localhost:3000/docs`.
|
|
92
|
+
|
|
93
|
+
## 🗺️ Roadmap
|
|
94
|
+
|
|
95
|
+
- [x] JWT authentication
|
|
96
|
+
- [x] Session/Cookies authentication
|
|
97
|
+
- [x] Google/GitHub OAuth
|
|
98
|
+
- [x] OAuth-only strategy
|
|
99
|
+
- [x] Generation without authentication
|
|
100
|
+
- [x] Refresh Token
|
|
101
|
+
- [x] Docker
|
|
102
|
+
- [x] CI (build, lint, test)
|
|
103
|
+
- [x] OAuth (Google/GitHub)
|
|
104
|
+
- [x] File uploads
|
|
105
|
+
- [x] Queues (BullMQ)
|
|
106
|
+
- [x] Transactional email
|
|
107
|
+
- [x] Complete RBAC (granular permissions)
|
|
108
|
+
- [x] Complete integration tests
|
|
109
|
+
- [x] Complete documentation (Swagger + architecture guide)
|
|
110
|
+
|
|
111
|
+
See the detailed [ROADMAP.md](ROADMAP.md).
|
|
112
|
+
|
|
113
|
+
### Configuring social login (OAuth)
|
|
114
|
+
|
|
115
|
+
To enable login through Google and GitHub, create an OAuth App with each provider and fill in `.env`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
APP_URL=http://localhost:3000
|
|
119
|
+
|
|
120
|
+
GOOGLE_CLIENT_ID=
|
|
121
|
+
GOOGLE_CLIENT_SECRET=
|
|
122
|
+
|
|
123
|
+
GITHUB_CLIENT_ID=
|
|
124
|
+
GITHUB_CLIENT_SECRET=
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- **Google**: create credentials in the [Google Cloud Console](https://console.cloud.google.com/apis/credentials) and configure the callback URL as `{APP_URL}/auth/google/callback`.
|
|
128
|
+
- **GitHub**: create an OAuth App under `Settings > Developer settings > OAuth Apps` and configure the callback URL as `{APP_URL}/auth/github/callback`.
|
|
129
|
+
|
|
130
|
+
Then access `GET /auth/google` or `GET /auth/github`. On callback, the API issues access/refresh tokens or establishes a cookie-based session according to the selected strategy. On first access, an account is created and linked to the provider.
|
|
131
|
+
|
|
132
|
+
### Session/Cookies authentication
|
|
133
|
+
|
|
134
|
+
When the project is generated with Session/Cookies, registration and login create a session persisted in the `sessions` table. `DrizzleSessionStore` integrates `express-session` with the selected database without depending on Prisma- or TypeORM-specific stores. The identifier is sent in the `nestforge.sid` cookie, configured with `httpOnly`, `sameSite=lax`, and `secure` in production.
|
|
135
|
+
|
|
136
|
+
Configure `.env`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
SESSION_SECRET=use-a-secret-with-at-least-32-characters
|
|
140
|
+
SESSION_MAX_AGE=604800000
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Password recovery and email verification
|
|
144
|
+
|
|
145
|
+
Every registration (`POST /auth/register`) automatically sends a verification email. Emails are queued with BullMQ/Redis and processed by a worker that sends them over SMTP. In development, everything goes to Mailpit (`http://localhost:8025`), so nothing is actually sent over the internet.
|
|
146
|
+
|
|
147
|
+
| Route | What it does |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `POST /auth/forgot-password` | Receives an `email` and queues the password reset link (the response is always generic and does not reveal whether the email exists) |
|
|
150
|
+
| `POST /auth/reset-password` | Receives a `token` + `password` and changes the password; it also revokes the user's active refresh tokens |
|
|
151
|
+
| `GET /auth/verify-email?token=...` | Confirms the email from the received link |
|
|
152
|
+
|
|
153
|
+
Reset and verification tokens expire after 1 hour and 24 hours, respectively, and can only be used once.
|
|
154
|
+
|
|
155
|
+
## 🔑 Roles & Permissions
|
|
156
|
+
|
|
157
|
+
| Role | Description |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `ADMIN` | full system access |
|
|
160
|
+
| `MANAGER` | manages users and reports |
|
|
161
|
+
| `USER` | standard access |
|
|
162
|
+
|
|
163
|
+
Each role has a fixed set of permissions mapped in `src/common/constants/role-permissions.ts`:
|
|
164
|
+
|
|
165
|
+
| Permission | ADMIN | MANAGER | USER |
|
|
166
|
+
|---|:---:|:---:|:---:|
|
|
167
|
+
| `user:create` | ✅ | ❌ | ❌ |
|
|
168
|
+
| `user:read` | ✅ | ✅ | ✅ |
|
|
169
|
+
| `user:update` | ✅ | ✅ | ❌ |
|
|
170
|
+
| `user:delete` | ✅ | ❌ | ❌ |
|
|
171
|
+
| `report:read` | ✅ | ✅ | ❌ |
|
|
172
|
+
|
|
173
|
+
On routes, use `@Permissions(Permission.UserCreate)` to require a specific permission or `@Roles(Role.ADMIN)` when role-based control is enough. Both guards (`RolesGuard` and `PermissionsGuard`) run globally and only block a route when it has the corresponding decorator.
|
|
174
|
+
|
|
175
|
+
## 👥 Users: pagination, filters, and avatar
|
|
176
|
+
|
|
177
|
+
`GET /users` accepts query parameters for paginating and filtering the list:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
GET /users?page=2&limit=20&search=jeiel&role=ADMIN
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| Parameter | Description |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `page` | current page (default: 1) |
|
|
186
|
+
| `limit` | items per page, up to 100 (default: 10) |
|
|
187
|
+
| `search` | searches by name or email (case-insensitive) |
|
|
188
|
+
| `role` | filters by `ADMIN`, `MANAGER`, or `USER` |
|
|
189
|
+
|
|
190
|
+
The response uses the format `{ data, meta: { total, page, limit, totalPages } }`.
|
|
191
|
+
|
|
192
|
+
To change the authenticated user's avatar:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
curl -X POST http://localhost:3000/users/me/avatar \
|
|
196
|
+
-H "Authorization: Bearer <accessToken>" \
|
|
197
|
+
-F "file=@/path/to/photo.png"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
PNG, JPEG, and WEBP files up to 2 MB are accepted. The file is saved under `./uploads/avatars` and served at `/uploads/avatars/<file>`.
|
|
201
|
+
|
|
202
|
+
## 🛡️ Security: serialization and CSRF
|
|
203
|
+
|
|
204
|
+
All input validation (`body`, `query`) uses **Zod** through [`nestjs-zod`](https://github.com/BenLorantfy/nestjs-zod): each DTO is a `z.object({...})` transformed into a class with `createZodDto(schema)` and globally validated by `ZodValidationPipe`. During bootstrap, `patchNestJsSwagger()` teaches Swagger to read these schemas automatically, so validation (Zod) and documentation (`@ApiProperty`) do not need to be duplicated as they would with `class-validator`. Exported schemas (for example, `createUserSchema`) can also be reused and combined (such as `updateUserSchema`, which is simply `createUserSchema.partial()`).
|
|
205
|
+
|
|
206
|
+
- 🪵 **Observability** — structured logs with Pino, health checks (`/health`), and Prometheus metrics (`/metrics`)
|
|
207
|
+
|
|
208
|
+
The seed creates three test accounts, one for each role:
|
|
209
|
+
|
|
210
|
+
| Email | Password | Role |
|
|
211
|
+
|---|---|---|
|
|
212
|
+
| `admin@nestforge.dev` | `admin123` | ADMIN |
|
|
213
|
+
| `manager@nestforge.dev` | `manager123` | MANAGER |
|
|
214
|
+
| `user@nestforge.dev` | `user1234` | USER |
|
|
215
|
+
|
|
216
|
+
## 📈 Observability
|
|
217
|
+
|
|
218
|
+
`GET /health` returns the aggregated status of the API — database, Redis, memory (heap/RSS), and disk space — using `@nestjs/terminus`. `DrizzleHealthIndicator` queries the selected database's native client, and each check appears individually in the response.
|
|
219
|
+
|
|
220
|
+
`GET /metrics` exposes Prometheus-format metrics through `prom-client`: standard Node.js metrics (CPU, memory, event loop), plus `http_request_duration_seconds` (histogram) and `http_requests_total` (counter), both with `method`, `route`, and `status_code` labels. Simply point a Prometheus scrape job at this route.
|
|
221
|
+
|
|
222
|
+
## 🧪 Tests
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npm run test # unit tests
|
|
226
|
+
npm run test:e2e # integration tests (E2E)
|
|
227
|
+
npm run test:cov # coverage
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
E2E tests (`test/*.e2e-spec.ts`) start the real application with NestJS and Drizzle and make requests with `supertest`, using the isolated database defined in `.env.test`. Before the first run, generate the migrations:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
npm run drizzle:generate
|
|
234
|
+
npm run test:e2e
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The `pretest:e2e` script automatically applies migrations to this database before every run. Each test cleans the tables before running (`test/utils/clean-database.ts`), so nothing needs to be reset manually between runs. Current coverage includes the complete authentication flow (registration, login, refresh, logout, duplicate email, invalid credentials) and user CRUD with RBAC (ADMIN can do everything, USER can read but cannot create, `/users/me`, and access without a token).
|
|
238
|
+
|
|
239
|
+
Unit tests (`src/**/*.spec.ts`) run in isolation with the Drizzle instance and `ioredis` mocked through `vi.fn()` and `vi.mock()`. They do not require a real database or Redis. Coverage includes `AuthService`, `UsersService`, `RolesGuard`, `PermissionsGuard`, `DrizzleHealthIndicator`, and `RedisHealthIndicator`.
|
|
240
|
+
|
|
241
|
+
## 📚 Additional documentation
|
|
242
|
+
|
|
243
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) — how the project is organized and why certain design decisions were made (Zod vs. class-validator, code-based vs. database-based permissions, BullMQ, etc.)
|
|
244
|
+
- [TESTING.md](TESTING.md) — how to validate migrations, build, unit tests, and E2E tests
|
|
245
|
+
- [docs/adding-a-module.md](docs/adding-a-module.md) — step-by-step instructions for adding a new feature according to the project's conventions
|
|
246
|
+
|
|
247
|
+
## 🤝 Contributing
|
|
248
|
+
|
|
249
|
+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for the complete guide.
|
|
250
|
+
|
|
251
|
+
## 📄 License
|
|
252
|
+
|
|
253
|
+
This project is licensed under the MIT License — see [LICENSE](LICENSE).
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
Made by [Jeiel Alves](https://github.com/jeiel2013) · [jeieldev.com.br](https://jeieldev.com.br)
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# NestForge
|
|
2
|
+
|
|
3
|
+
[English](README.md) | **Português**
|
|
4
|
+
|
|
5
|
+
> Production-ready NestJS starter with Drizzle ORM, Authentication, Docker, Testing, CI/CD and Clean Architecture.
|
|
6
|
+
|
|
7
|
+
[](https://github.com/jeiel2013/nestforge/actions/workflows/ci.yml)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
[](https://nestjs.com)
|
|
11
|
+
|
|
12
|
+
NestForge é um boilerplate de NestJS pensado para acelerar o início de projetos backend sérios, com autenticação completa, arquitetura limpa, segurança e observabilidade já configuradas. A ideia é você clonar, rodar `docker compose up` e já ter uma API pronta para evoluir.
|
|
13
|
+
|
|
14
|
+
## ✨ Features
|
|
15
|
+
|
|
16
|
+
- 🔐 **Autenticação configurável** — JWT com access/refresh token, Session/Cookies persistida com Drizzle, OAuth-only ou nenhuma autenticação
|
|
17
|
+
- 🌐 **OAuth** — Google e GitHub, integrado à estratégia de token ou sessão escolhida
|
|
18
|
+
- 👥 **RBAC** — Roles (Admin, Manager, User) e Permissions granulares
|
|
19
|
+
- 🛡️ **Segurança** — Helmet, CORS, Rate Limiting, validação e serialização com Zod
|
|
20
|
+
- 🗄️ **Banco de dados** — Drizzle ORM com PostgreSQL, MySQL ou SQLite
|
|
21
|
+
- 📨 **E-mails** — filas com BullMQ + Redis, testado localmente com Mailpit
|
|
22
|
+
- 📄 **Documentação automática** — Swagger
|
|
23
|
+
- 🪵 **Logs estruturados** — Pino
|
|
24
|
+
- ✅ **Testes** — unitários e de integração com Vitest
|
|
25
|
+
- 🐳 **Docker** — ambiente completo com um comando
|
|
26
|
+
- ⚙️ **CI/CD** — GitHub Actions (build, lint, test)
|
|
27
|
+
|
|
28
|
+
## 🧱 Stack
|
|
29
|
+
|
|
30
|
+
| Camada | Tecnologia |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Framework | NestJS + TypeScript |
|
|
33
|
+
| ORM / Query Builder | Drizzle ORM |
|
|
34
|
+
| Banco | PostgreSQL, MySQL ou SQLite |
|
|
35
|
+
| Cache / Filas | Redis + BullMQ |
|
|
36
|
+
| Autenticação | JWT, Session/Cookies ou OAuth com Passport |
|
|
37
|
+
| Validação | Zod + nestjs-zod (schemas viram DTO + Swagger automaticamente) |
|
|
38
|
+
| Docs | Swagger |
|
|
39
|
+
| E-mail (dev) | Mailpit |
|
|
40
|
+
| Testes | Vitest |
|
|
41
|
+
| CI | GitHub Actions |
|
|
42
|
+
|
|
43
|
+
## 📁 Estrutura de pastas
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
src/
|
|
47
|
+
│
|
|
48
|
+
├── auth/ # login, sessões/tokens, OAuth, guards e strategies
|
|
49
|
+
├── users/ # CRUD de usuários
|
|
50
|
+
├── common/ # decorators, filters, guards, interceptors, pipes, utils
|
|
51
|
+
├── config/ # configuração tipada e validada (env)
|
|
52
|
+
├── database/ # conexão Drizzle, schemas, configuração, migrations e seed
|
|
53
|
+
├── modules/ # módulos de domínio adicionais
|
|
54
|
+
├── shared/ # código compartilhado entre módulos
|
|
55
|
+
├── jobs/ # filas e workers (BullMQ)
|
|
56
|
+
├── mail/ # templates e envio de e-mail
|
|
57
|
+
└── main.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 🚀 Começando
|
|
61
|
+
|
|
62
|
+
### Pré-requisitos
|
|
63
|
+
|
|
64
|
+
- Node.js 20+
|
|
65
|
+
- Docker e Docker Compose
|
|
66
|
+
|
|
67
|
+
### Rodando com Docker (recomendado)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone https://github.com/jeiel2013/nestforge.git
|
|
71
|
+
cd nestforge
|
|
72
|
+
cp .env.example .env
|
|
73
|
+
docker compose up
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Isso sobe a API e os serviços escolhidos durante a geração, como PostgreSQL ou MySQL, Redis e Mailpit. Projetos SQLite não precisam de um container de banco.
|
|
77
|
+
|
|
78
|
+
### Rodando localmente
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install
|
|
82
|
+
cp .env.example .env
|
|
83
|
+
npm run migration:generate
|
|
84
|
+
npm run migration:migrate
|
|
85
|
+
npm run seed
|
|
86
|
+
npm run start:dev
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
O Drizzle Kit lê `drizzle.config.ts`, gera as migrations SQL em `drizzle/` e usa apenas o schema correspondente ao banco escolhido durante a geração do projeto.
|
|
90
|
+
|
|
91
|
+
A documentação Swagger fica disponível em `http://localhost:3000/docs`.
|
|
92
|
+
|
|
93
|
+
## 🗺️ Roadmap
|
|
94
|
+
|
|
95
|
+
- [x] Autenticação por JWT
|
|
96
|
+
- [x] Autenticação por Session/Cookies
|
|
97
|
+
- [x] OAuth Google/GitHub
|
|
98
|
+
- [x] Estratégia OAuth-only
|
|
99
|
+
- [x] Geração sem autenticação
|
|
100
|
+
- [x] Refresh Token
|
|
101
|
+
- [x] Docker
|
|
102
|
+
- [x] CI (build, lint, test)
|
|
103
|
+
- [x] OAuth (Google/GitHub)
|
|
104
|
+
- [x] Upload de arquivos
|
|
105
|
+
- [x] Filas (BullMQ)
|
|
106
|
+
- [x] E-mails transacionais
|
|
107
|
+
- [x] RBAC completo (permissions granulares)
|
|
108
|
+
- [x] Testes de integração completos
|
|
109
|
+
- [x] Documentação completa (Swagger + guia de arquitetura)
|
|
110
|
+
|
|
111
|
+
Veja o [ROADMAP.pt-BR.md](ROADMAP.pt-BR.md) detalhado.
|
|
112
|
+
|
|
113
|
+
### Configurando o login social (OAuth)
|
|
114
|
+
|
|
115
|
+
Para habilitar login via Google e GitHub, crie um OAuth App em cada provedor e preencha no `.env`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
APP_URL=http://localhost:3000
|
|
119
|
+
|
|
120
|
+
GOOGLE_CLIENT_ID=
|
|
121
|
+
GOOGLE_CLIENT_SECRET=
|
|
122
|
+
|
|
123
|
+
GITHUB_CLIENT_ID=
|
|
124
|
+
GITHUB_CLIENT_SECRET=
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- **Google**: crie as credenciais no [Google Cloud Console](https://console.cloud.google.com/apis/credentials) e configure a URL de callback como `{APP_URL}/auth/google/callback`.
|
|
128
|
+
- **GitHub**: crie um OAuth App em `Settings > Developer settings > OAuth Apps` e configure a mesma URL de callback, trocando para `{APP_URL}/auth/github/callback`.
|
|
129
|
+
|
|
130
|
+
Depois é só acessar `GET /auth/google` ou `GET /auth/github`. No callback, a API emite access/refresh tokens ou estabelece uma sessão por cookie, conforme a estratégia escolhida. Se for o primeiro acesso, uma conta é criada e vinculada ao provedor.
|
|
131
|
+
|
|
132
|
+
### Autenticação por Session/Cookies
|
|
133
|
+
|
|
134
|
+
Quando o projeto é gerado com Session/Cookies, cadastro e login criam uma sessão persistida na tabela `sessions`. O `DrizzleSessionStore` integra o `express-session` ao banco escolhido sem depender de stores específicos do Prisma ou TypeORM. O identificador é enviado no cookie `nestforge.sid`, configurado com `httpOnly`, `sameSite=lax` e `secure` em produção.
|
|
135
|
+
|
|
136
|
+
Configure no `.env`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
SESSION_SECRET=use-um-segredo-com-pelo-menos-32-caracteres
|
|
140
|
+
SESSION_MAX_AGE=604800000
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Recuperação de senha e verificação de e-mail
|
|
144
|
+
|
|
145
|
+
Todo cadastro (`POST /auth/register`) já dispara um e-mail de verificação automaticamente. Os e-mails são enfileirados com BullMQ/Redis e processados por um worker que envia via SMTP — em desenvolvimento, tudo cai no Mailpit (`http://localhost:8025`), então nada sai pra internet de verdade.
|
|
146
|
+
|
|
147
|
+
| Rota | O que faz |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `POST /auth/forgot-password` | Recebe um `email` e enfileira o envio do link de redefinição (resposta sempre genérica, não revela se o e-mail existe) |
|
|
150
|
+
| `POST /auth/reset-password` | Recebe `token` + `password` e troca a senha; também revoga os refresh tokens ativos do usuário |
|
|
151
|
+
| `GET /auth/verify-email?token=...` | Confirma o e-mail a partir do link recebido |
|
|
152
|
+
|
|
153
|
+
Os tokens de reset e verificação expiram em 1 hora e 24 horas, respectivamente, e são de uso único.
|
|
154
|
+
|
|
155
|
+
## 🔑 Roles & Permissions
|
|
156
|
+
|
|
157
|
+
| Role | Descrição |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `ADMIN` | acesso total ao sistema |
|
|
160
|
+
| `MANAGER` | gerencia usuários e relatórios |
|
|
161
|
+
| `USER` | acesso padrão |
|
|
162
|
+
|
|
163
|
+
Cada role tem um conjunto fixo de permissões, mapeado em `src/common/constants/role-permissions.ts`:
|
|
164
|
+
|
|
165
|
+
| Permission | ADMIN | MANAGER | USER |
|
|
166
|
+
|---|:---:|:---:|:---:|
|
|
167
|
+
| `user:create` | ✅ | ❌ | ❌ |
|
|
168
|
+
| `user:read` | ✅ | ✅ | ✅ |
|
|
169
|
+
| `user:update` | ✅ | ✅ | ❌ |
|
|
170
|
+
| `user:delete` | ✅ | ❌ | ❌ |
|
|
171
|
+
| `report:read` | ✅ | ✅ | ❌ |
|
|
172
|
+
|
|
173
|
+
Nas rotas, use `@Permissions(Permission.UserCreate)` para exigir uma permissão específica, ou `@Roles(Role.ADMIN)` quando o controle por cargo já for suficiente. Os dois guards (`RolesGuard` e `PermissionsGuard`) rodam globalmente e só bloqueiam a rota se ela tiver o decorator correspondente.
|
|
174
|
+
|
|
175
|
+
## 👥 Usuários: paginação, filtros e avatar
|
|
176
|
+
|
|
177
|
+
`GET /users` aceita query params pra paginar e filtrar a listagem:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
GET /users?page=2&limit=20&search=jeiel&role=ADMIN
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| Parâmetro | Descrição |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `page` | página atual (padrão: 1) |
|
|
186
|
+
| `limit` | itens por página, até 100 (padrão: 10) |
|
|
187
|
+
| `search` | busca por nome ou e-mail (case-insensitive) |
|
|
188
|
+
| `role` | filtra por `ADMIN`, `MANAGER` ou `USER` |
|
|
189
|
+
|
|
190
|
+
A resposta vem no formato `{ data, meta: { total, page, limit, totalPages } }`.
|
|
191
|
+
|
|
192
|
+
Pra trocar o avatar do usuário autenticado:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
curl -X POST http://localhost:3000/users/me/avatar \
|
|
196
|
+
-H "Authorization: Bearer <accessToken>" \
|
|
197
|
+
-F "file=@/caminho/da/foto.png"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Aceita PNG, JPEG e WEBP até 2MB; o arquivo fica salvo em `./uploads/avatars` e é servido em `/uploads/avatars/<arquivo>`.
|
|
201
|
+
|
|
202
|
+
## 🛡️ Segurança: serialização e CSRF
|
|
203
|
+
|
|
204
|
+
Toda validação de entrada (`body`, `query`) usa **Zod** via [`nestjs-zod`](https://github.com/BenLorantfy/nestjs-zod): cada DTO é um `z.object({...})` transformado em classe com `createZodDto(schema)`, validado globalmente pelo `ZodValidationPipe`. O `patchNestJsSwagger()` no bootstrap ensina o Swagger a ler esses schemas automaticamente — não precisa duplicar validação (Zod) e documentação (`@ApiProperty`) como no `class-validator`. Os schemas exportados (ex.: `createUserSchema`) também podem ser reaproveitados/combinados (como o `updateUserSchema`, que é só um `createUserSchema.partial()`).
|
|
205
|
+
|
|
206
|
+
- 🪵 **Observabilidade** — logs estruturados com Pino, health checks (`/health`) e métricas Prometheus (`/metrics`)
|
|
207
|
+
|
|
208
|
+
O seed cria três contas de teste, uma por role:
|
|
209
|
+
|
|
210
|
+
| E-mail | Senha | Role |
|
|
211
|
+
|---|---|---|
|
|
212
|
+
| `admin@nestforge.dev` | `admin123` | ADMIN |
|
|
213
|
+
| `manager@nestforge.dev` | `manager123` | MANAGER |
|
|
214
|
+
| `user@nestforge.dev` | `user1234` | USER |
|
|
215
|
+
|
|
216
|
+
## 📈 Observabilidade
|
|
217
|
+
|
|
218
|
+
`GET /health` retorna o status agregado da API — banco, Redis, memória (heap/RSS) e espaço em disco — usando `@nestjs/terminus`. O `DrizzleHealthIndicator` consulta o cliente nativo do banco selecionado e cada verificação aparece individualmente na resposta.
|
|
219
|
+
|
|
220
|
+
`GET /metrics` expõe métricas no formato do Prometheus (via `prom-client`): as métricas padrão de Node.js (CPU, memória, event loop) mais `http_request_duration_seconds` (histograma) e `http_requests_total` (contador), ambas com labels de `method`, `route` e `status_code`. Basta apontar um scrape job do Prometheus pra essa rota.
|
|
221
|
+
|
|
222
|
+
## 🧪 Testes
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npm run test # unitários
|
|
226
|
+
npm run test:e2e # integração (e2e)
|
|
227
|
+
npm run test:cov # cobertura
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Os testes e2e (`test/*.e2e-spec.ts`) sobem a aplicação real com NestJS e Drizzle e executam requisições com `supertest`, usando o banco isolado definido em `.env.test`. Antes da primeira execução, gere as migrations:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
npm run drizzle:generate
|
|
234
|
+
npm run test:e2e
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
O script `pretest:e2e` já aplica as migrations nesse banco automaticamente antes de cada rodada. Cada teste limpa as tabelas antes de rodar (`test/utils/clean-database.ts`), então não precisa zerar nada manualmente entre execuções. Hoje cobrem o fluxo de autenticação completo (registro, login, refresh, logout, e-mail duplicado, credenciais inválidas) e o CRUD de usuários com RBAC (ADMIN consegue tudo, USER lê mas não cria, `/users/me`, acesso sem token).
|
|
238
|
+
|
|
239
|
+
Os testes unitários (`src/**/*.spec.ts`) rodam isolados, com a instância do Drizzle e o `ioredis` simulados com `vi.fn()` e `vi.mock()`. Eles não dependem de banco ou Redis reais. A cobertura inclui `AuthService`, `UsersService`, `RolesGuard`, `PermissionsGuard`, `DrizzleHealthIndicator` e `RedisHealthIndicator`.
|
|
240
|
+
|
|
241
|
+
## 📚 Documentação adicional
|
|
242
|
+
|
|
243
|
+
- [ARCHITECTURE.pt-BR.md](ARCHITECTURE.pt-BR.md) — como o projeto é organizado e por que certas decisões de design foram tomadas (Zod vs. class-validator, permissions em código vs. banco, BullMQ, etc.)
|
|
244
|
+
- [TESTING.pt-BR.md](TESTING.pt-BR.md) — como validar migrations, build, testes unitários e testes E2E
|
|
245
|
+
- [docs/adding-a-module.md](docs/adding-a-module.md) — passo a passo pra adicionar um recurso novo seguindo as convenções do projeto
|
|
246
|
+
|
|
247
|
+
## 🤝 Contribuindo
|
|
248
|
+
|
|
249
|
+
Contribuições são bem-vindas! Veja o [CONTRIBUTING.pt-BR.md](CONTRIBUTING.pt-BR.md) para o guia completo.
|
|
250
|
+
|
|
251
|
+
## 📄 Licença
|
|
252
|
+
|
|
253
|
+
Este projeto está sob a licença MIT — veja [LICENSE](LICENSE).
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
Feito por [Jeiel Alves](https://github.com/jeiel2013) · [jeieldev.com.br](https://jeieldev.com.br)
|