@ngxtm/devkit 3.3.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.js +59 -13
- package/cli/rules.js +248 -0
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: .NET Tooling
|
|
3
|
+
description: Essential tooling for .NET development and CI/CD.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [dotnet, tooling, testing, build, nuget]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/*.csproj', '**/*.sln', '.editorconfig', 'Directory.Build.props']
|
|
8
|
+
keywords: [PackageReference, dotnet, test, build, publish]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# .NET Tooling
|
|
12
|
+
|
|
13
|
+
## **Priority: P1 (OPERATIONAL)**
|
|
14
|
+
|
|
15
|
+
Essential tooling for .NET development, testing, and CI/CD.
|
|
16
|
+
|
|
17
|
+
## Implementation Guidelines
|
|
18
|
+
|
|
19
|
+
- **Project Files**: SDK-style `.csproj`. Use `Directory.Build.props` for shared settings.
|
|
20
|
+
- **Central Package Management**: `Directory.Packages.props` for version consistency.
|
|
21
|
+
- **Testing**: xUnit or NUnit. FluentAssertions for readable assertions. Moq for mocking.
|
|
22
|
+
- **Code Analysis**: Enable built-in analyzers. Consider StyleCop, SonarQube.
|
|
23
|
+
- **Build**: `dotnet build`, `dotnet publish`. Use Release config for production.
|
|
24
|
+
- **EditorConfig**: Consistent code style across team.
|
|
25
|
+
- **CI/CD**: GitHub Actions, Azure DevOps, or GitLab CI.
|
|
26
|
+
|
|
27
|
+
## Anti-Patterns
|
|
28
|
+
|
|
29
|
+
- **No `packages.config`**: Migrate to `PackageReference`.
|
|
30
|
+
- **No skipping tests in CI**: Tests must pass before merge.
|
|
31
|
+
- **No ignoring warnings**: Fix or suppress with documented justification.
|
|
32
|
+
- **No floating versions**: Pin versions (`8.0.0`, not `8.*`).
|
|
33
|
+
|
|
34
|
+
## Code
|
|
35
|
+
|
|
36
|
+
```xml
|
|
37
|
+
<!-- Directory.Build.props (shared across all projects) -->
|
|
38
|
+
<Project>
|
|
39
|
+
<PropertyGroup>
|
|
40
|
+
<TargetFramework>net8.0</TargetFramework>
|
|
41
|
+
<Nullable>enable</Nullable>
|
|
42
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
43
|
+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
44
|
+
<AnalysisLevel>latest-recommended</AnalysisLevel>
|
|
45
|
+
</PropertyGroup>
|
|
46
|
+
</Project>
|
|
47
|
+
|
|
48
|
+
<!-- Directory.Packages.props (Central Package Management) -->
|
|
49
|
+
<Project>
|
|
50
|
+
<PropertyGroup>
|
|
51
|
+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
|
52
|
+
</PropertyGroup>
|
|
53
|
+
<ItemGroup>
|
|
54
|
+
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
|
55
|
+
<PackageVersion Include="FluentValidation" Version="11.9.0" />
|
|
56
|
+
<PackageVersion Include="xunit" Version="2.6.6" />
|
|
57
|
+
</ItemGroup>
|
|
58
|
+
</Project>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```csharp
|
|
62
|
+
// xUnit test with FluentAssertions
|
|
63
|
+
public class UserServiceTests
|
|
64
|
+
{
|
|
65
|
+
[Fact]
|
|
66
|
+
public async Task GetUser_WithValidId_ReturnsUser()
|
|
67
|
+
{
|
|
68
|
+
// Arrange
|
|
69
|
+
var mockRepo = new Mock<IUserRepository>();
|
|
70
|
+
mockRepo.Setup(r => r.GetByIdAsync(1, default))
|
|
71
|
+
.ReturnsAsync(new User { Id = 1, Name = "Test" });
|
|
72
|
+
var sut = new UserService(mockRepo.Object);
|
|
73
|
+
|
|
74
|
+
// Act
|
|
75
|
+
var result = await sut.GetUserAsync(1);
|
|
76
|
+
|
|
77
|
+
// Assert
|
|
78
|
+
result.Should().NotBeNull();
|
|
79
|
+
result!.Name.Should().Be("Test");
|
|
80
|
+
mockRepo.Verify(r => r.GetByIdAsync(1, default), Times.Once);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Reference & Examples
|
|
86
|
+
|
|
87
|
+
For CI/CD configuration and Docker setup:
|
|
88
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
89
|
+
|
|
90
|
+
## Related Topics
|
|
91
|
+
|
|
92
|
+
language | best-practices | security
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# .NET Tooling Reference
|
|
2
|
+
|
|
3
|
+
Testing, CI/CD, and build configuration patterns.
|
|
4
|
+
|
|
5
|
+
## References
|
|
6
|
+
|
|
7
|
+
- [**Testing Setup**](testing-setup.md) - xUnit, NUnit, integration tests.
|
|
8
|
+
- [**CI/CD**](ci-cd.md) - GitHub Actions, Azure DevOps pipelines.
|
|
9
|
+
- [**Docker**](docker.md) - Multi-stage builds for .NET.
|
|
10
|
+
|
|
11
|
+
## Project File (.csproj) Reference
|
|
12
|
+
|
|
13
|
+
```xml
|
|
14
|
+
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
15
|
+
<PropertyGroup>
|
|
16
|
+
<TargetFramework>net8.0</TargetFramework>
|
|
17
|
+
<Nullable>enable</Nullable>
|
|
18
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
19
|
+
|
|
20
|
+
<!-- Code analysis -->
|
|
21
|
+
<AnalysisLevel>latest-recommended</AnalysisLevel>
|
|
22
|
+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
23
|
+
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
|
24
|
+
|
|
25
|
+
<!-- Assembly info -->
|
|
26
|
+
<Version>1.0.0</Version>
|
|
27
|
+
<Authors>Your Name</Authors>
|
|
28
|
+
|
|
29
|
+
<!-- Build optimization -->
|
|
30
|
+
<PublishTrimmed>true</PublishTrimmed>
|
|
31
|
+
<PublishSingleFile>true</PublishSingleFile>
|
|
32
|
+
<SelfContained>true</SelfContained>
|
|
33
|
+
</PropertyGroup>
|
|
34
|
+
|
|
35
|
+
<ItemGroup>
|
|
36
|
+
<!-- Package references (versions from Directory.Packages.props) -->
|
|
37
|
+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
|
|
38
|
+
<PackageReference Include="Serilog.AspNetCore" />
|
|
39
|
+
</ItemGroup>
|
|
40
|
+
|
|
41
|
+
<ItemGroup>
|
|
42
|
+
<!-- Project references -->
|
|
43
|
+
<ProjectReference Include="..\Domain\Domain.csproj" />
|
|
44
|
+
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
|
|
45
|
+
</ItemGroup>
|
|
46
|
+
</Project>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## GitHub Actions CI/CD
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
# .github/workflows/ci.yml
|
|
53
|
+
name: CI/CD
|
|
54
|
+
|
|
55
|
+
on:
|
|
56
|
+
push:
|
|
57
|
+
branches: [main, develop]
|
|
58
|
+
pull_request:
|
|
59
|
+
branches: [main]
|
|
60
|
+
|
|
61
|
+
env:
|
|
62
|
+
DOTNET_VERSION: '8.0.x'
|
|
63
|
+
|
|
64
|
+
jobs:
|
|
65
|
+
build-and-test:
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
|
|
70
|
+
- name: Setup .NET
|
|
71
|
+
uses: actions/setup-dotnet@v4
|
|
72
|
+
with:
|
|
73
|
+
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
74
|
+
|
|
75
|
+
- name: Restore dependencies
|
|
76
|
+
run: dotnet restore
|
|
77
|
+
|
|
78
|
+
- name: Build
|
|
79
|
+
run: dotnet build --no-restore --configuration Release
|
|
80
|
+
|
|
81
|
+
- name: Test
|
|
82
|
+
run: dotnet test --no-build --configuration Release --collect:"XPlat Code Coverage" --results-directory ./coverage
|
|
83
|
+
|
|
84
|
+
- name: Upload coverage
|
|
85
|
+
uses: codecov/codecov-action@v3
|
|
86
|
+
with:
|
|
87
|
+
directory: ./coverage
|
|
88
|
+
fail_ci_if_error: true
|
|
89
|
+
|
|
90
|
+
publish:
|
|
91
|
+
needs: build-and-test
|
|
92
|
+
if: github.ref == 'refs/heads/main'
|
|
93
|
+
runs-on: ubuntu-latest
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v4
|
|
96
|
+
|
|
97
|
+
- name: Setup .NET
|
|
98
|
+
uses: actions/setup-dotnet@v4
|
|
99
|
+
with:
|
|
100
|
+
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
101
|
+
|
|
102
|
+
- name: Publish
|
|
103
|
+
run: dotnet publish src/WebApi/WebApi.csproj -c Release -o ./publish
|
|
104
|
+
|
|
105
|
+
- name: Build and push Docker image
|
|
106
|
+
uses: docker/build-push-action@v5
|
|
107
|
+
with:
|
|
108
|
+
context: .
|
|
109
|
+
push: true
|
|
110
|
+
tags: ghcr.io/${{ github.repository }}:latest
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Docker Multi-Stage Build
|
|
114
|
+
|
|
115
|
+
```dockerfile
|
|
116
|
+
# Dockerfile
|
|
117
|
+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
|
118
|
+
WORKDIR /src
|
|
119
|
+
|
|
120
|
+
# Copy csproj files and restore
|
|
121
|
+
COPY ["src/WebApi/WebApi.csproj", "src/WebApi/"]
|
|
122
|
+
COPY ["src/Domain/Domain.csproj", "src/Domain/"]
|
|
123
|
+
COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"]
|
|
124
|
+
COPY ["Directory.Build.props", "./"]
|
|
125
|
+
COPY ["Directory.Packages.props", "./"]
|
|
126
|
+
RUN dotnet restore "src/WebApi/WebApi.csproj"
|
|
127
|
+
|
|
128
|
+
# Copy everything and build
|
|
129
|
+
COPY . .
|
|
130
|
+
RUN dotnet publish "src/WebApi/WebApi.csproj" -c Release -o /app/publish --no-restore
|
|
131
|
+
|
|
132
|
+
# Runtime image
|
|
133
|
+
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
|
|
134
|
+
WORKDIR /app
|
|
135
|
+
|
|
136
|
+
# Create non-root user
|
|
137
|
+
RUN adduser --disabled-password --gecos "" appuser
|
|
138
|
+
USER appuser
|
|
139
|
+
|
|
140
|
+
COPY --from=build /app/publish .
|
|
141
|
+
|
|
142
|
+
ENV ASPNETCORE_URLS=http://+:8080
|
|
143
|
+
EXPOSE 8080
|
|
144
|
+
|
|
145
|
+
ENTRYPOINT ["dotnet", "WebApi.dll"]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Integration Testing with WebApplicationFactory
|
|
149
|
+
|
|
150
|
+
```csharp
|
|
151
|
+
// CustomWebApplicationFactory.cs
|
|
152
|
+
public class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram>
|
|
153
|
+
where TProgram : class
|
|
154
|
+
{
|
|
155
|
+
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
|
156
|
+
{
|
|
157
|
+
builder.ConfigureServices(services =>
|
|
158
|
+
{
|
|
159
|
+
// Replace real database with in-memory
|
|
160
|
+
var descriptor = services.SingleOrDefault(
|
|
161
|
+
d => d.ServiceType == typeof(DbContextOptions<AppDbContext>));
|
|
162
|
+
|
|
163
|
+
if (descriptor != null)
|
|
164
|
+
services.Remove(descriptor);
|
|
165
|
+
|
|
166
|
+
services.AddDbContext<AppDbContext>(options =>
|
|
167
|
+
options.UseInMemoryDatabase("TestDb"));
|
|
168
|
+
|
|
169
|
+
// Replace external services with fakes
|
|
170
|
+
services.AddScoped<IEmailService, FakeEmailService>();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
builder.UseEnvironment("Testing");
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Integration tests
|
|
178
|
+
public class UsersApiTests : IClassFixture<CustomWebApplicationFactory<Program>>
|
|
179
|
+
{
|
|
180
|
+
private readonly HttpClient _client;
|
|
181
|
+
private readonly CustomWebApplicationFactory<Program> _factory;
|
|
182
|
+
|
|
183
|
+
public UsersApiTests(CustomWebApplicationFactory<Program> factory)
|
|
184
|
+
{
|
|
185
|
+
_factory = factory;
|
|
186
|
+
_client = factory.CreateClient();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
[Fact]
|
|
190
|
+
public async Task GetUsers_ReturnsSuccessAndUsers()
|
|
191
|
+
{
|
|
192
|
+
// Arrange - seed data
|
|
193
|
+
using var scope = _factory.Services.CreateScope();
|
|
194
|
+
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
195
|
+
db.Users.Add(new User { Name = "Test User", Email = "test@example.com" });
|
|
196
|
+
await db.SaveChangesAsync();
|
|
197
|
+
|
|
198
|
+
// Act
|
|
199
|
+
var response = await _client.GetAsync("/api/users");
|
|
200
|
+
|
|
201
|
+
// Assert
|
|
202
|
+
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
|
203
|
+
var users = await response.Content.ReadFromJsonAsync<List<UserDto>>();
|
|
204
|
+
users.Should().ContainSingle(u => u.Email == "test@example.com");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
[Fact]
|
|
208
|
+
public async Task CreateUser_WithValidData_ReturnsCreated()
|
|
209
|
+
{
|
|
210
|
+
// Arrange
|
|
211
|
+
var newUser = new CreateUserDto { Name = "New User", Email = "new@example.com" };
|
|
212
|
+
|
|
213
|
+
// Act
|
|
214
|
+
var response = await _client.PostAsJsonAsync("/api/users", newUser);
|
|
215
|
+
|
|
216
|
+
// Assert
|
|
217
|
+
response.StatusCode.Should().Be(HttpStatusCode.Created);
|
|
218
|
+
response.Headers.Location.Should().NotBeNull();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## EditorConfig
|
|
224
|
+
|
|
225
|
+
```ini
|
|
226
|
+
# .editorconfig
|
|
227
|
+
root = true
|
|
228
|
+
|
|
229
|
+
[*]
|
|
230
|
+
indent_style = space
|
|
231
|
+
indent_size = 4
|
|
232
|
+
end_of_line = lf
|
|
233
|
+
charset = utf-8
|
|
234
|
+
trim_trailing_whitespace = true
|
|
235
|
+
insert_final_newline = true
|
|
236
|
+
|
|
237
|
+
[*.cs]
|
|
238
|
+
# Naming conventions
|
|
239
|
+
dotnet_naming_rule.private_fields_should_be_camel_case.severity = error
|
|
240
|
+
dotnet_naming_rule.private_fields_should_be_camel_case.symbols = private_fields
|
|
241
|
+
dotnet_naming_rule.private_fields_should_be_camel_case.style = camel_case_underscore
|
|
242
|
+
|
|
243
|
+
dotnet_naming_symbols.private_fields.applicable_kinds = field
|
|
244
|
+
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
|
|
245
|
+
|
|
246
|
+
dotnet_naming_style.camel_case_underscore.required_prefix = _
|
|
247
|
+
dotnet_naming_style.camel_case_underscore.capitalization = camel_case
|
|
248
|
+
|
|
249
|
+
# Code style
|
|
250
|
+
csharp_style_var_for_built_in_types = false:suggestion
|
|
251
|
+
csharp_style_var_when_type_is_apparent = true:suggestion
|
|
252
|
+
csharp_style_expression_bodied_methods = when_on_single_line:suggestion
|
|
253
|
+
csharp_prefer_braces = true:warning
|
|
254
|
+
|
|
255
|
+
# Formatting
|
|
256
|
+
csharp_new_line_before_open_brace = all
|
|
257
|
+
csharp_new_line_before_else = true
|
|
258
|
+
csharp_new_line_before_catch = true
|
|
259
|
+
csharp_new_line_before_finally = true
|
|
260
|
+
|
|
261
|
+
[*.{json,yml,yaml}]
|
|
262
|
+
indent_size = 2
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Benchmark.NET Setup
|
|
266
|
+
|
|
267
|
+
```csharp
|
|
268
|
+
// Install: dotnet add package BenchmarkDotNet
|
|
269
|
+
|
|
270
|
+
[MemoryDiagnoser]
|
|
271
|
+
[SimpleJob(RuntimeMoniker.Net80)]
|
|
272
|
+
public class StringConcatBenchmarks
|
|
273
|
+
{
|
|
274
|
+
private readonly string[] _strings = Enumerable.Range(0, 100)
|
|
275
|
+
.Select(i => $"String{i}").ToArray();
|
|
276
|
+
|
|
277
|
+
[Benchmark(Baseline = true)]
|
|
278
|
+
public string ConcatWithPlus()
|
|
279
|
+
{
|
|
280
|
+
string result = "";
|
|
281
|
+
foreach (var s in _strings)
|
|
282
|
+
result += s;
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
[Benchmark]
|
|
287
|
+
public string ConcatWithStringBuilder()
|
|
288
|
+
{
|
|
289
|
+
var sb = new StringBuilder();
|
|
290
|
+
foreach (var s in _strings)
|
|
291
|
+
sb.Append(s);
|
|
292
|
+
return sb.ToString();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
[Benchmark]
|
|
296
|
+
public string ConcatWithJoin() => string.Join("", _strings);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Run: dotnet run -c Release
|
|
300
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Flutter AutoRoute Navigation
|
|
3
|
+
description: Typed routing, nested routes, and guards using auto_route.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [navigation, auto-route, routing]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/router.dart', '**/app_router.dart']
|
|
8
|
+
keywords: [AutoRoute, AutoRouter, router, guards, navigate, push]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# AutoRoute Navigation
|
|
12
|
+
|
|
13
|
+
## **Priority: P1 (HIGH)**
|
|
14
|
+
|
|
15
|
+
Type-safe routing system with code generation using `auto_route`.
|
|
16
|
+
|
|
17
|
+
## Structure
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
core/router/
|
|
21
|
+
├── app_router.dart # Router configuration
|
|
22
|
+
└── app_router.gr.dart # Generated routes
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Implementation Guidelines
|
|
26
|
+
|
|
27
|
+
- **@RoutePage**: Annotate all screen/page widgets with `@RoutePage()`.
|
|
28
|
+
- **Router Config**: Extend `_$AppRouter` and annotate with `@AutoRouterConfig`.
|
|
29
|
+
- **Typed Navigation**: Use generated route classes (e.g., `HomeRoute()`). Never use strings.
|
|
30
|
+
- **Nested Routes & Tabs**: Use `children` in `AutoRoute` for tabs. When navigating to a route with nested tabs, use the `children` parameter to define the initial active sub-route (e.g., `context.navigateTo(OrdersTabRoute(children: [ViewByOrdersPageRoute()]))`).
|
|
31
|
+
- **Guards**: Implement `AutoRouteGuard` for authentication/authorization logic.
|
|
32
|
+
|
|
33
|
+
- **Parameters**: Constructors of `@RoutePage` widgets automatically become route parameters.
|
|
34
|
+
- **Declarative**: Prefer `context.pushRoute()` or `context.replaceRoute()`.
|
|
35
|
+
|
|
36
|
+
## Reference & Examples
|
|
37
|
+
|
|
38
|
+
For full Router configuration and Auth Guard implementation:
|
|
39
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
40
|
+
|
|
41
|
+
## Related Topics
|
|
42
|
+
|
|
43
|
+
go-router-navigation | layer-based-clean-architecture
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# AutoRoute Routing Reference
|
|
2
|
+
|
|
3
|
+
Detailed examples for implementing a scalable, type-safe routing system in Flutter.
|
|
4
|
+
|
|
5
|
+
## References
|
|
6
|
+
|
|
7
|
+
- [**AppRouter Configuration**](router-config.md) - Standard setup with `@AutoRouterConfig`.
|
|
8
|
+
- [**Auth Guards**](guards.md) - Protecting routes based on authentication state.
|
|
9
|
+
- [**Nested Routes & Tabs**](nested-routes.md) - Implementation for bottom navigation bars or sub-flows.
|
|
10
|
+
|
|
11
|
+
## **Quick Navigation Command**
|
|
12
|
+
|
|
13
|
+
```dart
|
|
14
|
+
// Navigating to a page with parameters
|
|
15
|
+
context.pushRoute(ProfileRoute(userId: '123'));
|
|
16
|
+
|
|
17
|
+
// Popping and returning a value
|
|
18
|
+
context.maybePop(true);
|
|
19
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# AppRouter Configuration
|
|
2
|
+
|
|
3
|
+
Standard setup for `auto_route` to ensure code generation and type-safety.
|
|
4
|
+
|
|
5
|
+
## **Router File (`app_router.dart`)**
|
|
6
|
+
|
|
7
|
+
```dart
|
|
8
|
+
import 'package:auto_route/auto_route.dart';
|
|
9
|
+
import 'app_router.gr.dart'; // Inherited generated classes
|
|
10
|
+
|
|
11
|
+
@AutoRouterConfig(replaceInRouteName: 'Page|Screen,Route')
|
|
12
|
+
class AppRouter extends _$AppRouter {
|
|
13
|
+
@override
|
|
14
|
+
List<AutoRoute> get routes => [
|
|
15
|
+
// 1. Initial Route
|
|
16
|
+
AutoRoute(page: SplashRoute.page, initial: true),
|
|
17
|
+
|
|
18
|
+
// 2. Protected Routes (with Guards)
|
|
19
|
+
AutoRoute(
|
|
20
|
+
page: DashboardRoute.page,
|
|
21
|
+
guards: [AuthGuard()],
|
|
22
|
+
),
|
|
23
|
+
|
|
24
|
+
// 3. Nested Routes (Tabs)
|
|
25
|
+
AutoRoute(
|
|
26
|
+
page: HomeTabsRoute.page,
|
|
27
|
+
children: [
|
|
28
|
+
AutoRoute(page: PostsRoute.page),
|
|
29
|
+
AutoRoute(page: SettingsRoute.page),
|
|
30
|
+
],
|
|
31
|
+
),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## **Dynamic Tab Initialization**
|
|
37
|
+
|
|
38
|
+
If you need to navigate to a tabbed route and set a specific initial tab based on logic:
|
|
39
|
+
|
|
40
|
+
```dart
|
|
41
|
+
context.navigateTo(
|
|
42
|
+
OrdersTabRoute(
|
|
43
|
+
children: params.tab == OrderTab.orders()
|
|
44
|
+
? [const ViewByOrdersPageRoute()]
|
|
45
|
+
: [const ViewByItemsPageRoute()],
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## **Typed Parameters**
|
|
51
|
+
|
|
52
|
+
When you define a Screen with a constructor, `auto_route` generates matching parameters:
|
|
53
|
+
|
|
54
|
+
```dart
|
|
55
|
+
@RoutePage()
|
|
56
|
+
class UserProfilePage extends StatelessWidget {
|
|
57
|
+
final String userId;
|
|
58
|
+
const UserProfilePage({required this.userId});
|
|
59
|
+
|
|
60
|
+
// Navigation: context.pushRoute(UserProfileRoute(userId: '123'));
|
|
61
|
+
}
|
|
62
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Flutter BLoC State Management
|
|
3
|
+
description: Standards for predictable state management using flutter_bloc, freezed, and equatable.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [state-management, bloc, cubit, freezed, equatable]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**_bloc.dart', '**_cubit.dart', '**_state.dart', '**_event.dart']
|
|
8
|
+
keywords:
|
|
9
|
+
[
|
|
10
|
+
BlocProvider,
|
|
11
|
+
BlocBuilder,
|
|
12
|
+
BlocListener,
|
|
13
|
+
Cubit,
|
|
14
|
+
Emitter,
|
|
15
|
+
transformer,
|
|
16
|
+
Equatable,
|
|
17
|
+
]
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# BLoC State Management
|
|
21
|
+
|
|
22
|
+
## **Priority: P0 (CRITICAL)**
|
|
23
|
+
|
|
24
|
+
Predictable state management separating business logic from UI using `bloc`, `freezed`, or `equatable`.
|
|
25
|
+
|
|
26
|
+
## Structure
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
presentation/blocs/
|
|
30
|
+
├── auth/
|
|
31
|
+
│ ├── auth_bloc.dart
|
|
32
|
+
│ ├── auth_event.dart # (@freezed or Equatable)
|
|
33
|
+
│ └── auth_state.dart # (@freezed or Equatable)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Implementation Guidelines
|
|
37
|
+
|
|
38
|
+
- **States & Events**: Default to `@freezed` (Priority). Use `Equatable` if the library is present in `pubspec.yaml`.
|
|
39
|
+
- **freezed**: Use for union states (initial, loading, success) and automatic `copyWith`.
|
|
40
|
+
- **Equatable**: Apply if code generation (build_runner) is avoided or `equatable` is the only comparison library in `pubspec.yaml`.
|
|
41
|
+
- Choose strategy:
|
|
42
|
+
- **Union State**: Exclusive UI phases (loading vs data).
|
|
43
|
+
- **Property-based State**: Complex forms (Option<$Either>, flags).
|
|
44
|
+
- **State Properties**: Use enums, sealed classes, or `Status` objects.
|
|
45
|
+
- **Error Handling**: Use `Failure` objects; avoid throwing exceptions.
|
|
46
|
+
- **Async Data**: Use `emit.forEach` or `emit.onEach` for streams.
|
|
47
|
+
- **Concurrency**: Use `transformer` (restartable, droppable) for event debouncing.
|
|
48
|
+
- **Testing**: Use `blocTest` for state transition verification.
|
|
49
|
+
- **Injection**: Register BLoCs as `@injectable` (Factory).
|
|
50
|
+
|
|
51
|
+
## Anti-Patterns
|
|
52
|
+
|
|
53
|
+
- **No Manual Emit**: Do not call `emit()` inside `Future.then`; always use `await` or `emit.forEach`.
|
|
54
|
+
- **No UI Logic**: Do not perform calculations or data formatting inside `BlocBuilder`.
|
|
55
|
+
- **No Cross-Bloc Reference**: Do not pass a BLoC instance into another BLoC; use streams or the UI layer to coordinate.
|
|
56
|
+
|
|
57
|
+
## Reference & Examples
|
|
58
|
+
|
|
59
|
+
For full BLoC/Cubit implementations and concurrency patterns:
|
|
60
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
61
|
+
|
|
62
|
+
## Related Topics
|
|
63
|
+
|
|
64
|
+
feature-based-clean-architecture | dependency-injection
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# BLoC State Management Reference
|
|
2
|
+
|
|
3
|
+
Detailed patterns for implementing BLoC/Cubit in production.
|
|
4
|
+
|
|
5
|
+
## References
|
|
6
|
+
|
|
7
|
+
- [**Full Auth BLoC (Union State)**](auth-bloc-example.md) - Best for distinct app phases.
|
|
8
|
+
- [**Property-Based State (Forms)**](property-based-state.md) - Best for persistent data and forms.
|
|
9
|
+
- [**Equatable Usage**](equatable-usage.md) - Lightweight alternative to Freezed.
|
|
10
|
+
- [**Cubit Minimal**](cubit-minimal.md) - Simple state management without events.
|
|
11
|
+
|
|
12
|
+
## **Concurrency Transformer**
|
|
13
|
+
|
|
14
|
+
```dart
|
|
15
|
+
// Restartable prevents multiple simultaneous requests
|
|
16
|
+
on<SearchEvent>(
|
|
17
|
+
_onSearch,
|
|
18
|
+
transformer: restartable(),
|
|
19
|
+
);
|
|
20
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Auth BLoC Full Implementation
|
|
2
|
+
|
|
3
|
+
## **Events (@freezed)**
|
|
4
|
+
|
|
5
|
+
```dart
|
|
6
|
+
@freezed
|
|
7
|
+
class AuthEvent with _$AuthEvent {
|
|
8
|
+
const factory AuthEvent.started() = _Started;
|
|
9
|
+
const factory AuthEvent.loginSubmitted(String email, String password) = _LoginSubmitted;
|
|
10
|
+
const factory AuthEvent.logoutPressed() = _LogoutPressed;
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## **States (@freezed)**
|
|
15
|
+
|
|
16
|
+
```dart
|
|
17
|
+
@freezed
|
|
18
|
+
class AuthState with _$AuthState {
|
|
19
|
+
const factory AuthState.initial() = _Initial;
|
|
20
|
+
const factory AuthState.loading() = _Loading;
|
|
21
|
+
const factory AuthState.authenticated(User user) = _Authenticated;
|
|
22
|
+
const factory AuthState.unauthenticated() = _Unauthenticated;
|
|
23
|
+
const factory AuthState.error(String message) = _Error;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## **BLoC Implementation**
|
|
28
|
+
|
|
29
|
+
```dart
|
|
30
|
+
class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|
31
|
+
final IAuthRepository _repository;
|
|
32
|
+
|
|
33
|
+
AuthBloc(this._repository) : super(const AuthState.initial()) {
|
|
34
|
+
on<_LoginSubmitted>(_onLogin);
|
|
35
|
+
on<_LogoutPressed>(_onLogout);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Future<void> _onLogin(_LoginSubmitted event, Emitter<AuthState> emit) async {
|
|
39
|
+
emit(const AuthState.loading());
|
|
40
|
+
final result = await _repository.login(event.email, event.password);
|
|
41
|
+
result.fold(
|
|
42
|
+
(failure) => emit(AuthState.error(failure.message)),
|
|
43
|
+
(user) => emit(AuthState.authenticated(user)),
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Future<void> _onLogout(_LogoutPressed event, Emitter<AuthState> emit) async {
|
|
48
|
+
await _repository.logout();
|
|
49
|
+
emit(const AuthState.unauthenticated());
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|