@devstroupe/devkit-cli 1.0.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.
Files changed (170) hide show
  1. package/README.md +40 -0
  2. package/dist/boilerplates/angular-template/.dockerignore +4 -0
  3. package/dist/boilerplates/angular-template/.postcssrc.json +5 -0
  4. package/dist/boilerplates/angular-template/Dockerfile +14 -0
  5. package/dist/boilerplates/angular-template/angular.json +85 -0
  6. package/dist/boilerplates/angular-template/components.json +5 -0
  7. package/dist/boilerplates/angular-template/framework.code-workspace +7 -0
  8. package/dist/boilerplates/angular-template/nginx.conf +23 -0
  9. package/dist/boilerplates/angular-template/node_modules/.bin/browserslist +21 -0
  10. package/dist/boilerplates/angular-template/node_modules/.bin/jiti +21 -0
  11. package/dist/boilerplates/angular-template/node_modules/.bin/lessc +21 -0
  12. package/dist/boilerplates/angular-template/node_modules/.bin/ng +21 -0
  13. package/dist/boilerplates/angular-template/node_modules/.bin/ng-xi18n +21 -0
  14. package/dist/boilerplates/angular-template/node_modules/.bin/ngc +21 -0
  15. package/dist/boilerplates/angular-template/node_modules/.bin/sass +21 -0
  16. package/dist/boilerplates/angular-template/node_modules/.bin/terser +21 -0
  17. package/dist/boilerplates/angular-template/node_modules/.bin/tsc +21 -0
  18. package/dist/boilerplates/angular-template/node_modules/.bin/tsserver +21 -0
  19. package/dist/boilerplates/angular-template/node_modules/.bin/vite +21 -0
  20. package/dist/boilerplates/angular-template/node_modules/.bin/vitest +21 -0
  21. package/dist/boilerplates/angular-template/node_modules/.bin/yaml +21 -0
  22. package/dist/boilerplates/angular-template/package.json +47 -0
  23. package/dist/boilerplates/angular-template/postcss.config.js +5 -0
  24. package/dist/boilerplates/angular-template/proxy.conf.json +7 -0
  25. package/dist/boilerplates/angular-template/src/app/app.component.html +3 -0
  26. package/dist/boilerplates/angular-template/src/app/app.component.ts +12 -0
  27. package/dist/boilerplates/angular-template/src/app/app.config.ts +59 -0
  28. package/dist/boilerplates/angular-template/src/app/app.entity-routes.ts +4 -0
  29. package/dist/boilerplates/angular-template/src/app/app.routes.ts +25 -0
  30. package/dist/boilerplates/angular-template/src/app/core/guards/auth.guard.ts +16 -0
  31. package/dist/boilerplates/angular-template/src/app/core/services/auth.service.ts +98 -0
  32. package/dist/boilerplates/angular-template/src/app/modules/auth/login/login.component.html +51 -0
  33. package/dist/boilerplates/angular-template/src/app/modules/auth/login/login.component.ts +47 -0
  34. package/dist/boilerplates/angular-template/src/app/modules/auth/register/register.component.html +59 -0
  35. package/dist/boilerplates/angular-template/src/app/modules/auth/register/register.component.ts +47 -0
  36. package/dist/boilerplates/angular-template/src/app/modules/dashboard/dashboard.component.html +14 -0
  37. package/dist/boilerplates/angular-template/src/app/modules/dashboard/dashboard.component.ts +23 -0
  38. package/dist/boilerplates/angular-template/src/app/shared/interceptors/tenant.interceptor.ts +25 -0
  39. package/dist/boilerplates/angular-template/src/index.html +64 -0
  40. package/dist/boilerplates/angular-template/src/main.ts +6 -0
  41. package/dist/boilerplates/angular-template/src/styles.css +9 -0
  42. package/dist/boilerplates/angular-template/tsconfig.json +36 -0
  43. package/dist/boilerplates/nest-template/Dockerfile +16 -0
  44. package/dist/boilerplates/nest-template/node_modules/.bin/acorn +21 -0
  45. package/dist/boilerplates/nest-template/node_modules/.bin/nest +21 -0
  46. package/dist/boilerplates/nest-template/node_modules/.bin/prettier +21 -0
  47. package/dist/boilerplates/nest-template/node_modules/.bin/tsc +21 -0
  48. package/dist/boilerplates/nest-template/node_modules/.bin/tsserver +21 -0
  49. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm +21 -0
  50. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm-ts-node-commonjs +21 -0
  51. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm-ts-node-esm +21 -0
  52. package/dist/boilerplates/nest-template/node_modules/.bin/webpack +21 -0
  53. package/dist/boilerplates/nest-template/package.json +43 -0
  54. package/dist/boilerplates/nest-template/src/app.module.ts +24 -0
  55. package/dist/boilerplates/nest-template/src/database/data-source.ts +16 -0
  56. package/dist/boilerplates/nest-template/src/database/migrations/1700000000000-create-users.ts +26 -0
  57. package/dist/boilerplates/nest-template/src/main.ts +46 -0
  58. package/dist/boilerplates/nest-template/src/modules/auth/auth.controller.ts +34 -0
  59. package/dist/boilerplates/nest-template/src/modules/auth/auth.module.ts +22 -0
  60. package/dist/boilerplates/nest-template/src/modules/auth/auth.service.ts +57 -0
  61. package/dist/boilerplates/nest-template/src/modules/auth/current-user.decorator.ts +8 -0
  62. package/dist/boilerplates/nest-template/src/modules/auth/jwt-auth.guard.ts +31 -0
  63. package/dist/boilerplates/nest-template/src/modules/auth/roles.decorator.ts +4 -0
  64. package/dist/boilerplates/nest-template/src/modules/auth/roles.guard.ts +24 -0
  65. package/dist/boilerplates/nest-template/src/modules/user/database-seed.service.ts +47 -0
  66. package/dist/boilerplates/nest-template/src/modules/user/domain/user.repository.ts +9 -0
  67. package/dist/boilerplates/nest-template/src/modules/user/domain/user.ts +9 -0
  68. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.orm-entity.ts +31 -0
  69. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.repository.adapter.ts +53 -0
  70. package/dist/boilerplates/nest-template/src/modules/user/service/user.service.ts +44 -0
  71. package/dist/boilerplates/nest-template/src/modules/user/user.module.ts +20 -0
  72. package/dist/boilerplates/nest-template/tsconfig.build.json +4 -0
  73. package/dist/boilerplates/nest-template/tsconfig.json +21 -0
  74. package/dist/index.d.ts +2 -0
  75. package/dist/index.js +1967 -0
  76. package/dist/migrations/sort-entities.d.ts +2 -0
  77. package/dist/migrations/sort-entities.js +30 -0
  78. package/dist/rules/linter-rules.d.ts +12 -0
  79. package/dist/rules/linter-rules.js +338 -0
  80. package/dist/rules/linter-rules.test.d.ts +1 -0
  81. package/dist/rules/linter-rules.test.js +214 -0
  82. package/dist/templates/angular/dialog-handler.template.d.ts +2 -0
  83. package/dist/templates/angular/dialog-handler.template.js +49 -0
  84. package/dist/templates/angular/form.template.d.ts +3 -0
  85. package/dist/templates/angular/form.template.js +453 -0
  86. package/dist/templates/angular/index.d.ts +4 -0
  87. package/dist/templates/angular/index.js +20 -0
  88. package/dist/templates/angular/list.template.d.ts +3 -0
  89. package/dist/templates/angular/list.template.js +213 -0
  90. package/dist/templates/angular/service.template.d.ts +1 -0
  91. package/dist/templates/angular/service.template.js +20 -0
  92. package/dist/templates/cli-templates.d.ts +2 -0
  93. package/dist/templates/cli-templates.js +18 -0
  94. package/dist/templates/nest/crud.templates.d.ts +9 -0
  95. package/dist/templates/nest/crud.templates.js +362 -0
  96. package/dist/templates/nest/index.d.ts +3 -0
  97. package/dist/templates/nest/index.js +19 -0
  98. package/dist/templates/nest/microservice.templates.d.ts +4 -0
  99. package/dist/templates/nest/microservice.templates.js +157 -0
  100. package/dist/templates/nest/migration.template.d.ts +3 -0
  101. package/dist/templates/nest/migration.template.js +127 -0
  102. package/dist/templates/relationship-templates.test.d.ts +1 -0
  103. package/dist/templates/relationship-templates.test.js +181 -0
  104. package/dist/templates/shared/names.d.ts +3 -0
  105. package/dist/templates/shared/names.js +14 -0
  106. package/dist/templates/shared/relationships.d.ts +27 -0
  107. package/dist/templates/shared/relationships.js +96 -0
  108. package/dist/templates/ui/components/avatar.template.d.ts +3 -0
  109. package/dist/templates/ui/components/avatar.template.js +66 -0
  110. package/dist/templates/ui/components/badge.template.d.ts +3 -0
  111. package/dist/templates/ui/components/badge.template.js +27 -0
  112. package/dist/templates/ui/components/button.template.d.ts +5 -0
  113. package/dist/templates/ui/components/button.template.js +64 -0
  114. package/dist/templates/ui/components/card-list.template.d.ts +5 -0
  115. package/dist/templates/ui/components/card-list.template.js +79 -0
  116. package/dist/templates/ui/components/dialog.template.d.ts +5 -0
  117. package/dist/templates/ui/components/dialog.template.js +51 -0
  118. package/dist/templates/ui/components/filter.template.d.ts +4 -0
  119. package/dist/templates/ui/components/filter.template.js +218 -0
  120. package/dist/templates/ui/components/index.d.ts +10 -0
  121. package/dist/templates/ui/components/index.js +26 -0
  122. package/dist/templates/ui/components/input.template.d.ts +4 -0
  123. package/dist/templates/ui/components/input.template.js +76 -0
  124. package/dist/templates/ui/components/select.template.d.ts +4 -0
  125. package/dist/templates/ui/components/select.template.js +176 -0
  126. package/dist/templates/ui/components/simple-list.template.d.ts +5 -0
  127. package/dist/templates/ui/components/simple-list.template.js +89 -0
  128. package/dist/templates/ui/components/table.template.d.ts +5 -0
  129. package/dist/templates/ui/components/table.template.js +112 -0
  130. package/dist/templates/ui/index.d.ts +9 -0
  131. package/dist/templates/ui/index.js +25 -0
  132. package/dist/templates/ui/layout/header.template.d.ts +5 -0
  133. package/dist/templates/ui/layout/header.template.js +236 -0
  134. package/dist/templates/ui/layout/index.d.ts +4 -0
  135. package/dist/templates/ui/layout/index.js +20 -0
  136. package/dist/templates/ui/layout/main-layout.template.d.ts +5 -0
  137. package/dist/templates/ui/layout/main-layout.template.js +126 -0
  138. package/dist/templates/ui/layout/shell.template.d.ts +5 -0
  139. package/dist/templates/ui/layout/shell.template.js +76 -0
  140. package/dist/templates/ui/layout/sidebar.template.d.ts +5 -0
  141. package/dist/templates/ui/layout/sidebar.template.js +412 -0
  142. package/dist/templates/ui/playground.template.d.ts +5 -0
  143. package/dist/templates/ui/playground.template.js +570 -0
  144. package/dist/templates/ui/readme.template.d.ts +1 -0
  145. package/dist/templates/ui/readme.template.js +23 -0
  146. package/dist/templates/ui/shared/colors.d.ts +1 -0
  147. package/dist/templates/ui/shared/colors.js +31 -0
  148. package/dist/templates/ui/shared/profile-component.template.d.ts +5 -0
  149. package/dist/templates/ui/shared/profile-component.template.js +403 -0
  150. package/dist/templates/ui/shared/profile-service.template.d.ts +1 -0
  151. package/dist/templates/ui/shared/profile-service.template.js +44 -0
  152. package/dist/templates/ui/shared/theme-service.template.d.ts +1 -0
  153. package/dist/templates/ui/shared/theme-service.template.js +47 -0
  154. package/dist/templates/ui/spartan/badge-directive.template.d.ts +3 -0
  155. package/dist/templates/ui/spartan/badge-directive.template.js +50 -0
  156. package/dist/templates/ui/spartan/button-directive.template.d.ts +3 -0
  157. package/dist/templates/ui/spartan/button-directive.template.js +82 -0
  158. package/dist/templates/ui/spartan/button-token.template.d.ts +3 -0
  159. package/dist/templates/ui/spartan/button-token.template.js +31 -0
  160. package/dist/templates/ui/spartan/hlm-core.template.d.ts +3 -0
  161. package/dist/templates/ui/spartan/hlm-core.template.js +322 -0
  162. package/dist/templates/ui/spartan/index.d.ts +5 -0
  163. package/dist/templates/ui/spartan/index.js +21 -0
  164. package/dist/templates/ui/spartan/input-directive.template.d.ts +3 -0
  165. package/dist/templates/ui/spartan/input-directive.template.js +31 -0
  166. package/dist/templates/ui/theme-css.template.d.ts +7 -0
  167. package/dist/templates/ui/theme-css.template.js +210 -0
  168. package/dist/templates/ui-templates.d.ts +1 -0
  169. package/dist/templates/ui-templates.js +17 -0
  170. package/package.json +50 -0
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules/typeorm/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules/typeorm/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typeorm/cli.js" "$@"
19
+ else
20
+ exec node "$basedir/../typeorm/cli.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules/typeorm/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules/typeorm/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typeorm/cli-ts-node-commonjs.js" "$@"
19
+ else
20
+ exec node "$basedir/../typeorm/cli-ts-node-commonjs.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules/typeorm/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules/typeorm/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/typeorm@0.3.30_babel-plugin-macros@3.1.0_mysql2@3.22.5_@types+node@20.19.43_/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typeorm/cli-ts-node-esm.js" "$@"
19
+ else
20
+ exec node "$basedir/../typeorm/cli-ts-node-esm.js" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/webpack@5.106.2/node_modules/webpack/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/webpack@5.106.2/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/webpack@5.106.2/node_modules/webpack/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/webpack@5.106.2/node_modules:/home/vitor/trabalho/devstroupe/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/webpack@5.106.2/node_modules/webpack/bin/webpack.js" "$@"
19
+ else
20
+ exec node "$basedir/../../../../node_modules/.pnpm/webpack@5.106.2/node_modules/webpack/bin/webpack.js" "$@"
21
+ fi
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "devkit-nest-boilerplate",
3
+ "version": "1.0.0",
4
+ "description": "Boilerplate NestJS integrado ao DT-DevKit",
5
+ "private": true,
6
+ "scripts": {
7
+ "build": "nest build",
8
+ "format": "prettier --write \"src/**/*.ts\"",
9
+ "start": "nest start",
10
+ "start:dev": "nest start --watch",
11
+ "start:debug": "nest start --debug --watch",
12
+ "start:prod": "node dist/main",
13
+ "migration:run": "typeorm-ts-node-commonjs -d src/database/data-source.ts migration:run",
14
+ "migration:revert": "typeorm-ts-node-commonjs -d src/database/data-source.ts migration:revert",
15
+ "migration:generate": "typeorm-ts-node-commonjs -d src/database/data-source.ts migration:generate src/database/migrations/schema"
16
+ },
17
+ "dependencies": {
18
+ "@nestjs/common": "^11.0.0",
19
+ "@nestjs/core": "^11.0.0",
20
+ "@nestjs/platform-express": "^11.0.0",
21
+ "@nestjs/swagger": "^11.0.0",
22
+ "@nestjs/typeorm": "^11.0.0",
23
+ "@nestjs/jwt": "^11.0.0",
24
+ "@nestjs/microservices": "^11.0.0",
25
+ "typeorm": "^0.3.20",
26
+ "mysql2": "^3.9.0",
27
+ "reflect-metadata": "^0.2.0",
28
+ "rxjs": "^7.8.1",
29
+ "bcryptjs": "^2.4.3",
30
+ "dotenv": "^16.4.5",
31
+ "@devstroupe/devkit-core": "workspace:*",
32
+ "@devstroupe/devkit-nest": "workspace:*"
33
+ },
34
+ "devDependencies": {
35
+ "@nestjs/cli": "^11.0.0",
36
+ "@nestjs/schematics": "^11.0.0",
37
+ "@types/express": "^5.0.0",
38
+ "@types/node": "^20.11.0",
39
+ "@types/bcryptjs": "^2.4.6",
40
+ "typescript": "^5.4.5",
41
+ "ts-node": "^10.9.2"
42
+ }
43
+ }
@@ -0,0 +1,24 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { TypeOrmModule } from '@nestjs/typeorm';
3
+ import { UserModule } from './modules/user/user.module';
4
+ import { AuthModule } from './modules/auth/auth.module';
5
+
6
+ @Module({
7
+ imports: [
8
+ TypeOrmModule.forRoot({
9
+ type: 'mysql',
10
+ host: process.env.DB_HOST || 'localhost',
11
+ port: Number(process.env.DB_PORT) || 3306,
12
+ username: process.env.DB_USER || 'root',
13
+ password: process.env.DB_PASSWORD || 'root',
14
+ database: process.env.DB_NAME || 'devstroupe',
15
+ autoLoadEntities: true,
16
+ synchronize: false,
17
+ }),
18
+ UserModule,
19
+ AuthModule,
20
+ ],
21
+ controllers: [],
22
+ providers: [],
23
+ })
24
+ export class AppModule {}
@@ -0,0 +1,16 @@
1
+ import 'reflect-metadata';
2
+ import 'dotenv/config';
3
+ import { DataSource } from 'typeorm';
4
+ import * as path from 'path';
5
+
6
+ export default new DataSource({
7
+ type: 'mysql',
8
+ host: process.env.DB_HOST || 'localhost',
9
+ port: Number(process.env.DB_PORT) || 3306,
10
+ username: process.env.DB_USER || 'root',
11
+ password: process.env.DB_PASSWORD || 'root',
12
+ database: process.env.DB_NAME || 'devstroupe',
13
+ entities: [path.join(__dirname, '../modules/**/infra/database/*.orm-entity{.ts,.js}')],
14
+ migrations: [path.join(__dirname, './migrations/*{.ts,.js}')],
15
+ synchronize: false,
16
+ });
@@ -0,0 +1,26 @@
1
+ import { MigrationInterface, QueryRunner, Table } from 'typeorm';
2
+
3
+ export class CreateUsers1700000000000 implements MigrationInterface {
4
+ name = 'CreateUsers1700000000000';
5
+
6
+ async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.createTable(new Table({
8
+ name: 'users',
9
+ columns: [
10
+ { name: 'id', type: 'int', isPrimary: true, isGenerated: true, generationStrategy: 'increment' },
11
+ { name: 'name', type: 'varchar', length: '255' },
12
+ { name: 'email', type: 'varchar', length: '255', isUnique: true },
13
+ { name: 'password', type: 'varchar', length: '255' },
14
+ { name: 'role', type: 'varchar', length: '50', default: "'USER'" },
15
+ { name: 'tenant_id', type: 'varchar', length: '255', isNullable: true },
16
+ { name: 'is_active', type: 'boolean', default: "'1'" },
17
+ { name: 'created_at', type: 'datetime', default: 'CURRENT_TIMESTAMP' },
18
+ { name: 'updated_at', type: 'datetime', default: 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP' }
19
+ ]
20
+ }), true);
21
+ }
22
+
23
+ async down(queryRunner: QueryRunner): Promise<void> {
24
+ await queryRunner.dropTable('users', true);
25
+ }
26
+ }
@@ -0,0 +1,46 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ // Carrega variáveis do arquivo .env manualmente se ele existir
5
+ const envPath = path.resolve(process.cwd(), '.env');
6
+ if (fs.existsSync(envPath)) {
7
+ const envConfig = fs.readFileSync(envPath, 'utf-8');
8
+ envConfig.split('\n').forEach((line) => {
9
+ const trimmed = line.trim();
10
+ if (trimmed && !trimmed.startsWith('#')) {
11
+ const [key, ...values] = trimmed.split('=');
12
+ const val = values.join('=').trim();
13
+ if (key && val && process.env[key.trim()] === undefined) {
14
+ process.env[key.trim()] = val.replace(/^['"]|['"]$/g, '');
15
+ }
16
+ }
17
+ });
18
+ }
19
+
20
+ import { NestFactory } from '@nestjs/core';
21
+ import { AppModule } from './app.module';
22
+ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
23
+
24
+ async function bootstrap() {
25
+ const app = await NestFactory.create(AppModule);
26
+
27
+ // Prefixo de rota global
28
+ app.setGlobalPrefix('api');
29
+
30
+ // Habilitar CORS
31
+ app.enableCors();
32
+
33
+ // Documentação do Swagger
34
+ const config = new DocumentBuilder()
35
+ .setTitle('DevsTroupe API')
36
+ .setDescription('Documentação das APIs geradas pelo DT-DevKit')
37
+ .setVersion('1.0')
38
+ .build();
39
+ const document = SwaggerModule.createDocument(app, config);
40
+ SwaggerModule.setup('docs', app, document);
41
+
42
+ await app.listen(13000);
43
+ console.log('Backend NestJS iniciado com sucesso na porta 13000!');
44
+ console.log('Documentação Swagger disponível em: http://localhost:13000/docs');
45
+ }
46
+ bootstrap();
@@ -0,0 +1,34 @@
1
+ import { Controller, Post, Body, Get, UseGuards } from '@nestjs/common';
2
+ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
3
+ import { AuthService } from './auth.service';
4
+ import { JwtAuthGuard } from './jwt-auth.guard';
5
+ import { CurrentUser } from './current-user.decorator';
6
+
7
+ @ApiTags('auth')
8
+ @Controller('auth')
9
+ export class AuthController {
10
+ constructor(private readonly authService: AuthService) {}
11
+
12
+ @Post('login')
13
+ @ApiOperation({ summary: 'Login de usuário e emissão de JWT' })
14
+ @ApiResponse({ status: 200, description: 'Login efetuado com sucesso.' })
15
+ async login(@Body() body: any) {
16
+ return this.authService.login(body.email, body.password);
17
+ }
18
+
19
+ @Post('register')
20
+ @ApiOperation({ summary: 'Auto-cadastro de novos usuários' })
21
+ @ApiResponse({ status: 201, description: 'Usuário cadastrado com sucesso.' })
22
+ async register(@Body() body: any) {
23
+ return this.authService.register(body);
24
+ }
25
+
26
+ @Get('me')
27
+ @UseGuards(JwtAuthGuard)
28
+ @ApiBearerAuth()
29
+ @ApiOperation({ summary: 'Retorna os dados do usuário autenticado' })
30
+ @ApiResponse({ status: 200, description: 'Dados retornados com sucesso.' })
31
+ async getMe(@CurrentUser() user: any) {
32
+ return this.authService.validateUserById(user.sub);
33
+ }
34
+ }
@@ -0,0 +1,22 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { JwtModule } from '@nestjs/jwt';
3
+ import { UserModule } from '../user/user.module';
4
+ import { AuthService } from './auth.service';
5
+ import { AuthController } from './auth.controller';
6
+ import { JwtAuthGuard } from './jwt-auth.guard';
7
+ import { RolesGuard } from './roles.guard';
8
+
9
+ @Module({
10
+ imports: [
11
+ UserModule,
12
+ JwtModule.register({
13
+ global: true,
14
+ secret: process.env.JWT_SECRET || 'devstroupe-secret-key-12345',
15
+ signOptions: { expiresIn: '1d' },
16
+ }),
17
+ ],
18
+ providers: [AuthService, JwtAuthGuard, RolesGuard],
19
+ controllers: [AuthController],
20
+ exports: [AuthService, JwtAuthGuard, RolesGuard],
21
+ })
22
+ export class AuthModule {}
@@ -0,0 +1,57 @@
1
+ import { Injectable, UnauthorizedException } from '@nestjs/common';
2
+ import { JwtService } from '@nestjs/jwt';
3
+ import * as bcrypt from 'bcryptjs';
4
+ import { UserService } from '../user/service/user.service';
5
+ import { User } from '../user/domain/user';
6
+
7
+ @Injectable()
8
+ export class AuthService {
9
+ constructor(
10
+ private readonly userService: UserService,
11
+ private readonly jwtService: JwtService,
12
+ ) {}
13
+
14
+ async register(data: Omit<User, 'id' | 'role' | 'isActive'>): Promise<User> {
15
+ return this.userService.create({
16
+ ...data,
17
+ role: 'USER',
18
+ isActive: true,
19
+ });
20
+ }
21
+
22
+ async login(email: string, pass: string): Promise<{ accessToken: string; user: Omit<User, 'password'> }> {
23
+ const user = await this.userService.findByEmail(email);
24
+ if (!user) {
25
+ throw new UnauthorizedException('Invalid credentials');
26
+ }
27
+
28
+ const isMatch = await bcrypt.compare(pass, user.password);
29
+ if (!isMatch) {
30
+ throw new UnauthorizedException('Invalid credentials');
31
+ }
32
+
33
+ if (!user.isActive) {
34
+ throw new UnauthorizedException('User is inactive');
35
+ }
36
+
37
+ const payload = {
38
+ sub: user.id,
39
+ email: user.email,
40
+ role: user.role,
41
+ tenantId: user.tenantId
42
+ };
43
+
44
+ const { password, ...result } = user;
45
+ return {
46
+ accessToken: await this.jwtService.signAsync(payload),
47
+ user: result,
48
+ };
49
+ }
50
+
51
+ async validateUserById(id: number): Promise<Omit<User, 'password'> | null> {
52
+ const user = await this.userService.findById(id);
53
+ if (!user) return null;
54
+ const { password, ...result } = user;
55
+ return result;
56
+ }
57
+ }
@@ -0,0 +1,8 @@
1
+ import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2
+
3
+ export const CurrentUser = createParamDecorator(
4
+ (data: unknown, ctx: ExecutionContext) => {
5
+ const request = ctx.switchToHttp().getRequest();
6
+ return request.user;
7
+ },
8
+ );
@@ -0,0 +1,31 @@
1
+ import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
2
+ import { JwtService } from '@nestjs/jwt';
3
+ import { Request } from 'express';
4
+
5
+ @Injectable()
6
+ export class JwtAuthGuard implements CanActivate {
7
+ constructor(private readonly jwtService: JwtService) {}
8
+
9
+ async canActivate(context: ExecutionContext): Promise<boolean> {
10
+ const request = context.switchToHttp().getRequest<Request>();
11
+ const token = this.extractTokenFromHeader(request);
12
+ if (!token) {
13
+ throw new UnauthorizedException('Token not found');
14
+ }
15
+ try {
16
+ const payload = await this.jwtService.verifyAsync(token, {
17
+ secret: process.env.JWT_SECRET || 'devstroupe-secret-key-12345',
18
+ });
19
+ // Injeta o payload decodificado (contendo sub, email, role, tenantId) na request
20
+ request['user'] = payload;
21
+ } catch {
22
+ throw new UnauthorizedException('Invalid or expired token');
23
+ }
24
+ return true;
25
+ }
26
+
27
+ private extractTokenFromHeader(request: Request): string | undefined {
28
+ const [type, token] = request.headers.authorization?.split(' ') ?? [];
29
+ return type === 'Bearer' ? token : undefined;
30
+ }
31
+ }
@@ -0,0 +1,4 @@
1
+ import { SetMetadata } from '@nestjs/common';
2
+
3
+ export const ROLES_KEY = 'roles';
4
+ export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);
@@ -0,0 +1,24 @@
1
+ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { ROLES_KEY } from './roles.decorator';
4
+
5
+ @Injectable()
6
+ export class RolesGuard implements CanActivate {
7
+ constructor(private readonly reflector: Reflector) {}
8
+
9
+ canActivate(context: ExecutionContext): boolean {
10
+ const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
11
+ context.getHandler(),
12
+ context.getClass(),
13
+ ]);
14
+ if (!requiredRoles) {
15
+ return true;
16
+ }
17
+ const request = context.switchToHttp().getRequest();
18
+ const user = request.user;
19
+ if (!user || !user.role) {
20
+ return false;
21
+ }
22
+ return requiredRoles.includes(user.role);
23
+ }
24
+ }
@@ -0,0 +1,47 @@
1
+ import { Injectable, OnApplicationBootstrap, Logger } from '@nestjs/common';
2
+ import { UserService } from './service/user.service';
3
+
4
+ @Injectable()
5
+ export class DatabaseSeedService implements OnApplicationBootstrap {
6
+ private readonly logger = new Logger(DatabaseSeedService.name);
7
+
8
+ constructor(private readonly userService: UserService) {}
9
+
10
+ async onApplicationBootstrap() {
11
+ await this.seedUsers();
12
+ }
13
+
14
+ private async seedUsers() {
15
+ try {
16
+ const adminEmail = 'admin@devstroupe.com';
17
+ const existingAdmin = await this.userService.findByEmail(adminEmail);
18
+ if (!existingAdmin) {
19
+ this.logger.log('Semente: Criando usuário administrador padrão...');
20
+ await this.userService.create({
21
+ name: 'Administrador DevsTroupe',
22
+ email: adminEmail,
23
+ password: 'adminpassword123',
24
+ role: 'ADMIN',
25
+ isActive: true,
26
+ });
27
+ this.logger.log('Semente: Usuário administrador cadastrado com sucesso!');
28
+ }
29
+
30
+ const userEmail = 'user@devstroupe.com';
31
+ const existingUser = await this.userService.findByEmail(userEmail);
32
+ if (!existingUser) {
33
+ this.logger.log('Semente: Criando usuário comum padrão...');
34
+ await this.userService.create({
35
+ name: 'Usuário Comum',
36
+ email: userEmail,
37
+ password: 'userpassword123',
38
+ role: 'USER',
39
+ isActive: true,
40
+ });
41
+ this.logger.log('Semente: Usuário comum cadastrado com sucesso!');
42
+ }
43
+ } catch (error) {
44
+ this.logger.error('Erro durante a execução do seeding de usuários:', error);
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,9 @@
1
+ import { User } from './user';
2
+
3
+ export interface IUserRepository {
4
+ create(user: Omit<User, 'id'>): Promise<User>;
5
+ update(id: number, user: Partial<User>): Promise<User>;
6
+ findById(id: number): Promise<User | null>;
7
+ findByEmail(email: string): Promise<User | null>;
8
+ delete(id: number): Promise<void>;
9
+ }
@@ -0,0 +1,9 @@
1
+ export class User {
2
+ id!: number;
3
+ name!: string;
4
+ email!: string;
5
+ password!: string;
6
+ role!: 'ADMIN' | 'USER';
7
+ tenantId?: string;
8
+ isActive!: boolean;
9
+ }
@@ -0,0 +1,31 @@
1
+ import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
2
+
3
+ @Entity('users')
4
+ export class UserOrmEntity {
5
+ @PrimaryGeneratedColumn()
6
+ id!: number;
7
+
8
+ @Column({ type: 'varchar', length: 255 })
9
+ name!: string;
10
+
11
+ @Column({ type: 'varchar', length: 255, unique: true })
12
+ email!: string;
13
+
14
+ @Column({ type: 'varchar', length: 255 })
15
+ password!: string;
16
+
17
+ @Column({ type: 'varchar', length: 50, default: 'USER' })
18
+ role!: 'ADMIN' | 'USER';
19
+
20
+ @Column({ type: 'varchar', length: 255, nullable: true, name: 'tenant_id' })
21
+ tenantId?: string;
22
+
23
+ @Column({ type: 'boolean', default: true, name: 'is_active' })
24
+ isActive!: boolean;
25
+
26
+ @CreateDateColumn({ name: 'created_at' })
27
+ createdAt!: Date;
28
+
29
+ @UpdateDateColumn({ name: 'updated_at' })
30
+ updatedAt!: Date;
31
+ }
@@ -0,0 +1,53 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectRepository } from '@nestjs/typeorm';
3
+ import { Repository } from 'typeorm';
4
+ import { IUserRepository } from '../../domain/user.repository';
5
+ import { User } from '../../domain/user';
6
+ import { UserOrmEntity } from './user.orm-entity';
7
+
8
+ @Injectable()
9
+ export class UserRepositoryAdapter implements IUserRepository {
10
+ constructor(
11
+ @InjectRepository(UserOrmEntity)
12
+ private readonly repo: Repository<UserOrmEntity>,
13
+ ) {}
14
+
15
+ private toDomain(orm: UserOrmEntity): User {
16
+ return {
17
+ id: orm.id,
18
+ name: orm.name,
19
+ email: orm.email,
20
+ password: orm.password,
21
+ role: orm.role,
22
+ tenantId: orm.tenantId,
23
+ isActive: orm.isActive,
24
+ };
25
+ }
26
+
27
+ async create(user: Omit<User, 'id'>): Promise<User> {
28
+ const created = this.repo.create(user);
29
+ const saved = await this.repo.save(created);
30
+ return this.toDomain(saved);
31
+ }
32
+
33
+ async update(id: number, user: Partial<User>): Promise<User> {
34
+ await this.repo.update(id, user);
35
+ const updated = await this.findById(id);
36
+ if (!updated) throw new Error('User not found after update');
37
+ return updated;
38
+ }
39
+
40
+ async findById(id: number): Promise<User | null> {
41
+ const found = await this.repo.findOne({ where: { id } });
42
+ return found ? this.toDomain(found) : null;
43
+ }
44
+
45
+ async findByEmail(email: string): Promise<User | null> {
46
+ const found = await this.repo.findOne({ where: { email } });
47
+ return found ? this.toDomain(found) : null;
48
+ }
49
+
50
+ async delete(id: number): Promise<void> {
51
+ await this.repo.delete(id);
52
+ }
53
+ }
@@ -0,0 +1,44 @@
1
+ import { Injectable, Inject } from '@nestjs/common';
2
+ import * as bcrypt from 'bcryptjs';
3
+ import { IUserRepository } from '../domain/user.repository';
4
+ import { User } from '../domain/user';
5
+
6
+ @Injectable()
7
+ export class UserService {
8
+ constructor(
9
+ @Inject('IUserRepository')
10
+ private readonly userRepo: IUserRepository,
11
+ ) {}
12
+
13
+ async create(user: Omit<User, 'id'>): Promise<User> {
14
+ const existing = await this.userRepo.findByEmail(user.email);
15
+ if (existing) {
16
+ throw new Error('Email already registered');
17
+ }
18
+
19
+ const hashedPassword = await bcrypt.hash(user.password, 10);
20
+ return this.userRepo.create({
21
+ ...user,
22
+ password: hashedPassword,
23
+ });
24
+ }
25
+
26
+ async findById(id: number): Promise<User | null> {
27
+ return this.userRepo.findById(id);
28
+ }
29
+
30
+ async findByEmail(email: string): Promise<User | null> {
31
+ return this.userRepo.findByEmail(email);
32
+ }
33
+
34
+ async update(id: number, user: Partial<User>): Promise<User> {
35
+ if (user.password) {
36
+ user.password = await bcrypt.hash(user.password, 10);
37
+ }
38
+ return this.userRepo.update(id, user);
39
+ }
40
+
41
+ async delete(id: number): Promise<void> {
42
+ await this.userRepo.delete(id);
43
+ }
44
+ }
@@ -0,0 +1,20 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { TypeOrmModule } from '@nestjs/typeorm';
3
+ import { UserOrmEntity } from './infra/database/user.orm-entity';
4
+ import { UserRepositoryAdapter } from './infra/database/user.repository.adapter';
5
+ import { UserService } from './service/user.service';
6
+ import { DatabaseSeedService } from './database-seed.service';
7
+
8
+ @Module({
9
+ imports: [TypeOrmModule.forFeature([UserOrmEntity])],
10
+ providers: [
11
+ UserService,
12
+ DatabaseSeedService,
13
+ {
14
+ provide: 'IUserRepository',
15
+ useClass: UserRepositoryAdapter,
16
+ },
17
+ ],
18
+ exports: [UserService],
19
+ })
20
+ export class UserModule {}