dsh-ecc-skills 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +99 -0
- package/cordis.patch.yml +5 -0
- package/lib/index.js +195 -0
- package/package.json +46 -0
- package/skills/accessibility/SKILL.md +147 -0
- package/skills/agent-architecture-audit/SKILL.md +257 -0
- package/skills/agent-eval/SKILL.md +147 -0
- package/skills/agent-harness-construction/SKILL.md +74 -0
- package/skills/agent-introspection-debugging/SKILL.md +154 -0
- package/skills/agent-payment-x402/SKILL.md +225 -0
- package/skills/agent-self-evaluation/SKILL.md +182 -0
- package/skills/agent-sort/SKILL.md +216 -0
- package/skills/agentic-engineering/SKILL.md +64 -0
- package/skills/agentic-os/SKILL.md +388 -0
- package/skills/ai-first-engineering/SKILL.md +52 -0
- package/skills/ai-regression-testing/SKILL.md +386 -0
- package/skills/android-clean-architecture/SKILL.md +340 -0
- package/skills/angular-developer/SKILL.md +155 -0
- package/skills/api-connector-builder/SKILL.md +121 -0
- package/skills/api-design/SKILL.md +524 -0
- package/skills/architecture-decision-records/SKILL.md +180 -0
- package/skills/article-writing/SKILL.md +80 -0
- package/skills/automation-audit-ops/SKILL.md +143 -0
- package/skills/autonomous-agent-harness/SKILL.md +274 -0
- package/skills/autonomous-loops/SKILL.md +611 -0
- package/skills/backend-patterns/SKILL.md +562 -0
- package/skills/benchmark/SKILL.md +95 -0
- package/skills/benchmark-methodology/SKILL.md +191 -0
- package/skills/benchmark-optimization-loop/SKILL.md +71 -0
- package/skills/blender-motion-state-inspection/SKILL.md +165 -0
- package/skills/blueprint/SKILL.md +106 -0
- package/skills/brand-discovery/SKILL.md +145 -0
- package/skills/brand-voice/SKILL.md +98 -0
- package/skills/browser-qa/SKILL.md +105 -0
- package/skills/bun-runtime/SKILL.md +85 -0
- package/skills/canary-watch/SKILL.md +108 -0
- package/skills/carrier-relationship-management/SKILL.md +212 -0
- package/skills/cisco-ios-patterns/SKILL.md +164 -0
- package/skills/ck/SKILL.md +148 -0
- package/skills/claude-devfleet/SKILL.md +112 -0
- package/skills/click-path-audit/SKILL.md +245 -0
- package/skills/clickhouse-io/SKILL.md +445 -0
- package/skills/code-tour/SKILL.md +254 -0
- package/skills/codebase-onboarding/SKILL.md +234 -0
- package/skills/codehealth-mcp/SKILL.md +167 -0
- package/skills/coding-standards/SKILL.md +551 -0
- package/skills/competitive-platform-analysis/SKILL.md +214 -0
- package/skills/competitive-report-structure/SKILL.md +162 -0
- package/skills/compose-multiplatform-patterns/SKILL.md +300 -0
- package/skills/config-gc/SKILL.md +120 -0
- package/skills/configure-ecc/SKILL.md +206 -0
- package/skills/connections-optimizer/SKILL.md +190 -0
- package/skills/content-engine/SKILL.md +132 -0
- package/skills/content-hash-cache-pattern/SKILL.md +162 -0
- package/skills/context-budget/SKILL.md +136 -0
- package/skills/continuous-agent-loop/SKILL.md +46 -0
- package/skills/contract-first/SKILL.md +287 -0
- package/skills/cost-aware-llm-pipeline/SKILL.md +184 -0
- package/skills/cost-tracking/SKILL.md +97 -0
- package/skills/council/SKILL.md +204 -0
- package/skills/council-multi-model/SKILL.md +167 -0
- package/skills/cpp-coding-standards/SKILL.md +724 -0
- package/skills/cpp-testing/SKILL.md +325 -0
- package/skills/crosspost/SKILL.md +112 -0
- package/skills/csharp-testing/SKILL.md +322 -0
- package/skills/customer-billing-ops/SKILL.md +141 -0
- package/skills/customs-trade-compliance/SKILL.md +263 -0
- package/skills/dart-flutter-patterns/SKILL.md +564 -0
- package/skills/dashboard-builder/SKILL.md +109 -0
- package/skills/data-scraper-agent/SKILL.md +765 -0
- package/skills/data-throughput-accelerator/SKILL.md +74 -0
- package/skills/database-migrations/SKILL.md +430 -0
- package/skills/deep-research/SKILL.md +160 -0
- package/skills/defi-amm-security/SKILL.md +167 -0
- package/skills/delivery-gate/SKILL.md +126 -0
- package/skills/deployment-patterns/SKILL.md +428 -0
- package/skills/design-system/SKILL.md +83 -0
- package/skills/dev-team/SKILL.md +203 -0
- package/skills/django-celery/SKILL.md +458 -0
- package/skills/django-patterns/SKILL.md +735 -0
- package/skills/django-security/SKILL.md +644 -0
- package/skills/django-tdd/SKILL.md +730 -0
- package/skills/django-verification/SKILL.md +470 -0
- package/skills/dmux-workflows/SKILL.md +192 -0
- package/skills/docker-patterns/SKILL.md +520 -0
- package/skills/documentation-lookup/SKILL.md +91 -0
- package/skills/dotnet-patterns/SKILL.md +322 -0
- package/skills/dynamic-workflow-mode/SKILL.md +124 -0
- package/skills/e2e-testing/SKILL.md +327 -0
- package/skills/ecc-tools-cost-audit/SKILL.md +161 -0
- package/skills/email-ops/SKILL.md +122 -0
- package/skills/energy-procurement/SKILL.md +228 -0
- package/skills/enterprise-agent-ops/SKILL.md +51 -0
- package/skills/error-handling/SKILL.md +377 -0
- package/skills/eval-harness/SKILL.md +271 -0
- package/skills/evm-token-decimals/SKILL.md +131 -0
- package/skills/exa-search/SKILL.md +108 -0
- package/skills/fal-ai-media/SKILL.md +289 -0
- package/skills/fastapi-patterns/SKILL.md +514 -0
- package/skills/finance-billing-ops/SKILL.md +128 -0
- package/skills/flox-environments/SKILL.md +497 -0
- package/skills/flutter-dart-code-review/SKILL.md +436 -0
- package/skills/foundation-models-on-device/SKILL.md +243 -0
- package/skills/frontend-a11y/SKILL.md +446 -0
- package/skills/frontend-design-direction/SKILL.md +93 -0
- package/skills/frontend-patterns/SKILL.md +657 -0
- package/skills/fsharp-testing/SKILL.md +281 -0
- package/skills/gan-style-harness/SKILL.md +279 -0
- package/skills/generating-python-installer/SKILL.md +820 -0
- package/skills/git-workflow/SKILL.md +716 -0
- package/skills/github-ops/SKILL.md +145 -0
- package/skills/golang-patterns/SKILL.md +676 -0
- package/skills/golang-testing/SKILL.md +721 -0
- package/skills/google-workspace-ops/SKILL.md +96 -0
- package/skills/growth-log/SKILL.md +128 -0
- package/skills/healthcare-cdss-patterns/SKILL.md +246 -0
- package/skills/healthcare-emr-patterns/SKILL.md +160 -0
- package/skills/healthcare-eval-harness/SKILL.md +208 -0
- package/skills/healthcare-phi-compliance/SKILL.md +146 -0
- package/skills/hermes-imports/SKILL.md +89 -0
- package/skills/hexagonal-architecture/SKILL.md +277 -0
- package/skills/hipaa-compliance/SKILL.md +79 -0
- package/skills/homelab-network-readiness/SKILL.md +170 -0
- package/skills/homelab-network-setup/SKILL.md +130 -0
- package/skills/homelab-pihole-dns/SKILL.md +275 -0
- package/skills/homelab-vlan-segmentation/SKILL.md +312 -0
- package/skills/homelab-wireguard-vpn/SKILL.md +306 -0
- package/skills/hookify-rules/SKILL.md +128 -0
- package/skills/inherit-legacy-style/SKILL.md +157 -0
- package/skills/intent-driven-development/SKILL.md +360 -0
- package/skills/inventory-demand-planning/SKILL.md +247 -0
- package/skills/investor-materials/SKILL.md +97 -0
- package/skills/investor-outreach/SKILL.md +92 -0
- package/skills/ios-icon-gen/SKILL.md +158 -0
- package/skills/iterative-retrieval/SKILL.md +212 -0
- package/skills/ito-baskets/SKILL.md +263 -0
- package/skills/ito-compute/SKILL.md +151 -0
- package/skills/ito-inference/SKILL.md +119 -0
- package/skills/ito-training/SKILL.md +123 -0
- package/skills/java-coding-standards/SKILL.md +384 -0
- package/skills/jira-integration/SKILL.md +303 -0
- package/skills/jpa-patterns/SKILL.md +152 -0
- package/skills/knowledge-ops/SKILL.md +155 -0
- package/skills/kotlin-coroutines-flows/SKILL.md +285 -0
- package/skills/kotlin-exposed-patterns/SKILL.md +720 -0
- package/skills/kotlin-ktor-patterns/SKILL.md +690 -0
- package/skills/kotlin-patterns/SKILL.md +712 -0
- package/skills/kotlin-testing/SKILL.md +825 -0
- package/skills/kubernetes-patterns/SKILL.md +756 -0
- package/skills/laravel-patterns/SKILL.md +416 -0
- package/skills/laravel-plugin-discovery/SKILL.md +230 -0
- package/skills/laravel-security/SKILL.md +948 -0
- package/skills/laravel-tdd/SKILL.md +675 -0
- package/skills/laravel-verification/SKILL.md +180 -0
- package/skills/latency-critical-systems/SKILL.md +75 -0
- package/skills/lead-intelligence/SKILL.md +322 -0
- package/skills/liquid-glass-design/SKILL.md +279 -0
- package/skills/living-docs-governance/SKILL.md +137 -0
- package/skills/llm-trading-agent-security/SKILL.md +147 -0
- package/skills/logistics-exception-management/SKILL.md +222 -0
- package/skills/loop-design-check/SKILL.md +143 -0
- package/skills/mailtrap-email-integration/SKILL.md +77 -0
- package/skills/make-interfaces-feel-better/SKILL.md +152 -0
- package/skills/manim-video/SKILL.md +90 -0
- package/skills/market-research/SKILL.md +76 -0
- package/skills/marketing-campaign/SKILL.md +114 -0
- package/skills/mcp-server-patterns/SKILL.md +70 -0
- package/skills/messages-ops/SKILL.md +105 -0
- package/skills/ml-adoption-playbook/SKILL.md +57 -0
- package/skills/mle-workflow/SKILL.md +348 -0
- package/skills/motion-advanced/SKILL.md +597 -0
- package/skills/motion-foundations/SKILL.md +300 -0
- package/skills/motion-patterns/SKILL.md +435 -0
- package/skills/motion-ui/SKILL.md +576 -0
- package/skills/mysql-patterns/SKILL.md +413 -0
- package/skills/nanoclaw-repl/SKILL.md +34 -0
- package/skills/nasiko-control-plane/SKILL.md +49 -0
- package/skills/nestjs-patterns/SKILL.md +231 -0
- package/skills/netmiko-ssh-automation/SKILL.md +174 -0
- package/skills/network-bgp-diagnostics/SKILL.md +168 -0
- package/skills/network-config-validation/SKILL.md +211 -0
- package/skills/network-interface-health/SKILL.md +153 -0
- package/skills/nextjs-turbopack/SKILL.md +58 -0
- package/skills/nodejs-keccak256/SKILL.md +103 -0
- package/skills/nutrient-document-processing/SKILL.md +168 -0
- package/skills/nuxt4-patterns/SKILL.md +101 -0
- package/skills/opensource-pipeline/SKILL.md +256 -0
- package/skills/orch-add-feature/SKILL.md +45 -0
- package/skills/orch-build-mvp/SKILL.md +49 -0
- package/skills/orch-change-feature/SKILL.md +43 -0
- package/skills/orch-fix-defect/SKILL.md +43 -0
- package/skills/orch-pipeline/SKILL.md +121 -0
- package/skills/orch-refine-code/SKILL.md +44 -0
- package/skills/parallel-execution-optimizer/SKILL.md +74 -0
- package/skills/perl-patterns/SKILL.md +505 -0
- package/skills/perl-security/SKILL.md +504 -0
- package/skills/perl-testing/SKILL.md +476 -0
- package/skills/plan-canvas/SKILL.md +196 -0
- package/skills/plankton-code-quality/SKILL.md +237 -0
- package/skills/postgres-patterns/SKILL.md +148 -0
- package/skills/prediction-market-oracle-research/SKILL.md +64 -0
- package/skills/prediction-market-risk-review/SKILL.md +61 -0
- package/skills/prisma-patterns/SKILL.md +401 -0
- package/skills/product-capability/SKILL.md +142 -0
- package/skills/product-lens/SKILL.md +93 -0
- package/skills/production-audit/SKILL.md +207 -0
- package/skills/production-scheduling/SKILL.md +238 -0
- package/skills/project-flow-ops/SKILL.md +112 -0
- package/skills/prompt-optimizer/SKILL.md +398 -0
- package/skills/python-patterns/SKILL.md +751 -0
- package/skills/python-testing/SKILL.md +817 -0
- package/skills/pytorch-patterns/SKILL.md +397 -0
- package/skills/quality-nonconformance/SKILL.md +260 -0
- package/skills/quarkus-patterns/SKILL.md +723 -0
- package/skills/quarkus-security/SKILL.md +468 -0
- package/skills/quarkus-tdd/SKILL.md +812 -0
- package/skills/quarkus-verification/SKILL.md +481 -0
- package/skills/ralphinho-rfc-pipeline/SKILL.md +68 -0
- package/skills/react-native-patterns/SKILL.md +326 -0
- package/skills/react-patterns/SKILL.md +342 -0
- package/skills/react-performance/SKILL.md +575 -0
- package/skills/react-testing/SKILL.md +424 -0
- package/skills/recsys-pipeline-architect/SKILL.md +115 -0
- package/skills/recursive-decision-ledger/SKILL.md +81 -0
- package/skills/redis-patterns/SKILL.md +404 -0
- package/skills/regex-vs-llm-structured-text/SKILL.md +221 -0
- package/skills/remotion-video-creation/SKILL.md +43 -0
- package/skills/repo-scan/SKILL.md +170 -0
- package/skills/research-ops/SKILL.md +113 -0
- package/skills/returns-reverse-logistics/SKILL.md +240 -0
- package/skills/rules-distill/SKILL.md +265 -0
- package/skills/rust-patterns/SKILL.md +500 -0
- package/skills/rust-testing/SKILL.md +501 -0
- package/skills/safety-guard/SKILL.md +76 -0
- package/skills/santa-method/SKILL.md +307 -0
- package/skills/scientific-db-pubmed-database/SKILL.md +176 -0
- package/skills/scientific-db-uspto-database/SKILL.md +178 -0
- package/skills/scientific-pkg-gget/SKILL.md +167 -0
- package/skills/scientific-thinking-literature-review/SKILL.md +193 -0
- package/skills/scientific-thinking-scholar-evaluation/SKILL.md +161 -0
- package/skills/search-first/SKILL.md +183 -0
- package/skills/security-bounty-hunter/SKILL.md +100 -0
- package/skills/security-scan/SKILL.md +166 -0
- package/skills/seo/SKILL.md +155 -0
- package/skills/skill-scout/SKILL.md +141 -0
- package/skills/skill-stocktake/SKILL.md +195 -0
- package/skills/social-graph-ranker/SKILL.md +155 -0
- package/skills/social-publisher/SKILL.md +130 -0
- package/skills/springboot-patterns/SKILL.md +315 -0
- package/skills/springboot-security/SKILL.md +273 -0
- package/skills/springboot-tdd/SKILL.md +159 -0
- package/skills/springboot-verification/SKILL.md +232 -0
- package/skills/swift-actor-persistence/SKILL.md +144 -0
- package/skills/swift-concurrency-6-2/SKILL.md +216 -0
- package/skills/swift-protocol-di-testing/SKILL.md +191 -0
- package/skills/swiftui-patterns/SKILL.md +259 -0
- package/skills/taste/SKILL.md +264 -0
- package/skills/tdd-workflow/SKILL.md +583 -0
- package/skills/team-agent-orchestration/SKILL.md +111 -0
- package/skills/team-builder/SKILL.md +169 -0
- package/skills/terminal-opener/SKILL.md +55 -0
- package/skills/terminal-ops/SKILL.md +110 -0
- package/skills/tinystruct-patterns/SKILL.md +279 -0
- package/skills/token-budget-advisor/SKILL.md +134 -0
- package/skills/ui-demo/SKILL.md +466 -0
- package/skills/ui-to-vue/SKILL.md +135 -0
- package/skills/uncloud/SKILL.md +344 -0
- package/skills/unified-memory/SKILL.md +170 -0
- package/skills/unified-notifications-ops/SKILL.md +188 -0
- package/skills/verification-loop/SKILL.md +129 -0
- package/skills/video-editing/SKILL.md +311 -0
- package/skills/videodb/SKILL.md +375 -0
- package/skills/vite-patterns/SKILL.md +450 -0
- package/skills/vue-patterns/SKILL.md +471 -0
- package/skills/windows-desktop-e2e/SKILL.md +888 -0
- package/skills/workspace-surface-audit/SKILL.md +126 -0
- package/skills/x-api/SKILL.md +235 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nestjs-patterns
|
|
3
|
+
description: NestJS architecture patterns for modules, controllers, providers, DTO validation, guards, interceptors, config, and production-grade TypeScript backends. Use when building or reviewing a NestJS backend — modules, providers, DTO validation, guards, or interceptors.
|
|
4
|
+
metadata:
|
|
5
|
+
origin: ECC
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# NestJS Development Patterns
|
|
9
|
+
|
|
10
|
+
Production-grade NestJS patterns for modular TypeScript backends.
|
|
11
|
+
|
|
12
|
+
## When to Activate
|
|
13
|
+
|
|
14
|
+
- Building NestJS APIs or services
|
|
15
|
+
- Structuring modules, controllers, and providers
|
|
16
|
+
- Adding DTO validation, guards, interceptors, or exception filters
|
|
17
|
+
- Configuring environment-aware settings and database integrations
|
|
18
|
+
- Testing NestJS units or HTTP endpoints
|
|
19
|
+
|
|
20
|
+
## Project Structure
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
src/
|
|
24
|
+
├── app.module.ts
|
|
25
|
+
├── main.ts
|
|
26
|
+
├── common/
|
|
27
|
+
│ ├── filters/
|
|
28
|
+
│ ├── guards/
|
|
29
|
+
│ ├── interceptors/
|
|
30
|
+
│ └── pipes/
|
|
31
|
+
├── config/
|
|
32
|
+
│ ├── configuration.ts
|
|
33
|
+
│ └── validation.ts
|
|
34
|
+
├── modules/
|
|
35
|
+
│ ├── auth/
|
|
36
|
+
│ │ ├── auth.controller.ts
|
|
37
|
+
│ │ ├── auth.module.ts
|
|
38
|
+
│ │ ├── auth.service.ts
|
|
39
|
+
│ │ ├── dto/
|
|
40
|
+
│ │ ├── guards/
|
|
41
|
+
│ │ └── strategies/
|
|
42
|
+
│ └── users/
|
|
43
|
+
│ ├── dto/
|
|
44
|
+
│ ├── entities/
|
|
45
|
+
│ ├── users.controller.ts
|
|
46
|
+
│ ├── users.module.ts
|
|
47
|
+
│ └── users.service.ts
|
|
48
|
+
└── prisma/ or database/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- Keep domain code inside feature modules.
|
|
52
|
+
- Put cross-cutting filters, decorators, guards, and interceptors in `common/`.
|
|
53
|
+
- Keep DTOs close to the module that owns them.
|
|
54
|
+
|
|
55
|
+
## Bootstrap and Global Validation
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
async function bootstrap() {
|
|
59
|
+
const app = await NestFactory.create(AppModule, { bufferLogs: true });
|
|
60
|
+
|
|
61
|
+
app.useGlobalPipes(
|
|
62
|
+
new ValidationPipe({
|
|
63
|
+
whitelist: true,
|
|
64
|
+
forbidNonWhitelisted: true,
|
|
65
|
+
transform: true,
|
|
66
|
+
transformOptions: { enableImplicitConversion: true },
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));
|
|
71
|
+
app.useGlobalFilters(new HttpExceptionFilter());
|
|
72
|
+
|
|
73
|
+
await app.listen(process.env.PORT ?? 3000);
|
|
74
|
+
}
|
|
75
|
+
bootstrap();
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- Always enable `whitelist` and `forbidNonWhitelisted` on public APIs.
|
|
79
|
+
- Prefer one global validation pipe instead of repeating validation config per route.
|
|
80
|
+
|
|
81
|
+
## Modules, Controllers, and Providers
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
@Module({
|
|
85
|
+
controllers: [UsersController],
|
|
86
|
+
providers: [UsersService],
|
|
87
|
+
exports: [UsersService],
|
|
88
|
+
})
|
|
89
|
+
export class UsersModule {}
|
|
90
|
+
|
|
91
|
+
@Controller('users')
|
|
92
|
+
export class UsersController {
|
|
93
|
+
constructor(private readonly usersService: UsersService) {}
|
|
94
|
+
|
|
95
|
+
@Get(':id')
|
|
96
|
+
getById(@Param('id', ParseUUIDPipe) id: string) {
|
|
97
|
+
return this.usersService.getById(id);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@Post()
|
|
101
|
+
create(@Body() dto: CreateUserDto) {
|
|
102
|
+
return this.usersService.create(dto);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Injectable()
|
|
107
|
+
export class UsersService {
|
|
108
|
+
constructor(private readonly usersRepo: UsersRepository) {}
|
|
109
|
+
|
|
110
|
+
async create(dto: CreateUserDto) {
|
|
111
|
+
return this.usersRepo.create(dto);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
- Controllers should stay thin: parse HTTP input, call a provider, return response DTOs.
|
|
117
|
+
- Put business logic in injectable services, not controllers.
|
|
118
|
+
- Export only the providers other modules genuinely need.
|
|
119
|
+
|
|
120
|
+
## DTOs and Validation
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
export class CreateUserDto {
|
|
124
|
+
@IsEmail()
|
|
125
|
+
email!: string;
|
|
126
|
+
|
|
127
|
+
@IsString()
|
|
128
|
+
@Length(2, 80)
|
|
129
|
+
name!: string;
|
|
130
|
+
|
|
131
|
+
@IsOptional()
|
|
132
|
+
@IsEnum(UserRole)
|
|
133
|
+
role?: UserRole;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- Validate every request DTO with `class-validator`.
|
|
138
|
+
- Use dedicated response DTOs or serializers instead of returning ORM entities directly.
|
|
139
|
+
- Avoid leaking internal fields such as password hashes, tokens, or audit columns.
|
|
140
|
+
|
|
141
|
+
## Auth, Guards, and Request Context
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
145
|
+
@Roles('admin')
|
|
146
|
+
@Get('admin/report')
|
|
147
|
+
getAdminReport(@Req() req: AuthenticatedRequest) {
|
|
148
|
+
return this.reportService.getForUser(req.user.id);
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- Keep auth strategies and guards module-local unless they are truly shared.
|
|
153
|
+
- Encode coarse access rules in guards, then do resource-specific authorization in services.
|
|
154
|
+
- Prefer explicit request types for authenticated request objects.
|
|
155
|
+
|
|
156
|
+
## Exception Filters and Error Shape
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
@Catch()
|
|
160
|
+
export class HttpExceptionFilter implements ExceptionFilter {
|
|
161
|
+
catch(exception: unknown, host: ArgumentsHost) {
|
|
162
|
+
const response = host.switchToHttp().getResponse<Response>();
|
|
163
|
+
const request = host.switchToHttp().getRequest<Request>();
|
|
164
|
+
|
|
165
|
+
if (exception instanceof HttpException) {
|
|
166
|
+
return response.status(exception.getStatus()).json({
|
|
167
|
+
path: request.url,
|
|
168
|
+
error: exception.getResponse(),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return response.status(500).json({
|
|
173
|
+
path: request.url,
|
|
174
|
+
error: 'Internal server error',
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- Keep one consistent error envelope across the API.
|
|
181
|
+
- Throw framework exceptions for expected client errors; log and wrap unexpected failures centrally.
|
|
182
|
+
|
|
183
|
+
## Config and Environment Validation
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
ConfigModule.forRoot({
|
|
187
|
+
isGlobal: true,
|
|
188
|
+
load: [configuration],
|
|
189
|
+
validate: validateEnv,
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- Validate env at boot, not lazily at first request.
|
|
194
|
+
- Keep config access behind typed helpers or config services.
|
|
195
|
+
- Split dev/staging/prod concerns in config factories instead of branching throughout feature code.
|
|
196
|
+
|
|
197
|
+
## Persistence and Transactions
|
|
198
|
+
|
|
199
|
+
- Keep repository / ORM code behind providers that speak domain language.
|
|
200
|
+
- For Prisma or TypeORM, isolate transactional workflows in services that own the unit of work.
|
|
201
|
+
- Do not let controllers coordinate multi-step writes directly.
|
|
202
|
+
|
|
203
|
+
## Testing
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
describe('UsersController', () => {
|
|
207
|
+
let app: INestApplication;
|
|
208
|
+
|
|
209
|
+
beforeAll(async () => {
|
|
210
|
+
const moduleRef = await Test.createTestingModule({
|
|
211
|
+
imports: [UsersModule],
|
|
212
|
+
}).compile();
|
|
213
|
+
|
|
214
|
+
app = moduleRef.createNestApplication();
|
|
215
|
+
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
|
|
216
|
+
await app.init();
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
- Unit test providers in isolation with mocked dependencies.
|
|
222
|
+
- Add request-level tests for guards, validation pipes, and exception filters.
|
|
223
|
+
- Reuse the same global pipes/filters in tests that you use in production.
|
|
224
|
+
|
|
225
|
+
## Production Defaults
|
|
226
|
+
|
|
227
|
+
- Enable structured logging and request correlation ids.
|
|
228
|
+
- Terminate on invalid env/config instead of booting partially.
|
|
229
|
+
- Prefer async provider initialization for DB/cache clients with explicit health checks.
|
|
230
|
+
- Keep background jobs and event consumers in their own modules, not inside HTTP controllers.
|
|
231
|
+
- Make rate limiting, auth, and audit logging explicit for public endpoints.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: netmiko-ssh-automation
|
|
3
|
+
description: Safe Python Netmiko patterns for read-only collection, bounded batch SSH, TextFSM parsing, guarded config changes, timeouts, and network automation error handling. Use when automating network device access with Python Netmiko, whether collecting state or pushing guarded config changes.
|
|
4
|
+
metadata:
|
|
5
|
+
origin: community
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Netmiko SSH Automation
|
|
9
|
+
|
|
10
|
+
Use this skill when writing or reviewing Python automation that connects to
|
|
11
|
+
network devices with Netmiko. Keep the default path read-only; config changes
|
|
12
|
+
need a separate change window, peer review, and rollback plan.
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- Collecting `show` command output across routers, switches, or firewalls.
|
|
17
|
+
- Building a small audit script for interface, routing, or config evidence.
|
|
18
|
+
- Adding timeouts and exception handling to network SSH scripts.
|
|
19
|
+
- Parsing command output with TextFSM when a template exists.
|
|
20
|
+
- Reviewing automation before it touches production devices.
|
|
21
|
+
|
|
22
|
+
## Safety Defaults
|
|
23
|
+
|
|
24
|
+
- Start with read-only `send_command()` collection.
|
|
25
|
+
- Keep inventory small and explicit; do not sweep whole address ranges.
|
|
26
|
+
- Use environment variables, a vault, or `getpass`; never hardcode credentials.
|
|
27
|
+
- Set connection and read timeouts.
|
|
28
|
+
- Limit concurrency so older devices are not overloaded.
|
|
29
|
+
- Require an explicit operator flag before `send_config_set()`.
|
|
30
|
+
- Do not call `save_config()` until the change has been verified and approved.
|
|
31
|
+
|
|
32
|
+
## Read-Only Connection Pattern
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import os
|
|
36
|
+
from getpass import getpass
|
|
37
|
+
from netmiko import ConnectHandler
|
|
38
|
+
from netmiko.exceptions import (
|
|
39
|
+
NetmikoAuthenticationException,
|
|
40
|
+
NetmikoTimeoutException,
|
|
41
|
+
ReadTimeout,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
device = {
|
|
45
|
+
"device_type": "cisco_ios",
|
|
46
|
+
"host": "192.0.2.10",
|
|
47
|
+
"username": os.environ.get("NETMIKO_USERNAME") or input("Username: "),
|
|
48
|
+
"password": os.environ.get("NETMIKO_PASSWORD") or getpass("Password: "),
|
|
49
|
+
"secret": os.environ.get("NETMIKO_ENABLE_SECRET"),
|
|
50
|
+
"conn_timeout": 10,
|
|
51
|
+
"auth_timeout": 20,
|
|
52
|
+
"banner_timeout": 15,
|
|
53
|
+
"read_timeout_override": 30,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
with ConnectHandler(**device) as conn:
|
|
58
|
+
if device.get("secret") and not conn.check_enable_mode():
|
|
59
|
+
conn.enable()
|
|
60
|
+
output = conn.send_command("show ip interface brief", read_timeout=30)
|
|
61
|
+
print(output)
|
|
62
|
+
except NetmikoAuthenticationException:
|
|
63
|
+
print("Authentication failed")
|
|
64
|
+
except NetmikoTimeoutException:
|
|
65
|
+
print("SSH connection timed out")
|
|
66
|
+
except ReadTimeout:
|
|
67
|
+
print("Command read timed out")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Use placeholder addresses from documentation ranges in examples. Keep real
|
|
71
|
+
inventory in an ignored local file or a secrets-managed system.
|
|
72
|
+
|
|
73
|
+
## Batch Collection
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
77
|
+
from typing import Any
|
|
78
|
+
|
|
79
|
+
def collect_show(device: dict[str, Any], command: str) -> dict[str, Any]:
|
|
80
|
+
host = device["host"]
|
|
81
|
+
try:
|
|
82
|
+
with ConnectHandler(**device) as conn:
|
|
83
|
+
output = conn.send_command(command, read_timeout=45)
|
|
84
|
+
return {"host": host, "ok": True, "output": output}
|
|
85
|
+
except (NetmikoAuthenticationException, NetmikoTimeoutException, ReadTimeout) as exc:
|
|
86
|
+
return {"host": host, "ok": False, "error": type(exc).__name__}
|
|
87
|
+
|
|
88
|
+
results = []
|
|
89
|
+
with ThreadPoolExecutor(max_workers=8) as pool:
|
|
90
|
+
futures = [pool.submit(collect_show, device, "show version") for device in devices]
|
|
91
|
+
for future in as_completed(futures):
|
|
92
|
+
results.append(future.result())
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Keep `max_workers` low unless the device estate and AAA systems are known to
|
|
96
|
+
handle higher connection volume.
|
|
97
|
+
|
|
98
|
+
## Structured Parsing
|
|
99
|
+
|
|
100
|
+
Netmiko can ask TextFSM, TTP, or Genie to parse supported command output. Treat
|
|
101
|
+
parser output as an optimization, not the only evidence path.
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
with ConnectHandler(**device) as conn:
|
|
105
|
+
parsed = conn.send_command(
|
|
106
|
+
"show ip interface brief",
|
|
107
|
+
use_textfsm=True,
|
|
108
|
+
raise_parsing_error=False,
|
|
109
|
+
read_timeout=30,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
if isinstance(parsed, str):
|
|
113
|
+
print("No parser template matched; store raw output for review")
|
|
114
|
+
else:
|
|
115
|
+
for row in parsed:
|
|
116
|
+
print(row)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If parsing drives a blocking decision, keep the raw command output alongside
|
|
120
|
+
the parsed result so an operator can inspect mismatches.
|
|
121
|
+
|
|
122
|
+
## Guarded Config Pattern
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
import os
|
|
126
|
+
|
|
127
|
+
commands = [
|
|
128
|
+
"interface GigabitEthernet0/1",
|
|
129
|
+
"description CHANGE-1234 UPLINK-TO-CORE",
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
apply_changes = os.environ.get("APPLY_NETWORK_CHANGES") == "1"
|
|
133
|
+
|
|
134
|
+
if not apply_changes:
|
|
135
|
+
print("Dry run only. Candidate commands:")
|
|
136
|
+
print("\n".join(commands))
|
|
137
|
+
else:
|
|
138
|
+
with ConnectHandler(**device) as conn:
|
|
139
|
+
conn.enable()
|
|
140
|
+
before = conn.send_command("show running-config interface GigabitEthernet0/1")
|
|
141
|
+
output = conn.send_config_set(commands)
|
|
142
|
+
after = conn.send_command("show running-config interface GigabitEthernet0/1")
|
|
143
|
+
print(before)
|
|
144
|
+
print(output)
|
|
145
|
+
print(after)
|
|
146
|
+
print("Verify behavior before saving startup config.")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Saving the config is a separate approval step. In production, include a rollback
|
|
150
|
+
snippet and capture before/after evidence in the change record.
|
|
151
|
+
|
|
152
|
+
## Review Checklist
|
|
153
|
+
|
|
154
|
+
- Does the script identify an explicit inventory source?
|
|
155
|
+
- Are credentials absent from source, logs, and exception messages?
|
|
156
|
+
- Are `conn_timeout`, `auth_timeout`, and command `read_timeout` set?
|
|
157
|
+
- Are failures reported per device without stopping the whole batch?
|
|
158
|
+
- Does the script avoid broad scans and unbounded concurrency?
|
|
159
|
+
- Are config changes behind a dry-run or explicit operator flag?
|
|
160
|
+
- Is `save_config()` separate from the initial push and tied to verification?
|
|
161
|
+
|
|
162
|
+
## Anti-Patterns
|
|
163
|
+
|
|
164
|
+
- Hardcoding passwords, enable secrets, or private keys in source.
|
|
165
|
+
- Sending config commands as the default code path.
|
|
166
|
+
- Running automation against a CIDR range instead of a reviewed inventory.
|
|
167
|
+
- Logging full running configs to shared systems without sanitization.
|
|
168
|
+
- Treating parser success as proof that the device state is correct.
|
|
169
|
+
|
|
170
|
+
## See Also
|
|
171
|
+
|
|
172
|
+
- Skill: `cisco-ios-patterns`
|
|
173
|
+
- Skill: `network-config-validation`
|
|
174
|
+
- Skill: `network-interface-health`
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: network-bgp-diagnostics
|
|
3
|
+
description: Diagnostics-only BGP troubleshooting patterns for neighbor state, route exchange, prefix policy, AS path inspection, and safe evidence collection. Use when a BGP neighbor is down, routes are missing, or prefix policy and AS path need inspection.
|
|
4
|
+
metadata:
|
|
5
|
+
origin: community
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Network BGP Diagnostics
|
|
9
|
+
|
|
10
|
+
Use this skill when a BGP session is down, flapping, established with missing
|
|
11
|
+
routes, or advertising unexpected prefixes. The default workflow is read-only
|
|
12
|
+
evidence collection; policy and reset actions belong in a reviewed change
|
|
13
|
+
window.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- BGP neighbors are stuck in Idle, Connect, Active, OpenSent, or OpenConfirm.
|
|
18
|
+
- A session is Established but expected prefixes are missing.
|
|
19
|
+
- A route-map, prefix-list, max-prefix limit, or AS path policy may be filtering
|
|
20
|
+
routes.
|
|
21
|
+
- You need before/after evidence for a BGP change.
|
|
22
|
+
- You are reviewing automation that parses BGP summary output.
|
|
23
|
+
|
|
24
|
+
## Read-Only Triage Flow
|
|
25
|
+
|
|
26
|
+
1. Identify the exact neighbor, address family, VRF, and local/remote ASNs.
|
|
27
|
+
2. Capture summary state and last reset reason.
|
|
28
|
+
3. Prove reachability to the peer source address.
|
|
29
|
+
4. Check route policy references before assuming transport failure.
|
|
30
|
+
5. Compare advertised, received, and installed routes where the platform
|
|
31
|
+
supports those commands.
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
show bgp summary
|
|
35
|
+
show bgp neighbors <peer>
|
|
36
|
+
show ip route <peer>
|
|
37
|
+
show tcp brief | include <peer>|:179
|
|
38
|
+
show logging | include BGP|<peer>
|
|
39
|
+
show running-config | section router bgp
|
|
40
|
+
show ip prefix-list
|
|
41
|
+
show route-map
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Use platform-specific address-family commands when the device uses VRFs, IPv6,
|
|
45
|
+
VPNv4, or EVPN. Do not assume global IPv4 unicast.
|
|
46
|
+
|
|
47
|
+
## State Interpretation
|
|
48
|
+
|
|
49
|
+
| State | First checks |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| Established with prefix count | Route exchange is up; inspect policy and table selection |
|
|
52
|
+
| Established with zero prefixes | Check inbound policy, max-prefix, advertised routes, and AFI/SAFI |
|
|
53
|
+
| Active | TCP session is not completing; check routing, source, ACLs, and peer reachability |
|
|
54
|
+
| Connect | TCP connection is in progress; check path and remote listener |
|
|
55
|
+
| OpenSent/OpenConfirm | TCP works; check ASN, authentication, timers, capabilities, and logs |
|
|
56
|
+
| Idle | Neighbor may be disabled, missing config, blocked by policy, or backoff timer |
|
|
57
|
+
|
|
58
|
+
## Transport Checks
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
ping <peer> source <local-source>
|
|
62
|
+
traceroute <peer> source <local-source>
|
|
63
|
+
show ip route <peer>
|
|
64
|
+
show bgp neighbors <peer> | include BGP state|Last reset|Local host|Foreign host
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If the peer is sourced from a loopback, confirm both directions route to the
|
|
68
|
+
loopback addresses and that the neighbor config uses the expected update source.
|
|
69
|
+
|
|
70
|
+
Avoid disabling ACLs or firewall policy as a diagnostic shortcut. Read hit
|
|
71
|
+
counters, logs, and path state first.
|
|
72
|
+
|
|
73
|
+
## Route Policy Checks
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
show bgp neighbors <peer> advertised-routes
|
|
77
|
+
show bgp neighbors <peer> routes
|
|
78
|
+
show ip prefix-list <name>
|
|
79
|
+
show route-map <name>
|
|
80
|
+
show bgp <prefix>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Some platforms require additional configuration before `received-routes` is
|
|
84
|
+
available. Do not add that configuration during incident triage unless the
|
|
85
|
+
operator approves the change.
|
|
86
|
+
|
|
87
|
+
## AS Path And Prefix Review
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
show bgp regexp _65001_
|
|
91
|
+
show bgp regexp ^65001$
|
|
92
|
+
show bgp <prefix>
|
|
93
|
+
show bgp neighbors <peer> advertised-routes | include Network|Path|<prefix>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Use AS-path regex carefully. `_65001_` matches AS 65001 as a token. Plain
|
|
97
|
+
`65001` can match longer ASNs or unrelated text.
|
|
98
|
+
|
|
99
|
+
## Parser Pattern
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
import re
|
|
103
|
+
from typing import Any
|
|
104
|
+
|
|
105
|
+
BGP_SUMMARY_RE = re.compile(
|
|
106
|
+
r"^(?P<neighbor>\d{1,3}(?:\.\d{1,3}){3})\s+"
|
|
107
|
+
r"(?P<version>\d+)\s+"
|
|
108
|
+
r"(?P<remote_as>\d+)\s+"
|
|
109
|
+
r"(?P<msg_rcvd>\d+)\s+"
|
|
110
|
+
r"(?P<msg_sent>\d+)\s+"
|
|
111
|
+
r"(?P<table_version>\d+)\s+"
|
|
112
|
+
r"(?P<input_queue>\d+)\s+"
|
|
113
|
+
r"(?P<output_queue>\d+)\s+"
|
|
114
|
+
r"(?P<uptime>\S+)\s+"
|
|
115
|
+
r"(?P<state_or_prefixes>\S+)$",
|
|
116
|
+
re.M,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
def parse_bgp_summary(raw: str) -> list[dict[str, Any]]:
|
|
120
|
+
rows = []
|
|
121
|
+
for match in BGP_SUMMARY_RE.finditer(raw):
|
|
122
|
+
state_or_prefixes = match.group("state_or_prefixes")
|
|
123
|
+
if state_or_prefixes.isdigit():
|
|
124
|
+
state = "Established"
|
|
125
|
+
prefixes_received = int(state_or_prefixes)
|
|
126
|
+
else:
|
|
127
|
+
state = state_or_prefixes
|
|
128
|
+
prefixes_received = None
|
|
129
|
+
rows.append({
|
|
130
|
+
"neighbor": match.group("neighbor"),
|
|
131
|
+
"remote_as": int(match.group("remote_as")),
|
|
132
|
+
"state": state,
|
|
133
|
+
"prefixes_received": prefixes_received,
|
|
134
|
+
"uptime": match.group("uptime"),
|
|
135
|
+
})
|
|
136
|
+
return rows
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Prefer structured parser output when available, but store raw output with the
|
|
140
|
+
incident record because BGP summary formats vary by platform and address family.
|
|
141
|
+
|
|
142
|
+
## Change-Window Only
|
|
143
|
+
|
|
144
|
+
These actions can affect routing and should not be suggested as automatic
|
|
145
|
+
diagnostics:
|
|
146
|
+
|
|
147
|
+
- Clearing a BGP session.
|
|
148
|
+
- Changing neighbor authentication, timers, update source, route-maps, or
|
|
149
|
+
prefix-lists.
|
|
150
|
+
- Enabling additional received-route storage.
|
|
151
|
+
- Relaxing firewall, ACL, or control-plane policy.
|
|
152
|
+
|
|
153
|
+
If a reset is approved, prefer the least disruptive soft or route-refresh option
|
|
154
|
+
supported by the platform and document exactly why it is safe.
|
|
155
|
+
|
|
156
|
+
## Anti-Patterns
|
|
157
|
+
|
|
158
|
+
- Assuming `Active` always means the remote side is down.
|
|
159
|
+
- Ignoring VRF, address family, or update-source differences.
|
|
160
|
+
- Using broad AS-path regex without token boundaries.
|
|
161
|
+
- Hard-resetting a peer before reading last reset reason and logs.
|
|
162
|
+
- Treating missing `received-routes` output as proof that no routes arrived.
|
|
163
|
+
|
|
164
|
+
## See Also
|
|
165
|
+
|
|
166
|
+
- Skill: `cisco-ios-patterns`
|
|
167
|
+
- Skill: `network-config-validation`
|
|
168
|
+
- Skill: `network-interface-health`
|