kybernus 3.0.0 → 3.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.
Files changed (110) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -2
  3. package/templates/java-spring/clean/.gitignore.hbs +72 -0
  4. package/templates/java-spring/clean/docker-compose.yml.hbs +6 -3
  5. package/templates/java-spring/clean/src/main/java/{{packagePath}}/application/usecase/PaymentUseCase.java.hbs +21 -17
  6. package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/persistence/entity/UserEntity.java.hbs +52 -0
  7. package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/persistence/repository/JpaUserRepository.java.hbs +12 -0
  8. package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/security/JwtAuthenticationFilter.java.hbs +64 -0
  9. package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/security/SecurityConfig.java.hbs +36 -0
  10. package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/stripe/StripeGateway.java.hbs +63 -0
  11. package/templates/java-spring/clean/src/main/resources/application.properties.hbs +6 -7
  12. package/templates/java-spring/hexagonal/.gitignore.hbs +72 -0
  13. package/templates/java-spring/hexagonal/docker-compose.yml.hbs +6 -3
  14. package/templates/java-spring/hexagonal/src/main/java/{{packagePath}}/adapters/outbound/security/JwtFilter.java.hbs +71 -0
  15. package/templates/java-spring/hexagonal/src/main/java/{{packagePath}}/adapters/outbound/security/SecurityConfig.java.hbs +35 -0
  16. package/templates/java-spring/hexagonal/src/main/java/{{packagePath}}/core/service/PaymentService.java.hbs +3 -3
  17. package/templates/java-spring/hexagonal/src/main/resources/application.properties.hbs +4 -4
  18. package/templates/java-spring/mvc/.gitignore.hbs +72 -0
  19. package/templates/java-spring/mvc/docker-compose.yml.hbs +6 -3
  20. package/templates/java-spring/mvc/src/main/java/{{packagePath}}/config/SecurityConfig.java.hbs +13 -12
  21. package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/AuthController.java.hbs +9 -8
  22. package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/PaymentsController.java.hbs +5 -6
  23. package/templates/java-spring/mvc/src/main/java/{{packagePath}}/service/StripeService.java.hbs +3 -3
  24. package/templates/java-spring/mvc/src/main/resources/application.yml.hbs +29 -26
  25. package/templates/nestjs/clean/.gitignore.hbs +42 -0
  26. package/templates/nestjs/clean/Dockerfile.hbs +6 -3
  27. package/templates/nestjs/clean/docker-compose.yml.hbs +1 -11
  28. package/templates/nestjs/clean/package.json.hbs +51 -41
  29. package/templates/nestjs/clean/src/app.module.ts.hbs +2 -1
  30. package/templates/nestjs/clean/src/application/payment.service.ts.hbs +72 -72
  31. package/templates/nestjs/clean/src/domain/entities/user.entity.ts.hbs +2 -2
  32. package/templates/nestjs/clean/src/domain/repositories/user.repository.ts.hbs +2 -2
  33. package/templates/nestjs/clean/src/infrastructure/database/repositories/prisma.user.repository.ts.hbs +18 -18
  34. package/templates/nestjs/clean/src/infrastructure/http/health.controller.ts.hbs +9 -0
  35. package/templates/nestjs/clean/src/main.ts.hbs +1 -4
  36. package/templates/nestjs/clean/src/payment.module.ts.hbs +12 -12
  37. package/templates/nestjs/hexagonal/.gitignore.hbs +42 -0
  38. package/templates/nestjs/hexagonal/Dockerfile.hbs +6 -3
  39. package/templates/nestjs/hexagonal/docker-compose.yml.hbs +1 -11
  40. package/templates/nestjs/hexagonal/package.json.hbs +51 -41
  41. package/templates/nestjs/hexagonal/src/adapters/inbound/health.controller.ts.hbs +9 -0
  42. package/templates/nestjs/hexagonal/src/app.module.ts.hbs +2 -1
  43. package/templates/nestjs/hexagonal/src/core/domain/user.entity.ts.hbs +6 -6
  44. package/templates/nestjs/hexagonal/src/core/ports/ports.ts.hbs +4 -4
  45. package/templates/nestjs/hexagonal/src/main.ts.hbs +1 -4
  46. package/templates/nestjs/mvc/.gitignore.hbs +42 -0
  47. package/templates/nestjs/mvc/Dockerfile.hbs +6 -3
  48. package/templates/nestjs/mvc/docker-compose.yml.hbs +1 -11
  49. package/templates/nestjs/mvc/package.json.hbs +49 -39
  50. package/templates/nestjs/mvc/src/auth/auth.controller.ts.hbs +11 -1
  51. package/templates/nestjs/mvc/src/auth/auth.service.ts.hbs +3 -1
  52. package/templates/nestjs/mvc/src/controllers/health.controller.ts.hbs +6 -6
  53. package/templates/nestjs/mvc/src/main.ts.hbs +1 -4
  54. package/templates/nestjs/mvc/src/models/create-item.dto.ts.hbs +5 -2
  55. package/templates/nestjs/mvc/src/prisma/prisma.service.ts.hbs +1 -0
  56. package/templates/nextjs/mvc/.gitignore.hbs +42 -0
  57. package/templates/nextjs/mvc/Dockerfile.hbs +23 -8
  58. package/templates/nextjs/mvc/docker-compose.yml.hbs +1 -1
  59. package/templates/nextjs/mvc/package.json.hbs +46 -36
  60. package/templates/nodejs-express/clean/.gitignore.hbs +42 -0
  61. package/templates/nodejs-express/clean/Dockerfile.hbs +6 -1
  62. package/templates/nodejs-express/clean/docker-compose.yml.hbs +2 -2
  63. package/templates/nodejs-express/clean/package.json.hbs +12 -2
  64. package/templates/nodejs-express/clean/src/config.ts.hbs +11 -0
  65. package/templates/nodejs-express/clean/src/domain/entities/User.ts.hbs +46 -8
  66. package/templates/nodejs-express/hexagonal/.gitignore.hbs +42 -0
  67. package/templates/nodejs-express/hexagonal/Dockerfile.hbs +1 -1
  68. package/templates/nodejs-express/hexagonal/docker-compose.yml.hbs +2 -2
  69. package/templates/nodejs-express/hexagonal/package.json.hbs +12 -2
  70. package/templates/nodejs-express/hexagonal/src/adapters/inbound/http/PaymentController.ts.hbs +21 -38
  71. package/templates/nodejs-express/hexagonal/src/adapters/outbound/persistence/prisma.ts.hbs +2 -0
  72. package/templates/nodejs-express/hexagonal/src/config.ts.hbs +9 -0
  73. package/templates/nodejs-express/hexagonal/src/core/AuthService.ts.hbs +5 -5
  74. package/templates/nodejs-express/hexagonal/src/core/PaymentService.ts.hbs +7 -22
  75. package/templates/nodejs-express/hexagonal/src/core/domain/entities/User.ts.hbs +24 -4
  76. package/templates/nodejs-express/mvc/.gitignore.hbs +42 -0
  77. package/templates/nodejs-express/mvc/package.json.hbs +12 -2
  78. package/templates/python-fastapi/clean/.gitignore.hbs +76 -0
  79. package/templates/python-fastapi/clean/app/application/services/payment_service.py.hbs +3 -3
  80. package/templates/python-fastapi/clean/app/config.py.hbs +6 -7
  81. package/templates/python-fastapi/clean/app/domain/usecases/login_user.py.hbs +15 -0
  82. package/templates/python-fastapi/clean/app/infrastructure/http/auth_controller.py.hbs +40 -6
  83. package/templates/python-fastapi/clean/app/infrastructure/http/payment_controller.py.hbs +5 -4
  84. package/templates/python-fastapi/clean/app/infrastructure/security/jwt.py.hbs +23 -0
  85. package/templates/python-fastapi/clean/app/main.py.hbs +3 -0
  86. package/templates/python-fastapi/clean/docker-compose.yml.hbs +5 -12
  87. package/templates/python-fastapi/clean/requirements.txt.hbs +3 -0
  88. package/templates/python-fastapi/hexagonal/.gitignore.hbs +76 -0
  89. package/templates/python-fastapi/hexagonal/app/adapters/inbound/http_adapter.py.hbs +6 -9
  90. package/templates/python-fastapi/hexagonal/app/adapters/inbound/payment_http_adapter.py.hbs +4 -3
  91. package/templates/python-fastapi/hexagonal/app/adapters/outbound/stripe_adapter.py.hbs +30 -19
  92. package/templates/python-fastapi/hexagonal/app/config.py.hbs +14 -4
  93. package/templates/python-fastapi/hexagonal/app/core/domain/user.py.hbs +3 -1
  94. package/templates/python-fastapi/hexagonal/app/core/payment_service.py.hbs +28 -18
  95. package/templates/python-fastapi/hexagonal/app/core/ports/__init__.py.hbs +3 -0
  96. package/templates/python-fastapi/hexagonal/app/core/ports/user_repository.py.hbs +15 -0
  97. package/templates/python-fastapi/hexagonal/app/infrastructure/database/session.py.hbs +7 -0
  98. package/templates/python-fastapi/hexagonal/app/infrastructure/database/user_repository.py.hbs +53 -0
  99. package/templates/python-fastapi/hexagonal/app/infrastructure/security/__init__.py.hbs +0 -0
  100. package/templates/python-fastapi/hexagonal/app/infrastructure/security/adapters.py.hbs +23 -0
  101. package/templates/python-fastapi/hexagonal/app/infrastructure/security/jwt.py.hbs +23 -0
  102. package/templates/python-fastapi/hexagonal/docker-compose.yml.hbs +5 -12
  103. package/templates/python-fastapi/hexagonal/requirements.txt.hbs +4 -0
  104. package/templates/python-fastapi/mvc/.gitignore.hbs +76 -0
  105. package/templates/python-fastapi/mvc/app/controllers/payments.py.hbs +3 -17
  106. package/templates/python-fastapi/mvc/app/middleware/security.py.hbs +24 -3
  107. package/templates/python-fastapi/mvc/app/schemas/item.py.hbs +3 -1
  108. package/templates/python-fastapi/mvc/docker-compose.yml.hbs +5 -12
  109. package/templates/python-fastapi/mvc/requirements.txt.hbs +3 -1
  110. package/templates/nodejs-express/hexagonal/src/adapters/outbound/persistence/prisma.ts +0 -5
@@ -1,41 +1,51 @@
1
1
  {
2
- "name": "{{kebabCase projectName}}",
3
- "version": "1.0.0",
4
- "description": "Generated by Kybernus CLI (Pro)",
5
- "scripts": {
6
- "dev": "nest start --watch",
7
- "build": "nest build",
8
- "start": "node dist/main.js",
9
- "lint": "eslint \"{src,test}/**/*.ts\"",
10
- "test": "jest",
11
- "db:generate": "prisma generate",
12
- "db:push": "prisma db push"
13
- },
14
- "dependencies": {
15
- "@nestjs/common": "^10.3.0",
16
- "@nestjs/core": "^10.3.0",
17
- "@nestjs/config": "^3.1.1",
18
- "@nestjs/jwt": "^10.2.0",
19
- "@nestjs/passport": "^10.0.3",
20
- "@nestjs/platform-express": "^10.3.0",
21
- "@prisma/client": "^5.10.2",
22
- "bcryptjs": "^2.4.3",
23
- "class-transformer": "^0.5.1",
24
- "class-validator": "^0.14.1",
25
- "passport": "^0.7.0",
26
- "passport-jwt": "^4.0.1",
27
- "reflect-metadata": "^0.2.1",
28
- "rxjs": "^7.8.1",
29
- "stripe": "^14.14.0",
30
- "uuid": "^9.0.1"
31
- },
32
- "devDependencies": {
33
- "@nestjs/cli": "^10.3.0",
34
- "@types/bcryptjs": "^2.4.6",
35
- "@types/node": "^20.11.0",
36
- "@types/passport-jwt": "^4.0.0",
37
- "@types/uuid": "^9.0.7",
38
- "prisma": "^5.10.2",
39
- "typescript": "^5.3.3"
40
- }
2
+ "name": "{{kebabCase projectName}}",
3
+ "version": "1.0.0",
4
+ "description": "Generated by Kybernus CLI (Pro)",
5
+ "scripts": {
6
+ "dev": "nest start --watch",
7
+ "build": "nest build",
8
+ "start": "node dist/main.js",
9
+ "lint": "eslint \"{src,test}/**/*.ts\"",
10
+ "test": "jest",
11
+ "db:generate": "prisma generate",
12
+ "db:push": "prisma db push"
13
+ },
14
+ "dependencies": {
15
+ "@nestjs/common": "^10.3.0",
16
+ "@nestjs/core": "^10.3.0",
17
+ "@nestjs/config": "^3.1.1",
18
+ "@nestjs/jwt": "^10.2.0",
19
+ "@nestjs/passport": "^10.0.3",
20
+ "@nestjs/platform-express": "^10.3.0",
21
+ "@prisma/client": "^5.10.2",
22
+ "bcryptjs": "^2.4.3",
23
+ "class-transformer": "^0.5.1",
24
+ "class-validator": "^0.14.1",
25
+ "passport": "^0.7.0",
26
+ "passport-jwt": "^4.0.1",
27
+ "reflect-metadata": "^0.2.1",
28
+ "rxjs": "^7.8.1",
29
+ "stripe": "^14.14.0",
30
+ "uuid": "^9.0.1"
31
+ },
32
+ "devDependencies": {
33
+ "@nestjs/cli": "^10.3.0",
34
+ "@types/bcryptjs": "^2.4.6",
35
+ "@types/node": "^20.11.0",
36
+ "@types/passport-jwt": "^4.0.0",
37
+ "@types/uuid": "^9.0.7",
38
+ "prisma": "^5.10.2",
39
+ "typescript": "^5.3.3"
40
+ },
41
+ "overrides": {
42
+ "rimraf": "^6.1.2",
43
+ "glob": "^11.0.0",
44
+ "inflight": "^1.0.6",
45
+ "@humanwhocodes/config-array": "^0.13.0",
46
+ "@humanwhocodes/object-schema": "^2.0.3",
47
+ "eslint": "^9.16.0",
48
+ "cookie": "^0.7.2",
49
+ "minimatch": "^9.0.8"
41
50
  }
51
+ }
@@ -1,15 +1,25 @@
1
1
  import { Controller, Post, Body, Get, UseGuards, Request } from '@nestjs/common';
2
2
  import { AuthGuard } from '@nestjs/passport';
3
3
  import { AuthService } from './auth.service';
4
+ import { IsEmail, IsString, MinLength } from 'class-validator';
4
5
 
5
6
  class RegisterDto {
7
+ @IsEmail()
6
8
  email: string;
9
+
10
+ @IsString()
7
11
  name: string;
12
+
13
+ @IsString()
14
+ @MinLength(6)
8
15
  password: string;
9
16
  }
10
17
 
11
18
  class LoginDto {
19
+ @IsEmail()
12
20
  email: string;
21
+
22
+ @IsString()
13
23
  password: string;
14
24
  }
15
25
 
@@ -32,4 +42,4 @@ export class AuthController {
32
42
  async me(@Request() req: any) {
33
43
  return { user: req.user };
34
44
  }
35
- }
45
+ }
@@ -39,7 +39,7 @@ export class AuthService {
39
39
  where: { email },
40
40
  });
41
41
 
42
- if (users || !(await bcrypt.compare(password, user.password))) {
42
+ if (!user || !(await bcrypt.compare(password, user.password))) {
43
43
  throw new UnauthorizedException('Invalid credentials');
44
44
  }
45
45
 
@@ -53,6 +53,8 @@ export class AuthService {
53
53
  select: { id: true, email: true, name: true }
54
54
  });
55
55
 
56
+ if (!user) return null;
57
+
56
58
  return user;
57
59
  }
58
60
  }
@@ -1,9 +1,9 @@
1
1
  import { Controller, Get } from '@nestjs/common';
2
2
 
3
- @Controller()
3
+ @Controller('health')
4
4
  export class HealthController {
5
- @Get('health')
6
- health() {
7
- return { status: 'ok' };
8
- }
9
- }
5
+ @Get()
6
+ check() {
7
+ return { status: 'ok' };
8
+ }
9
+ }
@@ -3,10 +3,7 @@ import { AppModule } from './app.module';
3
3
  import { ValidationPipe } from '@nestjs/common';
4
4
 
5
5
  async function bootstrap() {
6
- const app = await NestFactory.create(AppModule, {
7
- // rawBody is required so that the Stripe webhook can verify the signature
8
- rawBody: true,
9
- });
6
+ const app = await NestFactory.create(AppModule);
10
7
 
11
8
  app.enableCors();
12
9
  app.setGlobalPrefix('api');
@@ -1,4 +1,4 @@
1
- import { IsString, IsOptional } from 'class-validator';
1
+ import { IsString, IsOptional, IsNumber } from 'class-validator';
2
2
 
3
3
  export class CreateItemDto {
4
4
  @IsString()
@@ -7,4 +7,7 @@ export class CreateItemDto {
7
7
  @IsString()
8
8
  @IsOptional()
9
9
  description?: string;
10
- }
10
+
11
+ @IsNumber()
12
+ price: number;
13
+ }
@@ -8,6 +8,7 @@ export class PrismaService extends PrismaClient implements OnModuleInit {
8
8
  }
9
9
 
10
10
  async enableShutdownHooks(app: INestApplication) {
11
+ // @ts-ignore
11
12
  this.$on('beforeExit', async () => {
12
13
  await app.close();
13
14
  });
@@ -0,0 +1,42 @@
1
+ # Dependencies
2
+ node_modules/
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # Build outputs
7
+ dist/
8
+ build/
9
+
10
+ # Environment variables
11
+ .env
12
+ .env.local
13
+ .env.development.local
14
+ .env.test.local
15
+ .env.production.local
16
+ !.env.example
17
+
18
+ # Logs
19
+ logs/
20
+ *.log
21
+ npm-debug.log*
22
+ yarn-debug.log*
23
+ yarn-error.log*
24
+ pnpm-debug.log*
25
+ lerna-debug.log*
26
+
27
+ # Coverage
28
+ coverage/
29
+ .nyc_output
30
+
31
+ # TypeScript
32
+ *.tsbuildinfo
33
+
34
+ # OS
35
+ .DS_Store
36
+ Thumbs.db
37
+
38
+ # Editor
39
+ .vscode/
40
+ .idea/
41
+ *.swp
42
+ *.swo
@@ -7,14 +7,18 @@ WORKDIR /app
7
7
 
8
8
  # Copy package files
9
9
  COPY package*.json ./
10
+ COPY prisma ./prisma/
10
11
 
11
12
  # Install dependencies
12
- RUN npm ci --only=production
13
+ RUN npm ci
14
+
15
+ # Generate Prisma Client
16
+ RUN npx prisma generate
13
17
 
14
18
  # Copy source code
15
19
  COPY . .
16
20
 
17
- # Build TypeScript
21
+ # Build Next.js application
18
22
  RUN npm run build
19
23
 
20
24
  # Production stage
@@ -22,14 +26,25 @@ FROM node:20-alpine AS production
22
26
 
23
27
  WORKDIR /app
24
28
 
29
+ # Copy package files for production install
30
+ COPY package*.json ./
31
+ COPY prisma ./prisma/
32
+
33
+ # Install only production dependencies
34
+ RUN npm ci --omit=dev
35
+
36
+ # Generate Prisma Client for production
37
+ RUN npx prisma generate
38
+
25
39
  # Create non-root user
26
40
  RUN addgroup -g 1001 -S nodejs && \
27
41
  adduser -S nodejs -u 1001
28
42
 
29
- # Copy built application
30
- COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
31
- COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
32
- COPY --from=builder --chown=nodejs:nodejs /app/package.json ./
43
+ # Copy built application and config
44
+ COPY --from=builder --chown=nodejs:nodejs /app/.next ./.next
45
+ COPY --from=builder --chown=nodejs:nodejs /app/public ./public
46
+ COPY --from=builder --chown=nodejs:nodejs /app/package.json ./package.json
47
+ COPY --from=builder --chown=nodejs:nodejs /app/next.config.js ./next.config.js
33
48
 
34
49
  # Switch to non-root user
35
50
  USER nodejs
@@ -39,7 +54,7 @@ EXPOSE 3000
39
54
 
40
55
  # Health check
41
56
  HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
42
- CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
57
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
43
58
 
44
59
  # Start application
45
- CMD ["node", "dist/index.js"]
60
+ CMD ["npm", "start"]
@@ -9,7 +9,7 @@ services:
9
9
  POSTGRES_PASSWORD: postgres
10
10
  POSTGRES_DB: {{snakeCase projectName}}
11
11
  ports:
12
- - "5432:5432"
12
+ - "5434:5432"
13
13
  volumes:
14
14
  - postgres_data:/var/lib/postgresql/data
15
15
  restart: unless-stopped
@@ -1,38 +1,48 @@
1
1
  {
2
- "name": "{{kebabCase projectName}}",
3
- "version": "1.0.0",
4
- "private": true,
5
- "scripts": {
6
- "dev": "next dev",
7
- "build": "next build",
8
- "start": "next start",
9
- "lint": "next lint",
10
- "db:generate": "prisma generate",
11
- "db:push": "prisma db push",
12
- "db:studio": "prisma studio"
13
- },
14
- "dependencies": {
15
- "next": "^16.0.0",
16
- "react": "^18.0.0",
17
- "react-dom": "^18.0.0",
18
- "@prisma/client": "^5.10.2",
19
- "@auth/prisma-adapter": "^1.5.0",
20
- "next-auth": "^4.24.6",
21
- "stripe": "^14.14.0",
22
- "zod": "^3.22.4",
23
- "bcryptjs": "^2.4.3"
24
- },
25
- "devDependencies": {
26
- "@types/node": "^20.11.19",
27
- "@types/react": "^18.2.57",
28
- "@types/react-dom": "^18.2.19",
29
- "@types/bcryptjs": "^2.4.6",
30
- "autoprefixer": "^10.4.17",
31
- "eslint": "^8.56.0",
32
- "eslint-config-next": "14.1.0",
33
- "postcss": "^8.4.33",
34
- "prisma": "^5.10.2",
35
- "tailwindcss": "^3.4.1",
36
- "typescript": "^5.3.3"
37
- }
2
+ "name": "{{kebabCase projectName}}",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint",
10
+ "db:generate": "prisma generate",
11
+ "db:push": "prisma db push",
12
+ "db:studio": "prisma studio"
13
+ },
14
+ "dependencies": {
15
+ "next": "^16.0.0",
16
+ "react": "^18.0.0",
17
+ "react-dom": "^18.0.0",
18
+ "@prisma/client": "^5.10.2",
19
+ "@auth/prisma-adapter": "^1.5.0",
20
+ "next-auth": "^4.24.6",
21
+ "stripe": "^14.14.0",
22
+ "zod": "^3.22.4",
23
+ "bcryptjs": "^2.4.3"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^20.11.19",
27
+ "@types/react": "^18.2.57",
28
+ "@types/react-dom": "^18.2.19",
29
+ "@types/bcryptjs": "^2.4.6",
30
+ "autoprefixer": "^10.4.17",
31
+ "eslint": "^9.16.0",
32
+ "eslint-config-next": "14.1.0",
33
+ "postcss": "^8.4.33",
34
+ "prisma": "^5.10.2",
35
+ "tailwindcss": "^3.4.1",
36
+ "typescript": "^5.3.3"
37
+ },
38
+ "overrides": {
39
+ "rimraf": "^6.1.2",
40
+ "glob": "^11.0.0",
41
+ "inflight": "^1.0.6",
42
+ "@humanwhocodes/config-array": "^0.13.0",
43
+ "@humanwhocodes/object-schema": "^2.0.3",
44
+ "eslint": "^9.16.0",
45
+ "cookie": "^0.7.2",
46
+ "minimatch": "^9.0.8"
38
47
  }
48
+ }
@@ -0,0 +1,42 @@
1
+ # Dependencies
2
+ node_modules/
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # Build outputs
7
+ dist/
8
+ build/
9
+
10
+ # Environment variables
11
+ .env
12
+ .env.local
13
+ .env.development.local
14
+ .env.test.local
15
+ .env.production.local
16
+ !.env.example
17
+
18
+ # Logs
19
+ logs/
20
+ *.log
21
+ npm-debug.log*
22
+ yarn-debug.log*
23
+ yarn-error.log*
24
+ pnpm-debug.log*
25
+ lerna-debug.log*
26
+
27
+ # Coverage
28
+ coverage/
29
+ .nyc_output
30
+
31
+ # TypeScript
32
+ *.tsbuildinfo
33
+
34
+ # OS
35
+ .DS_Store
36
+ Thumbs.db
37
+
38
+ # Editor
39
+ .vscode/
40
+ .idea/
41
+ *.swp
42
+ *.swo
@@ -7,9 +7,13 @@ WORKDIR /app
7
7
 
8
8
  # Copy package files
9
9
  COPY package*.json ./
10
+ COPY prisma ./prisma/
10
11
 
11
12
  # Install dependencies
12
- RUN npm ci --only=production
13
+ RUN npm ci
14
+
15
+ # Generate Prisma client
16
+ RUN npx prisma generate
13
17
 
14
18
  # Copy source code
15
19
  COPY . .
@@ -30,6 +34,7 @@ RUN addgroup -g 1001 -S nodejs && \
30
34
  COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
31
35
  COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
32
36
  COPY --from=builder --chown=nodejs:nodejs /app/package.json ./
37
+ COPY --from=builder --chown=nodejs:nodejs /app/prisma ./prisma
33
38
 
34
39
  # Switch to non-root user
35
40
  USER nodejs
@@ -7,9 +7,9 @@ services:
7
7
  environment:
8
8
  POSTGRES_USER: postgres
9
9
  POSTGRES_PASSWORD: password
10
- POSTGRES_DB: {{kebabCase projectName}}_db
10
+ POSTGRES_DB: {{kebabCase projectName}}_clean_db
11
11
  ports:
12
- - '5432:5432'
12
+ - '5434:5432'
13
13
  volumes:
14
14
  - postgres_data:/var/lib/postgresql/data
15
15
 
@@ -46,8 +46,8 @@
46
46
  "@types/bcryptjs": "^2.4.6",
47
47
  "typescript": "^5.3.3",
48
48
  "tsx": "^4.7.1",
49
- "rimraf": "^5.0.5",
50
- "eslint": "^9.0.0",
49
+ "rimraf": "^6.1.2",
50
+ "eslint": "^9.16.0",
51
51
  "@typescript-eslint/eslint-plugin": "^8.0.0",
52
52
  "@typescript-eslint/parser": "^8.0.0",
53
53
  "prettier": "^3.2.5",
@@ -57,5 +57,15 @@
57
57
  },
58
58
  "engines": {
59
59
  "node": ">=18.0.0"
60
+ },
61
+ "overrides": {
62
+ "rimraf": "^6.1.2",
63
+ "glob": "^11.0.0",
64
+ "inflight": "^1.0.6",
65
+ "@humanwhocodes/config-array": "^0.13.0",
66
+ "@humanwhocodes/object-schema": "^2.0.3",
67
+ "eslint": "^9.16.0",
68
+ "cookie": "^0.7.2",
69
+ "minimatch": "^9.0.8"
60
70
  }
61
71
  }
@@ -0,0 +1,11 @@
1
+ import dotenv from 'dotenv';
2
+
3
+ dotenv.config();
4
+
5
+ export const config = {
6
+ port: process.env.PORT ? parseInt(process.env.PORT, 10) : 3000,
7
+ jwtSecret: process.env.JWT_SECRET || 'your-secret-key',
8
+ databaseUrl: process.env.DATABASE_URL,
9
+ stripeSecretKey: process.env.STRIPE_SECRET_KEY,
10
+ stripeWebhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
11
+ };
@@ -28,11 +28,49 @@ export class User {
28
28
  if (!props.email || !props.email.includes('@')) {
29
29
  throw new Error('Invalid email format');
30
30
  }
31
- if (!props.password || props.password.length < 8) { throw new Error('Password must be at least 8 characters'); } return
32
- new User(props); } static restore(props: UserProps): User { return new User(props); } get id(): string | undefined {
33
- return this.props.id; } get email(): string { return this.props.email; } get name(): string { return
34
- this.props.name; } get password(): string { return this.props.password; } get stripeCustomerId(): string | undefined
35
- { return this.props.stripeCustomerId; } setStripeCustomerId(customerId: string): void {
36
- this.props.stripeCustomerId=customerId; this.props.updatedAt=new Date(); } toJSON() { return { id: this.props.id,
37
- email: this.props.email, name: this.props.name, stripeCustomerId: this.props.stripeCustomerId, createdAt:
38
- this.props.createdAt, updatedAt: this.props.updatedAt, }; } }
31
+ if (!props.password || props.password.length < 8) {
32
+ throw new Error('Password must be at least 8 characters');
33
+ }
34
+ return new User(props);
35
+ }
36
+
37
+ static restore(props: UserProps): User {
38
+ return new User(props);
39
+ }
40
+
41
+ get id(): string | undefined {
42
+ return this.props.id;
43
+ }
44
+
45
+ get email(): string {
46
+ return this.props.email;
47
+ }
48
+
49
+ get name(): string {
50
+ return this.props.name;
51
+ }
52
+
53
+ get password(): string {
54
+ return this.props.password;
55
+ }
56
+
57
+ get stripeCustomerId(): string | undefined {
58
+ return this.props.stripeCustomerId;
59
+ }
60
+
61
+ setStripeCustomerId(customerId: string): void {
62
+ this.props.stripeCustomerId = customerId;
63
+ this.props.updatedAt = new Date();
64
+ }
65
+
66
+ toJSON() {
67
+ return {
68
+ id: this.props.id,
69
+ email: this.props.email,
70
+ name: this.props.name,
71
+ stripeCustomerId: this.props.stripeCustomerId,
72
+ createdAt: this.props.createdAt,
73
+ updatedAt: this.props.updatedAt,
74
+ };
75
+ }
76
+ }
@@ -0,0 +1,42 @@
1
+ # Dependencies
2
+ node_modules/
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # Build outputs
7
+ dist/
8
+ build/
9
+
10
+ # Environment variables
11
+ .env
12
+ .env.local
13
+ .env.development.local
14
+ .env.test.local
15
+ .env.production.local
16
+ !.env.example
17
+
18
+ # Logs
19
+ logs/
20
+ *.log
21
+ npm-debug.log*
22
+ yarn-debug.log*
23
+ yarn-error.log*
24
+ pnpm-debug.log*
25
+ lerna-debug.log*
26
+
27
+ # Coverage
28
+ coverage/
29
+ .nyc_output
30
+
31
+ # TypeScript
32
+ *.tsbuildinfo
33
+
34
+ # OS
35
+ .DS_Store
36
+ Thumbs.db
37
+
38
+ # Editor
39
+ .vscode/
40
+ .idea/
41
+ *.swp
42
+ *.swo
@@ -9,7 +9,7 @@ WORKDIR /app
9
9
  COPY package*.json ./
10
10
 
11
11
  # Install dependencies
12
- RUN npm ci --only=production
12
+ RUN npm ci
13
13
 
14
14
  # Copy source code
15
15
  COPY . .
@@ -7,9 +7,9 @@ services:
7
7
  environment:
8
8
  POSTGRES_USER: postgres
9
9
  POSTGRES_PASSWORD: password
10
- POSTGRES_DB: {{kebabCase projectName}}_db
10
+ POSTGRES_DB: {{kebabCase projectName}}_hexagonal_db
11
11
  ports:
12
- - '5432:5432'
12
+ - '5433:5432'
13
13
  volumes:
14
14
  - postgres_data:/var/lib/postgresql/data
15
15
 
@@ -46,8 +46,8 @@
46
46
  "@types/bcryptjs": "^2.4.6",
47
47
  "typescript": "^5.3.3",
48
48
  "tsx": "^4.7.1",
49
- "rimraf": "^5.0.5",
50
- "eslint": "^9.0.0",
49
+ "rimraf": "^6.1.2",
50
+ "eslint": "^9.16.0",
51
51
  "@typescript-eslint/eslint-plugin": "^8.0.0",
52
52
  "@typescript-eslint/parser": "^8.0.0",
53
53
  "prettier": "^3.2.5",
@@ -57,5 +57,15 @@
57
57
  },
58
58
  "engines": {
59
59
  "node": ">=18.0.0"
60
+ },
61
+ "overrides": {
62
+ "rimraf": "^6.1.2",
63
+ "glob": "^11.0.0",
64
+ "inflight": "^1.0.6",
65
+ "@humanwhocodes/config-array": "^0.13.0",
66
+ "@humanwhocodes/object-schema": "^2.0.3",
67
+ "eslint": "^9.16.0",
68
+ "cookie": "^0.7.2",
69
+ "minimatch": "^9.0.8"
60
70
  }
61
71
  }