@ryuenn3123/agentic-senior-core 1.8.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 (78) hide show
  1. package/.agent-context/blueprints/api-nextjs.md +184 -0
  2. package/.agent-context/blueprints/aspnet-api.md +247 -0
  3. package/.agent-context/blueprints/ci-github-actions.md +226 -0
  4. package/.agent-context/blueprints/ci-gitlab.md +200 -0
  5. package/.agent-context/blueprints/fastapi-service.md +210 -0
  6. package/.agent-context/blueprints/go-service.md +217 -0
  7. package/.agent-context/blueprints/graphql-grpc-api.md +51 -0
  8. package/.agent-context/blueprints/infrastructure-as-code.md +62 -0
  9. package/.agent-context/blueprints/kubernetes-manifests.md +76 -0
  10. package/.agent-context/blueprints/laravel-api.md +223 -0
  11. package/.agent-context/blueprints/nestjs-logic.md +247 -0
  12. package/.agent-context/blueprints/observability.md +227 -0
  13. package/.agent-context/blueprints/spring-boot-api.md +218 -0
  14. package/.agent-context/policies/llm-judge-threshold.json +20 -0
  15. package/.agent-context/profiles/platform.md +13 -0
  16. package/.agent-context/profiles/regulated.md +13 -0
  17. package/.agent-context/profiles/startup.md +13 -0
  18. package/.agent-context/prompts/init-project.md +86 -0
  19. package/.agent-context/prompts/refactor.md +45 -0
  20. package/.agent-context/prompts/review-code.md +47 -0
  21. package/.agent-context/review-checklists/architecture-review.md +70 -0
  22. package/.agent-context/review-checklists/frontend-usability.md +33 -0
  23. package/.agent-context/review-checklists/performance-audit.md +65 -0
  24. package/.agent-context/review-checklists/pr-checklist.md +97 -0
  25. package/.agent-context/review-checklists/release-operations.md +29 -0
  26. package/.agent-context/review-checklists/security-audit.md +113 -0
  27. package/.agent-context/rules/api-docs.md +186 -0
  28. package/.agent-context/rules/architecture.md +198 -0
  29. package/.agent-context/rules/database-design.md +202 -0
  30. package/.agent-context/rules/efficiency-vs-hype.md +143 -0
  31. package/.agent-context/rules/error-handling.md +234 -0
  32. package/.agent-context/rules/event-driven.md +226 -0
  33. package/.agent-context/rules/frontend-architecture.md +66 -0
  34. package/.agent-context/rules/git-workflow.md +200 -0
  35. package/.agent-context/rules/microservices.md +174 -0
  36. package/.agent-context/rules/naming-conv.md +141 -0
  37. package/.agent-context/rules/performance.md +168 -0
  38. package/.agent-context/rules/realtime.md +47 -0
  39. package/.agent-context/rules/security.md +195 -0
  40. package/.agent-context/rules/testing.md +178 -0
  41. package/.agent-context/stacks/csharp.md +149 -0
  42. package/.agent-context/stacks/go.md +181 -0
  43. package/.agent-context/stacks/java.md +135 -0
  44. package/.agent-context/stacks/php.md +178 -0
  45. package/.agent-context/stacks/python.md +153 -0
  46. package/.agent-context/stacks/ruby.md +80 -0
  47. package/.agent-context/stacks/rust.md +86 -0
  48. package/.agent-context/stacks/typescript.md +317 -0
  49. package/.agent-context/state/architecture-map.md +25 -0
  50. package/.agent-context/state/dependency-map.md +32 -0
  51. package/.agent-override.md +36 -0
  52. package/.agents/workflows/init-project.md +29 -0
  53. package/.agents/workflows/refactor.md +29 -0
  54. package/.agents/workflows/review-code.md +29 -0
  55. package/.cursorrules +140 -0
  56. package/.gemini/instructions.md +97 -0
  57. package/.github/ISSUE_TEMPLATE/v1.7-frontend-work-item.yml +54 -0
  58. package/.github/copilot-instructions.md +104 -0
  59. package/.github/workflows/benchmark-detection.yml +38 -0
  60. package/.github/workflows/frontend-usability-gate.yml +36 -0
  61. package/.github/workflows/release-gate.yml +32 -0
  62. package/.github/workflows/sbom-compliance.yml +32 -0
  63. package/.windsurfrules +106 -0
  64. package/AGENTS.md +131 -0
  65. package/CONTRIBUTING.md +136 -0
  66. package/LICENSE +21 -0
  67. package/README.md +239 -0
  68. package/bin/agentic-senior-core.js +1147 -0
  69. package/mcp.json +29 -0
  70. package/package.json +50 -0
  71. package/scripts/detection-benchmark.mjs +138 -0
  72. package/scripts/frontend-usability-audit.mjs +87 -0
  73. package/scripts/generate-sbom.mjs +61 -0
  74. package/scripts/init-project.ps1 +105 -0
  75. package/scripts/init-project.sh +131 -0
  76. package/scripts/llm-judge.mjs +664 -0
  77. package/scripts/release-gate.mjs +116 -0
  78. package/scripts/validate.mjs +554 -0
@@ -0,0 +1,62 @@
1
+ # Infrastructure as Code (IaC) Blueprint
2
+
3
+ > ClickOps is a sin. If it's not in code, it doesn't exist. Treats your servers like cattle, not pets.
4
+
5
+ ## 1. Tooling (March 2026)
6
+ - **Standard:** Terraform / OpenTofu (HCL) or Pulumi (TypeScript/Go/Python).
7
+ - **BANNED:** AWS CloudFormation (verbose, slow, vendor-locked) unless mandated by enterprise policy. AWS CDK is acceptable but requires rigorous linting to prevent runaway loops.
8
+
9
+ ## 2. Directory Structure (Blast Radius Management)
10
+ Never put all your infrastructure into a single `main.tf` or a single state file.
11
+ - **BANNED:** Flat structure. A single mistake could destroy the database while updating an S3 bucket.
12
+ - **REQUIRED (Component/Environment Split):**
13
+ ```
14
+ infrastructure/
15
+ modules/
16
+ vpc/
17
+ rds/
18
+ eks/
19
+ environments/
20
+ dev/
21
+ vpc/ (depends on modules/vpc)
22
+ rds/ (runs its own state file)
23
+ prod/
24
+ vpc/
25
+ rds/
26
+ ```
27
+
28
+ ## 3. Remote State & Locking
29
+ State files contain sensitive data (passwords, IP addresses) and represent the source of truth for your physical architecture.
30
+ - **Rule:** ALWAYS use a remote backend (S3, GCS, HCP Terraform) with state locking (DynamoDB, native GCS/HCP).
31
+ - **BANNED:** Committing `terraform.tfstate` or `Pulumi.dev.yaml` to Git. Ensure `*.tfstate` is in `.gitignore`.
32
+
33
+ ## 4. Hardcoded Values & Secrets
34
+ - **Rule:** NEVER hardcode ARNs, IPs, or passwords in your IaC.
35
+ - **REQUIRED:** Pass variables via `.tfvars` (which are gitignored) or environment variables (`TF_VAR_db_password`). Use a Secret Manager (AWS Secrets Manager, HashiCorp Vault) and reference the secret dynamically.
36
+ - **Example:**
37
+ ```hcl
38
+ # ❌ BANNED
39
+ password = "SuperSecretPassword123!"
40
+
41
+ # ✅ REQUIRED
42
+ data "aws_secretsmanager_secret_version" "db" {
43
+ secret_id = aws_secretsmanager_secret.db.id
44
+ }
45
+ password = jsondecode(data.aws_secretsmanager_secret_version.db.secret_string)["password"]
46
+ ```
47
+
48
+ ## 5. Principle of Least Privilege (IAM)
49
+ - **Rule:** Wildcards (`*`) in IAM policies are strictly banned unless absolutely necessary (e.g., specific S3 actions).
50
+ - **BANNED:** Assigning `AmazonS3FullAccess` to a worker node that only needs to read from one bucket.
51
+ - **REQUIRED:** Explicit resource ARNs and explicit Actions.
52
+ ```hcl
53
+ statement {
54
+ effect = "Allow"
55
+ actions = ["s3:GetObject"]
56
+ resources = ["arn:aws:s3:::my-specific-bucket/uploads/*"]
57
+ }
58
+ ```
59
+
60
+ ## 6. Immutable Infrastructure
61
+ - **Rule:** If a server is unhealthy, terminate it. Do not SSH into it to fix it.
62
+ - **Rule:** Use Auto Scaling Groups (ASGs) even if the desired capacity is 1. This ensures the component is self-healing.
@@ -0,0 +1,76 @@
1
+ # Kubernetes Manifests Blueprint
2
+
3
+ > Kubernetes is a declarative state machine. Tell it what you want, not how to do it.
4
+
5
+ ## 1. Bare Minimum Requirements
6
+ Every application deployed to Kubernetes MUST include at minimum:
7
+ 1. `Deployment` (or `StatefulSet`/`DaemonSet`)
8
+ 2. `Service`
9
+ 3. `ConfigMap` (for non-sensitive config)
10
+ 4. `Secret` (managed externally, e.g., via ExternalSecrets)
11
+ 5. `Ingress` (or `Gateway APIRoute`)
12
+
13
+ ## 2. Resource Limits & Requests (Mandatory)
14
+ A container without resource limits is a noisy neighbor that will eventually crash the node.
15
+ - **Rule:** EVERY container in a Pod MUST have BOTH `requests` and `limits` defined for CPU and Memory.
16
+ - **BANNED:** Omitting the `resources` block.
17
+ - **REQUIRED:**
18
+ ```yaml
19
+ resources:
20
+ requests:
21
+ memory: "256Mi"
22
+ cpu: "100m"
23
+ limits:
24
+ memory: "512Mi"
25
+ cpu: "500m"
26
+ ```
27
+
28
+ ## 3. Liveness & Readiness Probes (Mandatory)
29
+ Kubernetes needs to know when your app is ready to serve traffic and if it needs to be restarted.
30
+ - **Rule:** EVERY container MUST define a `readinessProbe` and a `livenessProbe`.
31
+ - **BANNED:** Assuming the container is ready just because the process started.
32
+ - **REQUIRED:**
33
+ ```yaml
34
+ livenessProbe:
35
+ httpGet:
36
+ path: /healthz
37
+ port: 8080
38
+ initialDelaySeconds: 5
39
+ periodSeconds: 10
40
+ readinessProbe:
41
+ httpGet:
42
+ path: /ready
43
+ port: 8080
44
+ initialDelaySeconds: 5
45
+ periodSeconds: 5
46
+ ```
47
+
48
+ ## 4. The `latest` Tag Fallacy
49
+ - **Rule:** NEVER use the `:latest` tag for container images in production.
50
+ - **Why:** Deployments containing the `latest` tag cannot be easily rolled back, and nodes may cache different versions of `latest`.
51
+ - **REQUIRED:** Use explicit semantic versioning (`:v1.2.3`) or Git SHA hashes (`:sha-7a8f9b`).
52
+
53
+ ## 5. Configuration & Secrets Management
54
+ - **Rule:** Application configuration must be injected via Environment Variables originating from `ConfigMaps` or `Secrets`.
55
+ - **BANNED:** Hardcoding environment variables in the `Deployment` manifest.
56
+ - **BANNED:** Storing Base64-encoded `Secret` manifests in version control.
57
+ - **REQUIRED:** Use tools like `External Secrets Operator` to pull secrets from AWS Secrets Manager / HashiCorp Vault into the cluster securely.
58
+ ```yaml
59
+ envFrom:
60
+ - configMapRef:
61
+ name: app-config
62
+ - secretRef:
63
+ name: app-secrets
64
+ ```
65
+
66
+ ## 6. Security Context
67
+ By default, containers run as `root`. This is a massive security risk.
68
+ - **Rule:** Containers MUST run as a non-root user. The filesystem should be read-only where possible.
69
+ - **REQUIRED:**
70
+ ```yaml
71
+ securityContext:
72
+ runAsNonRoot: true
73
+ runAsUser: 1000
74
+ readOnlyRootFilesystem: true
75
+ allowPrivilegeEscalation: false
76
+ ```
@@ -0,0 +1,223 @@
1
+ # Blueprint: Laravel API
2
+
3
+ > PHP backend API service using Laravel 12, PHP 8.5+, Form Requests, Eloquent, and Scribe for docs.
4
+
5
+ ## Tech Stack
6
+
7
+ | Layer | Technology |
8
+ |-------|-----------|
9
+ | Framework | Laravel 12 |
10
+ | Validation | Form Requests |
11
+ | ORM | Eloquent |
12
+ | Migration | Laravel Migrations |
13
+ | Testing | Pest PHP |
14
+ | Static analysis | PHPStan (level 8) |
15
+ | Formatting | Laravel Pint |
16
+ | API docs | Scribe |
17
+
18
+ ---
19
+
20
+ ## Project Structure
21
+
22
+ ```
23
+ project-name/
24
+ ├── app/
25
+ │ ├── Modules/
26
+ │ │ └── User/
27
+ │ │ ├── Controllers/
28
+ │ │ │ └── UserController.php
29
+ │ │ ├── Services/
30
+ │ │ │ └── UserService.php
31
+ │ │ ├── Repositories/
32
+ │ │ │ └── UserRepository.php
33
+ │ │ ├── Requests/
34
+ │ │ │ ├── StoreUserRequest.php
35
+ │ │ │ └── UpdateUserRequest.php
36
+ │ │ ├── Resources/
37
+ │ │ │ └── UserResource.php
38
+ │ │ ├── Models/
39
+ │ │ │ └── User.php
40
+ │ │ ├── Policies/
41
+ │ │ │ └── UserPolicy.php
42
+ │ │ └── Exceptions/
43
+ │ │ └── UserNotFoundException.php
44
+ │ │
45
+ │ ├── Shared/
46
+ │ │ ├── Exceptions/
47
+ │ │ │ └── Handler.php
48
+ │ │ └── Traits/
49
+ │ │ └── ApiResponse.php
50
+ │ │
51
+ │ └── Providers/
52
+
53
+ ├── database/
54
+ │ ├── factories/
55
+ │ │ └── UserFactory.php
56
+ │ ├── migrations/
57
+ │ └── seeders/
58
+
59
+ ├── routes/
60
+ │ └── api.php
61
+
62
+ ├── tests/
63
+ │ ├── Feature/
64
+ │ │ └── User/
65
+ │ │ └── UserEndpointTest.php
66
+ │ └── Unit/
67
+ │ └── User/
68
+ │ └── UserServiceTest.php
69
+
70
+ ├── phpstan.neon
71
+ ├── .env.example
72
+ ├── composer.json
73
+ └── Dockerfile
74
+ ```
75
+
76
+ ---
77
+
78
+ ## File Patterns
79
+
80
+ ### Controller — Thin Transport Layer
81
+ ```php
82
+ <?php
83
+
84
+ declare(strict_types=1);
85
+
86
+ namespace App\Modules\User\Controllers;
87
+
88
+ use App\Modules\User\Requests\StoreUserRequest;
89
+ use App\Modules\User\Resources\UserResource;
90
+ use App\Modules\User\Services\UserService;
91
+ use Illuminate\Http\JsonResponse;
92
+ use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
93
+ use Symfony\Component\HttpFoundation\Response;
94
+
95
+ final class UserController
96
+ {
97
+ public function __construct(
98
+ private readonly UserService $userService,
99
+ ) {}
100
+
101
+ public function store(StoreUserRequest $request): JsonResponse
102
+ {
103
+ $user = $this->userService->create($request->validated());
104
+
105
+ return (new UserResource($user))
106
+ ->response()
107
+ ->setStatusCode(Response::HTTP_CREATED);
108
+ }
109
+
110
+ public function index(): AnonymousResourceCollection
111
+ {
112
+ return UserResource::collection(
113
+ $this->userService->listPaginated()
114
+ );
115
+ }
116
+ }
117
+ ```
118
+
119
+ ### Form Request — Boundary Validation
120
+ ```php
121
+ <?php
122
+
123
+ declare(strict_types=1);
124
+
125
+ namespace App\Modules\User\Requests;
126
+
127
+ use Illuminate\Foundation\Http\FormRequest;
128
+
129
+ final class StoreUserRequest extends FormRequest
130
+ {
131
+ /** @return array<string, array<int, string>> */
132
+ public function rules(): array
133
+ {
134
+ return [
135
+ 'name' => ['required', 'string', 'max:100'],
136
+ 'email' => ['required', 'email', 'unique:users,email'],
137
+ 'password' => ['required', 'string', 'min:8', 'confirmed'],
138
+ ];
139
+ }
140
+ }
141
+ ```
142
+
143
+ ### Service — Business Logic
144
+ ```php
145
+ <?php
146
+
147
+ declare(strict_types=1);
148
+
149
+ namespace App\Modules\User\Services;
150
+
151
+ use App\Modules\User\Models\User;
152
+ use App\Modules\User\Repositories\UserRepository;
153
+ use Illuminate\Contracts\Pagination\LengthAwarePaginator;
154
+ use Illuminate\Support\Facades\Hash;
155
+ use Illuminate\Support\Facades\Log;
156
+
157
+ final class UserService
158
+ {
159
+ public function __construct(
160
+ private readonly UserRepository $userRepository,
161
+ ) {}
162
+
163
+ /** @param array{name: string, email: string, password: string} $data */
164
+ public function create(array $data): User
165
+ {
166
+ $data['password'] = Hash::make($data['password']);
167
+ $user = $this->userRepository->create($data);
168
+
169
+ Log::info('User created', ['user_id' => $user->id, 'email' => $user->email]);
170
+
171
+ return $user;
172
+ }
173
+
174
+ public function listPaginated(int $perPage = 15): LengthAwarePaginator
175
+ {
176
+ return $this->userRepository->paginate($perPage);
177
+ }
178
+ }
179
+ ```
180
+
181
+ ### API Resource — Response Transformer
182
+ ```php
183
+ <?php
184
+
185
+ declare(strict_types=1);
186
+
187
+ namespace App\Modules\User\Resources;
188
+
189
+ use Illuminate\Http\Request;
190
+ use Illuminate\Http\Resources\Json\JsonResource;
191
+
192
+ /** @mixin \App\Modules\User\Models\User */
193
+ final class UserResource extends JsonResource
194
+ {
195
+ /** @return array<string, mixed> */
196
+ public function toArray(Request $request): array
197
+ {
198
+ return [
199
+ 'id' => $this->id,
200
+ 'name' => $this->name,
201
+ 'email' => $this->email,
202
+ 'created_at' => $this->created_at?->toISOString(),
203
+ ];
204
+ // NEVER expose: password, remember_token, email_verified_at (unless needed)
205
+ }
206
+ }
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Scaffolding Checklist
212
+
213
+ - [ ] Create Laravel project: `composer create-project laravel/laravel`
214
+ - [ ] Set up modular structure under `app/Modules/`
215
+ - [ ] Create shared error handler with consistent JSON responses
216
+ - [ ] Create shared `ApiResponse` trait for standard response format
217
+ - [ ] Install and configure PHPStan level 8
218
+ - [ ] Install and configure Laravel Pint
219
+ - [ ] Install Pest PHP for testing
220
+ - [ ] Install Scribe for API documentation
221
+ - [ ] Create first module following the pattern above
222
+ - [ ] Create `.env.example` with all required variables
223
+ - [ ] Run `php artisan test`, `./vendor/bin/phpstan`, `./vendor/bin/pint` — zero errors
@@ -0,0 +1,247 @@
1
+ # Blueprint: NestJS Module (Clean Architecture)
2
+
3
+ > This blueprint defines how to scaffold a NestJS application or module.
4
+ > Every module follows strict layering. No shortcuts.
5
+
6
+ ## Tech Stack
7
+ - **Runtime:** Node.js 20+ / Bun
8
+ - **Framework:** NestJS 10+
9
+ - **Validation:** Zod + nestjs-zod (or class-validator)
10
+ - **ORM:** Prisma (or Drizzle)
11
+ - **Documentation:** @nestjs/swagger (OpenAPI auto-generated)
12
+ - **Testing:** Vitest (or Jest)
13
+ - **Logger:** nestjs-pino
14
+
15
+ ## Project Structure
16
+
17
+ ```
18
+ project-name/
19
+ ├── src/
20
+ │ ├── main.ts # Bootstrap + Swagger setup
21
+ │ ├── app.module.ts # Root module
22
+ │ │
23
+ │ ├── modules/ # Feature modules
24
+ │ │ ├── user/
25
+ │ │ │ ├── user.module.ts # Module registration
26
+ │ │ │ ├── user.controller.ts # Transport layer (HTTP)
27
+ │ │ │ ├── user.service.ts # Application layer (business logic)
28
+ │ │ │ ├── user.repository.ts # Infrastructure layer (data access)
29
+ │ │ │ ├── dto/
30
+ │ │ │ │ ├── create-user.dto.ts # Input validation schemas
31
+ │ │ │ │ ├── update-user.dto.ts
32
+ │ │ │ │ └── user-response.dto.ts # Output serialization
33
+ │ │ │ ├── entities/
34
+ │ │ │ │ └── user.entity.ts # Domain entity
35
+ │ │ │ ├── guards/
36
+ │ │ │ │ └── user-owner.guard.ts # Authorization guard
37
+ │ │ │ └── __tests__/
38
+ │ │ │ ├── user.controller.spec.ts
39
+ │ │ │ └── user.service.spec.ts
40
+ │ │ │
41
+ │ │ ├── auth/
42
+ │ │ │ ├── auth.module.ts
43
+ │ │ │ ├── auth.controller.ts
44
+ │ │ │ ├── auth.service.ts
45
+ │ │ │ ├── strategies/
46
+ │ │ │ │ ├── jwt.strategy.ts
47
+ │ │ │ │ └── local.strategy.ts
48
+ │ │ │ └── guards/
49
+ │ │ │ └── jwt-auth.guard.ts
50
+ │ │ │
51
+ │ │ └── health/
52
+ │ │ ├── health.module.ts
53
+ │ │ └── health.controller.ts
54
+ │ │
55
+ │ ├── shared/ # Cross-cutting concerns
56
+ │ │ ├── config/
57
+ │ │ │ ├── app.config.ts # Zod-validated config
58
+ │ │ │ └── database.config.ts
59
+ │ │ ├── errors/
60
+ │ │ │ ├── app-error.ts # Base error class
61
+ │ │ │ └── http-exception.filter.ts # Global exception filter
62
+ │ │ ├── interceptors/
63
+ │ │ │ ├── logging.interceptor.ts # Request logging
64
+ │ │ │ └── transform.interceptor.ts # Response transformation
65
+ │ │ ├── pipes/
66
+ │ │ │ └── zod-validation.pipe.ts # Zod validation pipe
67
+ │ │ ├── decorators/
68
+ │ │ │ └── current-user.decorator.ts
69
+ │ │ └── lib/
70
+ │ │ ├── prisma.service.ts # Prisma client lifecycle
71
+ │ │ └── logger.module.ts # Pino logger module
72
+ │ │
73
+ │ └── common/
74
+ │ └── types/
75
+ │ └── api-response.ts # Standardized API response type
76
+
77
+ ├── prisma/
78
+ │ ├── schema.prisma
79
+ │ └── migrations/
80
+
81
+ ├── test/ # E2E tests
82
+ │ └── app.e2e-spec.ts
83
+
84
+ ├── .env.example
85
+ ├── nest-cli.json
86
+ ├── tsconfig.json # Strict mode!
87
+ ├── tsconfig.build.json
88
+ ├── vitest.config.ts
89
+ └── package.json
90
+ ```
91
+
92
+ ## Module Pattern (The Law)
93
+
94
+ ```typescript
95
+ // src/modules/user/user.module.ts
96
+ import { Module } from '@nestjs/common';
97
+ import { UserController } from './user.controller';
98
+ import { UserService } from './user.service';
99
+ import { UserRepository } from './user.repository';
100
+
101
+ @Module({
102
+ controllers: [UserController],
103
+ providers: [UserService, UserRepository],
104
+ exports: [UserService], // Only export the service — never the repository
105
+ })
106
+ export class UserModule {}
107
+ ```
108
+
109
+ ## Controller Pattern (Transport ONLY)
110
+
111
+ ```typescript
112
+ // src/modules/user/user.controller.ts
113
+ import { Controller, Get, Post, Body, Param, Query, UseGuards } from '@nestjs/common';
114
+ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
115
+ import { UserService } from './user.service';
116
+ import { CreateUserDto } from './dto/create-user.dto';
117
+ import { UserResponseDto } from './dto/user-response.dto';
118
+ import { JwtAuthGuard } from '@/shared/guards/jwt-auth.guard';
119
+
120
+ @ApiTags('Users')
121
+ @Controller('users')
122
+ export class UserController {
123
+ constructor(private readonly userService: UserService) {}
124
+
125
+ @ApiOperation({ summary: 'Create a new user' })
126
+ @ApiResponse({ status: 201, type: UserResponseDto })
127
+ @ApiResponse({ status: 400, description: 'Validation error' })
128
+ @ApiResponse({ status: 409, description: 'Email already exists' })
129
+ @Post()
130
+ async create(@Body() dto: CreateUserDto): Promise<UserResponseDto> {
131
+ // Controller does: validate input (via pipe) → call service → return response
132
+ // Controller does NOT: query database, check business rules, format data
133
+ return this.userService.create(dto);
134
+ }
135
+
136
+ @ApiBearerAuth()
137
+ @UseGuards(JwtAuthGuard)
138
+ @ApiOperation({ summary: 'List users with pagination' })
139
+ @Get()
140
+ async findAll(
141
+ @Query('page') page: number = 1,
142
+ @Query('limit') limit: number = 20,
143
+ ): Promise<UserResponseDto[]> {
144
+ return this.userService.findAll({ page, limit });
145
+ }
146
+ }
147
+ ```
148
+
149
+ ## Service Pattern (Business Logic)
150
+
151
+ ```typescript
152
+ // src/modules/user/user.service.ts
153
+ import { Injectable, ConflictException } from '@nestjs/common';
154
+ import { UserRepository } from './user.repository';
155
+ import { CreateUserDto } from './dto/create-user.dto';
156
+ import { hash } from 'bcrypt';
157
+
158
+ @Injectable()
159
+ export class UserService {
160
+ constructor(private readonly userRepository: UserRepository) {}
161
+
162
+ async create(dto: CreateUserDto): Promise<UserResponseDto> {
163
+ // Business rule: email must be unique
164
+ const existingUser = await this.userRepository.findByEmail(dto.email);
165
+ if (existingUser) {
166
+ throw new ConflictException('Email already registered');
167
+ }
168
+
169
+ // Business rule: hash password before storage
170
+ const hashedPassword = await hash(dto.password, 12);
171
+
172
+ return this.userRepository.create({
173
+ ...dto,
174
+ password: hashedPassword,
175
+ });
176
+ }
177
+ }
178
+ ```
179
+
180
+ ## Repository Pattern (Data Access Only)
181
+
182
+ ```typescript
183
+ // src/modules/user/user.repository.ts
184
+ import { Injectable } from '@nestjs/common';
185
+ import { PrismaService } from '@/shared/lib/prisma.service';
186
+ import { User } from '@prisma/client';
187
+
188
+ @Injectable()
189
+ export class UserRepository {
190
+ constructor(private readonly prisma: PrismaService) {}
191
+
192
+ async findByEmail(email: string): Promise<User | null> {
193
+ return this.prisma.user.findUnique({ where: { email } });
194
+ }
195
+
196
+ async create(data: Omit<User, 'id' | 'createdAt' | 'updatedAt'>): Promise<User> {
197
+ return this.prisma.user.create({ data });
198
+ }
199
+
200
+ async findAll(params: { skip: number; take: number }): Promise<User[]> {
201
+ return this.prisma.user.findMany({
202
+ skip: params.skip,
203
+ take: params.take,
204
+ select: { id: true, email: true, name: true, createdAt: true },
205
+ // NEVER select password
206
+ });
207
+ }
208
+ }
209
+ ```
210
+
211
+ ## Swagger Setup (Mandatory)
212
+
213
+ ```typescript
214
+ // src/main.ts
215
+ import { NestFactory } from '@nestjs/core';
216
+ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
217
+ import { AppModule } from './app.module';
218
+
219
+ async function bootstrap() {
220
+ const app = await NestFactory.create(AppModule);
221
+
222
+ // Swagger — auto-generates API documentation
223
+ const config = new DocumentBuilder()
224
+ .setTitle('API Documentation')
225
+ .setVersion('1.0')
226
+ .addBearerAuth()
227
+ .build();
228
+
229
+ const document = SwaggerModule.createDocument(app, config);
230
+ SwaggerModule.setup('docs', app, document);
231
+
232
+ await app.listen(3000);
233
+ }
234
+ bootstrap();
235
+ ```
236
+
237
+ ## Scaffolding Checklist
238
+
239
+ - [ ] Every module follows Controller → Service → Repository layering
240
+ - [ ] DTOs use Zod or class-validator for ALL input validation
241
+ - [ ] Swagger decorators on every controller method
242
+ - [ ] Global exception filter catches and formats all errors
243
+ - [ ] Repository NEVER exposes raw Prisma client outside its module
244
+ - [ ] Service is exported, Repository is NOT (module encapsulation)
245
+ - [ ] Tests exist for service logic (unit) and controller routes (integration)
246
+ - [ ] Environment variables validated with Zod at startup
247
+ - [ ] Health check endpoint exists at `/health`