From 0823aa2e08884fa38dc0a8567283f097b25e7078 Mon Sep 17 00:00:00 2001 From: Agoston Fung Date: Mon, 15 Sep 2025 11:49:46 +0200 Subject: [PATCH 1/2] add some instructions --- rules/platform/angular-ts.instructions.md | 52 +++++++++++++++++ rules/platform/bicep.instructions.md | 9 +++ rules/platform/dotnet.instructions.md | 70 +++++++++++++++++++++++ rules/platform/typescript.instructions.md | 57 ++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 rules/platform/angular-ts.instructions.md create mode 100644 rules/platform/bicep.instructions.md create mode 100644 rules/platform/dotnet.instructions.md create mode 100644 rules/platform/typescript.instructions.md diff --git a/rules/platform/angular-ts.instructions.md b/rules/platform/angular-ts.instructions.md new file mode 100644 index 0000000..d59e30e --- /dev/null +++ b/rules/platform/angular-ts.instructions.md @@ -0,0 +1,52 @@ +You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices. + +## TypeScript Best Practices + +- Use strict type checking +- Prefer type inference when the type is obvious +- Avoid the `any` type; use `unknown` when type is uncertain + +## Angular Best Practices + +- Always use standalone components over NgModules +- Must NOT set `standalone: true` inside Angular decorators. It's the default. +- Use signals for state management +- Implement lazy loading for feature routes +- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead +- Use `NgOptimizedImage` for all static images. + - `NgOptimizedImage` does not work for inline base64 images. + +## Components + +- Keep components small and focused on a single responsibility +- Use `input()` and `output()` functions instead of decorators +- Use `computed()` for derived state +- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator +- Prefer inline templates for small components +- Prefer Reactive forms instead of Template-driven ones +- Do NOT use `ngClass`, use `class` bindings instead +- DO NOT use `ngStyle`, use `style` bindings instead + +## State Management + +- Use signals for local component state +- Use `computed()` for derived state +- Keep state transformations pure and predictable +- Do NOT use `mutate` on signals, use `update` or `set` instead + +## Templates + +- Keep templates simple and avoid complex logic +- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` +- Use the async pipe to handle observables + +## Services + +- Design services around a single responsibility +- Use the `providedIn: 'root'` option for singleton services +- Use the `inject()` function instead of constructor injection + +## Common pitfalls + +- Control flow (`@if`): + - You cannot use `as` expressions in `@else if (...)`. E.g. invalid code: `@else if (bla(); as x)`. diff --git a/rules/platform/bicep.instructions.md b/rules/platform/bicep.instructions.md new file mode 100644 index 0000000..f1b5dc4 --- /dev/null +++ b/rules/platform/bicep.instructions.md @@ -0,0 +1,9 @@ +You are an expert at Azure Bicep. + +Review the bicep in FILE and generate errors to enhance the script base on best practices +(https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/best-practices). + +- Generate the top 3 most important annotations. +- Limit range to a single line. +- Do NOT generate notes. +- If a line starts with "#disable-next-line genaiscript", ignore the next line. diff --git a/rules/platform/dotnet.instructions.md b/rules/platform/dotnet.instructions.md new file mode 100644 index 0000000..d184831 --- /dev/null +++ b/rules/platform/dotnet.instructions.md @@ -0,0 +1,70 @@ + + # .NET Development Rules + + You are a senior .NET backend developer and an expert in C#, ASP.NET Core, and Entity Framework Core. + + ## Code Style and Structure + - Write concise, idiomatic C# code with accurate examples. + - Follow .NET and ASP.NET Core conventions and best practices. + - Use object-oriented and functional programming patterns as appropriate. + - Prefer LINQ and lambda expressions for collection operations. + - Use descriptive variable and method names (e.g., 'IsUserSignedIn', 'CalculateTotal'). + - Structure files according to .NET conventions (Controllers, Models, Services, etc.). + + ## Naming Conventions + - Use PascalCase for class names, method names, and public members. + - Use camelCase for local variables and private fields. + - Use UPPERCASE for constants. + - Prefix interface names with "I" (e.g., 'IUserService'). + + ## C# and .NET Usage + - Use C# 10+ features when appropriate (e.g., record types, pattern matching, null-coalescing assignment). + - Leverage built-in ASP.NET Core features and middleware. + - Use Entity Framework Core effectively for database operations. + + ## Syntax and Formatting + - Follow the C# Coding Conventions (https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) + - Use C#'s expressive syntax (e.g., null-conditional operators, string interpolation) + - Use 'var' for implicit typing when the type is obvious. + + ## Error Handling and Validation + - Use exceptions for exceptional cases, not for control flow. + - Implement proper error logging using built-in .NET logging or a third-party logger. + - Use Data Annotations or Fluent Validation for model validation. + - Implement global exception handling middleware. + - Return appropriate HTTP status codes and consistent error responses. + + ## API Design + - Follow RESTful API design principles. + - Use attribute routing in controllers. + - Implement versioning for your API. + - Use action filters for cross-cutting concerns. + + ## Performance Optimization + - Use asynchronous programming with async/await for I/O-bound operations. + - Implement caching strategies using IMemoryCache or distributed caching. + - Use efficient LINQ queries and avoid N+1 query problems. + - Implement pagination for large data sets. + + ## Key Conventions + - Use Dependency Injection for loose coupling and testability. + - Implement repository pattern or use Entity Framework Core directly, depending on the complexity. + - Use AutoMapper for object-to-object mapping if needed. + - Implement background tasks using IHostedService or BackgroundService. + + ## Testing + - Write unit tests using xUnit, NUnit, or MSTest. + - Use Moq or NSubstitute for mocking dependencies. + - Implement integration tests for API endpoints. + + ## Security + - Use Authentication and Authorization middleware. + - Implement JWT authentication for stateless API authentication. + - Use HTTPS and enforce SSL. + - Implement proper CORS policies. + + ## API Documentation + - Use Swagger/OpenAPI for API documentation (as per installed Swashbuckle.AspNetCore package). + - Provide XML comments for controllers and models to enhance Swagger documentation. + + Follow the official Microsoft documentation and ASP.NET Core guides for best practices in routing, controllers, models, and other API components. diff --git a/rules/platform/typescript.instructions.md b/rules/platform/typescript.instructions.md new file mode 100644 index 0000000..ed652ea --- /dev/null +++ b/rules/platform/typescript.instructions.md @@ -0,0 +1,57 @@ +--- +description: TypeScript coding standards and best practices for modern web development +globs: **/*.ts, **/*.tsx, **/*.d.ts +--- + +# TypeScript Best Practices + +## Type System +- Prefer interfaces over types for object definitions +- Use type for unions, intersections, and mapped types +- Avoid using `any`, prefer `unknown` for unknown types +- Use strict TypeScript configuration +- Leverage TypeScript's built-in utility types +- Use generics for reusable type patterns + +## Naming Conventions +- Use PascalCase for type names and interfaces +- Use camelCase for variables and functions +- Use UPPER_CASE for constants +- Use descriptive names with auxiliary verbs (e.g., isLoading, hasError) +- Prefix interfaces for React props with 'Props' (e.g., ButtonProps) + +## Code Organization +- Keep type definitions close to where they're used +- Export types and interfaces from dedicated type files when shared +- Use barrel exports (index.ts) for organizing exports +- Place shared types in a `types` directory +- Co-locate component props with their components + +## Functions +- Use explicit return types for public functions +- Use arrow functions for callbacks and methods +- Implement proper error handling with custom error types +- Use function overloads for complex type scenarios +- Prefer async/await over Promises + +## Best Practices +- Enable strict mode in tsconfig.json +- Use readonly for immutable properties +- Leverage discriminated unions for type safety +- Use type guards for runtime type checking +- Implement proper null checking +- Avoid type assertions unless necessary + +## Error Handling +- Create custom error types for domain-specific errors +- Use Result types for operations that can fail +- Implement proper error boundaries +- Use try-catch blocks with typed catch clauses +- Handle Promise rejections properly + +## Patterns +- Use the Builder pattern for complex object creation +- Implement the Repository pattern for data access +- Use the Factory pattern for object creation +- Leverage dependency injection +- Use the Module pattern for encapsulation From b316cbf2a5d3bc416d63b8fcba17d0ad62e885b3 Mon Sep 17 00:00:00 2001 From: Agoston Fung Date: Wed, 17 Sep 2025 14:00:42 +0200 Subject: [PATCH 2/2] use template --- rules/platform/angular-ts.instructions.md | 52 ----- rules/platform/angular-ts.rules.mdc | 227 ++++++++++++++++++++++ rules/platform/bicep.instructions.md | 9 - rules/platform/bicep.rules.mdc | 126 ++++++++++++ rules/platform/dotnet.instructions.md | 70 ------- rules/platform/dotnet.rules.mdc | 166 ++++++++++++++++ rules/platform/typescript.instructions.md | 57 ------ rules/platform/typescript.rules.mdc | 144 ++++++++++++++ 8 files changed, 663 insertions(+), 188 deletions(-) delete mode 100644 rules/platform/angular-ts.instructions.md create mode 100644 rules/platform/angular-ts.rules.mdc delete mode 100644 rules/platform/bicep.instructions.md create mode 100644 rules/platform/bicep.rules.mdc delete mode 100644 rules/platform/dotnet.instructions.md create mode 100644 rules/platform/dotnet.rules.mdc delete mode 100644 rules/platform/typescript.instructions.md create mode 100644 rules/platform/typescript.rules.mdc diff --git a/rules/platform/angular-ts.instructions.md b/rules/platform/angular-ts.instructions.md deleted file mode 100644 index d59e30e..0000000 --- a/rules/platform/angular-ts.instructions.md +++ /dev/null @@ -1,52 +0,0 @@ -You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices. - -## TypeScript Best Practices - -- Use strict type checking -- Prefer type inference when the type is obvious -- Avoid the `any` type; use `unknown` when type is uncertain - -## Angular Best Practices - -- Always use standalone components over NgModules -- Must NOT set `standalone: true` inside Angular decorators. It's the default. -- Use signals for state management -- Implement lazy loading for feature routes -- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead -- Use `NgOptimizedImage` for all static images. - - `NgOptimizedImage` does not work for inline base64 images. - -## Components - -- Keep components small and focused on a single responsibility -- Use `input()` and `output()` functions instead of decorators -- Use `computed()` for derived state -- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator -- Prefer inline templates for small components -- Prefer Reactive forms instead of Template-driven ones -- Do NOT use `ngClass`, use `class` bindings instead -- DO NOT use `ngStyle`, use `style` bindings instead - -## State Management - -- Use signals for local component state -- Use `computed()` for derived state -- Keep state transformations pure and predictable -- Do NOT use `mutate` on signals, use `update` or `set` instead - -## Templates - -- Keep templates simple and avoid complex logic -- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` -- Use the async pipe to handle observables - -## Services - -- Design services around a single responsibility -- Use the `providedIn: 'root'` option for singleton services -- Use the `inject()` function instead of constructor injection - -## Common pitfalls - -- Control flow (`@if`): - - You cannot use `as` expressions in `@else if (...)`. E.g. invalid code: `@else if (bla(); as x)`. diff --git a/rules/platform/angular-ts.rules.mdc b/rules/platform/angular-ts.rules.mdc new file mode 100644 index 0000000..e393ff4 --- /dev/null +++ b/rules/platform/angular-ts.rules.mdc @@ -0,0 +1,227 @@ +# Angular + TypeScript Frontend Rules + +Concise, practical rules for building maintainable, performant, and accessible Angular apps with modern TypeScript and Angular features. + +## Context + +Guidance for day-to-day Angular component, template, service, and state design using the latest standalone APIs and signals. + +*Applies to:* Angular applications and libraries (v16+), SPA/MPA frontends, design systems +*Level:* Operational/Tactical +*Audience:* Frontend engineers, tech leads, reviewers + +## Core Principles + +1. **Type safety by default:** Enable strict typing, prefer inference, and avoid unsafe escape hatches. +2. **Idiomatic modern Angular:** Prefer standalone APIs, signals, native control flow, and `inject()`. +3. **Simplicity and SRP:** Keep components/services small, focused, and predictable. +4. **Performance-first UI:** OnPush change detection, reactive patterns, and lazy loading by default. + +## Rules + +### Must Have (Critical) +Non-negotiable rules that must always be followed. Violation of these rules should block progress. + +- **RULE-001:** Use strict TypeScript; avoid `any` and prefer `unknown` when type is uncertain; use type inference when obvious. +- **RULE-002:** Use standalone components; do NOT set `standalone: true` in Angular decorators (it's the default). +- **RULE-003:** Use signals for component/local state; use `set`/`update` only; do NOT use `mutate`. +- **RULE-004:** Use `computed()` for derived state. +- **RULE-005:** Use `input()` and `output()` functions instead of decorators. +- **RULE-006:** Set `changeDetection: ChangeDetectionStrategy.OnPush` on all components. +- **RULE-007:** Use native template control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch`. +- **RULE-008:** Do NOT use `@HostBinding` or `@HostListener`; define host bindings/listeners in the `host` property of `@Component`/`@Directive`. +- **RULE-009:** Do NOT use `ngClass`/`ngStyle`; use `class` and `style` bindings instead. +- **RULE-010:** Prefer Reactive Forms over Template-driven Forms for new code. +- **RULE-011:** Use `inject()` for dependency injection in services and where appropriate. +- **RULE-012:** Use `providedIn: 'root'` for singleton services. +- **RULE-013:** Implement lazy loading for feature routes. +- **RULE-014:** Use `NgOptimizedImage` for static images; do NOT use it for inline base64 images. +- **RULE-015:** Keep components and services single-responsibility and small. +- **RULE-016:** In template control flow, do not use `as` expressions in `@else if (...)`; refactor to compute values beforehand. + +### Should Have (Important) +Strong recommendations that should be followed unless there's a compelling reason not to. + +- **RULE-101:** Prefer inline templates for small components; use separate files for complex markup. +- **RULE-102:** Keep templates simple; move complex logic to TypeScript. +- **RULE-103:** Keep state transformations pure and predictable. +- **RULE-104:** Use the `async` pipe to handle Observables in templates; avoid manual `subscribe()` for rendering. +- **RULE-105:** Design services around a single responsibility; avoid god-services. + +### Could Have (Preferred) +Best practices and preferences that improve quality but are not blocking. + +- **RULE-201:** Favor explicit `readonly` and immutable patterns where it clarifies intent. +- **RULE-202:** Co-locate small, leaf components with their feature; promote only when reused. +- **RULE-203:** Document public component inputs/outputs with concise JSDoc for design system surfaces. + +## Patterns & Anti-Patterns + +### ✅ Do This +Concrete examples of what good implementation looks like + +```typescript +// Component with signals, computed state, OnPush, host bindings, native control flow, and class/style bindings +import { Component, ChangeDetectionStrategy, input, output, signal, computed } from '@angular/core'; + +@Component({ + selector: 'app-counter', + // no `standalone: true` (default) + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'counter', + '(click)': 'onClick()' + }, + template: ` + @if (count() > 0) { + {{ label() }}: {{ count() }} + } @else { + Empty + } + + ` +}) +export class CounterComponent { + readonly label = input('Count'); + readonly changed = output(); + + private readonly size = input<'sm' | 'lg'>('sm'); + readonly count = signal(0); + readonly isLarge = computed(() => this.size() === 'lg'); + + inc() { + this.count.update(c => c + 1); + this.changed.emit(this.count()); + } + + onClick() { + // handle host click via host listener in metadata + } +} +``` + +```html + +
+ @if (user$ | async; as user) { +

{{ user.name }}

+ } @else { + + } +
+``` + +### ❌ Don't Do This +Concrete examples of what to avoid + +```typescript +// Anti-patterns: decorators for IO, HostBinding/HostListener, mutate(), star control flow, ngClass/ngStyle +import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, HostBinding, HostListener, signal } from '@angular/core'; + +@Component({ + selector: 'app-bad', + standalone: true, // ❌ don't set; it's default + changeDetection: ChangeDetectionStrategy.Default, // ❌ should be OnPush + template: ` +
+ {{ label }}: {{ count() }} +
+ ` +}) +export class BadComponent { + @Input() label!: string; // ❌ use input() + @Output() changed = new EventEmitter(); // ❌ use output() + + @HostBinding('class.bad') bad = true; // ❌ use host metadata + @HostListener('click') onClick() {} // ❌ use host metadata + + color = 'red'; + large = false; + count = signal(0); + + inc() { + this.count.mutate(c => { c++; }); // ❌ don't use mutate + this.changed.emit(this.count()); + } +} +``` + +```html + +@if (getUser() as user) { +
{{ user.name }}
+} @else if (getAccount() as account) { +
{{ account.id }}
+} +``` + +```typescript +// Avoid manual subscribe for template rendering +userService.user$.subscribe(u => this.user = u); // ❌ prefer async pipe +``` + +## Decision Framework + +*When rules conflict:* +1. Favor type safety, correctness, and accessibility over convenience. +2. Prefer modern Angular primitives (standalone, signals, `inject()`, native control flow) over legacy patterns. +3. Choose the simplest solution that satisfies SRP and performance (OnPush, lazy loading). + +*When facing edge cases:* +- Legacy or third-party constraints: wrap/adapter pattern; isolate exceptions locally. +- Dynamic styling/events: prefer explicit `class`/`style` bindings and `host` metadata; avoid `ngClass`/`ngStyle` and decorators. +- Template complexity: extract components/pipes or move logic to TS until templates are declarative. + +## Exceptions & Waivers + +*Valid reasons for exceptions:* +- Interoperating with legacy modules/libraries that require deprecated patterns. +- Temporary migration windows while incrementally adopting signals/standalone APIs. +- Performance or security constraints that necessitate an alternative approach with measurements. + +*Process for exceptions:* +1. Document the exception, rationale, and scope in an ADR or README. +2. Obtain tech lead approval. +3. Time-box the exception and add a cleanup task. + +## Quality Gates + +- **Automated checks:** TS `strict` enabled; ESLint rules for Angular best practices; template parser rules to flag `*ngIf/*ngFor`, `@HostBinding/@HostListener`, `ngClass/ngStyle` usage; CI check for OnPush and use of `input()/output()` and `inject()` patterns. +- **Code review focus:** Standalone usage (no explicit `standalone: true`), signals and computed correctness, OnPush, host metadata vs decorators, native control flow, DI via `inject()`, Reactive Forms, lazy-loaded routes, NgOptimizedImage usage, async pipe usage. +- **Testing requirements:** Unit tests around computed state; component change detection with OnPush; service DI via `inject()`; route lazy loading verified via router configuration tests; template tests validating async pipe rendering. + +## Related Rules + +- rules/platform/typescript.instructions.md - Complementary TypeScript guidance +- rules/code-quality.mdc - Actionable review comments +- rules/clean-code.mdc - General maintainability practices + +## References + +- [Angular Signals](https://angular.dev/guide/signals) - Modern reactive state management +- [Standalone APIs](https://angular.dev/guide/standalone-components) - Simplified component architecture +- [Control Flow](https://angular.dev/guide/template-control-flow) - Native template control structures +- [Dependency Injection and inject()](https://angular.dev/guide/di) - Modern DI patterns +- [Reactive Forms](https://angular.dev/guide/forms) - Type-safe form handling +- [Host Bindings/Listeners](https://angular.dev/guide/directives#host-listeners-and-host-bindings) - Component host interactions +- [NgOptimizedImage](https://angular.dev/guide/image-directive) - Performance-optimized images +- [Async Pipe](https://angular.dev/api/common/AsyncPipe) - Observable template integration + +--- + +## TL;DR + +Build with strict typing, modern Angular primitives, and simple, SRP-aligned components. + +*Key Principles:* +- Type-safe by default; prefer inference. +- Use standalone, signals, `inject()`, and native control flow. +- Keep things small, predictable, and OnPush. + +*Critical Rules:* +- Don't set `standalone: true`; use signals with `set`/`update` and `computed()`; use `input()`/`output()`; OnPush; no `@HostBinding/@HostListener`, no `ngClass/ngStyle`. +- Use native `@if/@for/@switch`, Reactive Forms, `inject()`, `providedIn: 'root'`, lazy routes, and the `async` pipe for Observables. +- Use `NgOptimizedImage` for static images; not for inline base64; avoid `as` in `@else if`. + +*Quick Decision Guide:* +When unsure, choose the modern Angular primitive that keeps templates declarative and components small; optimize for OnPush and type safety. diff --git a/rules/platform/bicep.instructions.md b/rules/platform/bicep.instructions.md deleted file mode 100644 index f1b5dc4..0000000 --- a/rules/platform/bicep.instructions.md +++ /dev/null @@ -1,9 +0,0 @@ -You are an expert at Azure Bicep. - -Review the bicep in FILE and generate errors to enhance the script base on best practices -(https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/best-practices). - -- Generate the top 3 most important annotations. -- Limit range to a single line. -- Do NOT generate notes. -- If a line starts with "#disable-next-line genaiscript", ignore the next line. diff --git a/rules/platform/bicep.rules.mdc b/rules/platform/bicep.rules.mdc new file mode 100644 index 0000000..82e9b45 --- /dev/null +++ b/rules/platform/bicep.rules.mdc @@ -0,0 +1,126 @@ +# Azure Bicep Review Rules (Annotation Generation) + +Rules for generating error annotations when reviewing Azure Bicep files against Microsoft best practices. Focused on precise, actionable, and minimal feedback for CI bots, code review tools, and LLM agents. + +## Context + +Guidance for producing annotations from a Bicep source file without modifying it. + +*Applies to:* Automated Bicep reviews, CI pipelines, IDE linters, LLM-based reviewers +*Level:* Operational +*Audience:* Platform engineers, DevOps, reviewers, and automation authors + +## Core Principles + +1. Best-practices driven: Derive findings from Azure Bicep best practices; avoid subjective opinions. +2. Minimal and actionable: Report only the most impactful issues with concise, fix-oriented messages. +3. Precise and respectful: Pinpoint a single line per finding and respect in-source suppression signals. + +## Rules + +### Must Have (Critical) +Non-negotiable rules that must always be followed. + +- RULE-001: Generate error annotations based on Azure Bicep best practices (see References). Do not alter the source file. +- RULE-002: Output only the top 3 most important annotations, ranked by impact and severity. +- RULE-003: Each annotation must target exactly one line (single-line range only). +- RULE-004: Do not generate notes or ancillary commentary; output errors only. +- RULE-005: If a line starts with "#disable-next-line genaiscript", ignore the next line entirely for annotation generation. + +### Should Have (Important) +Strong recommendations to improve clarity and usefulness. + +- RULE-101: Prefer findings that materially improve security, reliability, or correctness over stylistic nits when prioritizing top 3. +- RULE-102: Provide a concise, actionable error message (≤1 sentence) that implies the fix without extra notes. +- RULE-103: Deduplicate similar issues; if multiple rules trigger on the same line, emit a single combined message. + +### Could Have (Preferred) +Helpful preferences that aren’t blocking. + +- RULE-201: When multiple candidate issues tie, prefer earlier lines and higher-severity categories (e.g., security > reliability > performance > style). +- RULE-202: Keep output format consistent and machine-readable for downstream tooling. +- RULE-203: Use stable identifiers (resource symbolic names, parameter names) when referencing entities in messages. + +## Patterns & Anti-Patterns + +### ✅ Do This +Concrete examples of good output shape. + +// Single-line, error-only, concise, respects suppression +{ + "line": 42, + "severity": "error", + "message": "Avoid hardcoding location; use a parameter or resourceGroup().location." +} + +// Suppression example: if line 10 starts with +// #disable-next-line genaiscript +// then do not emit any annotation for line 11. + +### ❌ Don't Do This +Concrete examples to avoid. + +// Multi-line range or more than 3 findings +[ + { "startLine": 5, "endLine": 9, "severity": "warning", "message": "..." }, + { "line": 20, "severity": "note", "message": "..." } +] + +// Emitting notes or exceeding the top-3 limit is not allowed. + +## Decision Framework + +*When rules conflict:* +1. Favor security/correctness issues over style or cosmetic concerns. +2. Prefer higher-severity, broadly impactful issues; then choose earliest line numbers. +3. If still tied, prefer de-duplicating into a single, clearer error message. + +*When facing edge cases:* +- Empty or comment-only files: produce no findings. +- Multiple issues on the same line: emit one concise, combined error. +- More than 3 issues: apply prioritization and emit only the top 3. + +## Exceptions & Waivers + +*Valid reasons for exceptions:* +- Controlled experiments or diagnostics requiring more than 3 findings in a temporary debug mode. +- Contractual integration that mandates a different output format. + +*Process for exceptions:* +1. Document the exception, scope, and duration in the pipeline/repo docs. +2. Obtain tech lead approval. +3. Time-box the exception and review periodically. + +## Quality Gates + +- Automated checks: Validate single-line ranges; enforce max of 3 errors; verify no notes are present; confirm suppression behavior. +- Code review focus: Prioritization soundness, message clarity, respect for suppression directives, consistency of output. +- Testing requirements: Unit tests for suppression, tie-breaking, de-duplication, empty files, and top-3 capping. + +## Related Rules + +- rules/code-quality.mdc - General guidance for actionable, minimal review comments +- rules/platform/dotnet.instructions.md - Example platform-specific instruction style + +## References + +- Azure Bicep best practices: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/best-practices + +--- + +## TL;DR + +Provide only the top 3 best-practice errors for a Bicep file, each tied to exactly one line, with no notes and with suppression respected. + +*Key Principles:* +- Base findings on Bicep best practices. +- Keep feedback minimal and actionable. +- Respect in-source suppression and be precise. + +*Critical Rules:* +- Emit errors only; no notes. +- At most 3 annotations; each is single-line. +- Ignore the next line after a "#disable-next-line genaiscript" directive. + +*Quick Decision Guide:* +When in doubt, prioritize security/correctness, choose the earlier line, and keep the message short and fix-oriented. diff --git a/rules/platform/dotnet.instructions.md b/rules/platform/dotnet.instructions.md deleted file mode 100644 index d184831..0000000 --- a/rules/platform/dotnet.instructions.md +++ /dev/null @@ -1,70 +0,0 @@ - - # .NET Development Rules - - You are a senior .NET backend developer and an expert in C#, ASP.NET Core, and Entity Framework Core. - - ## Code Style and Structure - - Write concise, idiomatic C# code with accurate examples. - - Follow .NET and ASP.NET Core conventions and best practices. - - Use object-oriented and functional programming patterns as appropriate. - - Prefer LINQ and lambda expressions for collection operations. - - Use descriptive variable and method names (e.g., 'IsUserSignedIn', 'CalculateTotal'). - - Structure files according to .NET conventions (Controllers, Models, Services, etc.). - - ## Naming Conventions - - Use PascalCase for class names, method names, and public members. - - Use camelCase for local variables and private fields. - - Use UPPERCASE for constants. - - Prefix interface names with "I" (e.g., 'IUserService'). - - ## C# and .NET Usage - - Use C# 10+ features when appropriate (e.g., record types, pattern matching, null-coalescing assignment). - - Leverage built-in ASP.NET Core features and middleware. - - Use Entity Framework Core effectively for database operations. - - ## Syntax and Formatting - - Follow the C# Coding Conventions (https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) - - Use C#'s expressive syntax (e.g., null-conditional operators, string interpolation) - - Use 'var' for implicit typing when the type is obvious. - - ## Error Handling and Validation - - Use exceptions for exceptional cases, not for control flow. - - Implement proper error logging using built-in .NET logging or a third-party logger. - - Use Data Annotations or Fluent Validation for model validation. - - Implement global exception handling middleware. - - Return appropriate HTTP status codes and consistent error responses. - - ## API Design - - Follow RESTful API design principles. - - Use attribute routing in controllers. - - Implement versioning for your API. - - Use action filters for cross-cutting concerns. - - ## Performance Optimization - - Use asynchronous programming with async/await for I/O-bound operations. - - Implement caching strategies using IMemoryCache or distributed caching. - - Use efficient LINQ queries and avoid N+1 query problems. - - Implement pagination for large data sets. - - ## Key Conventions - - Use Dependency Injection for loose coupling and testability. - - Implement repository pattern or use Entity Framework Core directly, depending on the complexity. - - Use AutoMapper for object-to-object mapping if needed. - - Implement background tasks using IHostedService or BackgroundService. - - ## Testing - - Write unit tests using xUnit, NUnit, or MSTest. - - Use Moq or NSubstitute for mocking dependencies. - - Implement integration tests for API endpoints. - - ## Security - - Use Authentication and Authorization middleware. - - Implement JWT authentication for stateless API authentication. - - Use HTTPS and enforce SSL. - - Implement proper CORS policies. - - ## API Documentation - - Use Swagger/OpenAPI for API documentation (as per installed Swashbuckle.AspNetCore package). - - Provide XML comments for controllers and models to enhance Swagger documentation. - - Follow the official Microsoft documentation and ASP.NET Core guides for best practices in routing, controllers, models, and other API components. diff --git a/rules/platform/dotnet.rules.mdc b/rules/platform/dotnet.rules.mdc new file mode 100644 index 0000000..34f4c26 --- /dev/null +++ b/rules/platform/dotnet.rules.mdc @@ -0,0 +1,166 @@ +# .NET Backend Development Rules + +Concise, practical rules for building ASP.NET Core and Entity Framework Core backend APIs in C# that are secure, maintainable, and performant. + +## Context + +Applies to: ASP.NET Core Web APIs, backend services, microservices using C# and EF Core +Level: Operational/Tactical +Audience: Backend developers, tech leads, reviewers + +## Core Principles + +1. Coding Conventions First: Prefer idiomatic C# and ASP.NET Core conventions for clarity and consistency. +2. Secure by Default: Enforce authentication, authorization, HTTPS, and CORS. +3. Reliability and Observability: Validate inputs, handle errors globally, and log meaningfully. +4. Performance Matters: Use async I/O, efficient EF Core queries, caching, and pagination. +5. RESTful, Versioned APIs: Predictable resource design with explicit versioning and documentation. +6. Dependency Inversion: Favor DI for testability and loose coupling. +7. Test What You Ship: Unit and integration tests are standard, not optional. + +## Rules + +### Must Have (Critical) +- RULE-001: Follow .NET/C# coding conventions and ASP.NET Core best practices. +- RULE-002: Enforce HTTPS; configure appropriate CORS policies. +- RULE-003: Implement authentication and authorization for protected endpoints (e.g., JWT). +- RULE-004: Implement global exception handling; return consistent error payloads with correct HTTP status codes. +- RULE-005: Validate request models using Data Annotations or FluentValidation. +- RULE-006: Use Dependency Injection for all services and data access. +- RULE-007: Design RESTful endpoints; use attribute routing. +- RULE-008: Version the API explicitly. +- RULE-009: Use async/await for all I/O-bound operations; avoid blocking calls. +- RULE-010: Use EF Core effectively; avoid N\+1 queries (e.g., via `Include`, proper projections). +- RULE-011: Implement pagination for large result sets. +- RULE-012: Provide Swagger/OpenAPI docs; add XML comments for controllers and models. +- RULE-013: Log errors and key events using the built-in logging abstractions. +- RULE-014: Maintain unit tests and integration tests for API endpoints. + +### Should Have (Important) +- RULE-101: Write concise, idiomatic C#; prefer expressive syntax (null\-conditional, string interpolation, pattern matching). +- RULE-102: Prefer LINQ and lambdas for collection operations. +- RULE-103: Use `var` when the type is obvious. +- RULE-104: Leverage built\-in ASP.NET Core middleware and features before custom implementations. +- RULE-105: Apply caching using `IMemoryCache` or distributed caches when appropriate. +- RULE-106: Use action filters for cross\-cutting concerns (e.g., validation, logging). +- RULE-107: Choose between repository pattern and direct EF Core usage based on complexity; avoid unnecessary abstraction. +- RULE-108: Use AutoMapper for object mapping when mapping is non\-trivial. +- RULE-109: Use xUnit/NUnit/MSTest for unit tests with Moq/NSubstitute for mocking. + +### Could Have (Preferred) +- RULE-201: Use modern C# (10\+) features where they improve clarity and safety. +- RULE-202: Implement background processing with `IHostedService`/`BackgroundService` for non\-request work. +- RULE-203: Apply distributed caching and response caching for high\-traffic endpoints. + +## Patterns & Anti-Patterns + +### ✅ Do This +- Asynchronous, validated, paginated query with DI, logging, and proper status codes. + +```csharp +[ApiController] +[Route("api/v{version:apiVersion}/orders")] +[ApiVersion("1.0")] +public class OrdersController : ControllerBase +{ + private readonly ILogger _logger; + private readonly AppDbContext _db; + + public OrdersController(ILogger logger, AppDbContext db) + { + _logger = logger; + _db = db; + } + + [HttpGet] + public async Task>> GetAsync([FromQuery] int page = 1, [FromQuery] int size = 20) + { + if (page < 1 || size is < 1 or > 200) return BadRequest("Invalid pagination parameters."); + + var query = _db.Orders + .AsNoTracking() + .OrderBy(o => o.Id) + .Select(o => new OrderDto(o.Id, o.Number, o.Total)); + + var total = await query.CountAsync(); + var items = await query.Skip((page - 1) * size).Take(size).ToListAsync(); + + return Ok(new PagedResult(items, total, page, size)); + } +} +``` + +### ❌ Don't Do This +- Blocking calls, unversioned routes, inconsistent errors, and N\+1 queries. + +```csharp +[Route("api/orders")] +public class OrdersController : Controller +{ + [HttpGet] + public IActionResult Get() + { + // Blocks thread, no paging, potential N+1 + var orders = new AppDbContext().Orders.ToList(); // newing DbContext, no DI + var result = new List(); + foreach (var o in orders) + { + var lines = new AppDbContext().OrderLines.Where(l => l.OrderId == o.Id).ToList(); + result.Add(new { o.Id, o.Number, Lines = lines }); + } + return Ok(result); // Always 200, no error shape + } +} +``` + +## Decision Framework + +When rules conflict: +1. Favor security and correctness over convenience or premature optimization. +2. Prefer framework conventions and official guidance over custom patterns. +3. Choose the simplest option that meets requirements; measure before optimizing. + +When facing edge cases: +- Validate assumptions with metrics and logs. +- Make behavior explicit via configuration and documentation. +- Add tests to lock in intended behavior. + +## Exceptions & Waivers + +Valid reasons for exceptions: +- Interoperability with legacy systems or constraints from external contracts. +- Temporary prototypes/spikes with time\-boxed scope. +- Performance\-critical hotspots justified by measurements. + +Process for exceptions: +1. Document the exception, rationale, and scope in ADR or README. +2. Obtain tech lead approval. +3. Set a review date and track remediation. + +## Quality Gates + +- Automated checks: `dotnet format`, analyzers (nullable enabled, IDE analyzers), StyleCop/Roslyn rules, API analyzers, security linters. +- Code review focus: RESTfulness, versioning, validation, error handling, async correctness, EF Core query efficiency, logging, tests. +- Testing requirements: Unit tests for services and controllers; integration tests for endpoints and data access; security and pagination covered. + +## Related Rules + +- `rules/platform/security.md` \- Security hardening and secrets handling +- `rules/platform/api-versioning.md` \- API versioning strategy +- `rules/platform/testing.md` \- Testing standards and tooling + +## References + +- https://learn.microsoft.com/aspnet/core \- ASP.NET Core docs +- https://learn.microsoft.com/ef/core \- Entity Framework Core docs +- https://learn.microsoft.com/dotnet/csharp/fundamentals/coding-style/coding-conventions \- C# coding conventions +- https://learn.microsoft.com/aspnet/core/fundamentals/logging \- Logging in ASP.NET Core +- https://learn.microsoft.com/aspnet/core/tutorials/getting-started-with-swashbuckle \- Swagger/OpenAPI with Swashbuckle + +--- + +## TL;DR + +- Key Principles: Follow conventions; secure by default; validate, log, and fail predictably; use async and efficient EF Core; DI everywhere; test and document. +- Critical Rules: Enforce HTTPS/auth; global exception handling and validation; RESTful, versioned endpoints; async I/O; avoid N\+1; paginate; Swagger with XML comments. +- Quick Decision Guide: Prefer built\-in features and official guidance; choose the simplest secure option; measure before optimizing. diff --git a/rules/platform/typescript.instructions.md b/rules/platform/typescript.instructions.md deleted file mode 100644 index ed652ea..0000000 --- a/rules/platform/typescript.instructions.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -description: TypeScript coding standards and best practices for modern web development -globs: **/*.ts, **/*.tsx, **/*.d.ts ---- - -# TypeScript Best Practices - -## Type System -- Prefer interfaces over types for object definitions -- Use type for unions, intersections, and mapped types -- Avoid using `any`, prefer `unknown` for unknown types -- Use strict TypeScript configuration -- Leverage TypeScript's built-in utility types -- Use generics for reusable type patterns - -## Naming Conventions -- Use PascalCase for type names and interfaces -- Use camelCase for variables and functions -- Use UPPER_CASE for constants -- Use descriptive names with auxiliary verbs (e.g., isLoading, hasError) -- Prefix interfaces for React props with 'Props' (e.g., ButtonProps) - -## Code Organization -- Keep type definitions close to where they're used -- Export types and interfaces from dedicated type files when shared -- Use barrel exports (index.ts) for organizing exports -- Place shared types in a `types` directory -- Co-locate component props with their components - -## Functions -- Use explicit return types for public functions -- Use arrow functions for callbacks and methods -- Implement proper error handling with custom error types -- Use function overloads for complex type scenarios -- Prefer async/await over Promises - -## Best Practices -- Enable strict mode in tsconfig.json -- Use readonly for immutable properties -- Leverage discriminated unions for type safety -- Use type guards for runtime type checking -- Implement proper null checking -- Avoid type assertions unless necessary - -## Error Handling -- Create custom error types for domain-specific errors -- Use Result types for operations that can fail -- Implement proper error boundaries -- Use try-catch blocks with typed catch clauses -- Handle Promise rejections properly - -## Patterns -- Use the Builder pattern for complex object creation -- Implement the Repository pattern for data access -- Use the Factory pattern for object creation -- Leverage dependency injection -- Use the Module pattern for encapsulation diff --git a/rules/platform/typescript.rules.mdc b/rules/platform/typescript.rules.mdc new file mode 100644 index 0000000..04a8093 --- /dev/null +++ b/rules/platform/typescript.rules.mdc @@ -0,0 +1,144 @@ +# TypeScript Development Rules + +TypeScript coding standards and best practices for modern web development. These rules ensure type safety, maintainability, and consistency across TypeScript codebases. + +## Context + +*Applies to:* All TypeScript files (**.ts, **.tsx, **.d.ts) in web applications, libraries, and Node.js projects +*Level:* Tactical/Operational - day-to-day development practices +*Audience:* Developers working with TypeScript codebases + +## Core Principles + +1. **Type Safety First:** Leverage TypeScript's type system to catch errors at compile time rather than runtime +2. **Explicit Over Implicit:** Prefer explicit type annotations and return types for better code documentation and IDE support +3. **Consistency in Conventions:** Follow established naming patterns and organizational structures for predictable codebases + +## Rules + +### Must Have (Critical) +Non-negotiable rules that must always be followed. Violation of these rules should block progress. + +- **TS-001:** Enable strict mode in tsconfig.json with all strict flags enabled +- **TS-002:** Never use `any` type - use `unknown` for truly unknown types or proper type definitions +- **TS-003:** Use explicit return types for all public functions and class methods +- **TS-004:** Implement proper null checking - avoid non-null assertion operator (!) unless absolutely necessary + +### Should Have (Important) +Strong recommendations that should be followed unless there's a compelling reason not to. + +- **TS-101:** Prefer interfaces over types for object definitions and extensible contracts +- **TS-102:** Use PascalCase for type names, interfaces, and classes; camelCase for variables and functions +- **TS-103:** Create custom error types for domain-specific errors instead of throwing generic Error objects +- **TS-104:** Use readonly for immutable properties and arrays to prevent accidental mutations +- **TS-105:** Leverage discriminated unions for type-safe state management and API responses + +### Could Have (Preferred) +Best practices and preferences that improve quality but are not blocking. + +- **TS-201:** Use descriptive boolean variable names with auxiliary verbs (isLoading, hasError, canEdit) +- **TS-202:** Prefix React component prop interfaces with 'Props' suffix (ButtonProps, HeaderProps) +- **TS-203:** Use barrel exports (index.ts) for clean module organization +- **TS-204:** Prefer async/await over Promise chains for better readability + +## Patterns & Anti-Patterns + +### ✅ Do This +```typescript +// Good: Explicit interface with proper naming +interface UserProps { + readonly id: string; + name: string; + isActive: boolean; +} + +// Good: Custom error type +class ValidationError extends Error { + constructor(public field: string, message: string) { + super(message); + this.name = 'ValidationError'; + } +} + +// Good: Explicit return type +function processUser(user: UserProps): Promise { + // implementation +} +``` + +### ❌ Don't Do This +```typescript +// Bad: Using any type +function processData(data: any): any { + return data.someProperty; +} + +// Bad: Implicit types and generic naming +function process(item) { + return item.prop; +} + +// Bad: Non-descriptive boolean naming +const flag = true; +const check = false; +``` + +## Decision Framework + +*When rules conflict:* +1. Prioritize type safety over convenience +2. Choose explicit over implicit when both are valid +3. Follow the strictest applicable rule + +*When facing edge cases:* +- Document the reasoning for unusual type patterns +- Consider if a union type or generic would be more appropriate +- Consult team for complex type scenarios involving advanced TypeScript features + +## Exceptions & Waivers + +*Valid reasons for exceptions:* +- Third-party library integration requiring `any` types (document with comments) +- Performance-critical code where type checking overhead is measured and significant +- Migration scenarios from JavaScript (time-bounded with migration plan) + +*Process for exceptions:* +1. Document the exception reason and timeline in code comments +2. Create tracking issue for resolution if temporary +3. Review exceptions quarterly for removal opportunities + +## Quality Gates + +- **Automated checks:** TypeScript compiler with strict mode, ESLint TypeScript rules, type coverage reports +- **Code review focus:** Proper type definitions, error handling patterns, naming consistency +- **Testing requirements:** Type tests for complex utilities, runtime validation for external data + +## Related Rules + +- Frontend Component Rules - TypeScript patterns for React/Vue components +- API Integration Rules - TypeScript patterns for external API consumption +- Testing Standards - TypeScript testing patterns and mocking strategies + +## References + +- [TypeScript Handbook](https://www.typescriptlang.org/docs/) - Official TypeScript documentation +- [TypeScript Deep Dive](https://basarat.gitbook.io/typescript/) - Advanced TypeScript patterns +- [Effective TypeScript](https://effectivetypescript.com/) - Best practices guide + +--- + +## TL;DR + +*Key Principles:* +- Type safety prevents runtime errors and improves developer experience +- Explicit types serve as living documentation and improve IDE support +- Consistent conventions make codebases predictable and maintainable + +*Critical Rules:* +- Must enable strict TypeScript configuration +- Must avoid `any` type in favor of proper type definitions +- Must use explicit return types for public functions +- Always implement proper null checking + +*Quick Decision Guide:* +When in doubt: Choose the option that provides better type safety and explicit documentation of intent.