@malamute/ai-rules 1.0.0 → 1.2.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 (133) hide show
  1. package/README.md +270 -121
  2. package/bin/cli.js +5 -2
  3. package/configs/_shared/.claude/rules/conventions/documentation.md +324 -0
  4. package/configs/_shared/.claude/rules/conventions/git.md +265 -0
  5. package/configs/_shared/.claude/rules/{performance.md → conventions/performance.md} +1 -1
  6. package/configs/_shared/.claude/rules/conventions/principles.md +334 -0
  7. package/configs/_shared/.claude/rules/devops/ci-cd.md +262 -0
  8. package/configs/_shared/.claude/rules/devops/docker.md +275 -0
  9. package/configs/_shared/.claude/rules/devops/nx.md +194 -0
  10. package/configs/_shared/.claude/rules/domain/backend/api-design.md +203 -0
  11. package/configs/_shared/.claude/rules/lang/csharp/async.md +220 -0
  12. package/configs/_shared/.claude/rules/lang/csharp/csharp.md +314 -0
  13. package/configs/_shared/.claude/rules/lang/csharp/linq.md +210 -0
  14. package/configs/_shared/.claude/rules/lang/python/async.md +337 -0
  15. package/configs/_shared/.claude/rules/lang/python/celery.md +476 -0
  16. package/configs/_shared/.claude/rules/lang/python/config.md +339 -0
  17. package/configs/{python/.claude/rules → _shared/.claude/rules/lang/python}/database/sqlalchemy.md +6 -1
  18. package/configs/_shared/.claude/rules/lang/python/deployment.md +523 -0
  19. package/configs/_shared/.claude/rules/lang/python/error-handling.md +330 -0
  20. package/configs/_shared/.claude/rules/lang/python/migrations.md +421 -0
  21. package/configs/_shared/.claude/rules/lang/python/python.md +172 -0
  22. package/configs/_shared/.claude/rules/lang/python/repository.md +383 -0
  23. package/configs/{python/.claude/rules → _shared/.claude/rules/lang/python}/testing.md +2 -69
  24. package/configs/_shared/.claude/rules/lang/typescript/async.md +447 -0
  25. package/configs/_shared/.claude/rules/lang/typescript/generics.md +356 -0
  26. package/configs/_shared/.claude/rules/lang/typescript/typescript.md +212 -0
  27. package/configs/_shared/.claude/rules/quality/error-handling.md +48 -0
  28. package/configs/_shared/.claude/rules/quality/logging.md +45 -0
  29. package/configs/_shared/.claude/rules/quality/observability.md +240 -0
  30. package/configs/_shared/.claude/rules/quality/testing-patterns.md +65 -0
  31. package/configs/_shared/.claude/rules/security/secrets-management.md +222 -0
  32. package/configs/_shared/.claude/skills/analysis/explore/SKILL.md +257 -0
  33. package/configs/_shared/.claude/skills/analysis/security-audit/SKILL.md +184 -0
  34. package/configs/_shared/.claude/skills/dev/api-endpoint/SKILL.md +126 -0
  35. package/configs/_shared/.claude/{commands/generate-tests.md → skills/dev/generate-tests/SKILL.md} +6 -0
  36. package/configs/_shared/.claude/{commands/fix-issue.md → skills/git/fix-issue/SKILL.md} +6 -0
  37. package/configs/_shared/.claude/{commands/review-pr.md → skills/git/review-pr/SKILL.md} +6 -0
  38. package/configs/_shared/.claude/skills/infra/deploy/SKILL.md +139 -0
  39. package/configs/_shared/.claude/skills/infra/docker/SKILL.md +95 -0
  40. package/configs/_shared/.claude/skills/infra/migration/SKILL.md +158 -0
  41. package/configs/_shared/.claude/skills/nx/nx-affected/SKILL.md +72 -0
  42. package/configs/_shared/.claude/skills/nx/nx-lib/SKILL.md +375 -0
  43. package/configs/_shared/CLAUDE.md +52 -149
  44. package/configs/angular/.claude/rules/{components.md → core/components.md} +69 -15
  45. package/configs/angular/.claude/rules/core/resource.md +285 -0
  46. package/configs/angular/.claude/rules/core/signals.md +323 -0
  47. package/configs/angular/.claude/rules/http.md +338 -0
  48. package/configs/angular/.claude/rules/routing.md +291 -0
  49. package/configs/angular/.claude/rules/ssr.md +312 -0
  50. package/configs/angular/.claude/rules/state/signal-store.md +408 -0
  51. package/configs/angular/.claude/rules/{state.md → state/state.md} +2 -2
  52. package/configs/angular/.claude/rules/testing.md +7 -7
  53. package/configs/angular/.claude/rules/ui/aria.md +422 -0
  54. package/configs/angular/.claude/rules/ui/forms.md +424 -0
  55. package/configs/angular/.claude/rules/ui/pipes-directives.md +335 -0
  56. package/configs/angular/.claude/settings.json +1 -0
  57. package/configs/angular/.claude/skills/ngrx-slice/SKILL.md +362 -0
  58. package/configs/angular/.claude/skills/signal-store/SKILL.md +445 -0
  59. package/configs/angular/CLAUDE.md +24 -216
  60. package/configs/dotnet/.claude/rules/background-services.md +552 -0
  61. package/configs/dotnet/.claude/rules/configuration.md +426 -0
  62. package/configs/dotnet/.claude/rules/ddd.md +447 -0
  63. package/configs/dotnet/.claude/rules/dependency-injection.md +343 -0
  64. package/configs/dotnet/.claude/rules/mediatr.md +320 -0
  65. package/configs/dotnet/.claude/rules/middleware.md +489 -0
  66. package/configs/dotnet/.claude/rules/result-pattern.md +363 -0
  67. package/configs/dotnet/.claude/rules/validation.md +388 -0
  68. package/configs/dotnet/.claude/settings.json +21 -3
  69. package/configs/dotnet/CLAUDE.md +53 -286
  70. package/configs/fastapi/.claude/rules/background-tasks.md +254 -0
  71. package/configs/fastapi/.claude/rules/dependencies.md +170 -0
  72. package/configs/{python → fastapi}/.claude/rules/fastapi.md +61 -1
  73. package/configs/fastapi/.claude/rules/lifespan.md +274 -0
  74. package/configs/fastapi/.claude/rules/middleware.md +229 -0
  75. package/configs/fastapi/.claude/rules/pydantic.md +433 -0
  76. package/configs/fastapi/.claude/rules/responses.md +251 -0
  77. package/configs/fastapi/.claude/rules/routers.md +202 -0
  78. package/configs/fastapi/.claude/rules/security.md +222 -0
  79. package/configs/fastapi/.claude/rules/testing.md +251 -0
  80. package/configs/fastapi/.claude/rules/websockets.md +298 -0
  81. package/configs/fastapi/.claude/settings.json +33 -0
  82. package/configs/fastapi/CLAUDE.md +144 -0
  83. package/configs/flask/.claude/rules/blueprints.md +208 -0
  84. package/configs/flask/.claude/rules/cli.md +285 -0
  85. package/configs/flask/.claude/rules/configuration.md +281 -0
  86. package/configs/flask/.claude/rules/context.md +238 -0
  87. package/configs/flask/.claude/rules/error-handlers.md +278 -0
  88. package/configs/flask/.claude/rules/extensions.md +278 -0
  89. package/configs/flask/.claude/rules/flask.md +171 -0
  90. package/configs/flask/.claude/rules/marshmallow.md +206 -0
  91. package/configs/flask/.claude/rules/security.md +267 -0
  92. package/configs/flask/.claude/rules/testing.md +284 -0
  93. package/configs/flask/.claude/settings.json +33 -0
  94. package/configs/flask/CLAUDE.md +166 -0
  95. package/configs/nestjs/.claude/rules/common-patterns.md +300 -0
  96. package/configs/nestjs/.claude/rules/filters.md +376 -0
  97. package/configs/nestjs/.claude/rules/interceptors.md +317 -0
  98. package/configs/nestjs/.claude/rules/middleware.md +321 -0
  99. package/configs/nestjs/.claude/rules/modules.md +26 -0
  100. package/configs/nestjs/.claude/rules/pipes.md +351 -0
  101. package/configs/nestjs/.claude/rules/websockets.md +451 -0
  102. package/configs/nestjs/.claude/settings.json +16 -2
  103. package/configs/nestjs/CLAUDE.md +57 -215
  104. package/configs/nextjs/.claude/rules/api-routes.md +358 -0
  105. package/configs/nextjs/.claude/rules/authentication.md +355 -0
  106. package/configs/nextjs/.claude/rules/components.md +52 -0
  107. package/configs/nextjs/.claude/rules/data-fetching.md +249 -0
  108. package/configs/nextjs/.claude/rules/database.md +400 -0
  109. package/configs/nextjs/.claude/rules/middleware.md +303 -0
  110. package/configs/nextjs/.claude/rules/routing.md +324 -0
  111. package/configs/nextjs/.claude/rules/seo.md +350 -0
  112. package/configs/nextjs/.claude/rules/server-actions.md +353 -0
  113. package/configs/nextjs/.claude/rules/state/zustand.md +6 -6
  114. package/configs/nextjs/.claude/settings.json +5 -0
  115. package/configs/nextjs/CLAUDE.md +69 -331
  116. package/package.json +23 -9
  117. package/src/cli.js +220 -0
  118. package/src/config.js +29 -0
  119. package/src/index.js +13 -0
  120. package/src/installer.js +361 -0
  121. package/src/merge.js +116 -0
  122. package/src/tech-config.json +29 -0
  123. package/src/utils.js +96 -0
  124. package/configs/python/.claude/rules/flask.md +0 -332
  125. package/configs/python/.claude/settings.json +0 -18
  126. package/configs/python/CLAUDE.md +0 -273
  127. package/src/install.js +0 -315
  128. /package/configs/_shared/.claude/rules/{accessibility.md → domain/frontend/accessibility.md} +0 -0
  129. /package/configs/_shared/.claude/rules/{security.md → security/security.md} +0 -0
  130. /package/configs/_shared/.claude/skills/{debug → dev/debug}/SKILL.md +0 -0
  131. /package/configs/_shared/.claude/skills/{learning → dev/learning}/SKILL.md +0 -0
  132. /package/configs/_shared/.claude/skills/{spec → dev/spec}/SKILL.md +0 -0
  133. /package/configs/_shared/.claude/skills/{review → git/review}/SKILL.md +0 -0
@@ -0,0 +1,426 @@
1
+ ---
2
+ paths:
3
+ - "**/appsettings*.json"
4
+ - "**/Options/**/*.cs"
5
+ - "**/*Options.cs"
6
+ - "**/*Settings.cs"
7
+ ---
8
+
9
+ # .NET Configuration
10
+
11
+ ## Options Pattern
12
+
13
+ ```csharp
14
+ // Options/DatabaseOptions.cs
15
+ public class DatabaseOptions
16
+ {
17
+ public const string SectionName = "Database";
18
+
19
+ public string ConnectionString { get; set; } = string.Empty;
20
+ public int CommandTimeout { get; set; } = 30;
21
+ public int MaxRetryCount { get; set; } = 3;
22
+ public bool EnableSensitiveDataLogging { get; set; } = false;
23
+ }
24
+
25
+ // Options/JwtOptions.cs
26
+ public class JwtOptions
27
+ {
28
+ public const string SectionName = "Jwt";
29
+
30
+ public string Secret { get; set; } = string.Empty;
31
+ public string Issuer { get; set; } = string.Empty;
32
+ public string Audience { get; set; } = string.Empty;
33
+ public int ExpirationMinutes { get; set; } = 60;
34
+ public int RefreshExpirationDays { get; set; } = 7;
35
+ }
36
+
37
+ // Options/CacheOptions.cs
38
+ public class CacheOptions
39
+ {
40
+ public const string SectionName = "Cache";
41
+
42
+ public string RedisConnectionString { get; set; } = string.Empty;
43
+ public int DefaultExpirationMinutes { get; set; } = 5;
44
+ public string InstanceName { get; set; } = "app";
45
+ }
46
+ ```
47
+
48
+ ## Options Validation
49
+
50
+ ```csharp
51
+ // Options/DatabaseOptionsValidator.cs
52
+ using FluentValidation;
53
+
54
+ public class DatabaseOptionsValidator : AbstractValidator<DatabaseOptions>
55
+ {
56
+ public DatabaseOptionsValidator()
57
+ {
58
+ RuleFor(x => x.ConnectionString)
59
+ .NotEmpty().WithMessage("Database connection string is required");
60
+
61
+ RuleFor(x => x.CommandTimeout)
62
+ .InclusiveBetween(1, 300);
63
+
64
+ RuleFor(x => x.MaxRetryCount)
65
+ .InclusiveBetween(0, 10);
66
+ }
67
+ }
68
+
69
+ // Using Data Annotations
70
+ public class JwtOptions
71
+ {
72
+ public const string SectionName = "Jwt";
73
+
74
+ [Required]
75
+ [MinLength(32)]
76
+ public string Secret { get; set; } = string.Empty;
77
+
78
+ [Required]
79
+ [Url]
80
+ public string Issuer { get; set; } = string.Empty;
81
+
82
+ [Required]
83
+ public string Audience { get; set; } = string.Empty;
84
+
85
+ [Range(1, 1440)]
86
+ public int ExpirationMinutes { get; set; } = 60;
87
+ }
88
+ ```
89
+
90
+ ## Registration
91
+
92
+ ```csharp
93
+ // Program.cs
94
+ builder.Services.AddOptions<DatabaseOptions>()
95
+ .Bind(builder.Configuration.GetSection(DatabaseOptions.SectionName))
96
+ .ValidateDataAnnotations()
97
+ .ValidateOnStart();
98
+
99
+ builder.Services.AddOptions<JwtOptions>()
100
+ .Bind(builder.Configuration.GetSection(JwtOptions.SectionName))
101
+ .ValidateDataAnnotations()
102
+ .ValidateOnStart();
103
+
104
+ // With FluentValidation
105
+ builder.Services.AddOptions<DatabaseOptions>()
106
+ .Bind(builder.Configuration.GetSection(DatabaseOptions.SectionName))
107
+ .Validate(options =>
108
+ {
109
+ var validator = new DatabaseOptionsValidator();
110
+ var result = validator.Validate(options);
111
+ return result.IsValid;
112
+ })
113
+ .ValidateOnStart();
114
+
115
+ // Named options
116
+ builder.Services.AddOptions<StorageOptions>("primary")
117
+ .Bind(builder.Configuration.GetSection("Storage:Primary"));
118
+ builder.Services.AddOptions<StorageOptions>("backup")
119
+ .Bind(builder.Configuration.GetSection("Storage:Backup"));
120
+ ```
121
+
122
+ ## Consuming Options
123
+
124
+ ```csharp
125
+ // Using IOptions<T> (singleton, no reload)
126
+ public class UserService
127
+ {
128
+ private readonly JwtOptions _jwtOptions;
129
+
130
+ public UserService(IOptions<JwtOptions> options)
131
+ {
132
+ _jwtOptions = options.Value;
133
+ }
134
+ }
135
+
136
+ // Using IOptionsSnapshot<T> (scoped, reloads on request)
137
+ public class AuthService
138
+ {
139
+ private readonly JwtOptions _jwtOptions;
140
+
141
+ public AuthService(IOptionsSnapshot<JwtOptions> options)
142
+ {
143
+ _jwtOptions = options.Value;
144
+ }
145
+ }
146
+
147
+ // Using IOptionsMonitor<T> (singleton, live reload)
148
+ public class CacheService
149
+ {
150
+ private readonly IOptionsMonitor<CacheOptions> _optionsMonitor;
151
+
152
+ public CacheService(IOptionsMonitor<CacheOptions> optionsMonitor)
153
+ {
154
+ _optionsMonitor = optionsMonitor;
155
+
156
+ // React to changes
157
+ _optionsMonitor.OnChange(options =>
158
+ {
159
+ _logger.LogInformation("Cache options changed");
160
+ });
161
+ }
162
+
163
+ public void DoWork()
164
+ {
165
+ var options = _optionsMonitor.CurrentValue;
166
+ }
167
+ }
168
+
169
+ // Named options
170
+ public class StorageService
171
+ {
172
+ private readonly StorageOptions _primaryOptions;
173
+ private readonly StorageOptions _backupOptions;
174
+
175
+ public StorageService(IOptionsSnapshot<StorageOptions> options)
176
+ {
177
+ _primaryOptions = options.Get("primary");
178
+ _backupOptions = options.Get("backup");
179
+ }
180
+ }
181
+ ```
182
+
183
+ ## appsettings.json Structure
184
+
185
+ ```json
186
+ {
187
+ "Database": {
188
+ "ConnectionString": "Host=localhost;Database=app;Username=user;Password=pass",
189
+ "CommandTimeout": 30,
190
+ "MaxRetryCount": 3
191
+ },
192
+ "Jwt": {
193
+ "Secret": "your-256-bit-secret-key-here-at-least-32-chars",
194
+ "Issuer": "https://api.example.com",
195
+ "Audience": "https://app.example.com",
196
+ "ExpirationMinutes": 60
197
+ },
198
+ "Cache": {
199
+ "RedisConnectionString": "localhost:6379",
200
+ "DefaultExpirationMinutes": 5,
201
+ "InstanceName": "myapp"
202
+ },
203
+ "Storage": {
204
+ "Primary": {
205
+ "Provider": "S3",
206
+ "BucketName": "primary-bucket"
207
+ },
208
+ "Backup": {
209
+ "Provider": "Azure",
210
+ "ContainerName": "backup-container"
211
+ }
212
+ },
213
+ "Logging": {
214
+ "LogLevel": {
215
+ "Default": "Information",
216
+ "Microsoft.AspNetCore": "Warning"
217
+ }
218
+ }
219
+ }
220
+ ```
221
+
222
+ ## Environment-Specific Configuration
223
+
224
+ ```json
225
+ // appsettings.Development.json
226
+ {
227
+ "Database": {
228
+ "ConnectionString": "Host=localhost;Database=app_dev",
229
+ "EnableSensitiveDataLogging": true
230
+ }
231
+ }
232
+
233
+ // appsettings.Production.json
234
+ {
235
+ "Database": {
236
+ "CommandTimeout": 60,
237
+ "MaxRetryCount": 5
238
+ },
239
+ "Logging": {
240
+ "LogLevel": {
241
+ "Default": "Warning"
242
+ }
243
+ }
244
+ }
245
+ ```
246
+
247
+ ## User Secrets (Development)
248
+
249
+ ```bash
250
+ # Initialize
251
+ dotnet user-secrets init
252
+
253
+ # Set secrets
254
+ dotnet user-secrets set "Database:ConnectionString" "Host=localhost;Database=app;Password=secret"
255
+ dotnet user-secrets set "Jwt:Secret" "my-super-secret-key-for-development"
256
+
257
+ # List secrets
258
+ dotnet user-secrets list
259
+ ```
260
+
261
+ ## Environment Variables
262
+
263
+ ```csharp
264
+ // Program.cs
265
+ builder.Configuration
266
+ .AddJsonFile("appsettings.json", optional: false)
267
+ .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
268
+ .AddEnvironmentVariables()
269
+ .AddUserSecrets<Program>(optional: true);
270
+
271
+ // Environment variables override JSON
272
+ // Database__ConnectionString -> Database:ConnectionString
273
+ // Use double underscore for nested keys
274
+ ```
275
+
276
+ ## Configuration Providers
277
+
278
+ ```csharp
279
+ // Azure Key Vault
280
+ builder.Configuration.AddAzureKeyVault(
281
+ new Uri($"https://{vaultName}.vault.azure.net/"),
282
+ new DefaultAzureCredential());
283
+
284
+ // AWS Secrets Manager
285
+ builder.Configuration.AddSecretsManager(configurator: options =>
286
+ {
287
+ options.SecretFilter = entry => entry.Name.StartsWith("myapp/");
288
+ options.KeyGenerator = (entry, key) => key.Replace("myapp/", "").Replace("/", ":");
289
+ });
290
+
291
+ // HashiCorp Vault
292
+ builder.Configuration.AddVault(options =>
293
+ {
294
+ options.Address = "https://vault.example.com";
295
+ options.Token = Environment.GetEnvironmentVariable("VAULT_TOKEN");
296
+ });
297
+ ```
298
+
299
+ ## Feature Flags
300
+
301
+ ```csharp
302
+ // Options/FeatureFlags.cs
303
+ public class FeatureFlags
304
+ {
305
+ public const string SectionName = "Features";
306
+
307
+ public bool EnableNewDashboard { get; set; }
308
+ public bool EnableBetaFeatures { get; set; }
309
+ public bool EnableAnalytics { get; set; }
310
+ }
311
+
312
+ // Usage
313
+ public class DashboardController
314
+ {
315
+ private readonly FeatureFlags _features;
316
+
317
+ public DashboardController(IOptions<FeatureFlags> options)
318
+ {
319
+ _features = options.Value;
320
+ }
321
+
322
+ [HttpGet]
323
+ public IActionResult Get()
324
+ {
325
+ if (_features.EnableNewDashboard)
326
+ {
327
+ return View("NewDashboard");
328
+ }
329
+
330
+ return View("Dashboard");
331
+ }
332
+ }
333
+ ```
334
+
335
+ ## Configuration Extension Methods
336
+
337
+ ```csharp
338
+ // Extensions/ConfigurationExtensions.cs
339
+ public static class ConfigurationExtensions
340
+ {
341
+ public static T GetRequiredOptions<T>(this IConfiguration configuration, string sectionName)
342
+ where T : new()
343
+ {
344
+ var options = new T();
345
+ var section = configuration.GetSection(sectionName);
346
+
347
+ if (!section.Exists())
348
+ {
349
+ throw new InvalidOperationException($"Configuration section '{sectionName}' not found");
350
+ }
351
+
352
+ section.Bind(options);
353
+ return options;
354
+ }
355
+ }
356
+
357
+ // Extensions/ServiceCollectionExtensions.cs
358
+ public static class ServiceCollectionExtensions
359
+ {
360
+ public static IServiceCollection AddAppOptions(
361
+ this IServiceCollection services,
362
+ IConfiguration configuration)
363
+ {
364
+ services.AddOptions<DatabaseOptions>()
365
+ .Bind(configuration.GetSection(DatabaseOptions.SectionName))
366
+ .ValidateDataAnnotations()
367
+ .ValidateOnStart();
368
+
369
+ services.AddOptions<JwtOptions>()
370
+ .Bind(configuration.GetSection(JwtOptions.SectionName))
371
+ .ValidateDataAnnotations()
372
+ .ValidateOnStart();
373
+
374
+ services.AddOptions<CacheOptions>()
375
+ .Bind(configuration.GetSection(CacheOptions.SectionName))
376
+ .ValidateDataAnnotations()
377
+ .ValidateOnStart();
378
+
379
+ return services;
380
+ }
381
+ }
382
+
383
+ // Program.cs
384
+ builder.Services.AddAppOptions(builder.Configuration);
385
+ ```
386
+
387
+ ## Anti-patterns
388
+
389
+ ```csharp
390
+ // BAD: Accessing configuration directly
391
+ public class UserService
392
+ {
393
+ public UserService(IConfiguration configuration)
394
+ {
395
+ var connectionString = configuration["Database:ConnectionString"]; // No type safety!
396
+ }
397
+ }
398
+
399
+ // GOOD: Use Options pattern
400
+ public UserService(IOptions<DatabaseOptions> options)
401
+ {
402
+ var connectionString = options.Value.ConnectionString;
403
+ }
404
+
405
+ // BAD: Hardcoding secrets
406
+ public class JwtService
407
+ {
408
+ private readonly string _secret = "hardcoded-secret"; // Security risk!
409
+ }
410
+
411
+ // GOOD: Use configuration/secrets
412
+ public JwtService(IOptions<JwtOptions> options)
413
+ {
414
+ _secret = options.Value.Secret;
415
+ }
416
+
417
+ // BAD: Not validating options
418
+ builder.Services.Configure<DatabaseOptions>(config.GetSection("Database"));
419
+ // Missing validation - could fail at runtime
420
+
421
+ // GOOD: Validate on start
422
+ builder.Services.AddOptions<DatabaseOptions>()
423
+ .Bind(config.GetSection("Database"))
424
+ .ValidateDataAnnotations()
425
+ .ValidateOnStart(); // Fails fast if invalid
426
+ ```