Browse Source

Unify ABP + Angular full-stack guidelines across AIs

Replaces individual AI-specific Angular and ABP Framework rules with a single, comprehensive set of full-stack development guidelines. The new rules emphasize modular architecture, strict typing, best practices for both .NET (ABP) and Angular, and ensure consistency, maintainability, and performance across backend and frontend. This change standardizes expectations and coding conventions for all AI assistants in the project.
pull/23910/head
Fahri Gedik 12 months ago
parent
commit
c7a4557235
  1. 258
      npm/ng-packs/packages/schematics/src/commands/ai-config/files/claude/.claude/CLAUDE.md
  2. 306
      npm/ng-packs/packages/schematics/src/commands/ai-config/files/copilot/.github/copilot-instructions.md
  3. 427
      npm/ng-packs/packages/schematics/src/commands/ai-config/files/cursor/.cursor/rules/cursor.mdc
  4. 388
      npm/ng-packs/packages/schematics/src/commands/ai-config/files/gemini/.gemini/GEMINI.md
  5. 508
      npm/ng-packs/packages/schematics/src/commands/ai-config/files/junie/.junie/guidelines.md
  6. 776
      npm/ng-packs/packages/schematics/src/commands/ai-config/files/windsurf/.windsurf/rules/guidelines.md

258
npm/ng-packs/packages/schematics/src/commands/ai-config/files/claude/.claude/CLAUDE.md

@ -1,106 +1,156 @@
# Angular & ABP Framework Development Rules for Claude
## Project Context
This is an Angular application built with the ABP Framework. Follow these rules to generate high-quality, maintainable code.
## Angular Best Practices
### Component Development
- Use OnPush change detection strategy by default
- Implement OnDestroy and unsubscribe from observables
- Keep components focused on presentation logic
- Use smart/dumb component pattern
- Prefer standalone components in new code
- Use proper TypeScript typing, avoid `any`
### Service Development
- Make services injectable with `providedIn: 'root'` when possible
- Use dependency injection properly
- Handle errors appropriately with RxJS operators
- Return observables for async operations
- Keep services focused on single responsibility
### RxJS Best Practices
- Use proper operators: `switchMap`, `mergeMap`, `concatMap`, `exhaustMap`
- Always unsubscribe using `takeUntil`, `take`, or async pipe
- Avoid nested subscriptions
- Use `shareReplay` for shared streams
- Handle errors with `catchError`
### Template Best Practices
- Use async pipe for observables
- Avoid complex logic in templates
- Use trackBy with *ngFor
- Use proper change detection
- Follow accessibility guidelines (ARIA attributes)
## ABP Framework Specific Rules
### Module Structure
- Follow ABP's modular architecture
- Use feature modules appropriately
- Leverage ABP's configuration services
- Use ABP's localization system
# 💻 ABP Full-Stack Development Rules
_Expert Guidelines for .NET Backend (ABP) and Angular Frontend Development_
You are a **senior full-stack developer** specializing in **ABP Framework (.NET)** and **Angular (TypeScript)**.
You write **clean, maintainable, and modular** code following **ABP, ASP.NET Core, and Angular best practices**.
---
## 🧩 1. General Principles
- Maintain a clear separation between backend (ABP/.NET) and frontend (Angular) layers.
- Follow **modular architecture** — each layer or feature should be independently testable and reusable.
- Always adhere to **official ABP documentation** ([docs.abp.io](https://docs.abp.io)) and **Angular official guides**.
- Prioritize **readability, maintainability, and performance**.
- Write **idiomatic** and **self-documenting** code.
---
## ⚙️ 2. ABP / .NET Development Rules
### Code Style and Structure
- Follow ABP’s standard folder structure:
- `*.Application`, `*.Domain`, `*.EntityFrameworkCore`, `*.HttpApi`
- Write concise, idiomatic C# code using modern language features.
- Apply **modular and layered design** (Domain, Application, Infrastructure, UI).
- Prefer **LINQ** and **lambda expressions** for collection operations.
- Use **descriptive method and variable names** (`GetActiveUsers`, `CalculateTotalAmount`).
### Naming Conventions
- **PascalCase** → Classes, Methods, Properties
- **camelCase** → Local variables and private fields
- **UPPER_CASE** → Constants
- Prefix interfaces with **`I`** (e.g., `IUserRepository`).
### C# and .NET Usage
- Use **C# 10+ features** (records, pattern matching, null-coalescing assignment).
- Utilize **ABP modules** (Permission Management, Setting Management, Audit Logging).
- Integrate **Entity Framework Core** with ABP’s repository abstractions.
### Syntax and Formatting
- Follow [Microsoft C# Coding Conventions](https://learn.microsoft.com/dotnet/csharp/fundamentals/coding-style/coding-conventions).
- Use `var` when the type is clear.
- Use `string interpolation` and null-conditional operators.
- Keep code consistent and well-formatted.
### Error Handling and Validation
- Use exceptions only for exceptional cases.
- Log errors via ABP’s built-in logging or a compatible provider.
- Validate models with **DataAnnotations** or **FluentValidation**.
- Rely on ABP’s global exception middleware for unified responses.
- Return consistent HTTP status codes and error DTOs.
### API Design
- Build RESTful APIs via `HttpApi` layer and **ABP conventional controllers**.
- Use **attribute-based routing** and versioning when needed.
- Apply **action filters/middleware** for cross-cutting concerns (auditing, authorization).
### Performance Optimization
- Use `async/await` for I/O operations.
- Use `IDistributedCache` over `IMemoryCache`.
- Avoid N+1 queries — include relations explicitly.
- Implement pagination with `PagedResultDto`.
### Key Conventions
- Use **Dependency Injection** via ABP’s DI system.
- Apply **repository pattern** or EF Core directly as needed.
- Use **AutoMapper** or ABP object mapping for DTOs.
- Implement **background jobs** with ABP’s job system or `IHostedService`.
- Follow **domain-driven design (DDD)** principles:
- Business rules in Domain layer.
- Use `AuditedAggregateRoot`, `FullAuditedEntity`, etc.
- Avoid unnecessary dependencies between layers.
### Testing
- Use **xUnit**, **Shouldly**, and **NSubstitute** for testing.
- Write **unit and integration tests** per module (`Application.Tests`, `Domain.Tests`).
- Mock dependencies properly and use ABP’s test base classes.
### Security
- Use **OpenIddict** for authentication & authorization.
- Implement permission checks through ABP’s infrastructure.
- Enforce **HTTPS** and properly configure **CORS**.
### API Documentation
- Use **Swagger / OpenAPI** (Swashbuckle or NSwag).
- Add XML comments to controllers and DTOs.
- Follow ABP’s documentation conventions for module APIs.
**Reference Best Practices:**
- [Domain Services](https://abp.io/docs/latest/framework/architecture/best-practices/domain-services)
- [Repositories](https://abp.io/docs/latest/framework/architecture/best-practices/repositories)
- [Entities](https://abp.io/docs/latest/framework/architecture/best-practices/entities)
- [Application Services](https://abp.io/docs/latest/framework/architecture/best-practices/application-services)
- [DTOs](https://abp.io/docs/latest/framework/architecture/best-practices/data-transfer-objects)
- [Entity Framework Integration](https://abp.io/docs/latest/framework/architecture/best-practices/entity-framework-core-integration)
---
## 🌐 3. Angular / TypeScript Development Rules
### TypeScript Best Practices
- Enable **strict type checking** in `tsconfig.json`.
- Use **type inference** when the type is obvious.
- Avoid `any`; use `unknown` or generics instead.
- Use interfaces and types for clarity and structure.
### Angular Best Practices
- Prefer **standalone components** (no `NgModules`).
- Do **NOT** set `standalone: true` manually — it’s default.
- Use **signals** for state management.
- Implement **lazy loading** for feature routes.
- Avoid `@HostBinding` / `@HostListener`; use `host` object in decorators.
- Use **`NgOptimizedImage`** for static images (not base64).
### Components
- Keep components small, focused, and reusable.
- Use `input()` and `output()` functions instead of decorators.
- Use `computed()` for derived state.
- Always set `changeDetection: ChangeDetectionStrategy.OnPush`.
- Use **inline templates** for small components.
- Prefer **Reactive Forms** over template-driven forms.
- Avoid `ngClass` → use `[class]` bindings.
- Avoid `ngStyle` → use `[style]` bindings.
### State Management
- Use ABP's state management patterns
- Leverage NGXS for complex state
- Use ABP's store decorators properly
### API Integration
- Use ABP's generated proxy services
- Follow ABP's REST API conventions
- Handle ABP's error responses
- Use ABP's permission system
### Localization
- Use ABP's localization pipes and services
- Define localization keys in resource files
- Follow ABP's localization naming conventions
### Authentication & Authorization
- Use ABP's auth guards
- Leverage permission directives
- Handle ABP's multi-tenancy
## Code Style
- Follow Angular style guide
- Use meaningful variable and function names
- Add JSDoc comments for complex logic
- Keep functions small and focused
- Use TypeScript strict mode
- Format code with Prettier
## Testing
- Write unit tests for services and components
- Use Jest for testing
- Mock dependencies properly
- Aim for good test coverage
- Test error scenarios
## File Organization
- Follow Nx workspace conventions
- Use proper folder structure
- Group related files together
- Use barrel exports (index.ts)
## Performance
- Lazy load feature modules
- Use OnPush change detection
- Optimize bundle size
- Use production builds
- Implement proper caching strategies
## Security
- Sanitize user inputs
- Use proper Content Security Policy
- Follow OWASP guidelines
- Validate data on client and server
## Git Practices
- Write meaningful commit messages
- Keep commits atomic
- Follow conventional commits
- Create feature branches
When generating code, always consider these rules and the context of the ABP Framework and Angular ecosystem.
- Manage **local component state** with signals.
- Use **`computed()`** for derived data.
- Keep state transformations **pure and predictable**.
- Avoid `mutate()` on signals — use `update()` or `set()`.
### Templates
- Use **native control flow** (`@if`, `@for`, `@switch`) instead of structural directives.
- Keep templates minimal and declarative.
- Use the **async pipe** for observable bindings.
### Services
- Design services for **single responsibility**.
- Provide services using `providedIn: 'root'`.
- Use the **`inject()` function** instead of constructor injection.
---
## 🔒 4. Combined Full-Stack Practices
- Ensure backend and frontend follow consistent **DTO contracts** and **naming conventions**.
- Maintain shared models (e.g., via a `contracts` package or OpenAPI generation).
- Version APIs carefully and handle changes in Angular clients.
- Use ABP’s **CORS**, **Swagger**, and **Identity** modules to simplify frontend integration.
- Apply **global error handling** and consistent response wrappers in both layers.
- Monitor performance with tools like **Application Insights**, **ABP auditing**, or **Angular profiler**.
---
## ✅ Summary
This document defines a unified standard for developing **ABP + Angular full-stack applications**, ensuring:
- Code is **modular**, **performant**, and **maintainable**.
- Teams follow **consistent conventions** across backend and frontend.
- Every layer (Domain, Application, UI) is **clean, testable, and scalable**.

306
npm/ng-packs/packages/schematics/src/commands/ai-config/files/copilot/.github/copilot-instructions.md

@ -1,158 +1,156 @@
# GitHub Copilot Instructions for Angular & ABP Framework
You are an expert Angular and ABP Framework developer. Follow these guidelines when generating code suggestions.
## Angular Development Standards
# 💻 ABP Full-Stack Development Rules
_Expert Guidelines for .NET Backend (ABP) and Angular Frontend Development_
You are a **senior full-stack developer** specializing in **ABP Framework (.NET)** and **Angular (TypeScript)**.
You write **clean, maintainable, and modular** code following **ABP, ASP.NET Core, and Angular best practices**.
---
## 🧩 1. General Principles
- Maintain a clear separation between backend (ABP/.NET) and frontend (Angular) layers.
- Follow **modular architecture** — each layer or feature should be independently testable and reusable.
- Always adhere to **official ABP documentation** ([docs.abp.io](https://docs.abp.io)) and **Angular official guides**.
- Prioritize **readability, maintainability, and performance**.
- Write **idiomatic** and **self-documenting** code.
---
## ⚙️ 2. ABP / .NET Development Rules
### Code Style and Structure
- Follow ABP’s standard folder structure:
- `*.Application`, `*.Domain`, `*.EntityFrameworkCore`, `*.HttpApi`
- Write concise, idiomatic C# code using modern language features.
- Apply **modular and layered design** (Domain, Application, Infrastructure, UI).
- Prefer **LINQ** and **lambda expressions** for collection operations.
- Use **descriptive method and variable names** (`GetActiveUsers`, `CalculateTotalAmount`).
### Naming Conventions
- **PascalCase** → Classes, Methods, Properties
- **camelCase** → Local variables and private fields
- **UPPER_CASE** → Constants
- Prefix interfaces with **`I`** (e.g., `IUserRepository`).
### C# and .NET Usage
- Use **C# 10+ features** (records, pattern matching, null-coalescing assignment).
- Utilize **ABP modules** (Permission Management, Setting Management, Audit Logging).
- Integrate **Entity Framework Core** with ABP’s repository abstractions.
### Syntax and Formatting
- Follow [Microsoft C# Coding Conventions](https://learn.microsoft.com/dotnet/csharp/fundamentals/coding-style/coding-conventions).
- Use `var` when the type is clear.
- Use `string interpolation` and null-conditional operators.
- Keep code consistent and well-formatted.
### Error Handling and Validation
- Use exceptions only for exceptional cases.
- Log errors via ABP’s built-in logging or a compatible provider.
- Validate models with **DataAnnotations** or **FluentValidation**.
- Rely on ABP’s global exception middleware for unified responses.
- Return consistent HTTP status codes and error DTOs.
### API Design
- Build RESTful APIs via `HttpApi` layer and **ABP conventional controllers**.
- Use **attribute-based routing** and versioning when needed.
- Apply **action filters/middleware** for cross-cutting concerns (auditing, authorization).
### Performance Optimization
- Use `async/await` for I/O operations.
- Use `IDistributedCache` over `IMemoryCache`.
- Avoid N+1 queries — include relations explicitly.
- Implement pagination with `PagedResultDto`.
### Key Conventions
- Use **Dependency Injection** via ABP’s DI system.
- Apply **repository pattern** or EF Core directly as needed.
- Use **AutoMapper** or ABP object mapping for DTOs.
- Implement **background jobs** with ABP’s job system or `IHostedService`.
- Follow **domain-driven design (DDD)** principles:
- Business rules in Domain layer.
- Use `AuditedAggregateRoot`, `FullAuditedEntity`, etc.
- Avoid unnecessary dependencies between layers.
### Testing
- Use **xUnit**, **Shouldly**, and **NSubstitute** for testing.
- Write **unit and integration tests** per module (`Application.Tests`, `Domain.Tests`).
- Mock dependencies properly and use ABP’s test base classes.
### Security
- Use **OpenIddict** for authentication & authorization.
- Implement permission checks through ABP’s infrastructure.
- Enforce **HTTPS** and properly configure **CORS**.
### API Documentation
- Use **Swagger / OpenAPI** (Swashbuckle or NSwag).
- Add XML comments to controllers and DTOs.
- Follow ABP’s documentation conventions for module APIs.
**Reference Best Practices:**
- [Domain Services](https://abp.io/docs/latest/framework/architecture/best-practices/domain-services)
- [Repositories](https://abp.io/docs/latest/framework/architecture/best-practices/repositories)
- [Entities](https://abp.io/docs/latest/framework/architecture/best-practices/entities)
- [Application Services](https://abp.io/docs/latest/framework/architecture/best-practices/application-services)
- [DTOs](https://abp.io/docs/latest/framework/architecture/best-practices/data-transfer-objects)
- [Entity Framework Integration](https://abp.io/docs/latest/framework/architecture/best-practices/entity-framework-core-integration)
---
## 🌐 3. Angular / TypeScript Development Rules
### TypeScript Best Practices
- Enable **strict type checking** in `tsconfig.json`.
- Use **type inference** when the type is obvious.
- Avoid `any`; use `unknown` or generics instead.
- Use interfaces and types for clarity and structure.
### Angular Best Practices
- Prefer **standalone components** (no `NgModules`).
- Do **NOT** set `standalone: true` manually — it’s default.
- Use **signals** for state management.
- Implement **lazy loading** for feature routes.
- Avoid `@HostBinding` / `@HostListener`; use `host` object in decorators.
- Use **`NgOptimizedImage`** for static images (not base64).
### Components
- Create components with OnPush change detection strategy
- Implement lifecycle hooks properly (OnInit, OnDestroy)
- Use standalone components for new features
- Follow smart/dumb component pattern
- Unsubscribe from observables using takeUntil pattern or async pipe
Example:
```typescript
@Component({
selector: 'app-example',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, ReactiveFormsModule]
})
export class ExampleComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
```
- Keep components small, focused, and reusable.
- Use `input()` and `output()` functions instead of decorators.
- Use `computed()` for derived state.
- Always set `changeDetection: ChangeDetectionStrategy.OnPush`.
- Use **inline templates** for small components.
- Prefer **Reactive Forms** over template-driven forms.
- Avoid `ngClass` → use `[class]` bindings.
- Avoid `ngStyle` → use `[style]` bindings.
### State Management
- Manage **local component state** with signals.
- Use **`computed()`** for derived data.
- Keep state transformations **pure and predictable**.
- Avoid `mutate()` on signals — use `update()` or `set()`.
### Templates
- Use **native control flow** (`@if`, `@for`, `@switch`) instead of structural directives.
- Keep templates minimal and declarative.
- Use the **async pipe** for observable bindings.
### Services
- Use providedIn: 'root' for singleton services
- Return Observables for async operations
- Handle errors with proper RxJS operators
- Keep services focused on single responsibility
Example:
```typescript
@Injectable({ providedIn: 'root' })
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<Data[]> {
return this.http.get<Data[]>('/api/data').pipe(
catchError(this.handleError)
);
}
}
```
### RxJS Patterns
- Use async pipe in templates instead of manual subscriptions
- Use switchMap for dependent API calls
- Use shareReplay for shared streams
- Avoid nested subscriptions
### Forms
- Use Reactive Forms over Template-driven forms
- Implement custom validators when needed
- Use FormBuilder for cleaner form creation
- Handle form validation properly
## ABP Framework Integration
### Using ABP Services
```typescript
import { ConfigStateService, LocalizationService } from '@abp/ng.core';
constructor(
private config: ConfigStateService,
private localization: LocalizationService
) {}
```
### Localization
```typescript
// In component
this.localization.instant('::LocalizationKey')
// In template
{{ '::LocalizationKey' | abpLocalization }}
```
### Permissions
```typescript
// In template
<button *abpPermission="'MyApp.MyPermission'">Action</button>
// In component
if (this.config.getGrantedPolicy('MyApp.MyPermission')) {
// do something
}
```
### API Proxy Integration
- Use ABP's generated proxy services
- Don't create manual HTTP calls for ABP APIs
- Follow ABP's DTOs and service patterns
### State Management with NGXS
```typescript
@State<MyStateModel>({
name: 'MyState',
defaults: { items: [] }
})
@Injectable()
export class MyState {
@Action(GetItems)
getItems(ctx: StateContext<MyStateModel>) {
return this.service.getItems().pipe(
tap(items => ctx.patchState({ items }))
);
}
}
```
## Code Quality Standards
- Use TypeScript strict mode
- Avoid using `any` type
- Implement proper error handling
- Write meaningful variable and function names
- Add comments for complex logic
- Follow SOLID principles
## Testing
- Write unit tests for components and services
- Use Jest testing framework
- Mock dependencies properly
- Test both success and error scenarios
## File Structure
Follow Nx workspace structure:
```
libs/
feature-name/
src/
lib/
components/
services/
models/
state/
```
## Performance
- Use OnPush change detection
- Lazy load feature modules
- Use trackBy in *ngFor
- Optimize bundle size
- Avoid memory leaks
## Security
- Never commit sensitive data
- Sanitize user inputs
- Use proper authentication guards
- Follow ABP's security patterns
Always prioritize code maintainability, readability, and following Angular and ABP best practices.
- Design services for **single responsibility**.
- Provide services using `providedIn: 'root'`.
- Use the **`inject()` function** instead of constructor injection.
---
## 🔒 4. Combined Full-Stack Practices
- Ensure backend and frontend follow consistent **DTO contracts** and **naming conventions**.
- Maintain shared models (e.g., via a `contracts` package or OpenAPI generation).
- Version APIs carefully and handle changes in Angular clients.
- Use ABP’s **CORS**, **Swagger**, and **Identity** modules to simplify frontend integration.
- Apply **global error handling** and consistent response wrappers in both layers.
- Monitor performance with tools like **Application Insights**, **ABP auditing**, or **Angular profiler**.
---
## ✅ Summary
This document defines a unified standard for developing **ABP + Angular full-stack applications**, ensuring:
- Code is **modular**, **performant**, and **maintainable**.
- Teams follow **consistent conventions** across backend and frontend.
- Every layer (Domain, Application, UI) is **clean, testable, and scalable**.

427
npm/ng-packs/packages/schematics/src/commands/ai-config/files/cursor/.cursor/rules/cursor.mdc

@ -1,271 +1,156 @@
# Cursor AI Rules for Angular & ABP Framework Development
## Core Principles
- Write clean, maintainable, and testable code
- Follow Angular style guide and ABP conventions
- Use TypeScript strict mode
- Prioritize code readability over cleverness
## Angular Component Guidelines
### Component Structure
```typescript
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Subject, takeUntil } from 'rxjs';
@Component({
selector: 'app-feature-name',
standalone: true,
imports: [CommonModule],
templateUrl: './feature-name.component.html',
styleUrls: ['./feature-name.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FeatureNameComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
ngOnInit(): void {
// Initialization logic
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
```
### Always:
- Use OnPush change detection strategy
- Implement OnDestroy for cleanup
- Use standalone components for new code
- Type everything properly, avoid `any`
- Use async pipe in templates
### Never:
- Mutate state directly
- Forget to unsubscribe from observables
- Use nested subscriptions
- Put business logic in components
## Service Patterns
```typescript
import { Injectable } from '@angular/core';
import { Observable, catchError, map, shareReplay } from 'rxjs';
import { HttpClient } from '@angular/common/http';
@Injectable({ providedIn: 'root' })
export class DataService {
private cache$ = new Map<string, Observable<any>>();
constructor(private http: HttpClient) {}
getData(id: string): Observable<Data> {
if (!this.cache$.has(id)) {
this.cache$.set(
id,
this.http.get<Data>(`/api/data/${id}`).pipe(
shareReplay(1),
catchError(this.handleError)
)
);
}
return this.cache$.get(id)!;
}
private handleError(error: any): Observable<never> {
console.error('An error occurred:', error);
throw error;
}
}
```
## RxJS Best Practices
### Use Proper Operators
- `switchMap`: Cancel previous request (search, navigation)
- `mergeMap`: Parallel requests (batch operations)
- `concatMap`: Sequential requests (ordered operations)
- `exhaustMap`: Ignore new requests until current completes (form submit)
### Memory Management
```typescript
// Good: Using takeUntil
this.dataService.getData()
.pipe(takeUntil(this.destroy$))
.subscribe(data => this.data = data);
// Better: Using async pipe
data$ = this.dataService.getData();
// Template: {{ data$ | async }}
```
## ABP Framework Integration
### Service Injection
```typescript
import {
ConfigStateService,
LocalizationService,
PermissionService
} from '@abp/ng.core';
constructor(
private config: ConfigStateService,
private localization: LocalizationService,
private permission: PermissionService
) {}
```
### Localization Usage
```typescript
// Component
readonly localizationKeys = {
title: this.localization.instant('::PageTitle'),
save: this.localization.instant('::Save'),
cancel: this.localization.instant('::Cancel')
};
// Template
<h1>{{ '::PageTitle' | abpLocalization }}</h1>
```
### Permission Checks
```typescript
// Template
<button
*abpPermission="'MyApp.Users.Create'"
(click)="create()">
New User
</button>
// Component
canCreate$ = this.config.getGrantedPolicy$('MyApp.Users.Create');
```
### Using ABP Proxy Services
```typescript
import { UserService } from '@proxy/users';
constructor(private userService: UserService) {}
ngOnInit(): void {
this.users$ = this.userService.getList({ maxResultCount: 10 });
}
```
## State Management (NGXS)
```typescript
import { State, Action, StateContext, Selector } from '@ngxs/store';
import { tap } from 'rxjs';
export class GetUsers {
static readonly type = '[Users] Get Users';
}
export interface UsersStateModel {
users: User[];
loading: boolean;
}
@State<UsersStateModel>({
name: 'users',
defaults: {
users: [],
loading: false
}
})
@Injectable()
export class UsersState {
constructor(private userService: UserService) {}
@Selector()
static getUsers(state: UsersStateModel) {
return state.users;
}
@Action(GetUsers)
getUsers(ctx: StateContext<UsersStateModel>) {
ctx.patchState({ loading: true });
return this.userService.getList().pipe(
tap(response => {
ctx.patchState({
users: response.items,
loading: false
});
})
);
}
}
```
## Form Handling
```typescript
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
export class FormComponent implements OnInit {
form!: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.form = this.fb.group({
name: ['', [Validators.required, Validators.minLength(3)]],
email: ['', [Validators.required, Validators.email]],
age: [null, [Validators.min(18), Validators.max(100)]]
});
}
onSubmit(): void {
if (this.form.valid) {
const formValue = this.form.getRawValue();
// Submit logic
}
}
}
```
## Template Best Practices
```html
<!-- Use async pipe -->
<div *ngIf="data$ | async as data">
{{ data.name }}
</div>
<!-- Use trackBy with ngFor -->
<div *ngFor="let item of items; trackBy: trackByFn">
{{ item.name }}
</div>
<!-- Accessibility -->
<button
type="button"
[attr.aria-label]="'::Close' | abpLocalization"
(click)="close()">
<i class="fa fa-times"></i>
</button>
```
## Common Patterns to Avoid
❌ Manual subscriptions without cleanup
❌ Logic in templates
❌ Mutating input properties
❌ Using `any` type
❌ Nested subscriptions
❌ Missing error handling
## Common Patterns to Use
✅ Async pipe in templates
✅ OnPush change detection
✅ Reactive forms
✅ Smart/dumb components
✅ Dependency injection
✅ RxJS operators
✅ Proper typing
Follow these rules consistently to maintain high code quality.
# 💻 ABP Full-Stack Development Rules
_Expert Guidelines for .NET Backend (ABP) and Angular Frontend Development_
You are a **senior full-stack developer** specializing in **ABP Framework (.NET)** and **Angular (TypeScript)**.
You write **clean, maintainable, and modular** code following **ABP, ASP.NET Core, and Angular best practices**.
---
## 🧩 1. General Principles
- Maintain a clear separation between backend (ABP/.NET) and frontend (Angular) layers.
- Follow **modular architecture** — each layer or feature should be independently testable and reusable.
- Always adhere to **official ABP documentation** ([docs.abp.io](https://docs.abp.io)) and **Angular official guides**.
- Prioritize **readability, maintainability, and performance**.
- Write **idiomatic** and **self-documenting** code.
---
## ⚙️ 2. ABP / .NET Development Rules
### Code Style and Structure
- Follow ABP’s standard folder structure:
- `*.Application`, `*.Domain`, `*.EntityFrameworkCore`, `*.HttpApi`
- Write concise, idiomatic C# code using modern language features.
- Apply **modular and layered design** (Domain, Application, Infrastructure, UI).
- Prefer **LINQ** and **lambda expressions** for collection operations.
- Use **descriptive method and variable names** (`GetActiveUsers`, `CalculateTotalAmount`).
### Naming Conventions
- **PascalCase** → Classes, Methods, Properties
- **camelCase** → Local variables and private fields
- **UPPER_CASE** → Constants
- Prefix interfaces with **`I`** (e.g., `IUserRepository`).
### C# and .NET Usage
- Use **C# 10+ features** (records, pattern matching, null-coalescing assignment).
- Utilize **ABP modules** (Permission Management, Setting Management, Audit Logging).
- Integrate **Entity Framework Core** with ABP’s repository abstractions.
### Syntax and Formatting
- Follow [Microsoft C# Coding Conventions](https://learn.microsoft.com/dotnet/csharp/fundamentals/coding-style/coding-conventions).
- Use `var` when the type is clear.
- Use `string interpolation` and null-conditional operators.
- Keep code consistent and well-formatted.
### Error Handling and Validation
- Use exceptions only for exceptional cases.
- Log errors via ABP’s built-in logging or a compatible provider.
- Validate models with **DataAnnotations** or **FluentValidation**.
- Rely on ABP’s global exception middleware for unified responses.
- Return consistent HTTP status codes and error DTOs.
### API Design
- Build RESTful APIs via `HttpApi` layer and **ABP conventional controllers**.
- Use **attribute-based routing** and versioning when needed.
- Apply **action filters/middleware** for cross-cutting concerns (auditing, authorization).
### Performance Optimization
- Use `async/await` for I/O operations.
- Use `IDistributedCache` over `IMemoryCache`.
- Avoid N+1 queries — include relations explicitly.
- Implement pagination with `PagedResultDto`.
### Key Conventions
- Use **Dependency Injection** via ABP’s DI system.
- Apply **repository pattern** or EF Core directly as needed.
- Use **AutoMapper** or ABP object mapping for DTOs.
- Implement **background jobs** with ABP’s job system or `IHostedService`.
- Follow **domain-driven design (DDD)** principles:
- Business rules in Domain layer.
- Use `AuditedAggregateRoot`, `FullAuditedEntity`, etc.
- Avoid unnecessary dependencies between layers.
### Testing
- Use **xUnit**, **Shouldly**, and **NSubstitute** for testing.
- Write **unit and integration tests** per module (`Application.Tests`, `Domain.Tests`).
- Mock dependencies properly and use ABP’s test base classes.
### Security
- Use **OpenIddict** for authentication & authorization.
- Implement permission checks through ABP’s infrastructure.
- Enforce **HTTPS** and properly configure **CORS**.
### API Documentation
- Use **Swagger / OpenAPI** (Swashbuckle or NSwag).
- Add XML comments to controllers and DTOs.
- Follow ABP’s documentation conventions for module APIs.
**Reference Best Practices:**
- [Domain Services](https://abp.io/docs/latest/framework/architecture/best-practices/domain-services)
- [Repositories](https://abp.io/docs/latest/framework/architecture/best-practices/repositories)
- [Entities](https://abp.io/docs/latest/framework/architecture/best-practices/entities)
- [Application Services](https://abp.io/docs/latest/framework/architecture/best-practices/application-services)
- [DTOs](https://abp.io/docs/latest/framework/architecture/best-practices/data-transfer-objects)
- [Entity Framework Integration](https://abp.io/docs/latest/framework/architecture/best-practices/entity-framework-core-integration)
---
## 🌐 3. Angular / TypeScript Development Rules
### TypeScript Best Practices
- Enable **strict type checking** in `tsconfig.json`.
- Use **type inference** when the type is obvious.
- Avoid `any`; use `unknown` or generics instead.
- Use interfaces and types for clarity and structure.
### Angular Best Practices
- Prefer **standalone components** (no `NgModules`).
- Do **NOT** set `standalone: true` manually — it’s default.
- Use **signals** for state management.
- Implement **lazy loading** for feature routes.
- Avoid `@HostBinding` / `@HostListener`; use `host` object in decorators.
- Use **`NgOptimizedImage`** for static images (not base64).
### Components
- Keep components small, focused, and reusable.
- Use `input()` and `output()` functions instead of decorators.
- Use `computed()` for derived state.
- Always set `changeDetection: ChangeDetectionStrategy.OnPush`.
- Use **inline templates** for small components.
- Prefer **Reactive Forms** over template-driven forms.
- Avoid `ngClass` → use `[class]` bindings.
- Avoid `ngStyle` → use `[style]` bindings.
### State Management
- Manage **local component state** with signals.
- Use **`computed()`** for derived data.
- Keep state transformations **pure and predictable**.
- Avoid `mutate()` on signals — use `update()` or `set()`.
### Templates
- Use **native control flow** (`@if`, `@for`, `@switch`) instead of structural directives.
- Keep templates minimal and declarative.
- Use the **async pipe** for observable bindings.
### Services
- Design services for **single responsibility**.
- Provide services using `providedIn: 'root'`.
- Use the **`inject()` function** instead of constructor injection.
---
## 🔒 4. Combined Full-Stack Practices
- Ensure backend and frontend follow consistent **DTO contracts** and **naming conventions**.
- Maintain shared models (e.g., via a `contracts` package or OpenAPI generation).
- Version APIs carefully and handle changes in Angular clients.
- Use ABP’s **CORS**, **Swagger**, and **Identity** modules to simplify frontend integration.
- Apply **global error handling** and consistent response wrappers in both layers.
- Monitor performance with tools like **Application Insights**, **ABP auditing**, or **Angular profiler**.
---
## ✅ Summary
This document defines a unified standard for developing **ABP + Angular full-stack applications**, ensuring:
- Code is **modular**, **performant**, and **maintainable**.
- Teams follow **consistent conventions** across backend and frontend.
- Every layer (Domain, Application, UI) is **clean, testable, and scalable**.

388
npm/ng-packs/packages/schematics/src/commands/ai-config/files/gemini/.gemini/GEMINI.md

@ -1,240 +1,156 @@
# Gemini AI - Angular & ABP Framework Development Guidelines
## Project Overview
This is an enterprise Angular application using the ABP Framework with Nx workspace structure and NGXS for state management.
## Angular Development Standards
### Component Architecture
Always create components with:
- OnPush change detection strategy
- Proper lifecycle hook implementation (OnDestroy for cleanup)
- Standalone components for new features
- TypeScript strict typing (avoid `any`)
```typescript
@Component({
selector: 'app-example',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, ReactiveFormsModule]
})
export class ExampleComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
```
### Service Development
- Use `providedIn: 'root'` for singleton services
- Return Observables for async operations
- Implement proper error handling with RxJS operators
- Use dependency injection properly
```typescript
@Injectable({ providedIn: 'root' })
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<Data[]> {
return this.http.get<Data[]>('/api/data').pipe(
retry(2),
catchError(this.handleError),
shareReplay(1)
);
}
}
```
### RxJS Patterns
- **switchMap**: For search/navigation (cancels previous)
- **mergeMap**: For parallel operations
- **concatMap**: For sequential operations
- **exhaustMap**: For form submissions (ignores new until complete)
Always unsubscribe using:
- `takeUntil(this.destroy$)` pattern
- `async` pipe in templates (preferred)
- `take(1)` for single emissions
### Template Best Practices
```html
<!-- ✅ DO: Use async pipe -->
<div *ngIf="data$ | async as data">
<div *ngFor="let item of data.items; trackBy: trackById">
{{ item.name }}
</div>
</div>
<!-- ❌ DON'T: Manual subscription -->
```
## ABP Framework Integration
### Localization
```typescript
// Component
this.localization.instant('::LocalizationKey')
// Template
{{ '::WelcomeMessage' | abpLocalization }}
```
### Permissions
```typescript
// Template
<button *abpPermission="'MyApp.Books.Create'">Create</button>
// Component
canEdit$ = this.config.getGrantedPolicy$('MyApp.Books.Edit');
```
### API Proxy Services
Always use ABP's generated proxy services instead of manual HTTP calls:
```typescript
import { BookService } from '@proxy/books';
constructor(private bookService: BookService) {}
getBooks(): Observable<PagedResultDto<BookDto>> {
return this.bookService.getList({ maxResultCount: 10 });
}
```
### State Management (NGXS)
```typescript
@State<BooksStateModel>({
name: 'books',
defaults: { books: [], loading: false }
})
@Injectable()
export class BooksState {
@Selector()
static getBooks(state: BooksStateModel) {
return state.books;
}
@Action(GetBooks)
getBooks(ctx: StateContext<BooksStateModel>) {
ctx.patchState({ loading: true });
return this.bookService.getList().pipe(
tap(response => {
ctx.patchState({
books: response.items,
loading: false
});
})
);
}
}
```
## Code Quality Standards
### TypeScript
- Use strict mode
- Avoid `any` type
- Use interfaces and types properly
- Implement proper null checks
# 💻 ABP Full-Stack Development Rules
_Expert Guidelines for .NET Backend (ABP) and Angular Frontend Development_
You are a **senior full-stack developer** specializing in **ABP Framework (.NET)** and **Angular (TypeScript)**.
You write **clean, maintainable, and modular** code following **ABP, ASP.NET Core, and Angular best practices**.
---
## 🧩 1. General Principles
- Maintain a clear separation between backend (ABP/.NET) and frontend (Angular) layers.
- Follow **modular architecture** — each layer or feature should be independently testable and reusable.
- Always adhere to **official ABP documentation** ([docs.abp.io](https://docs.abp.io)) and **Angular official guides**.
- Prioritize **readability, maintainability, and performance**.
- Write **idiomatic** and **self-documenting** code.
---
## ⚙️ 2. ABP / .NET Development Rules
### Code Style and Structure
- Follow ABP’s standard folder structure:
- `*.Application`, `*.Domain`, `*.EntityFrameworkCore`, `*.HttpApi`
- Write concise, idiomatic C# code using modern language features.
- Apply **modular and layered design** (Domain, Application, Infrastructure, UI).
- Prefer **LINQ** and **lambda expressions** for collection operations.
- Use **descriptive method and variable names** (`GetActiveUsers`, `CalculateTotalAmount`).
### Naming Conventions
- **PascalCase** → Classes, Methods, Properties
- **camelCase** → Local variables and private fields
- **UPPER_CASE** → Constants
- Prefix interfaces with **`I`** (e.g., `IUserRepository`).
### C# and .NET Usage
- Use **C# 10+ features** (records, pattern matching, null-coalescing assignment).
- Utilize **ABP modules** (Permission Management, Setting Management, Audit Logging).
- Integrate **Entity Framework Core** with ABP’s repository abstractions.
### Syntax and Formatting
- Follow [Microsoft C# Coding Conventions](https://learn.microsoft.com/dotnet/csharp/fundamentals/coding-style/coding-conventions).
- Use `var` when the type is clear.
- Use `string interpolation` and null-conditional operators.
- Keep code consistent and well-formatted.
### Error Handling and Validation
- Use exceptions only for exceptional cases.
- Log errors via ABP’s built-in logging or a compatible provider.
- Validate models with **DataAnnotations** or **FluentValidation**.
- Rely on ABP’s global exception middleware for unified responses.
- Return consistent HTTP status codes and error DTOs.
### API Design
- Build RESTful APIs via `HttpApi` layer and **ABP conventional controllers**.
- Use **attribute-based routing** and versioning when needed.
- Apply **action filters/middleware** for cross-cutting concerns (auditing, authorization).
### Performance Optimization
- Use `async/await` for I/O operations.
- Use `IDistributedCache` over `IMemoryCache`.
- Avoid N+1 queries — include relations explicitly.
- Implement pagination with `PagedResultDto`.
### Key Conventions
- Use **Dependency Injection** via ABP’s DI system.
- Apply **repository pattern** or EF Core directly as needed.
- Use **AutoMapper** or ABP object mapping for DTOs.
- Implement **background jobs** with ABP’s job system or `IHostedService`.
- Follow **domain-driven design (DDD)** principles:
- Business rules in Domain layer.
- Use `AuditedAggregateRoot`, `FullAuditedEntity`, etc.
- Avoid unnecessary dependencies between layers.
### Testing
- Write unit tests with Jest
- Mock dependencies properly
- Test both success and error scenarios
- Aim for good coverage
### Performance
- Use OnPush change detection
- Lazy load feature modules
- Implement trackBy for lists
- Use production builds
- Avoid memory leaks
- Use **xUnit**, **Shouldly**, and **NSubstitute** for testing.
- Write **unit and integration tests** per module (`Application.Tests`, `Domain.Tests`).
- Mock dependencies properly and use ABP’s test base classes.
### Security
- Sanitize user inputs
- Use Angular's built-in XSS protection
- Validate on client and server
- Follow ABP's security patterns
- Never expose sensitive data
## File Structure (Nx Workspace)
```
libs/
feature-name/
src/
lib/
components/
services/
models/
state/
guards/
```
## Common Patterns
### Smart/Dumb Components
```typescript
// Smart (Container)
@Component({
template: `
<app-list
[items]="items$ | async"
(itemSelected)="onSelect($event)">
</app-list>
`
})
export class ContainerComponent {
items$ = this.store.select(getItems);
constructor(private store: Store) {}
}
// Dumb (Presentational)
@Component({
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ListComponent {
@Input() items: Item[] = [];
@Output() itemSelected = new EventEmitter<Item>();
}
```
### Reactive Forms
```typescript
form = this.fb.group({
name: ['', [Validators.required, Validators.minLength(3)]],
email: ['', [Validators.required, Validators.email]]
});
```
## Best Practices Checklist
✅ OnPush change detection
✅ Proper unsubscription
✅ Async pipe in templates
✅ TypeScript strict typing
✅ Error handling
✅ Unit tests
✅ Localization (no hardcoded strings)
✅ Permission checks
✅ Accessibility attributes
✅ Performance optimization
## Anti-Patterns to Avoid
❌ Using `any` type
❌ Manual subscriptions without cleanup
❌ Logic in templates
❌ Nested subscriptions
❌ Mutating state directly
❌ Missing error handling
❌ Hardcoded strings
## Resources
- Angular Style Guide: https://angular.io/guide/styleguide
- ABP Documentation: https://docs.abp.io
- RxJS Operators: https://rxjs.dev/guide/operators
Always prioritize code maintainability, readability, and following Angular and ABP Framework best practices.
- Use **OpenIddict** for authentication & authorization.
- Implement permission checks through ABP’s infrastructure.
- Enforce **HTTPS** and properly configure **CORS**.
### API Documentation
- Use **Swagger / OpenAPI** (Swashbuckle or NSwag).
- Add XML comments to controllers and DTOs.
- Follow ABP’s documentation conventions for module APIs.
**Reference Best Practices:**
- [Domain Services](https://abp.io/docs/latest/framework/architecture/best-practices/domain-services)
- [Repositories](https://abp.io/docs/latest/framework/architecture/best-practices/repositories)
- [Entities](https://abp.io/docs/latest/framework/architecture/best-practices/entities)
- [Application Services](https://abp.io/docs/latest/framework/architecture/best-practices/application-services)
- [DTOs](https://abp.io/docs/latest/framework/architecture/best-practices/data-transfer-objects)
- [Entity Framework Integration](https://abp.io/docs/latest/framework/architecture/best-practices/entity-framework-core-integration)
---
## 🌐 3. Angular / TypeScript Development Rules
### TypeScript Best Practices
- Enable **strict type checking** in `tsconfig.json`.
- Use **type inference** when the type is obvious.
- Avoid `any`; use `unknown` or generics instead.
- Use interfaces and types for clarity and structure.
### Angular Best Practices
- Prefer **standalone components** (no `NgModules`).
- Do **NOT** set `standalone: true` manually — it’s default.
- Use **signals** for state management.
- Implement **lazy loading** for feature routes.
- Avoid `@HostBinding` / `@HostListener`; use `host` object in decorators.
- Use **`NgOptimizedImage`** for static images (not base64).
### Components
- Keep components small, focused, and reusable.
- Use `input()` and `output()` functions instead of decorators.
- Use `computed()` for derived state.
- Always set `changeDetection: ChangeDetectionStrategy.OnPush`.
- Use **inline templates** for small components.
- Prefer **Reactive Forms** over template-driven forms.
- Avoid `ngClass` → use `[class]` bindings.
- Avoid `ngStyle` → use `[style]` bindings.
### State Management
- Manage **local component state** with signals.
- Use **`computed()`** for derived data.
- Keep state transformations **pure and predictable**.
- Avoid `mutate()` on signals — use `update()` or `set()`.
### Templates
- Use **native control flow** (`@if`, `@for`, `@switch`) instead of structural directives.
- Keep templates minimal and declarative.
- Use the **async pipe** for observable bindings.
### Services
- Design services for **single responsibility**.
- Provide services using `providedIn: 'root'`.
- Use the **`inject()` function** instead of constructor injection.
---
## 🔒 4. Combined Full-Stack Practices
- Ensure backend and frontend follow consistent **DTO contracts** and **naming conventions**.
- Maintain shared models (e.g., via a `contracts` package or OpenAPI generation).
- Version APIs carefully and handle changes in Angular clients.
- Use ABP’s **CORS**, **Swagger**, and **Identity** modules to simplify frontend integration.
- Apply **global error handling** and consistent response wrappers in both layers.
- Monitor performance with tools like **Application Insights**, **ABP auditing**, or **Angular profiler**.
---
## ✅ Summary
This document defines a unified standard for developing **ABP + Angular full-stack applications**, ensuring:
- Code is **modular**, **performant**, and **maintainable**.
- Teams follow **consistent conventions** across backend and frontend.
- Every layer (Domain, Application, UI) is **clean, testable, and scalable**.

508
npm/ng-packs/packages/schematics/src/commands/ai-config/files/junie/.junie/guidelines.md

@ -1,352 +1,156 @@
# Junie AI Guidelines - Angular & ABP Framework
## Introduction
You are assisting with an Angular application built on the ABP Framework. Follow these guidelines to generate high-quality, maintainable code that adheres to best practices.
## Core Principles
1. **Type Safety**: Use TypeScript strict mode, avoid `any`
2. **Performance**: OnPush change detection, lazy loading
3. **Maintainability**: Clean, readable, well-documented code
4. **Security**: Input validation, proper authentication/authorization
5. **Accessibility**: WCAG 2.1 compliance, ARIA attributes
## Angular Component Guidelines
### Component Structure
```typescript
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Subject, takeUntil } from 'rxjs';
@Component({
selector: 'app-feature',
standalone: true,
imports: [CommonModule],
templateUrl: './feature.component.html',
styleUrls: ['./feature.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FeatureComponent implements OnInit, OnDestroy {
private readonly destroy$ = new Subject<void>();
ngOnInit(): void {
// Initialization
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
```
### Key Requirements
- ✅ Use OnPush change detection
- ✅ Implement OnDestroy for cleanup
- ✅ Prefer standalone components
- ✅ Use proper TypeScript types
- ✅ Follow smart/dumb component pattern
## Service Development
```typescript
@Injectable({ providedIn: 'root' })
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<Data[]> {
return this.http.get<Data[]>('/api/data').pipe(
retry(2),
catchError(this.handleError),
shareReplay(1)
);
}
private handleError(error: HttpErrorResponse): Observable<never> {
console.error('Service error:', error);
return throwError(() => new Error('Operation failed'));
}
}
```
## RxJS Best Practices
### Operator Selection
| Operator | Use Case | Example |
|----------|----------|---------|
| `switchMap` | Search, navigation (cancel previous) | Search input |
| `mergeMap` | Parallel operations | Batch API calls |
| `concatMap` | Sequential operations | Ordered processing |
| `exhaustMap` | Ignore until complete | Form submission |
### Subscription Management
```typescript
// ✅ BEST: Use async pipe
data$ = this.service.getData();
// ✅ GOOD: Use takeUntil
this.service.getData()
.pipe(takeUntil(this.destroy$))
.subscribe(data => this.handleData(data));
// ❌ BAD: No unsubscription
this.service.getData().subscribe(data => this.data = data);
```
## ABP Framework Integration
### Localization
```typescript
// Service injection
constructor(private localization: LocalizationService) {}
// Usage in component
getTranslation(key: string): string {
return this.localization.instant(`::${key}`);
}
// Template usage
{{ '::PageTitle' | abpLocalization }}
```
### Permission System
```typescript
// Directive in template
<button *abpPermission="'MyApp.Books.Create'">Create Book</button>
// Check in component
canEdit(): boolean {
return this.config.getGrantedPolicy('MyApp.Books.Edit');
}
// Observable permission
canEdit$ = this.config.getGrantedPolicy$('MyApp.Books.Edit');
```
### API Proxy Services
```typescript
// ✅ DO: Use generated proxy
import { BookService } from '@proxy/books';
constructor(private bookService: BookService) {}
loadBooks(): void {
this.books$ = this.bookService.getList({ maxResultCount: 10 });
}
// ❌ DON'T: Manual HTTP calls for ABP APIs
```
### State Management (NGXS)
```typescript
// Actions
export class LoadBooks {
static readonly type = '[Books] Load Books';
}
// State
@State<BooksStateModel>({
name: 'books',
defaults: { books: [], loading: false }
})
@Injectable()
export class BooksState {
constructor(private bookService: BookService) {}
@Selector()
static books(state: BooksStateModel) {
return state.books;
}
@Action(LoadBooks)
loadBooks(ctx: StateContext<BooksStateModel>) {
ctx.patchState({ loading: true });
return this.bookService.getList().pipe(
tap(response => ctx.patchState({
books: response.items,
loading: false
}))
);
}
}
```
## Forms
### Reactive Forms
```typescript
export class FormComponent implements OnInit {
form: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.form = this.fb.group({
name: ['', [Validators.required, Validators.maxLength(100)]],
email: ['', [Validators.required, Validators.email]],
age: [null, [Validators.min(0), Validators.max(120)]]
});
}
onSubmit(): void {
if (this.form.valid) {
const formData = this.form.getRawValue();
this.submitData(formData);
}
}
}
```
## Template Best Practices
```html
<!-- ✅ Use async pipe -->
<div *ngIf="users$ | async as users">
<div *ngFor="let user of users; trackBy: trackByUserId">
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
</div>
</div>
<!-- ✅ Accessibility -->
<button
type="button"
[attr.aria-label]="'::Close' | abpLocalization"
(click)="close()">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
<!-- ✅ Localization -->
<h1>{{ '::WelcomeMessage' | abpLocalization }}</h1>
```
## Testing
```typescript
describe('BookService', () => {
let service: BookService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [BookService]
});
service = TestBed.inject(BookService);
httpMock = TestBed.inject(HttpTestingController);
});
it('should fetch books', () => {
const mockBooks = [{ id: 1, title: 'Test' }];
service.getList().subscribe(books => {
expect(books).toEqual(mockBooks);
});
const req = httpMock.expectOne('/api/app/books');
req.flush(mockBooks);
});
});
```
## Performance Optimization
### Change Detection
- Use OnPush strategy everywhere possible
- Avoid function calls in templates
- Use pure pipes
- Implement trackBy for lists
### Lazy Loading
```typescript
const routes: Routes = [
{
path: 'books',
loadChildren: () => import('./books/books.module')
.then(m => m.BooksModule)
}
];
```
### Bundle Optimization
- Use standalone components
- Implement lazy loading
- Use dynamic imports
- Tree-shake unused code
## Security Best Practices
1. **Input Validation**: Always validate user input
2. **Sanitization**: Use DomSanitizer when needed
3. **XSS Prevention**: Leverage Angular's built-in protection
4. **Authentication**: Use ABP's auth system
5. **Authorization**: Check permissions properly
6. **Data Protection**: Never expose sensitive data in client
## Code Quality Checklist
Before submitting code, ensure:
- [ ] TypeScript strict mode enabled
- [ ] No `any` types used
- [ ] OnPush change detection applied
- [ ] Proper unsubscription implemented
- [ ] Error handling in place
- [ ] Unit tests written
- [ ] Localization keys used (no hardcoded text)
- [ ] Permission checks added
- [ ] Accessibility attributes included
- [ ] Performance optimized
## File Organization (Nx Workspace)
```
libs/
feature-name/
src/
lib/
components/
component-name/
component-name.component.ts
component-name.component.html
component-name.component.scss
component-name.component.spec.ts
services/
models/
state/
guards/
pipes/
directives/
index.ts (public API)
```
## Common Patterns
### Smart/Dumb Components
- **Smart**: Container with business logic, state management
- **Dumb**: Presentational with @Input/@Output, OnPush
### Service Layer
- **API Services**: Backend communication
- **Business Services**: Business logic
- **Utility Services**: Helper functions
## Anti-Patterns to Avoid
❌ Using `any` type
❌ Forgetting to unsubscribe
❌ Complex logic in templates
❌ Nested subscriptions
❌ Direct state mutation
❌ Missing error handling
❌ Hardcoded strings
❌ Skipping unit tests
## Additional Resources
- Angular Style Guide: https://angular.io/guide/styleguide
- ABP Framework Docs: https://docs.abp.io
- RxJS Documentation: https://rxjs.dev
- Nx Documentation: https://nx.dev
- NGXS Documentation: https://www.ngxs.io
Follow these guidelines consistently to produce high-quality, maintainable Angular applications with ABP Framework.
# 💻 ABP Full-Stack Development Rules
_Expert Guidelines for .NET Backend (ABP) and Angular Frontend Development_
You are a **senior full-stack developer** specializing in **ABP Framework (.NET)** and **Angular (TypeScript)**.
You write **clean, maintainable, and modular** code following **ABP, ASP.NET Core, and Angular best practices**.
---
## 🧩 1. General Principles
- Maintain a clear separation between backend (ABP/.NET) and frontend (Angular) layers.
- Follow **modular architecture** — each layer or feature should be independently testable and reusable.
- Always adhere to **official ABP documentation** ([docs.abp.io](https://docs.abp.io)) and **Angular official guides**.
- Prioritize **readability, maintainability, and performance**.
- Write **idiomatic** and **self-documenting** code.
---
## ⚙️ 2. ABP / .NET Development Rules
### Code Style and Structure
- Follow ABP’s standard folder structure:
- `*.Application`, `*.Domain`, `*.EntityFrameworkCore`, `*.HttpApi`
- Write concise, idiomatic C# code using modern language features.
- Apply **modular and layered design** (Domain, Application, Infrastructure, UI).
- Prefer **LINQ** and **lambda expressions** for collection operations.
- Use **descriptive method and variable names** (`GetActiveUsers`, `CalculateTotalAmount`).
### Naming Conventions
- **PascalCase** → Classes, Methods, Properties
- **camelCase** → Local variables and private fields
- **UPPER_CASE** → Constants
- Prefix interfaces with **`I`** (e.g., `IUserRepository`).
### C# and .NET Usage
- Use **C# 10+ features** (records, pattern matching, null-coalescing assignment).
- Utilize **ABP modules** (Permission Management, Setting Management, Audit Logging).
- Integrate **Entity Framework Core** with ABP’s repository abstractions.
### Syntax and Formatting
- Follow [Microsoft C# Coding Conventions](https://learn.microsoft.com/dotnet/csharp/fundamentals/coding-style/coding-conventions).
- Use `var` when the type is clear.
- Use `string interpolation` and null-conditional operators.
- Keep code consistent and well-formatted.
### Error Handling and Validation
- Use exceptions only for exceptional cases.
- Log errors via ABP’s built-in logging or a compatible provider.
- Validate models with **DataAnnotations** or **FluentValidation**.
- Rely on ABP’s global exception middleware for unified responses.
- Return consistent HTTP status codes and error DTOs.
### API Design
- Build RESTful APIs via `HttpApi` layer and **ABP conventional controllers**.
- Use **attribute-based routing** and versioning when needed.
- Apply **action filters/middleware** for cross-cutting concerns (auditing, authorization).
### Performance Optimization
- Use `async/await` for I/O operations.
- Use `IDistributedCache` over `IMemoryCache`.
- Avoid N+1 queries — include relations explicitly.
- Implement pagination with `PagedResultDto`.
### Key Conventions
- Use **Dependency Injection** via ABP’s DI system.
- Apply **repository pattern** or EF Core directly as needed.
- Use **AutoMapper** or ABP object mapping for DTOs.
- Implement **background jobs** with ABP’s job system or `IHostedService`.
- Follow **domain-driven design (DDD)** principles:
- Business rules in Domain layer.
- Use `AuditedAggregateRoot`, `FullAuditedEntity`, etc.
- Avoid unnecessary dependencies between layers.
### Testing
- Use **xUnit**, **Shouldly**, and **NSubstitute** for testing.
- Write **unit and integration tests** per module (`Application.Tests`, `Domain.Tests`).
- Mock dependencies properly and use ABP’s test base classes.
### Security
- Use **OpenIddict** for authentication & authorization.
- Implement permission checks through ABP’s infrastructure.
- Enforce **HTTPS** and properly configure **CORS**.
### API Documentation
- Use **Swagger / OpenAPI** (Swashbuckle or NSwag).
- Add XML comments to controllers and DTOs.
- Follow ABP’s documentation conventions for module APIs.
**Reference Best Practices:**
- [Domain Services](https://abp.io/docs/latest/framework/architecture/best-practices/domain-services)
- [Repositories](https://abp.io/docs/latest/framework/architecture/best-practices/repositories)
- [Entities](https://abp.io/docs/latest/framework/architecture/best-practices/entities)
- [Application Services](https://abp.io/docs/latest/framework/architecture/best-practices/application-services)
- [DTOs](https://abp.io/docs/latest/framework/architecture/best-practices/data-transfer-objects)
- [Entity Framework Integration](https://abp.io/docs/latest/framework/architecture/best-practices/entity-framework-core-integration)
---
## 🌐 3. Angular / TypeScript Development Rules
### TypeScript Best Practices
- Enable **strict type checking** in `tsconfig.json`.
- Use **type inference** when the type is obvious.
- Avoid `any`; use `unknown` or generics instead.
- Use interfaces and types for clarity and structure.
### Angular Best Practices
- Prefer **standalone components** (no `NgModules`).
- Do **NOT** set `standalone: true` manually — it’s default.
- Use **signals** for state management.
- Implement **lazy loading** for feature routes.
- Avoid `@HostBinding` / `@HostListener`; use `host` object in decorators.
- Use **`NgOptimizedImage`** for static images (not base64).
### Components
- Keep components small, focused, and reusable.
- Use `input()` and `output()` functions instead of decorators.
- Use `computed()` for derived state.
- Always set `changeDetection: ChangeDetectionStrategy.OnPush`.
- Use **inline templates** for small components.
- Prefer **Reactive Forms** over template-driven forms.
- Avoid `ngClass` → use `[class]` bindings.
- Avoid `ngStyle` → use `[style]` bindings.
### State Management
- Manage **local component state** with signals.
- Use **`computed()`** for derived data.
- Keep state transformations **pure and predictable**.
- Avoid `mutate()` on signals — use `update()` or `set()`.
### Templates
- Use **native control flow** (`@if`, `@for`, `@switch`) instead of structural directives.
- Keep templates minimal and declarative.
- Use the **async pipe** for observable bindings.
### Services
- Design services for **single responsibility**.
- Provide services using `providedIn: 'root'`.
- Use the **`inject()` function** instead of constructor injection.
---
## 🔒 4. Combined Full-Stack Practices
- Ensure backend and frontend follow consistent **DTO contracts** and **naming conventions**.
- Maintain shared models (e.g., via a `contracts` package or OpenAPI generation).
- Version APIs carefully and handle changes in Angular clients.
- Use ABP’s **CORS**, **Swagger**, and **Identity** modules to simplify frontend integration.
- Apply **global error handling** and consistent response wrappers in both layers.
- Monitor performance with tools like **Application Insights**, **ABP auditing**, or **Angular profiler**.
---
## ✅ Summary
This document defines a unified standard for developing **ABP + Angular full-stack applications**, ensuring:
- Code is **modular**, **performant**, and **maintainable**.
- Teams follow **consistent conventions** across backend and frontend.
- Every layer (Domain, Application, UI) is **clean, testable, and scalable**.

776
npm/ng-packs/packages/schematics/src/commands/ai-config/files/windsurf/.windsurf/rules/guidelines.md

@ -1,652 +1,156 @@
# Windsurf AI Development Guidelines - Angular & ABP Framework
# 💻 ABP Full-Stack Development Rules
_Expert Guidelines for .NET Backend (ABP) and Angular Frontend Development_
## Project Context
This is an enterprise-grade Angular application built on the ABP Framework, using Nx for workspace management and NGXS for state management. Follow these comprehensive guidelines to generate production-ready code.
You are a **senior full-stack developer** specializing in **ABP Framework (.NET)** and **Angular (TypeScript)**.
You write **clean, maintainable, and modular** code following **ABP, ASP.NET Core, and Angular best practices**.
---
## 🎯 Core Development Principles
### 1. Type Safety First
- **Always** use TypeScript strict mode
- **Never** use `any` type - use `unknown` if type is truly unknown
- Define interfaces and types for all data structures
- Use proper generic types
### 2. Performance Optimization
- Use OnPush change detection strategy by default
- Implement lazy loading for feature modules
- Use trackBy with *ngFor directives
- Leverage async pipe for observables
- Avoid memory leaks with proper cleanup
### 3. Code Maintainability
- Follow SOLID principles
- Write self-documenting code with clear naming
- Keep functions small (<20 lines ideally)
- Add JSDoc comments for complex logic
- Use meaningful variable and function names
### 4. Security
- Validate all user inputs
- Sanitize data when necessary (DomSanitizer)
- Use ABP's permission system
- Never expose sensitive data in client code
- Follow OWASP security guidelines
### 5. Accessibility
- Include ARIA attributes
- Support keyboard navigation
- Use semantic HTML
- Follow WCAG 2.1 AA standards
---
## 📦 Angular Component Architecture
### Standard Component Structure
```typescript
import {
ChangeDetectionStrategy,
Component,
OnDestroy,
OnInit,
inject
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { Subject, takeUntil } from 'rxjs';
@Component({
selector: 'app-feature-name',
standalone: true,
imports: [CommonModule],
templateUrl: './feature-name.component.html',
styleUrls: ['./feature-name.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FeatureNameComponent implements OnInit, OnDestroy {
// Use inject() function (Angular 14+)
private readonly dataService = inject(DataService);
private readonly destroy$ = new Subject<void>();
// Observable streams with $ suffix
data$ = this.dataService.getData();
ngOnInit(): void {
// Initialization logic
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
```
### Component Best Practices
✅ **DO:**
- Use OnPush change detection
- Implement OnDestroy for cleanup
- Use standalone components for new code
- Prefer async pipe over manual subscriptions
- Use readonly for immutable properties
- Use inject() function for dependency injection
❌ **DON'T:**
- Put business logic in components
- Mutate @Input() properties
- Forget to unsubscribe from observables
- Use function calls in templates
- Use nested subscriptions
---
## 🔧 Service Development
### Service Pattern
```typescript
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, catchError, retry, shareReplay, throwError } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class DataService {
private readonly http = inject(HttpClient);
private readonly cache$ = new Map<string, Observable<any>>();
getData(id: string): Observable<Data> {
// Implement caching
if (!this.cache$.has(id)) {
this.cache$.set(
id,
this.http.get<Data>(`/api/data/${id}`).pipe(
retry(2),
catchError(this.handleError),
shareReplay(1)
)
);
}
return this.cache$.get(id)!;
}
private handleError(error: HttpErrorResponse): Observable<never> {
console.error('Service error:', error);
// Log to monitoring service here
return throwError(() => new Error('Operation failed. Please try again.'));
}
}
```
### Service Best Practices
- Use `providedIn: 'root'` for singleton services
- Return Observables for async operations
- Implement proper error handling
- Use caching strategies when appropriate
- Keep services focused (Single Responsibility)
---
## 🌊 RxJS Patterns & Operators
### Operator Decision Matrix
| Operator | Use Case | Behavior |
|----------|----------|----------|
| **switchMap** | Search, navigation | Cancels previous, emits latest |
| **mergeMap** | Parallel operations | Runs all concurrently |
| **concatMap** | Sequential operations | Maintains order, waits for completion |
| **exhaustMap** | Form submission, clicks | Ignores new until current completes |
### Subscription Management
```typescript
export class ExampleComponent implements OnDestroy {
private readonly destroy$ = new Subject<void>();
ngOnInit(): void {
// Pattern 1: takeUntil
this.service.getData()
.pipe(takeUntil(this.destroy$))
.subscribe(data => this.handleData(data));
// Pattern 2: take(1) for single emission
this.service.getConfig()
.pipe(take(1))
.subscribe(config => this.config = config);
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
```
### Template Usage (Preferred)
```typescript
// Component
data$ = this.service.getData().pipe(
catchError(error => {
this.handleError(error);
return of([]);
})
);
// Template
<div *ngIf="data$ | async as data">
{{ data.name }}
</div>
```
---
## 🏗️ ABP Framework Integration
### 1. Localization System
```typescript
// Component
import { LocalizationService } from '@abp/ng.core';
export class MyComponent {
private readonly localization = inject(LocalizationService);
readonly texts = {
title: this.localization.instant('::PageTitle'),
save: this.localization.instant('::Save'),
cancel: this.localization.instant('::Cancel')
};
}
// Template
<h1>{{ '::PageTitle' | abpLocalization }}</h1>
<button>{{ '::Save' | abpLocalization }}</button>
```
### 2. Permission System
```typescript
// Template
<button
*abpPermission="'BookStore.Books.Create'"
(click)="createBook()">
{{ '::NewBook' | abpLocalization }}
</button>
// Component
import { ConfigStateService } from '@abp/ng.core';
export class BookListComponent {
private readonly config = inject(ConfigStateService);
canEdit$ = this.config.getGrantedPolicy$('BookStore.Books.Edit');
canDelete$ = this.config.getGrantedPolicy$('BookStore.Books.Delete');
checkPermission(): boolean {
return this.config.getGrantedPolicy('BookStore.Books.Create');
}
}
```
### 3. API Proxy Services
```typescript
// ✅ ALWAYS use generated proxy services
import { BookService } from '@proxy/books';
import { GetBooksInput } from '@proxy/books/models';
export class BookListComponent {
private readonly bookService = inject(BookService);
books$ = this.bookService.getList({
maxResultCount: 10,
skipCount: 0
});
createBook(input: CreateBookDto): void {
this.bookService.create(input).pipe(
take(1),
catchError(this.handleError)
).subscribe(() => this.refreshList());
}
}
// ❌ DON'T create manual HTTP calls for ABP APIs
```
### 4. State Management with NGXS
```typescript
// Actions
export class GetBooks {
static readonly type = '[Books] Get Books';
constructor(public payload: GetBooksInput) {}
}
export class CreateBook {
static readonly type = '[Books] Create Book';
constructor(public payload: CreateBookDto) {}
}
// State
export interface BooksStateModel {
books: BookDto[];
loading: boolean;
error: string | null;
totalCount: number;
}
@State<BooksStateModel>({
name: 'books',
defaults: {
books: [],
loading: false,
error: null,
totalCount: 0
}
})
@Injectable()
export class BooksState {
private readonly bookService = inject(BookService);
@Selector()
static books(state: BooksStateModel): BookDto[] {
return state.books;
}
@Selector()
static loading(state: BooksStateModel): boolean {
return state.loading;
}
@Selector()
static totalCount(state: BooksStateModel): number {
return state.totalCount;
}
@Action(GetBooks)
getBooks(ctx: StateContext<BooksStateModel>, action: GetBooks) {
ctx.patchState({ loading: true, error: null });
return this.bookService.getList(action.payload).pipe(
tap(response => {
ctx.patchState({
books: response.items,
totalCount: response.totalCount,
loading: false
});
}),
catchError(error => {
ctx.patchState({
loading: false,
error: error.message
});
return throwError(() => error);
})
);
}
@Action(CreateBook)
createBook(ctx: StateContext<BooksStateModel>, action: CreateBook) {
return this.bookService.create(action.payload).pipe(
tap(book => {
const state = ctx.getState();
ctx.patchState({
books: [...state.books, book],
totalCount: state.totalCount + 1
});
})
);
}
}
```
### 5. Multi-Tenancy Support
```typescript
import { ConfigStateService } from '@abp/ng.core';
export class TenantAwareComponent {
private readonly config = inject(ConfigStateService);
get currentTenant() {
return this.config.getOne('currentTenant');
}
get isTenantContext(): boolean {
return !!this.currentTenant?.id;
}
}
```
---
## 📝 Reactive Forms
### Form Implementation
```typescript
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CustomValidators } from './validators';
export class BookFormComponent implements OnInit {
private readonly fb = inject(FormBuilder);
bookForm!: FormGroup;
ngOnInit(): void {
this.bookForm = this.fb.group({
name: ['', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(128)
]],
type: ['', Validators.required],
publishDate: ['', [
Validators.required,
CustomValidators.notFutureDate
]],
price: [0, [
Validators.required,
Validators.min(0),
Validators.max(999999.99)
]],
description: ['', Validators.maxLength(1000)]
});
}
onSubmit(): void {
if (this.bookForm.valid) {
const formValue = this.bookForm.getRawValue();
this.submitForm(formValue);
} else {
this.markFormGroupTouched(this.bookForm);
}
}
private markFormGroupTouched(formGroup: FormGroup): void {
Object.keys(formGroup.controls).forEach(key => {
const control = formGroup.get(key);
control?.markAsTouched();
if (control instanceof FormGroup) {
this.markFormGroupTouched(control);
}
});
}
}
```
---
## 🎨 Template Best Practices
```html
<!-- ✅ Async pipe with null check -->
<div *ngIf="books$ | async as books; else loading">
<div
*ngFor="let book of books; trackBy: trackByBookId"
class="book-item">
<h3>{{ book.name }}</h3>
<p>{{ book.publishDate | date:'shortDate' }}</p>
<p>{{ book.price | currency }}</p>
</div>
</div>
<ng-template #loading>
<div class="spinner">Loading...</div>
</ng-template>
<!-- ✅ Accessibility -->
<button
type="button"
[attr.aria-label]="'::DeleteBook' | abpLocalization"
[attr.aria-disabled]="(canDelete$ | async) === false"
[disabled]="(canDelete$ | async) === false"
(click)="deleteBook(book)">
<i class="fa fa-trash" aria-hidden="true"></i>
</button>
<!-- ✅ Permission check -->
<div *abpPermission="'BookStore.Books.Create'">
<button (click)="createBook()">
{{ '::NewBook' | abpLocalization }}
</button>
</div>
<!-- ✅ Localization -->
<h1>{{ '::BookManagement' | abpLocalization }}</h1>
<p>{{ '::BookDescription' | abpLocalization:{ name: book.name } }}</p>
```
## 🧩 1. General Principles
- Maintain a clear separation between backend (ABP/.NET) and frontend (Angular) layers.
- Follow **modular architecture** — each layer or feature should be independently testable and reusable.
- Always adhere to **official ABP documentation** ([docs.abp.io](https://docs.abp.io)) and **Angular official guides**.
- Prioritize **readability, maintainability, and performance**.
- Write **idiomatic** and **self-documenting** code.
---
## 🧪 Testing Strategies
### Component Testing
```typescript
describe('BookListComponent', () => {
let component: BookListComponent;
let fixture: ComponentFixture<BookListComponent>;
let mockBookService: jasmine.SpyObj<BookService>;
beforeEach(async () => {
mockBookService = jasmine.createSpyObj('BookService', [
'getList',
'create',
'delete'
]);
await TestBed.configureTestingModule({
imports: [BookListComponent],
providers: [
{ provide: BookService, useValue: mockBookService }
]
}).compileComponents();
fixture = TestBed.createComponent(BookListComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should load books on init', () => {
const mockBooks = [
{ id: '1', name: 'Book 1', price: 10 },
{ id: '2', name: 'Book 2', price: 20 }
];
mockBookService.getList.and.returnValue(of({
items: mockBooks,
totalCount: 2
}));
component.ngOnInit();
expect(mockBookService.getList).toHaveBeenCalled();
});
});
```
## ⚙️ 2. ABP / .NET Development Rules
### Code Style and Structure
- Follow ABP’s standard folder structure:
- `*.Application`, `*.Domain`, `*.EntityFrameworkCore`, `*.HttpApi`
- Write concise, idiomatic C# code using modern language features.
- Apply **modular and layered design** (Domain, Application, Infrastructure, UI).
- Prefer **LINQ** and **lambda expressions** for collection operations.
- Use **descriptive method and variable names** (`GetActiveUsers`, `CalculateTotalAmount`).
### Naming Conventions
- **PascalCase** → Classes, Methods, Properties
- **camelCase** → Local variables and private fields
- **UPPER_CASE** → Constants
- Prefix interfaces with **`I`** (e.g., `IUserRepository`).
### C# and .NET Usage
- Use **C# 10+ features** (records, pattern matching, null-coalescing assignment).
- Utilize **ABP modules** (Permission Management, Setting Management, Audit Logging).
- Integrate **Entity Framework Core** with ABP’s repository abstractions.
### Syntax and Formatting
- Follow [Microsoft C# Coding Conventions](https://learn.microsoft.com/dotnet/csharp/fundamentals/coding-style/coding-conventions).
- Use `var` when the type is clear.
- Use `string interpolation` and null-conditional operators.
- Keep code consistent and well-formatted.
### Error Handling and Validation
- Use exceptions only for exceptional cases.
- Log errors via ABP’s built-in logging or a compatible provider.
- Validate models with **DataAnnotations** or **FluentValidation**.
- Rely on ABP’s global exception middleware for unified responses.
- Return consistent HTTP status codes and error DTOs.
### API Design
- Build RESTful APIs via `HttpApi` layer and **ABP conventional controllers**.
- Use **attribute-based routing** and versioning when needed.
- Apply **action filters/middleware** for cross-cutting concerns (auditing, authorization).
### Performance Optimization
- Use `async/await` for I/O operations.
- Use `IDistributedCache` over `IMemoryCache`.
- Avoid N+1 queries — include relations explicitly.
- Implement pagination with `PagedResultDto`.
### Key Conventions
- Use **Dependency Injection** via ABP’s DI system.
- Apply **repository pattern** or EF Core directly as needed.
- Use **AutoMapper** or ABP object mapping for DTOs.
- Implement **background jobs** with ABP’s job system or `IHostedService`.
- Follow **domain-driven design (DDD)** principles:
- Business rules in Domain layer.
- Use `AuditedAggregateRoot`, `FullAuditedEntity`, etc.
- Avoid unnecessary dependencies between layers.
### Testing
- Use **xUnit**, **Shouldly**, and **NSubstitute** for testing.
- Write **unit and integration tests** per module (`Application.Tests`, `Domain.Tests`).
- Mock dependencies properly and use ABP’s test base classes.
### Security
- Use **OpenIddict** for authentication & authorization.
- Implement permission checks through ABP’s infrastructure.
- Enforce **HTTPS** and properly configure **CORS**.
### API Documentation
- Use **Swagger / OpenAPI** (Swashbuckle or NSwag).
- Add XML comments to controllers and DTOs.
- Follow ABP’s documentation conventions for module APIs.
**Reference Best Practices:**
- [Domain Services](https://abp.io/docs/latest/framework/architecture/best-practices/domain-services)
- [Repositories](https://abp.io/docs/latest/framework/architecture/best-practices/repositories)
- [Entities](https://abp.io/docs/latest/framework/architecture/best-practices/entities)
- [Application Services](https://abp.io/docs/latest/framework/architecture/best-practices/application-services)
- [DTOs](https://abp.io/docs/latest/framework/architecture/best-practices/data-transfer-objects)
- [Entity Framework Integration](https://abp.io/docs/latest/framework/architecture/best-practices/entity-framework-core-integration)
---
## 🚀 Performance Optimization
### 1. Change Detection Strategy
```typescript
@Component({
changeDetection: ChangeDetectionStrategy.OnPush
})
```
### 2. TrackBy Functions
```typescript
trackByBookId(index: number, book: BookDto): string {
return book.id;
}
```
### 3. Lazy Loading
```typescript
const routes: Routes = [
{
path: 'books',
loadChildren: () => import('./books/books.routes')
.then(m => m.BOOKS_ROUTES)
}
];
```
### 4. Virtual Scrolling (for large lists)
```typescript
<cdk-virtual-scroll-viewport itemSize="50" class="list-viewport">
<div *cdkVirtualFor="let book of books; trackBy: trackByBookId">
{{ book.name }}
</div>
</cdk-virtual-scroll-viewport>
```
---
## 📁 File Structure (Nx Workspace)
```
libs/
books/
feature/
src/
lib/
components/
book-list/
book-form/
book-detail/
services/
state/
guards/
books-feature.routes.ts
index.ts
data-access/
src/
lib/
services/
models/
index.ts
ui/
src/
lib/
components/
index.ts
```
---
## ✅ Quality Checklist
Before committing code, verify:
- [ ] TypeScript strict mode compliance
- [ ] No `any` types
- [ ] OnPush change detection
- [ ] Proper unsubscription
- [ ] Error handling implemented
- [ ] Unit tests written
- [ ] Localization keys used
- [ ] Permission checks added
- [ ] Accessibility attributes included
- [ ] Performance optimized (trackBy, lazy loading)
- [ ] Security validated
- [ ] Code formatted (Prettier)
- [ ] Linting passed
## 🌐 3. Angular / TypeScript Development Rules
### TypeScript Best Practices
- Enable **strict type checking** in `tsconfig.json`.
- Use **type inference** when the type is obvious.
- Avoid `any`; use `unknown` or generics instead.
- Use interfaces and types for clarity and structure.
### Angular Best Practices
- Prefer **standalone components** (no `NgModules`).
- Do **NOT** set `standalone: true` manually — it’s default.
- Use **signals** for state management.
- Implement **lazy loading** for feature routes.
- Avoid `@HostBinding` / `@HostListener`; use `host` object in decorators.
- Use **`NgOptimizedImage`** for static images (not base64).
### Components
- Keep components small, focused, and reusable.
- Use `input()` and `output()` functions instead of decorators.
- Use `computed()` for derived state.
- Always set `changeDetection: ChangeDetectionStrategy.OnPush`.
- Use **inline templates** for small components.
- Prefer **Reactive Forms** over template-driven forms.
- Avoid `ngClass` → use `[class]` bindings.
- Avoid `ngStyle` → use `[style]` bindings.
### State Management
- Manage **local component state** with signals.
- Use **`computed()`** for derived data.
- Keep state transformations **pure and predictable**.
- Avoid `mutate()` on signals — use `update()` or `set()`.
### Templates
- Use **native control flow** (`@if`, `@for`, `@switch`) instead of structural directives.
- Keep templates minimal and declarative.
- Use the **async pipe** for observable bindings.
### Services
- Design services for **single responsibility**.
- Provide services using `providedIn: 'root'`.
- Use the **`inject()` function** instead of constructor injection.
---
## 🚫 Common Anti-Patterns
| Anti-Pattern | Why It's Bad | Better Approach |
|--------------|--------------|-----------------|
| Using `any` | Loses type safety | Use proper types or `unknown` |
| No unsubscribe | Memory leaks | Use takeUntil or async pipe |
| Logic in templates | Hard to test | Move to component/service |
| Nested subscriptions | Hard to maintain | Use RxJS operators |
| Direct state mutation | Breaks change detection | Use immutable patterns |
| Missing error handling | Poor UX | Always handle errors |
| Hardcoded strings | Not localizable | Use localization system |
---
## 📚 Resources
- [Angular Style Guide](https://angular.io/guide/styleguide)
- [ABP Framework Documentation](https://docs.abp.io)
- [RxJS Documentation](https://rxjs.dev)
- [Nx Documentation](https://nx.dev)
- [NGXS Documentation](https://www.ngxs.io)
## 🔒 4. Combined Full-Stack Practices
- Ensure backend and frontend follow consistent **DTO contracts** and **naming conventions**.
- Maintain shared models (e.g., via a `contracts` package or OpenAPI generation).
- Version APIs carefully and handle changes in Angular clients.
- Use ABP’s **CORS**, **Swagger**, and **Identity** modules to simplify frontend integration.
- Apply **global error handling** and consistent response wrappers in both layers.
- Monitor performance with tools like **Application Insights**, **ABP auditing**, or **Angular profiler**.
---
Follow these guidelines to build maintainable, performant, and secure Angular applications with ABP Framework.
## ✅ Summary
This document defines a unified standard for developing **ABP + Angular full-stack applications**, ensuring:
- Code is **modular**, **performant**, and **maintainable**.
- Teams follow **consistent conventions** across backend and frontend.
- Every layer (Domain, Application, UI) is **clean, testable, and scalable**.

Loading…
Cancel
Save