@mohantn/gate-keeper 2.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 (272) hide show
  1. package/.github/instructions/dotnet-api-integration.instructions.md +416 -0
  2. package/.github/instructions/dotnet-development.instructions.md +353 -0
  3. package/.github/instructions/dotnet-testing.instructions.md +406 -0
  4. package/.github/instructions/gate-keeper.instructions.md +91 -0
  5. package/.github/instructions/react-development.instructions.md +315 -0
  6. package/.github/instructions/react-testing-optimization.instructions.md +373 -0
  7. package/.github/instructions/uiux.instructions.md +261 -0
  8. package/LICENSE +21 -0
  9. package/README.md +181 -0
  10. package/dist/analyzer/coverage-analyzer.d.ts +126 -0
  11. package/dist/analyzer/coverage-analyzer.d.ts.map +1 -0
  12. package/dist/analyzer/coverage-analyzer.js +633 -0
  13. package/dist/analyzer/coverage-analyzer.js.map +1 -0
  14. package/dist/analyzer/csharp-analyzer.d.ts +28 -0
  15. package/dist/analyzer/csharp-analyzer.d.ts.map +1 -0
  16. package/dist/analyzer/csharp-analyzer.js +437 -0
  17. package/dist/analyzer/csharp-analyzer.js.map +1 -0
  18. package/dist/analyzer/pattern-detector.d.ts +5 -0
  19. package/dist/analyzer/pattern-detector.d.ts.map +1 -0
  20. package/dist/analyzer/pattern-detector.js +74 -0
  21. package/dist/analyzer/pattern-detector.js.map +1 -0
  22. package/dist/analyzer/refactoring-advisor.d.ts +7 -0
  23. package/dist/analyzer/refactoring-advisor.d.ts.map +1 -0
  24. package/dist/analyzer/refactoring-advisor.js +280 -0
  25. package/dist/analyzer/refactoring-advisor.js.map +1 -0
  26. package/dist/analyzer/sonar-eslint-runner.d.ts +3 -0
  27. package/dist/analyzer/sonar-eslint-runner.d.ts.map +1 -0
  28. package/dist/analyzer/sonar-eslint-runner.js +136 -0
  29. package/dist/analyzer/sonar-eslint-runner.js.map +1 -0
  30. package/dist/analyzer/sonar-rule-map.d.ts +19 -0
  31. package/dist/analyzer/sonar-rule-map.d.ts.map +1 -0
  32. package/dist/analyzer/sonar-rule-map.js +67 -0
  33. package/dist/analyzer/sonar-rule-map.js.map +1 -0
  34. package/dist/analyzer/string-analyzer.d.ts +27 -0
  35. package/dist/analyzer/string-analyzer.d.ts.map +1 -0
  36. package/dist/analyzer/string-analyzer.js +274 -0
  37. package/dist/analyzer/string-analyzer.js.map +1 -0
  38. package/dist/analyzer/typescript-analyzer.d.ts +27 -0
  39. package/dist/analyzer/typescript-analyzer.d.ts.map +1 -0
  40. package/dist/analyzer/typescript-analyzer.js +437 -0
  41. package/dist/analyzer/typescript-analyzer.js.map +1 -0
  42. package/dist/analyzer/universal-analyzer.d.ts +10 -0
  43. package/dist/analyzer/universal-analyzer.d.ts.map +1 -0
  44. package/dist/analyzer/universal-analyzer.js +155 -0
  45. package/dist/analyzer/universal-analyzer.js.map +1 -0
  46. package/dist/cache/quality-cache.d.ts +119 -0
  47. package/dist/cache/quality-cache.d.ts.map +1 -0
  48. package/dist/cache/quality-cache.js +130 -0
  49. package/dist/cache/quality-cache.js.map +1 -0
  50. package/dist/cache/sqlite-cache.d.ts +43 -0
  51. package/dist/cache/sqlite-cache.d.ts.map +1 -0
  52. package/dist/cache/sqlite-cache.js +346 -0
  53. package/dist/cache/sqlite-cache.js.map +1 -0
  54. package/dist/cli/query-repl.d.ts +37 -0
  55. package/dist/cli/query-repl.d.ts.map +1 -0
  56. package/dist/cli/query-repl.js +298 -0
  57. package/dist/cli/query-repl.js.map +1 -0
  58. package/dist/cli/repl-algorithms.d.ts +49 -0
  59. package/dist/cli/repl-algorithms.d.ts.map +1 -0
  60. package/dist/cli/repl-algorithms.js +147 -0
  61. package/dist/cli/repl-algorithms.js.map +1 -0
  62. package/dist/cli/setup-core.d.ts +38 -0
  63. package/dist/cli/setup-core.d.ts.map +1 -0
  64. package/dist/cli/setup-core.js +427 -0
  65. package/dist/cli/setup-core.js.map +1 -0
  66. package/dist/cli/setup.d.ts +25 -0
  67. package/dist/cli/setup.d.ts.map +1 -0
  68. package/dist/cli/setup.js +159 -0
  69. package/dist/cli/setup.js.map +1 -0
  70. package/dist/cli-entry.d.ts +19 -0
  71. package/dist/cli-entry.d.ts.map +1 -0
  72. package/dist/cli-entry.js +178 -0
  73. package/dist/cli-entry.js.map +1 -0
  74. package/dist/daemon/watch-mode.d.ts +41 -0
  75. package/dist/daemon/watch-mode.d.ts.map +1 -0
  76. package/dist/daemon/watch-mode.js +163 -0
  77. package/dist/daemon/watch-mode.js.map +1 -0
  78. package/dist/daemon.d.ts +24 -0
  79. package/dist/daemon.d.ts.map +1 -0
  80. package/dist/daemon.js +357 -0
  81. package/dist/daemon.js.map +1 -0
  82. package/dist/github/app.d.ts +34 -0
  83. package/dist/github/app.d.ts.map +1 -0
  84. package/dist/github/app.js +261 -0
  85. package/dist/github/app.js.map +1 -0
  86. package/dist/github/commenter.d.ts +67 -0
  87. package/dist/github/commenter.d.ts.map +1 -0
  88. package/dist/github/commenter.js +155 -0
  89. package/dist/github/commenter.js.map +1 -0
  90. package/dist/graph/dependency-graph.d.ts +28 -0
  91. package/dist/graph/dependency-graph.d.ts.map +1 -0
  92. package/dist/graph/dependency-graph.js +198 -0
  93. package/dist/graph/dependency-graph.js.map +1 -0
  94. package/dist/graph/global-graph.d.ts +65 -0
  95. package/dist/graph/global-graph.d.ts.map +1 -0
  96. package/dist/graph/global-graph.js +153 -0
  97. package/dist/graph/global-graph.js.map +1 -0
  98. package/dist/graph/graph-algorithms.d.ts +90 -0
  99. package/dist/graph/graph-algorithms.d.ts.map +1 -0
  100. package/dist/graph/graph-algorithms.js +180 -0
  101. package/dist/graph/graph-algorithms.js.map +1 -0
  102. package/dist/graph/graph-export.d.ts +68 -0
  103. package/dist/graph/graph-export.d.ts.map +1 -0
  104. package/dist/graph/graph-export.js +264 -0
  105. package/dist/graph/graph-export.js.map +1 -0
  106. package/dist/graph/graph-report.d.ts +34 -0
  107. package/dist/graph/graph-report.d.ts.map +1 -0
  108. package/dist/graph/graph-report.js +136 -0
  109. package/dist/graph/graph-report.js.map +1 -0
  110. package/dist/graph/graph-summary.d.ts +68 -0
  111. package/dist/graph/graph-summary.d.ts.map +1 -0
  112. package/dist/graph/graph-summary.js +213 -0
  113. package/dist/graph/graph-summary.js.map +1 -0
  114. package/dist/graph/graphify-ignore.d.ts +32 -0
  115. package/dist/graph/graphify-ignore.d.ts.map +1 -0
  116. package/dist/graph/graphify-ignore.js +124 -0
  117. package/dist/graph/graphify-ignore.js.map +1 -0
  118. package/dist/graph/question-suggester.d.ts +30 -0
  119. package/dist/graph/question-suggester.d.ts.map +1 -0
  120. package/dist/graph/question-suggester.js +113 -0
  121. package/dist/graph/question-suggester.js.map +1 -0
  122. package/dist/graph/relationship-extractor.d.ts +40 -0
  123. package/dist/graph/relationship-extractor.d.ts.map +1 -0
  124. package/dist/graph/relationship-extractor.js +254 -0
  125. package/dist/graph/relationship-extractor.js.map +1 -0
  126. package/dist/graph/relationship-types.d.ts +24 -0
  127. package/dist/graph/relationship-types.d.ts.map +1 -0
  128. package/dist/graph/relationship-types.js +21 -0
  129. package/dist/graph/relationship-types.js.map +1 -0
  130. package/dist/graph/surprising-connections.d.ts +39 -0
  131. package/dist/graph/surprising-connections.d.ts.map +1 -0
  132. package/dist/graph/surprising-connections.js +127 -0
  133. package/dist/graph/surprising-connections.js.map +1 -0
  134. package/dist/hook-pre-tool-use.d.ts +14 -0
  135. package/dist/hook-pre-tool-use.d.ts.map +1 -0
  136. package/dist/hook-pre-tool-use.js +167 -0
  137. package/dist/hook-pre-tool-use.js.map +1 -0
  138. package/dist/hook-receiver.d.ts +29 -0
  139. package/dist/hook-receiver.d.ts.map +1 -0
  140. package/dist/hook-receiver.js +327 -0
  141. package/dist/hook-receiver.js.map +1 -0
  142. package/dist/hooks/git-hooks.d.ts +30 -0
  143. package/dist/hooks/git-hooks.d.ts.map +1 -0
  144. package/dist/hooks/git-hooks.js +179 -0
  145. package/dist/hooks/git-hooks.js.map +1 -0
  146. package/dist/mcp/cache-preload.d.ts +29 -0
  147. package/dist/mcp/cache-preload.d.ts.map +1 -0
  148. package/dist/mcp/cache-preload.js +103 -0
  149. package/dist/mcp/cache-preload.js.map +1 -0
  150. package/dist/mcp/handlers/analysis.d.ts +4 -0
  151. package/dist/mcp/handlers/analysis.d.ts.map +1 -0
  152. package/dist/mcp/handlers/analysis.js +196 -0
  153. package/dist/mcp/handlers/analysis.js.map +1 -0
  154. package/dist/mcp/handlers/context.d.ts +25 -0
  155. package/dist/mcp/handlers/context.d.ts.map +1 -0
  156. package/dist/mcp/handlers/context.js +382 -0
  157. package/dist/mcp/handlers/context.js.map +1 -0
  158. package/dist/mcp/handlers/graph-intelligence.d.ts +26 -0
  159. package/dist/mcp/handlers/graph-intelligence.d.ts.map +1 -0
  160. package/dist/mcp/handlers/graph-intelligence.js +371 -0
  161. package/dist/mcp/handlers/graph-intelligence.js.map +1 -0
  162. package/dist/mcp/handlers/graph-query.d.ts +25 -0
  163. package/dist/mcp/handlers/graph-query.d.ts.map +1 -0
  164. package/dist/mcp/handlers/graph-query.js +410 -0
  165. package/dist/mcp/handlers/graph-query.js.map +1 -0
  166. package/dist/mcp/handlers/graph.d.ts +5 -0
  167. package/dist/mcp/handlers/graph.d.ts.map +1 -0
  168. package/dist/mcp/handlers/graph.js +283 -0
  169. package/dist/mcp/handlers/graph.js.map +1 -0
  170. package/dist/mcp/handlers/impact-format.d.ts +9 -0
  171. package/dist/mcp/handlers/impact-format.d.ts.map +1 -0
  172. package/dist/mcp/handlers/impact-format.js +189 -0
  173. package/dist/mcp/handlers/impact-format.js.map +1 -0
  174. package/dist/mcp/handlers/impact.d.ts +4 -0
  175. package/dist/mcp/handlers/impact.d.ts.map +1 -0
  176. package/dist/mcp/handlers/impact.js +139 -0
  177. package/dist/mcp/handlers/impact.js.map +1 -0
  178. package/dist/mcp/handlers/improvement.d.ts +4 -0
  179. package/dist/mcp/handlers/improvement.d.ts.map +1 -0
  180. package/dist/mcp/handlers/improvement.js +136 -0
  181. package/dist/mcp/handlers/improvement.js.map +1 -0
  182. package/dist/mcp/handlers/index.d.ts +14 -0
  183. package/dist/mcp/handlers/index.d.ts.map +1 -0
  184. package/dist/mcp/handlers/index.js +36 -0
  185. package/dist/mcp/handlers/index.js.map +1 -0
  186. package/dist/mcp/handlers/platform-installer.d.ts +10 -0
  187. package/dist/mcp/handlers/platform-installer.d.ts.map +1 -0
  188. package/dist/mcp/handlers/platform-installer.js +168 -0
  189. package/dist/mcp/handlers/platform-installer.js.map +1 -0
  190. package/dist/mcp/handlers/pr-review.d.ts +33 -0
  191. package/dist/mcp/handlers/pr-review.d.ts.map +1 -0
  192. package/dist/mcp/handlers/pr-review.js +170 -0
  193. package/dist/mcp/handlers/pr-review.js.map +1 -0
  194. package/dist/mcp/handlers/shared.d.ts +20 -0
  195. package/dist/mcp/handlers/shared.d.ts.map +1 -0
  196. package/dist/mcp/handlers/shared.js +27 -0
  197. package/dist/mcp/handlers/shared.js.map +1 -0
  198. package/dist/mcp/handlers/types.d.ts +46 -0
  199. package/dist/mcp/handlers/types.d.ts.map +1 -0
  200. package/dist/mcp/handlers/types.js +3 -0
  201. package/dist/mcp/handlers/types.js.map +1 -0
  202. package/dist/mcp/helpers.d.ts +36 -0
  203. package/dist/mcp/helpers.d.ts.map +1 -0
  204. package/dist/mcp/helpers.js +199 -0
  205. package/dist/mcp/helpers.js.map +1 -0
  206. package/dist/mcp/installer.d.ts +22 -0
  207. package/dist/mcp/installer.d.ts.map +1 -0
  208. package/dist/mcp/installer.js +341 -0
  209. package/dist/mcp/installer.js.map +1 -0
  210. package/dist/mcp/server.d.ts +111 -0
  211. package/dist/mcp/server.d.ts.map +1 -0
  212. package/dist/mcp/server.js +216 -0
  213. package/dist/mcp/server.js.map +1 -0
  214. package/dist/mcp/token-tracker.d.ts +47 -0
  215. package/dist/mcp/token-tracker.d.ts.map +1 -0
  216. package/dist/mcp/token-tracker.js +93 -0
  217. package/dist/mcp/token-tracker.js.map +1 -0
  218. package/dist/quality-loop/file-lock.d.ts +12 -0
  219. package/dist/quality-loop/file-lock.d.ts.map +1 -0
  220. package/dist/quality-loop/file-lock.js +38 -0
  221. package/dist/quality-loop/file-lock.js.map +1 -0
  222. package/dist/quality-loop/fix-worker.d.ts +44 -0
  223. package/dist/quality-loop/fix-worker.d.ts.map +1 -0
  224. package/dist/quality-loop/fix-worker.js +414 -0
  225. package/dist/quality-loop/fix-worker.js.map +1 -0
  226. package/dist/quality-loop/orchestrator.d.ts +137 -0
  227. package/dist/quality-loop/orchestrator.d.ts.map +1 -0
  228. package/dist/quality-loop/orchestrator.js +894 -0
  229. package/dist/quality-loop/orchestrator.js.map +1 -0
  230. package/dist/quality-loop/queue-manager.d.ts +45 -0
  231. package/dist/quality-loop/queue-manager.d.ts.map +1 -0
  232. package/dist/quality-loop/queue-manager.js +173 -0
  233. package/dist/quality-loop/queue-manager.js.map +1 -0
  234. package/dist/rating/rating-calculator.d.ts +15 -0
  235. package/dist/rating/rating-calculator.d.ts.map +1 -0
  236. package/dist/rating/rating-calculator.js +136 -0
  237. package/dist/rating/rating-calculator.js.map +1 -0
  238. package/dist/types/agent.d.ts +49 -0
  239. package/dist/types/agent.d.ts.map +1 -0
  240. package/dist/types/agent.js +7 -0
  241. package/dist/types/agent.js.map +1 -0
  242. package/dist/types.d.ts +156 -0
  243. package/dist/types.d.ts.map +1 -0
  244. package/dist/types.js +3 -0
  245. package/dist/types.js.map +1 -0
  246. package/dist/util/fix-text.d.ts +7 -0
  247. package/dist/util/fix-text.d.ts.map +1 -0
  248. package/dist/util/fix-text.js +13 -0
  249. package/dist/util/fix-text.js.map +1 -0
  250. package/dist/viz/graph-viz.d.ts +40 -0
  251. package/dist/viz/graph-viz.d.ts.map +1 -0
  252. package/dist/viz/graph-viz.js +332 -0
  253. package/dist/viz/graph-viz.js.map +1 -0
  254. package/dist/viz/viz-helpers.d.ts +13 -0
  255. package/dist/viz/viz-helpers.d.ts.map +1 -0
  256. package/dist/viz/viz-helpers.js +134 -0
  257. package/dist/viz/viz-helpers.js.map +1 -0
  258. package/dist/viz/viz-routes.d.ts +28 -0
  259. package/dist/viz/viz-routes.d.ts.map +1 -0
  260. package/dist/viz/viz-routes.js +333 -0
  261. package/dist/viz/viz-routes.js.map +1 -0
  262. package/dist/viz/viz-scanner.d.ts +20 -0
  263. package/dist/viz/viz-scanner.d.ts.map +1 -0
  264. package/dist/viz/viz-scanner.js +241 -0
  265. package/dist/viz/viz-scanner.js.map +1 -0
  266. package/dist/viz/viz-server.d.ts +38 -0
  267. package/dist/viz/viz-server.d.ts.map +1 -0
  268. package/dist/viz/viz-server.js +240 -0
  269. package/dist/viz/viz-server.js.map +1 -0
  270. package/package.json +89 -0
  271. package/scripts/postinstall.js +28 -0
  272. package/scripts/setup.sh +113 -0
@@ -0,0 +1,353 @@
1
+ # .NET Core 8 Development Instructions
2
+
3
+ **Scope**: All `.cs` files | **Version**: 2.0 | **Tags**: `csharp`, `.net`, `dotnet-core-8`, `cqrs`, `clean-architecture`
4
+
5
+ **Related Files**: See [dotnet-api-integration.instructions.md](./dotnet-api-integration.instructions.md) for DI/API patterns, [dotnet-testing.instructions.md](./dotnet-testing.instructions.md) for testing
6
+
7
+ ## 🔴 MANDATORY: Using Statements Organization
8
+ Group at top: **System** → **Third-party** (Microsoft, AutoMapper) → **Application** (RetailApp.*). Never fully-qualify.
9
+
10
+ ```csharp
11
+ using System;
12
+ using System.Collections.Generic;
13
+ using Microsoft.AspNetCore.Mvc;
14
+ using AutoMapper;
15
+ using RetailApp.Application.Products.Services;
16
+
17
+ namespace RetailApp.Presentation.Controllers;
18
+ ```
19
+
20
+ ## Architecture Patterns
21
+
22
+ | Pattern | Rules |
23
+ |---------|-------|
24
+ | **CQRS** | Commands (write) → `ICommand<TResult>` handlers; Queries (read) separate |
25
+ | **Clean Architecture** | Core → Application → Infrastructure → Presentation |
26
+ | **Single Class Per File** | One public type per file |
27
+ | **Repository Pattern** | Generic `IRepository<T>` + `IUnitOfWork` |
28
+ | **Service Layer** | Business logic, validation, DI via constructor |
29
+ | **Async/Await** | All I/O async; support CancellationToken |
30
+
31
+ ## Database Conventions
32
+
33
+ - **C# Properties**: PascalCase (ProductName, RetailerId)
34
+ - **Database**: snake_case (product_name, retailer_id)
35
+ - **Foreign Keys**: {EntityName}_id (retailer_id, product_id)
36
+ - **Indexes**: idx_table_column (idx_products_retailer_id)
37
+ - **Audit Fields**: CreatedAt, UpdatedAt, CreatedBy, UpdatedBy
38
+
39
+ ## Core Code Patterns
40
+
41
+ ### BaseEntity
42
+ ```csharp
43
+ public abstract class BaseEntity {
44
+ public Guid Id { get; set; }
45
+ public DateTime CreatedAt { get; set; }
46
+ public DateTime? UpdatedAt { get; set; }
47
+ public string? CreatedBy { get; set; }
48
+ public string? UpdatedBy { get; set; }
49
+ }
50
+ ```
51
+
52
+ ### Command Handler (CQRS)
53
+ ```csharp
54
+ public class CreateProductCommandHandler : ICommandHandler<CreateProductCommand, ProductDto> {
55
+ private readonly IUnitOfWork _unitOfWork;
56
+ private readonly ProductMapper _mapper;
57
+ private readonly ILogger<CreateProductCommandHandler> _logger;
58
+
59
+ public async Task<ProductDto> HandleAsync(CreateProductCommand command, CancellationToken ct) {
60
+ var product = _mapper.MapToEntity(command);
61
+ await _unitOfWork.Products.AddAsync(product, ct);
62
+ await _unitOfWork.SaveChangesAsync(ct);
63
+ return _mapper.MapToDto(product);
64
+ }
65
+ }
66
+ ```
67
+
68
+ ### Query Handler (CQRS)
69
+ ```csharp
70
+ public class GetProductQueryHandler : IQueryHandler<GetProductQuery, ProductDto> {
71
+ private readonly IRepository<Product> _repository;
72
+ private readonly ProductMapper _mapper;
73
+
74
+ public async Task<ProductDto> HandleAsync(GetProductQuery query, CancellationToken ct) {
75
+ var product = await _repository.GetByIdAsync(query.ProductId, ct);
76
+ if (product == null) throw new NotFoundException("Product not found");
77
+ return _mapper.MapToDto(product);
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Service Layer
83
+ ```csharp
84
+ public class ProductService : IProductService {
85
+ private readonly IUnitOfWork _unitOfWork;
86
+ private readonly ILogger<ProductService> _logger;
87
+
88
+ public async Task<ProductDto> CreateProductAsync(CreateProductCommand cmd, CancellationToken ct) {
89
+ var product = Product.Create(cmd.Name, cmd.Price, cmd.RetailerId);
90
+ await _unitOfWork.Products.AddAsync(product, ct);
91
+ await _unitOfWork.SaveChangesAsync(ct);
92
+ return new ProductDto { Id = product.Id, Name = product.Name };
93
+ }
94
+ }
95
+ ```
96
+
97
+ ### Entity
98
+ ```csharp
99
+ public class Product : BaseEntity {
100
+ public string Name { get; set; } = string.Empty;
101
+ public decimal Price { get; set; }
102
+ public int StockQuantity { get; set; }
103
+ public string RetailerId { get; set; } = string.Empty;
104
+
105
+ public static Product Create(string name, decimal price, string retailerId) {
106
+ if (price < 0) throw new ArgumentOutOfRangeException(nameof(price));
107
+ return new Product { Id = Guid.NewGuid(), Name = name, Price = price, RetailerId = retailerId };
108
+ }
109
+ }
110
+ ```
111
+
112
+ ### Entity Configuration (Fluent API)
113
+ ```csharp
114
+ public class ProductConfiguration : IEntityTypeConfiguration<Product> {
115
+ public void Configure(EntityTypeBuilder<Product> builder) {
116
+ builder.ToTable("products");
117
+ builder.HasKey(p => p.Id);
118
+ builder.Property(p => p.Name).HasMaxLength(255).IsRequired();
119
+ builder.Property(p => p.Price).HasPrecision(10, 2);
120
+ builder.HasIndex(p => p.RetailerId).HasDatabaseName("idx_products_retailer_id");
121
+ }
122
+ }
123
+ ```
124
+
125
+ ### Repository Pattern
126
+ ```csharp
127
+ public interface IRepository<T> where T : BaseEntity {
128
+ Task<T?> GetByIdAsync(Guid id, CancellationToken ct);
129
+ Task<IEnumerable<T>> ListAsync(CancellationToken ct);
130
+ Task AddAsync(T entity, CancellationToken ct);
131
+ void Update(T entity);
132
+ void Delete(T entity);
133
+ }
134
+
135
+ public class Repository<T> : IRepository<T> where T : BaseEntity {
136
+ protected readonly DbContext _dbContext;
137
+
138
+ public async Task<T?> GetByIdAsync(Guid id, CancellationToken ct) =>
139
+ await _dbContext.Set<T>().FirstOrDefaultAsync(x => x.Id == id, ct);
140
+ public async Task<IEnumerable<T>> ListAsync(CancellationToken ct) =>
141
+ await _dbContext.Set<T>().ToListAsync(ct);
142
+ public async Task AddAsync(T entity, CancellationToken ct) {
143
+ await _dbContext.Set<T>().AddAsync(entity, ct);
144
+ }
145
+ public void Update(T entity) => _dbContext.Set<T>().Update(entity);
146
+ public void Delete(T entity) => _dbContext.Set<T>().Remove(entity);
147
+ }
148
+ ```
149
+
150
+ ### Unit of Work Pattern
151
+ ```csharp
152
+ public interface IUnitOfWork : IAsyncDisposable {
153
+ IRepository<Product> Products { get; }
154
+ IRepository<Order> Orders { get; }
155
+ Task<int> SaveChangesAsync(CancellationToken ct = default);
156
+ Task BeginTransactionAsync(CancellationToken ct = default);
157
+ Task CommitTransactionAsync(CancellationToken ct = default);
158
+ Task RollbackTransactionAsync(CancellationToken ct = default);
159
+ }
160
+ ```
161
+
162
+ ### Multi-Table Transactions
163
+ ```csharp
164
+ await _unitOfWork.BeginTransactionAsync(ct);
165
+ try {
166
+ await _unitOfWork.Products.AddAsync(product, ct);
167
+ await _unitOfWork.Orders.AddAsync(order, ct);
168
+ await _unitOfWork.SaveChangesAsync(ct);
169
+ await _unitOfWork.CommitTransactionAsync(ct);
170
+ } catch {
171
+ await _unitOfWork.RollbackTransactionAsync(ct);
172
+ throw;
173
+ }
174
+ ```
175
+
176
+ ### Mapperly Configuration
177
+ ```bash
178
+ dotnet add package Mapperly
179
+ ```
180
+
181
+ ```csharp
182
+ [Mapper]
183
+ public partial class ProductMapper {
184
+ public partial ProductDto MapToDto(Product product);
185
+ public partial Product MapToEntity(CreateProductCommand command);
186
+ }
187
+
188
+ // Advanced: Collections & nested objects
189
+ [Mapper]
190
+ public partial class OrderMapper {
191
+ public partial OrderDto MapToDto(Order order);
192
+
193
+ [MapProperty(nameof(Order.Items), nameof(OrderDto.LineItems))]
194
+ public partial OrderDto CustomMapping(Order order);
195
+
196
+ private string MapStatus(OrderStatus status) => status.ToString();
197
+ }
198
+ ```
199
+
200
+ ## Async Best Practices
201
+
202
+ ### Async/Await Patterns
203
+ ```csharp
204
+ // ✅ GOOD: Async method returns Task
205
+ public async Task<ProductDto> GetProductAsync(string id, CancellationToken ct) {
206
+ return await _repository.GetByIdAsync(id, ct);
207
+ }
208
+
209
+ // ❌ BAD: Async void - cannot be awaited, hides exceptions
210
+ public async void ProcessProductAsync(string id) { }
211
+
212
+ // ✅ GOOD: Properly wait in background jobs
213
+ [DisableConcurrentExecution(10, "Background-Job")]
214
+ public class BackgroundPublishJobHandler {
215
+ public async Task ExecuteAsync(CancellationToken ct) {
216
+ await ProcessBatchAsync(ct);
217
+ }
218
+ }
219
+ ```
220
+
221
+ ## Code Style & Formatting
222
+
223
+ ### Naming Conventions
224
+ ```csharp
225
+ // Naming conventions
226
+ public class ProductService { // PascalCase for class names
227
+ private readonly ILogger _logger; // camelCase with underscore for private fields
228
+ public string ProductName { get; set; } // PascalCase for properties
229
+
230
+ public async Task<Product> GetProductAsync(string id) { // Async suffix
231
+ var product = await _repository.GetAsync(id); // camelCase for local variables
232
+ return product;
233
+ }
234
+ }
235
+
236
+ // Interface naming
237
+ public interface IProductRepository { } // I prefix
238
+ public interface IProductService { } // I prefix
239
+ ```
240
+
241
+ ### Run formatting
242
+ ```bash
243
+ dotnet format # Auto-fix style issues
244
+ dotnet format --verify-no-changes # Check only
245
+ ```
246
+
247
+ ## Performance Best Practices
248
+
249
+ ### Query Optimization
250
+ ```csharp
251
+ // ✅ GOOD: Async streaming for large datasets
252
+ public async IAsyncEnumerable<ProductDto> GetProductsStreamAsync(CancellationToken ct) {
253
+ await foreach (var product in _dbContext.Products.AsAsyncEnumerable().WithCancellation(ct)) {
254
+ yield return _mapper.MapToDto(product);
255
+ }
256
+ }
257
+
258
+ // ✅ GOOD: Pagination
259
+ public async Task<PagedResult<ProductDto>> GetProductsPaginatedAsync(
260
+ int pageNumber, int pageSize, CancellationToken ct) {
261
+ var total = await _dbContext.Products.CountAsync(ct);
262
+ var items = await _dbContext.Products
263
+ .Skip((pageNumber - 1) * pageSize)
264
+ .Take(pageSize)
265
+ .ToListAsync(ct);
266
+ return new PagedResult<ProductDto> {
267
+ Items = items.Select(_mapper.MapToDto),
268
+ Total = total
269
+ };
270
+ }
271
+
272
+ // ✅ GOOD: Explicit includes, no lazy loading
273
+ public async Task<Product> GetProductWithDetailsAsync(string id, CancellationToken ct) {
274
+ return await _dbContext.Products
275
+ .Include(p => p.Category)
276
+ .Include(p => p.Supplier)
277
+ .FirstOrDefaultAsync(p => p.Id == id, ct);
278
+ }
279
+
280
+ // ✅ GOOD: Memory caching with TTL
281
+ public async Task<ProductDto> GetProductCachedAsync(string id, CancellationToken ct) {
282
+ return await _cache.GetOrCreateAsync($"product:{id}", async entry => {
283
+ entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
284
+ return await GetProductAsync(id, ct);
285
+ });
286
+ }
287
+ ```
288
+
289
+ ## Essential CLI Commands
290
+
291
+ ```bash
292
+ # Package Management
293
+ dotnet add package PackageName
294
+ dotnet restore
295
+ dotnet list package --outdated
296
+
297
+ # Build & Run
298
+ dotnet build
299
+ dotnet build --configuration Release
300
+ dotnet run
301
+ dotnet watch run
302
+ dotnet clean
303
+
304
+ # EF Migrations
305
+ dotnet ef migrations add InitialCreate --project Infrastructure
306
+ dotnet ef migrations list
307
+ dotnet ef database update
308
+ dotnet ef database drop --force
309
+ dotnet ef migrations script > migration.sql
310
+
311
+ # Publishing
312
+ dotnet publish --configuration Release --output ./publish
313
+ dotnet publish --self-contained -r linux-x64
314
+
315
+ # Code Quality
316
+ dotnet format
317
+ dotnet build --verbosity diagnostic
318
+ ```
319
+
320
+ ## Quick Checklist ✅
321
+
322
+ - Using statements: System → Third-party → Application
323
+ - One public type per file
324
+ - CQRS: Commands & Queries in separate handlers
325
+ - Repository + Unit of Work for data access
326
+ - Service layer for business logic
327
+ - Mapperly for DTO mapping
328
+ - Entity properties: PascalCase; DB columns: snake_case
329
+ - Audit fields in BaseEntity
330
+ - Foreign keys follow {EntityName}_id pattern
331
+ - All async methods support CancellationToken
332
+ - Transactions for multi-table operations
333
+ - No fully-qualified namespace references
334
+
335
+ ## Common Mistakes ❌
336
+
337
+ - Using fully-qualified names instead of `using` statements
338
+ - Multiple public types in one file
339
+ - Missing CancellationToken in async methods
340
+ - Business logic in controllers/endpoints
341
+ - Missing audit field updates
342
+ - Skipped transaction handling for multi-table ops
343
+ - No logging of important operations
344
+ - Missing error handling
345
+ - Ignoring test failures
346
+
347
+ ## Resources
348
+
349
+ - [Microsoft .NET Docs](https://docs.microsoft.com/dotnet/)
350
+ - [Entity Framework Core](https://docs.microsoft.com/ef/core/)
351
+ - [CQRS Pattern](https://martinfowler.com/bliki/CQRS.html)
352
+ - [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
353
+ - [Mapperly](https://mapperly.riok.app/)