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
@@ -6,85 +6,85 @@ import { StripeProvider } from '../infrastructure/stripe.provider';
6
6
 
7
7
  @Injectable()
8
8
  export class PaymentService {
9
- constructor(
10
- private readonly userRepository: UserRepository,
11
- private readonly stripeProvider: StripeProvider,
12
- private readonly configService: ConfigService,
13
- ) {}
9
+ constructor(
10
+ private readonly userRepository: UserRepository,
11
+ private readonly stripeProvider: StripeProvider,
12
+ private readonly configService: ConfigService,
13
+ ) {}
14
14
 
15
- async createCheckoutSession(userId: string, priceId: string) {
16
- const user = await this.userRepository.findById(userId);
17
- if (!user) throw new NotFoundException('User not found');
15
+ async createCheckoutSession(userId: string, priceId: string) {
16
+ const user = await this.userRepository.findById(userId);
17
+ if (!user) throw new NotFoundException('User not found');
18
18
 
19
- let customerId = user.stripeCustomerId;
19
+ let customerId = user.stripeCustomerId;
20
20
 
21
- if (!customerId) {
22
- const customer = await this.stripeProvider.createCustomer(user.email, userId);
23
- customerId = customer.id;
24
- user.stripeCustomerId = customerId;
25
- await this.userRepository.save(user);
26
- }
21
+ if (!customerId) {
22
+ const customer = await this.stripeProvider.createCustomer(user.email, userId);
23
+ customerId = customer.id;
24
+ user.stripeCustomerId = customerId;
25
+ await this.userRepository.save(user);
26
+ }
27
27
 
28
- return this.stripeProvider.createCheckoutSession(
29
- customerId,
30
- priceId,
31
- userId,
32
- `${this.configService.get('FRONTEND_URL')}/success?session_id={CHECKOUT_SESSION_ID}`,
33
- `${this.configService.get('FRONTEND_URL')}/cancel`,
34
- );
35
- }
28
+ return this.stripeProvider.createCheckoutSession(
29
+ customerId,
30
+ priceId,
31
+ userId,
32
+ `${this.configService.get('FRONTEND_URL')}/success?session_id={CHECKOUT_SESSION_ID}`,
33
+ `${this.configService.get('FRONTEND_URL')}/cancel`,
34
+ );
35
+ }
36
36
 
37
- async createPortalSession(userId: string) {
38
- const user = await this.userRepository.findById(userId);
39
- if (!user?.stripeCustomerId) throw new NotFoundException('No Stripe customer found for this user');
37
+ async createPortalSession(userId: string) {
38
+ const user = await this.userRepository.findById(userId);
39
+ if (!user?.stripeCustomerId) throw new NotFoundException('No Stripe customer found for this user');
40
40
 
41
- return this.stripeProvider.createPortalSession(
42
- user.stripeCustomerId,
43
- `${this.configService.get('FRONTEND_URL')}/dashboard`,
44
- );
45
- }
41
+ return this.stripeProvider.createPortalSession(
42
+ user.stripeCustomerId,
43
+ `${this.configService.get('FRONTEND_URL')}/dashboard`,
44
+ );
45
+ }
46
46
 
47
- async handleWebhook(payload: Buffer, signature: string) {
48
- let event: Stripe.Event;
49
- try {
50
- event = this.stripeProvider.constructEvent(payload, signature);
51
- } catch (err: any) {
52
- throw new Error(`Webhook signature verification failed: ${err.message}`);
53
- }
47
+ async handleWebhook(payload: Buffer, signature: string) {
48
+ let event: Stripe.Event;
49
+ try {
50
+ event = this.stripeProvider.constructEvent(payload, signature);
51
+ } catch (err: any) {
52
+ throw new Error(`Webhook signature verification failed: ${err.message}`);
53
+ }
54
54
 
55
- switch (event.type) {
56
- case 'checkout.session.completed': {
57
- const session = event.data.object as Stripe.Checkout.Session;
58
- const userId = session.client_reference_id;
59
- if (userId && session.customer) {
60
- const user = await this.userRepository.findById(userId);
61
- if (user) {
62
- user.stripeCustomerId = session.customer as string;
63
- await this.userRepository.save(user);
64
- }
65
- }
66
- console.log('Checkout completed for user:', userId);
67
- break;
68
- }
69
- case 'customer.subscription.updated': {
70
- const sub = event.data.object as Stripe.Subscription;
71
- console.log('Subscription updated:', sub.id, '| Status:', sub.status);
72
- break;
73
- }
74
- case 'customer.subscription.deleted': {
75
- const sub = event.data.object as Stripe.Subscription;
76
- console.log('Subscription deleted:', sub.id);
77
- break;
78
- }
79
- case 'invoice.payment_failed': {
80
- const invoice = event.data.object as Stripe.Invoice;
81
- console.log('Payment failed for invoice:', invoice.id);
82
- break;
83
- }
84
- default:
85
- console.log('Unhandled Stripe event:', event.type);
86
- }
55
+ switch (event.type) {
56
+ case 'checkout.session.completed': {
57
+ const session = event.data.object as Stripe.Checkout.Session;
58
+ const userId = session.client_reference_id;
59
+ if (userId && session.customer) {
60
+ const user = await this.userRepository.findById(userId);
61
+ if (user) {
62
+ user.stripeCustomerId = session.customer as string;
63
+ await this.userRepository.save(user);
64
+ }
65
+ }
66
+ console.log('Checkout completed for user:', userId);
67
+ break;
68
+ }
69
+ case 'customer.subscription.updated': {
70
+ const sub = event.data.object as Stripe.Subscription;
71
+ console.log('Subscription updated:', sub.id, '| Status:', sub.status);
72
+ break;
73
+ }
74
+ case 'customer.subscription.deleted': {
75
+ const sub = event.data.object as Stripe.Subscription;
76
+ console.log('Subscription deleted:', sub.id);
77
+ break;
78
+ }
79
+ case 'invoice.payment_failed': {
80
+ const invoice = event.data.object as Stripe.Invoice;
81
+ console.log('Payment failed for invoice:', invoice.id);
82
+ break;
83
+ }
84
+ default:
85
+ console.log('Unhandled Stripe event:', event.type);
86
+ }
87
87
 
88
- return { received: true };
89
- }
88
+ return { received: true };
90
89
  }
90
+ }
@@ -4,9 +4,9 @@ export class User {
4
4
  public readonly email: string,
5
5
  public readonly name: string,
6
6
  public readonly password: string,
7
- public readonly stripeCustomerId?: string,
7
+ public stripeCustomerId?: string,
8
8
  public readonly createdAt: Date = new Date(),
9
9
  ) {
10
10
  if (!email.includes('@')) throw new Error('Invalid email');
11
11
  }
12
- }
12
+ }
@@ -1,6 +1,6 @@
1
1
  import { User } from '../entities/user.entity';
2
2
 
3
3
  export abstract class IUserRepository {
4
- abstract findByEmail(email: string): Promise<User | null>;
4
+ abstract findByEmail(email: string): Promise<User | null>;
5
5
  abstract save(user: User): Promise<User>;
6
- }
6
+ }
@@ -5,28 +5,28 @@ import { PrismaService } from '../prisma.service';
5
5
 
6
6
  @Injectable()
7
7
  export class PrismaUserRepository implements IUserRepository {
8
- constructor(private prisma: PrismaService) {}
8
+ constructor(private prisma: PrismaService) {}
9
9
 
10
- async findByEmail(email: string): Promise<User | null> {
11
- const user = await this.prisma.user.findUnique({ where: { email } });
12
- if (!user) return null;
13
- return new User(user.id, user.name, user.email, user.password);
10
+ async findByEmail(email: string): Promise<User | null> {
11
+ const user = await this.prisma.user.findUnique({ where: { email } });
12
+ if (!user) return null;
13
+ return new User(user.id, user.name, user.email, user.password);
14
14
  }
15
15
 
16
16
  async save(user: User): Promise<User> {
17
17
  const savedUser = await this.prisma.user.upsert({
18
- where: { email: user.email },
19
- update: {
20
- name: user.name,
21
- password: user.password,
22
- },
23
- create: {
24
- id: user.id,
25
- name: user.name,
26
- email: user.email,
27
- password: user.password,
28
- },
18
+ where: { email: user.email },
19
+ update: {
20
+ name: user.name,
21
+ password: user.password,
22
+ },
23
+ create: {
24
+ id: user.id,
25
+ name: user.name,
26
+ email: user.email,
27
+ password: user.password,
28
+ },
29
29
  });
30
30
  return new User(savedUser.id, savedUser.name, savedUser.email, savedUser.password);
31
- }
32
- }
31
+ }
32
+ }
@@ -0,0 +1,9 @@
1
+ import { Controller, Get } from '@nestjs/common';
2
+
3
+ @Controller('health')
4
+ export class HealthController {
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 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');
@@ -8,16 +8,16 @@ import { PrismaUserRepository } from './infrastructure/database/prisma.user.repo
8
8
  import { PrismaService } from './infrastructure/database/prisma.service';
9
9
 
10
10
  @Module({
11
- imports: [ConfigModule],
12
- controllers: [PaymentController],
13
- providers: [
14
- PaymentService,
15
- StripeProvider,
16
- PrismaService,
17
- {
18
- provide: UserRepository,
19
- useClass: PrismaUserRepository,
20
- },
21
- ],
11
+ imports: [ConfigModule],
12
+ controllers: [PaymentController],
13
+ providers: [
14
+ PaymentService,
15
+ StripeProvider,
16
+ PrismaService,
17
+ {
18
+ provide: UserRepository,
19
+ useClass: PrismaUserRepository,
20
+ },
21
+ ],
22
22
  })
23
- export class PaymentModule {}
23
+ export class PaymentModule {}
@@ -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 . .
@@ -26,6 +26,9 @@ WORKDIR /app
26
26
  RUN addgroup -g 1001 -S nodejs && \
27
27
  adduser -S nodejs -u 1001
28
28
 
29
+ # Add openssl
30
+ RUN apk add --no-cache openssl
31
+
29
32
  # Copy built application
30
33
  COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
31
34
  COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
@@ -39,7 +42,7 @@ EXPOSE 3000
39
42
 
40
43
  # Health check
41
44
  HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
42
- CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
45
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
43
46
 
44
47
  # Start application
45
- CMD ["node", "dist/index.js"]
48
+ CMD node dist/main.js
@@ -1,16 +1,6 @@
1
1
  version: '3.8'
2
2
 
3
3
  services:
4
- app:
5
- build: .
6
- container_name: {{kebabCase projectName}}-app
7
- ports:
8
- - "3000:3000"
9
- environment:
10
- - DATABASE_URL=postgresql://postgres:postgres@db:5432/{{snakeCase projectName}}
11
- depends_on:
12
- - db
13
-
14
4
  db:
15
5
  image: postgres:15-alpine
16
6
  container_name: {{kebabCase projectName}}-db
@@ -19,7 +9,7 @@ services:
19
9
  POSTGRES_PASSWORD: postgres
20
10
  POSTGRES_DB: {{snakeCase projectName}}
21
11
  ports:
22
- - "5432:5432"
12
+ - "5434:5432"
23
13
  volumes:
24
14
  - postgres_data:/var/lib/postgresql/data
25
15
  restart: unless-stopped
@@ -1,43 +1,53 @@
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
- "migrate:dev": "prisma migrate dev",
12
- "migrate:deploy": "prisma migrate deploy",
13
- "generate": "prisma generate"
14
- },
15
- "dependencies": {
16
- "@nestjs/common": "^10.3.0",
17
- "@nestjs/core": "^10.3.0",
18
- "@nestjs/config": "^3.1.1",
19
- "@nestjs/jwt": "^10.2.0",
20
- "@nestjs/passport": "^10.0.3",
21
- "@nestjs/platform-express": "^10.3.0",
22
- "@prisma/client": "^5.10.2",
23
- "bcryptjs": "^2.4.3",
24
- "class-transformer": "^0.5.1",
25
- "class-validator": "^0.14.1",
26
- "passport": "^0.7.0",
27
- "passport-jwt": "^4.0.1",
28
- "reflect-metadata": "^0.2.1",
29
- "rxjs": "^7.8.1",
30
- "stripe": "^14.14.0",
31
- "uuid": "^9.0.1"
32
- },
33
- "devDependencies": {
34
- "@nestjs/cli": "^10.3.0",
35
- "@types/bcryptjs": "^2.4.6",
36
- "@types/node": "^20.11.0",
37
- "@types/passport-jwt": "^4.0.0",
38
- "@types/uuid": "^9.0.7",
39
- "prisma": "^5.10.2",
40
- "typescript": "^5.3.3",
41
- "eslint": "^8.56.0"
42
- }
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
+ "migrate:dev": "prisma migrate dev",
12
+ "migrate:deploy": "prisma migrate deploy",
13
+ "generate": "prisma generate"
14
+ },
15
+ "dependencies": {
16
+ "@nestjs/common": "^10.3.0",
17
+ "@nestjs/core": "^10.3.0",
18
+ "@nestjs/config": "^3.1.1",
19
+ "@nestjs/jwt": "^10.2.0",
20
+ "@nestjs/passport": "^10.0.3",
21
+ "@nestjs/platform-express": "^10.3.0",
22
+ "@prisma/client": "^5.10.2",
23
+ "bcryptjs": "^2.4.3",
24
+ "class-transformer": "^0.5.1",
25
+ "class-validator": "^0.14.1",
26
+ "passport": "^0.7.0",
27
+ "passport-jwt": "^4.0.1",
28
+ "reflect-metadata": "^0.2.1",
29
+ "rxjs": "^7.8.1",
30
+ "stripe": "^14.14.0",
31
+ "uuid": "^9.0.1"
32
+ },
33
+ "devDependencies": {
34
+ "@nestjs/cli": "^10.3.0",
35
+ "@types/bcryptjs": "^2.4.6",
36
+ "@types/node": "^20.11.0",
37
+ "@types/passport-jwt": "^4.0.0",
38
+ "@types/uuid": "^9.0.7",
39
+ "prisma": "^5.10.2",
40
+ "typescript": "^5.3.3",
41
+ "eslint": "^9.16.0"
42
+ },
43
+ "overrides": {
44
+ "rimraf": "^6.1.2",
45
+ "glob": "^11.0.0",
46
+ "inflight": "^1.0.6",
47
+ "@humanwhocodes/config-array": "^0.13.0",
48
+ "@humanwhocodes/object-schema": "^2.0.3",
49
+ "eslint": "^9.16.0",
50
+ "cookie": "^0.7.2",
51
+ "minimatch": "^9.0.8"
43
52
  }
53
+ }
@@ -0,0 +1,9 @@
1
+ import { Controller, Get } from '@nestjs/common';
2
+
3
+ @Controller('health')
4
+ export class HealthController {
5
+ @Get()
6
+ check() {
7
+ return { status: 'ok' };
8
+ }
9
+ }
@@ -3,6 +3,7 @@ import { ConfigModule } from '@nestjs/config';
3
3
  import { AuthModule } from './auth.module';
4
4
  import { PaymentModule } from './payment.module';
5
5
  import { PrismaService } from './adapters/outbound/persistence/prisma.service';
6
+ import { HealthController } from './adapters/inbound/health.controller';
6
7
 
7
8
  @Module({
8
9
  imports: [
@@ -12,7 +13,7 @@ import { PrismaService } from './adapters/outbound/persistence/prisma.service';
12
13
  AuthModule,
13
14
  PaymentModule,
14
15
  ],
15
- controllers: [],
16
+ controllers: [HealthController],
16
17
  providers: [PrismaService],
17
18
  exports: [PrismaService],
18
19
  })
@@ -1,8 +1,8 @@
1
1
  export class User {
2
- constructor(
3
- public readonly id: string,
4
- public readonly email: string,
5
- public readonly name: string,
6
- public readonly password: string,
7
- ) {}
2
+ constructor(
3
+ public readonly id: string,
4
+ public readonly email: string,
5
+ public readonly name: string,
6
+ public readonly password: string,
7
+ ) {}
8
8
  }
@@ -1,9 +1,9 @@
1
1
  import { User } from '../domain/user.entity';
2
2
 
3
3
  export interface IUserRepositoryPort {
4
- save(user: User): Promise<User>;
5
- }
4
+ save(user: User): Promise<User>;
5
+ }
6
6
 
7
- export interface IAuthPort {
7
+ export interface IAuthPort {
8
8
  register(email: string, name: string, password: string): Promise<User>;
9
- }
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 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');
@@ -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 . .
@@ -26,6 +26,9 @@ WORKDIR /app
26
26
  RUN addgroup -g 1001 -S nodejs && \
27
27
  adduser -S nodejs -u 1001
28
28
 
29
+ # Add openssl
30
+ RUN apk add --no-cache openssl
31
+
29
32
  # Copy built application
30
33
  COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
31
34
  COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
@@ -39,7 +42,7 @@ EXPOSE 3000
39
42
 
40
43
  # Health check
41
44
  HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
42
- CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
45
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
43
46
 
44
47
  # Start application
45
- CMD ["node", "dist/index.js"]
48
+ CMD node dist/main.js
@@ -1,16 +1,6 @@
1
1
  version: '3.8'
2
2
 
3
3
  services:
4
- app:
5
- build: .
6
- container_name: {{kebabCase projectName}}-app
7
- ports:
8
- - "3000:3000"
9
- environment:
10
- - DATABASE_URL=postgresql://postgres:postgres@db:5432/{{snakeCase projectName}}
11
- depends_on:
12
- - db
13
-
14
4
  db:
15
5
  image: postgres:15-alpine
16
6
  container_name: {{kebabCase projectName}}-db
@@ -19,7 +9,7 @@ services:
19
9
  POSTGRES_PASSWORD: postgres
20
10
  POSTGRES_DB: {{snakeCase projectName}}
21
11
  ports:
22
- - "5432:5432"
12
+ - "5434:5432"
23
13
  volumes:
24
14
  - postgres_data:/var/lib/postgresql/data
25
15
  restart: unless-stopped