@softspark/ai-toolkit 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -29
- package/CHANGELOG.md +39 -0
- package/README.md +170 -27
- package/app/.claude-plugin/plugin.json +2 -2
- package/app/ARCHITECTURE.md +35 -19
- package/app/agents/ai-engineer.md +47 -5
- package/app/agents/fact-checker.md +1 -1
- package/app/agents/llm-ops-engineer.md +2 -2
- package/app/agents/{mcp-server-architect.md → mcp-specialist.md} +124 -18
- package/app/agents/mcp-testing-engineer.md +2 -2
- package/app/agents/nlp-engineer.md +1 -1
- package/app/agents/orchestrator.md +3 -4
- package/app/agents/project-planner.md +1 -1
- package/app/agents/technical-researcher.md +71 -21
- package/app/hooks/commit-quality.sh +53 -0
- package/app/hooks/governance-capture.sh +77 -0
- package/app/hooks/guard-config.sh +46 -0
- package/app/hooks/mcp-health.sh +53 -0
- package/app/hooks/pre-compact-save.sh +34 -0
- package/app/hooks/session-context.sh +60 -0
- package/app/hooks.json +60 -0
- package/app/mcp-templates/README.md +105 -0
- package/app/mcp-templates/brave-search.json +13 -0
- package/app/mcp-templates/cloudflare.json +14 -0
- package/app/mcp-templates/context7.json +10 -0
- package/app/mcp-templates/custom-template.json +13 -0
- package/app/mcp-templates/datadog.json +15 -0
- package/app/mcp-templates/docker.json +10 -0
- package/app/mcp-templates/fetch.json +10 -0
- package/app/mcp-templates/filesystem.json +10 -0
- package/app/mcp-templates/git.json +10 -0
- package/app/mcp-templates/github.json +13 -0
- package/app/mcp-templates/google-drive.json +15 -0
- package/app/mcp-templates/google-maps.json +13 -0
- package/app/mcp-templates/grafana.json +14 -0
- package/app/mcp-templates/linear.json +13 -0
- package/app/mcp-templates/memory.json +10 -0
- package/app/mcp-templates/notion.json +13 -0
- package/app/mcp-templates/postgres.json +10 -0
- package/app/mcp-templates/puppeteer.json +10 -0
- package/app/mcp-templates/redis.json +13 -0
- package/app/mcp-templates/sentry.json +14 -0
- package/app/mcp-templates/sequential-thinking.json +10 -0
- package/app/mcp-templates/slack.json +14 -0
- package/app/mcp-templates/sqlite.json +10 -0
- package/app/mcp-templates/supabase.json +14 -0
- package/app/mcp-templates/vercel.json +13 -0
- package/app/plugins/research-pack/README.md +1 -1
- package/app/plugins/research-pack/plugin.json +1 -1
- package/app/rules/claude-toolkit-rules.md +1 -1
- package/app/rules/common/coding-style.md +52 -0
- package/app/rules/common/git-workflow.md +45 -0
- package/app/rules/common/performance.md +49 -0
- package/app/rules/common/security.md +59 -0
- package/app/rules/common/testing.md +53 -0
- package/app/rules/cpp/coding-style.md +55 -0
- package/app/rules/cpp/frameworks.md +55 -0
- package/app/rules/cpp/patterns.md +57 -0
- package/app/rules/cpp/security.md +61 -0
- package/app/rules/cpp/testing.md +58 -0
- package/app/rules/csharp/coding-style.md +54 -0
- package/app/rules/csharp/frameworks.md +60 -0
- package/app/rules/csharp/patterns.md +61 -0
- package/app/rules/csharp/security.md +60 -0
- package/app/rules/csharp/testing.md +58 -0
- package/app/rules/dart/coding-style.md +61 -0
- package/app/rules/dart/frameworks.md +59 -0
- package/app/rules/dart/patterns.md +62 -0
- package/app/rules/dart/security.md +60 -0
- package/app/rules/dart/testing.md +60 -0
- package/app/rules/golang/coding-style.md +50 -0
- package/app/rules/golang/frameworks.md +56 -0
- package/app/rules/golang/patterns.md +52 -0
- package/app/rules/golang/security.md +61 -0
- package/app/rules/golang/testing.md +54 -0
- package/app/rules/java/coding-style.md +56 -0
- package/app/rules/java/frameworks.md +54 -0
- package/app/rules/java/patterns.md +59 -0
- package/app/rules/java/security.md +60 -0
- package/app/rules/java/testing.md +55 -0
- package/app/rules/kotlin/coding-style.md +56 -0
- package/app/rules/kotlin/frameworks.md +54 -0
- package/app/rules/kotlin/patterns.md +54 -0
- package/app/rules/kotlin/security.md +62 -0
- package/app/rules/kotlin/testing.md +56 -0
- package/app/rules/php/coding-style.md +53 -0
- package/app/rules/php/frameworks.md +57 -0
- package/app/rules/php/patterns.md +63 -0
- package/app/rules/php/security.md +61 -0
- package/app/rules/php/testing.md +60 -0
- package/app/rules/python/coding-style.md +52 -0
- package/app/rules/python/frameworks.md +53 -0
- package/app/rules/python/patterns.md +53 -0
- package/app/rules/python/security.md +58 -0
- package/app/rules/python/testing.md +52 -0
- package/app/rules/ruby/coding-style.md +56 -0
- package/app/rules/ruby/frameworks.md +56 -0
- package/app/rules/ruby/patterns.md +61 -0
- package/app/rules/ruby/security.md +61 -0
- package/app/rules/ruby/testing.md +63 -0
- package/app/rules/rust/coding-style.md +52 -0
- package/app/rules/rust/frameworks.md +59 -0
- package/app/rules/rust/patterns.md +58 -0
- package/app/rules/rust/security.md +64 -0
- package/app/rules/rust/testing.md +54 -0
- package/app/rules/swift/coding-style.md +55 -0
- package/app/rules/swift/frameworks.md +63 -0
- package/app/rules/swift/patterns.md +63 -0
- package/app/rules/swift/security.md +63 -0
- package/app/rules/swift/testing.md +60 -0
- package/app/rules/typescript/coding-style.md +51 -0
- package/app/rules/typescript/frameworks.md +51 -0
- package/app/rules/typescript/patterns.md +51 -0
- package/app/rules/typescript/security.md +55 -0
- package/app/rules/typescript/testing.md +52 -0
- package/app/skills/app-builder/SKILL.md +1 -1
- package/app/skills/brand-voice/SKILL.md +92 -0
- package/app/skills/council/SKILL.md +133 -0
- package/app/skills/introspect/SKILL.md +125 -0
- package/bin/ai-toolkit.js +103 -2
- package/kb/reference/agents-catalog.md +10 -13
- package/kb/reference/architecture-overview.md +29 -6
- package/kb/reference/commands-catalog.md +4 -4
- package/kb/reference/competitive-features-implementation.md +677 -0
- package/kb/reference/extension-api.md +175 -0
- package/kb/reference/hooks-catalog.md +90 -14
- package/kb/reference/language-rules.md +167 -0
- package/kb/reference/manifest-install.md +165 -0
- package/kb/reference/mcp-templates.md +110 -0
- package/kb/reference/skills-catalog.md +9 -6
- package/llms-full.txt +1511 -59
- package/llms.txt +8 -3
- package/package.json +2 -2
- package/scripts/inject_hook_cli.py +330 -0
- package/scripts/install.py +241 -7
- package/scripts/install_steps/ai_tools.py +63 -1
- package/scripts/install_steps/detect_language.py +50 -0
- package/scripts/install_steps/install_state.py +117 -0
- package/scripts/mcp_manager.py +206 -0
- package/app/agents/mcp-expert.md +0 -228
- package/app/agents/rag-engineer.md +0 -201
- package/app/agents/research-synthesizer.md +0 -138
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: csharp
|
|
3
|
+
category: frameworks
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# C# Frameworks
|
|
8
|
+
|
|
9
|
+
## ASP.NET Core
|
|
10
|
+
- Use minimal APIs for simple endpoints. Use controllers for complex APIs.
|
|
11
|
+
- Use `[ApiController]` attribute for automatic model validation and error responses.
|
|
12
|
+
- Use `Results.Ok()`, `Results.NotFound()` for typed HTTP results.
|
|
13
|
+
- Use endpoint filters / middleware for cross-cutting concerns.
|
|
14
|
+
- Use `IHostedService` / `BackgroundService` for long-running background tasks.
|
|
15
|
+
- Map routes with `app.MapGet()`, `app.MapPost()` for minimal API style.
|
|
16
|
+
|
|
17
|
+
## Entity Framework Core
|
|
18
|
+
- Use code-first migrations: `dotnet ef migrations add`, `dotnet ef database update`.
|
|
19
|
+
- Use `DbContext` with scoped lifetime (one per request).
|
|
20
|
+
- Use `AsNoTracking()` for read-only queries. Use `AsTracking()` only for updates.
|
|
21
|
+
- Use `Include()` / `ThenInclude()` for eager loading related entities.
|
|
22
|
+
- Use shadow properties for audit fields (`CreatedAt`, `UpdatedAt`).
|
|
23
|
+
- Use `HasQueryFilter()` for soft-delete and multi-tenancy global filters.
|
|
24
|
+
|
|
25
|
+
## Blazor
|
|
26
|
+
- Use Blazor Server for internal tools. Use Blazor WASM for public-facing SPAs.
|
|
27
|
+
- Use `@inject` for dependency injection in components.
|
|
28
|
+
- Use `EventCallback<T>` for parent-child component communication.
|
|
29
|
+
- Use `CascadingValue` for deeply shared state (theme, auth).
|
|
30
|
+
- Use `StateContainer` pattern with events for cross-component state management.
|
|
31
|
+
|
|
32
|
+
## SignalR
|
|
33
|
+
- Use strongly-typed hubs: `Hub<IClientMethods>` for compile-time safety.
|
|
34
|
+
- Use `HubContext<T>` for sending messages from outside hubs.
|
|
35
|
+
- Use groups for targeted broadcasting: `Groups.AddToGroupAsync()`.
|
|
36
|
+
- Configure automatic reconnection on the client side.
|
|
37
|
+
|
|
38
|
+
## MassTransit / Messaging
|
|
39
|
+
- Use MassTransit for message bus abstraction over RabbitMQ/Azure Service Bus.
|
|
40
|
+
- Define messages as `record` types for immutability.
|
|
41
|
+
- Use consumers (`IConsumer<T>`) for message handling.
|
|
42
|
+
- Use sagas for long-running, multi-step workflows with state.
|
|
43
|
+
- Use retry and circuit breaker policies for transient failures.
|
|
44
|
+
|
|
45
|
+
## Logging
|
|
46
|
+
- Use `ILogger<T>` via DI. Never instantiate loggers manually.
|
|
47
|
+
- Use structured logging: `_logger.LogInformation("User {UserId} logged in", userId)`.
|
|
48
|
+
- Use Serilog with sinks for structured, centralized logging.
|
|
49
|
+
- Use log scopes for request correlation: `using (_logger.BeginScope(...))`.
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
- Use `appsettings.json` + environment-specific overrides + environment variables.
|
|
53
|
+
- Bind configuration sections to strongly-typed classes with `IOptions<T>`.
|
|
54
|
+
- Use `IOptionsMonitor<T>` for configuration that changes at runtime.
|
|
55
|
+
- Validate configuration at startup with `ValidateDataAnnotations()`.
|
|
56
|
+
|
|
57
|
+
## Health Checks
|
|
58
|
+
- Use `app.MapHealthChecks("/health")` for liveness probes.
|
|
59
|
+
- Register custom health checks for database, cache, and external service dependencies.
|
|
60
|
+
- Use `AspNetCore.HealthChecks.*` NuGet packages for common checks.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: csharp
|
|
3
|
+
category: patterns
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# C# Patterns
|
|
8
|
+
|
|
9
|
+
## Error Handling
|
|
10
|
+
- Use exceptions for truly exceptional conditions. Use `Result<T>` pattern for expected failures.
|
|
11
|
+
- Create domain exception hierarchies: `class DomainException : Exception`.
|
|
12
|
+
- Use `when` clause in catch: `catch (HttpRequestException e) when (e.StatusCode == 404)`.
|
|
13
|
+
- Use `ExceptionDispatchInfo.Capture(e).Throw()` to preserve original stack trace.
|
|
14
|
+
- Return `Result<T, Error>` types for operations with expected failure modes.
|
|
15
|
+
|
|
16
|
+
## Async Patterns
|
|
17
|
+
- Use `Task.WhenAll()` for concurrent independent operations.
|
|
18
|
+
- Use `SemaphoreSlim` for async-compatible resource limiting.
|
|
19
|
+
- Use `Channel<T>` for async producer-consumer patterns.
|
|
20
|
+
- Use `IAsyncEnumerable<T>` for streaming data from async sources.
|
|
21
|
+
- Use `Polly` for retry, circuit breaker, and timeout policies.
|
|
22
|
+
- Never use `.Result` or `.Wait()` on tasks (deadlock risk). Always `await`.
|
|
23
|
+
|
|
24
|
+
## Dependency Injection
|
|
25
|
+
- Use constructor injection exclusively. Avoid service locator pattern.
|
|
26
|
+
- Register services in `Program.cs` or `IServiceCollection` extension methods.
|
|
27
|
+
- Use `Scoped` for request-lifetime services, `Singleton` for stateless, `Transient` for lightweight.
|
|
28
|
+
- Use `IOptions<T>` pattern for configuration injection.
|
|
29
|
+
- Validate DI registrations at startup with `ValidateOnBuild = true`.
|
|
30
|
+
|
|
31
|
+
## LINQ
|
|
32
|
+
- Use method syntax for complex queries. Use query syntax for joins.
|
|
33
|
+
- Use `FirstOrDefault()` over `First()` for safe access.
|
|
34
|
+
- Use `AsNoTracking()` for read-only EF Core queries (performance).
|
|
35
|
+
- Avoid materializing large collections: use `IQueryable<T>` until final projection.
|
|
36
|
+
- Use `Select()` to project only needed columns from database queries.
|
|
37
|
+
|
|
38
|
+
## Disposable Pattern
|
|
39
|
+
- Implement `IAsyncDisposable` for async cleanup.
|
|
40
|
+
- Use `await using var resource = ...;` for deterministic async disposal.
|
|
41
|
+
- Use `IDisposable` with `using` declaration (C# 8) for scope-based cleanup.
|
|
42
|
+
- Register disposable services in DI container (auto-disposed at scope end).
|
|
43
|
+
|
|
44
|
+
## Mediator / CQRS
|
|
45
|
+
- Use MediatR for command/query separation and pipeline behaviors.
|
|
46
|
+
- Commands: `IRequest<Result>` for mutations. Queries: `IRequest<T>` for reads.
|
|
47
|
+
- Use pipeline behaviors for cross-cutting: validation, logging, transactions.
|
|
48
|
+
- Keep handlers thin: delegate to domain services for business logic.
|
|
49
|
+
|
|
50
|
+
## Value Objects
|
|
51
|
+
- Use `record` types for value objects with structural equality.
|
|
52
|
+
- Use factory methods with validation: `public static Result<Email> Create(string value)`.
|
|
53
|
+
- Override `ToString()` for logging-friendly representations.
|
|
54
|
+
- Use implicit/explicit operators sparingly for primitive wrapper conversions.
|
|
55
|
+
|
|
56
|
+
## Anti-Patterns
|
|
57
|
+
- Service locator: inject dependencies, do not resolve from container.
|
|
58
|
+
- `async void`: use only for event handlers. Everything else returns `Task`.
|
|
59
|
+
- Nested `try-catch`: flatten with early returns or guard clauses.
|
|
60
|
+
- Anemic domain model: put behavior in domain objects, not only services.
|
|
61
|
+
- Over-abstracting: do not create interfaces for classes with only one implementation.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: csharp
|
|
3
|
+
category: security
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# C# Security
|
|
8
|
+
|
|
9
|
+
## Input Validation
|
|
10
|
+
- Use data annotations (`[Required]`, `[StringLength]`, `[Range]`) on request models.
|
|
11
|
+
- Use `[ApiController]` for automatic 400 responses on validation failure.
|
|
12
|
+
- Use FluentValidation for complex, rule-based validation logic.
|
|
13
|
+
- Never trust client-provided IDs. Verify resource ownership server-side.
|
|
14
|
+
- Sanitize HTML input with a library like HtmlSanitizer. Never render raw user HTML.
|
|
15
|
+
|
|
16
|
+
## SQL Injection
|
|
17
|
+
- Use EF Core parameterized queries exclusively. Never concatenate SQL.
|
|
18
|
+
- Use `FromSqlInterpolated()` over `FromSqlRaw()` for raw SQL (auto-parameterized).
|
|
19
|
+
- Use stored procedures via `context.Database.ExecuteSqlInterpolatedAsync()`.
|
|
20
|
+
- Audit all `FromSqlRaw()` calls for parameter interpolation risks.
|
|
21
|
+
- Use Dapper with parameterized queries: `@param` syntax in SQL strings.
|
|
22
|
+
|
|
23
|
+
## Authentication
|
|
24
|
+
- Use ASP.NET Core Identity for user management and password hashing.
|
|
25
|
+
- Use `AddAuthentication().AddJwtBearer()` for JWT-based API auth.
|
|
26
|
+
- Use short-lived access tokens (15 min) with refresh token rotation.
|
|
27
|
+
- Use `[Authorize]` attribute globally. Use `[AllowAnonymous]` selectively.
|
|
28
|
+
- Use HTTPS redirection: `app.UseHttpsRedirection()`.
|
|
29
|
+
|
|
30
|
+
## Authorization
|
|
31
|
+
- Use policy-based authorization: `[Authorize(Policy = "AdminOnly")]`.
|
|
32
|
+
- Use `IAuthorizationHandler` for custom authorization logic.
|
|
33
|
+
- Use resource-based authorization for object-level access control.
|
|
34
|
+
- Default deny: apply `[Authorize]` at controller/app level, opt out per endpoint.
|
|
35
|
+
- Check ownership in service layer, not just role membership.
|
|
36
|
+
|
|
37
|
+
## CSRF and XSS
|
|
38
|
+
- Use anti-forgery tokens for form-based submissions.
|
|
39
|
+
- Razor/Blazor auto-encodes output. Never use `@Html.Raw()` with user data.
|
|
40
|
+
- Set `Content-Security-Policy` headers to restrict script sources.
|
|
41
|
+
- Use `SameSite=Strict` on cookies for CSRF mitigation.
|
|
42
|
+
- Enable CORS only for specific origins. Never use `AllowAnyOrigin()` with credentials.
|
|
43
|
+
|
|
44
|
+
## Data Protection
|
|
45
|
+
- Use `IDataProtectionProvider` for symmetric encryption of sensitive data.
|
|
46
|
+
- Use `SecureString` or `ProtectedData` for in-memory sensitive data (limited use).
|
|
47
|
+
- Use ASP.NET Core Data Protection API for token and cookie encryption.
|
|
48
|
+
- Hash passwords with `PasswordHasher<T>` (PBKDF2 with salt).
|
|
49
|
+
|
|
50
|
+
## Secrets Management
|
|
51
|
+
- Use `dotnet user-secrets` for local development. Use Azure Key Vault for production.
|
|
52
|
+
- Use `IConfiguration` with environment variable providers. Never hardcode secrets.
|
|
53
|
+
- Use `[SensitiveData]` attributes to exclude fields from logging and serialization.
|
|
54
|
+
- Never log request headers containing Authorization or cookie values.
|
|
55
|
+
|
|
56
|
+
## Dependency Security
|
|
57
|
+
- Run `dotnet list package --vulnerable` to check for known CVEs.
|
|
58
|
+
- Use Dependabot or NuGetAudit for automated vulnerability scanning.
|
|
59
|
+
- Pin package versions explicitly. Avoid floating version ranges.
|
|
60
|
+
- Update `Microsoft.AspNetCore.*` packages promptly for security patches.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: csharp
|
|
3
|
+
category: testing
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# C# Testing
|
|
8
|
+
|
|
9
|
+
## Framework
|
|
10
|
+
- Use xUnit as the primary test framework (modern, extensible).
|
|
11
|
+
- Use NSubstitute for mocking (clean syntax, no setup boilerplate).
|
|
12
|
+
- Use FluentAssertions for readable, expressive assertions.
|
|
13
|
+
- Use Testcontainers for integration tests with databases and services.
|
|
14
|
+
|
|
15
|
+
## File Naming
|
|
16
|
+
- Test files: `FooTests.cs` in a separate `*.Tests` project.
|
|
17
|
+
- Mirror source project namespace structure in test project.
|
|
18
|
+
- Integration tests: separate `*.IntegrationTests` project.
|
|
19
|
+
- Use `[Collection("Database")]` for shared fixtures across test classes.
|
|
20
|
+
|
|
21
|
+
## Structure
|
|
22
|
+
- Use `[Fact]` for single test cases. Use `[Theory]` for parameterized tests.
|
|
23
|
+
- Use `[InlineData]` or `[MemberData]` for test data in theories.
|
|
24
|
+
- Use constructor injection for per-test setup. Use `IClassFixture<T>` for shared setup.
|
|
25
|
+
- Name tests: `MethodName_Scenario_ExpectedResult`.
|
|
26
|
+
|
|
27
|
+
## Assertions (FluentAssertions)
|
|
28
|
+
- Use `result.Should().Be(expected)` for value assertions.
|
|
29
|
+
- Use `action.Should().Throw<InvalidOperationException>()` for exception testing.
|
|
30
|
+
- Use `collection.Should().ContainSingle(x => x.Id == 1)` for collection assertions.
|
|
31
|
+
- Use `result.Should().BeEquivalentTo(expected)` for deep object comparison.
|
|
32
|
+
- Use `execution.Should().CompleteWithinAsync(5.Seconds())` for timeout assertions.
|
|
33
|
+
|
|
34
|
+
## Mocking (NSubstitute)
|
|
35
|
+
- Create mocks: `var repo = Substitute.For<IUserRepository>()`.
|
|
36
|
+
- Stub returns: `repo.GetAsync(1).Returns(user)`.
|
|
37
|
+
- Verify calls: `repo.Received(1).SaveAsync(Arg.Any<User>())`.
|
|
38
|
+
- Use `Arg.Is<T>(predicate)` for argument matching.
|
|
39
|
+
- Use `ReturnsForAnyArgs()` for lenient stubs in arrangement-focused tests.
|
|
40
|
+
|
|
41
|
+
## Integration Testing
|
|
42
|
+
- Use `WebApplicationFactory<Program>` for ASP.NET Core integration tests.
|
|
43
|
+
- Override services with `WithWebHostBuilder(b => b.ConfigureServices(...))`.
|
|
44
|
+
- Use `HttpClient` from factory for endpoint testing.
|
|
45
|
+
- Use `Respawn` for database cleanup between tests.
|
|
46
|
+
- Use `[Collection]` attribute to prevent parallel execution of shared-resource tests.
|
|
47
|
+
|
|
48
|
+
## Test Data
|
|
49
|
+
- Use Builder pattern for complex test data: `new UserBuilder().WithName("Ada").Build()`.
|
|
50
|
+
- Use `AutoFixture` for auto-generated test data.
|
|
51
|
+
- Use `Bogus` library for realistic fake data generation.
|
|
52
|
+
- Keep test data creation close to the test, not in distant shared files.
|
|
53
|
+
|
|
54
|
+
## Best Practices
|
|
55
|
+
- Test behavior, not implementation. Avoid testing private methods.
|
|
56
|
+
- Keep tests independent. No shared mutable state between tests.
|
|
57
|
+
- Use `CancellationToken.None` explicitly in async test calls.
|
|
58
|
+
- Run tests in CI with `dotnet test --blame-hang-timeout 60s`.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: dart
|
|
3
|
+
category: coding-style
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dart Coding Style
|
|
8
|
+
|
|
9
|
+
## Naming
|
|
10
|
+
- PascalCase: classes, enums, typedefs, extensions, mixins.
|
|
11
|
+
- camelCase: variables, functions, methods, parameters, named constants.
|
|
12
|
+
- snake_case: libraries, packages, directories, source files.
|
|
13
|
+
- UPPER_SNAKE: not used in Dart. Use camelCase for constants.
|
|
14
|
+
- Prefix private members with `_`: `_internalState`, `_helper()`.
|
|
15
|
+
|
|
16
|
+
## Null Safety
|
|
17
|
+
- Enable sound null safety (default since Dart 2.12).
|
|
18
|
+
- Use `?` types only when null is semantically meaningful.
|
|
19
|
+
- Use `!` operator sparingly. Prefer null checks or `??` fallback.
|
|
20
|
+
- Use `late` keyword only when initialization is guaranteed before access.
|
|
21
|
+
- Use `required` keyword for mandatory named parameters.
|
|
22
|
+
|
|
23
|
+
## Classes
|
|
24
|
+
- Use `const` constructors for immutable classes.
|
|
25
|
+
- Use factory constructors for caching, subtype selection, or validation.
|
|
26
|
+
- Use named constructors for clarity: `Point.fromJson(json)`.
|
|
27
|
+
- Use `final` fields for immutable properties.
|
|
28
|
+
- Use `@immutable` annotation on classes that should be immutable.
|
|
29
|
+
|
|
30
|
+
## Functions
|
|
31
|
+
- Use named parameters for functions with >2 parameters.
|
|
32
|
+
- Use `required` for mandatory named parameters.
|
|
33
|
+
- Use default values for optional parameters.
|
|
34
|
+
- Use fat arrow (`=>`) for single-expression functions.
|
|
35
|
+
- Always specify return types for public functions.
|
|
36
|
+
|
|
37
|
+
## Collections
|
|
38
|
+
- Use collection literals: `[]`, `{}`, `<String, int>{}`.
|
|
39
|
+
- Use `if` and `for` inside collection literals for conditional/iterative building.
|
|
40
|
+
- Use spread operator: `[...list1, ...list2]`.
|
|
41
|
+
- Use `whereType<T>()` for type-safe filtering.
|
|
42
|
+
- Prefer `const` collections when values are known at compile time.
|
|
43
|
+
|
|
44
|
+
## Async
|
|
45
|
+
- Use `async`/`await` for all asynchronous operations.
|
|
46
|
+
- Return `Future<T>` from async functions. Never return `void`.
|
|
47
|
+
- Use `Stream<T>` for continuous data (events, real-time updates).
|
|
48
|
+
- Use `Future.wait()` for concurrent independent operations.
|
|
49
|
+
- Use `Completer<T>` only when wrapping callback-based APIs.
|
|
50
|
+
|
|
51
|
+
## Imports
|
|
52
|
+
- Order: `dart:` SDK, `package:` external, relative project imports.
|
|
53
|
+
- Use `show`/`hide` to limit import scope when names conflict.
|
|
54
|
+
- Use `as` prefix for namespace conflicts: `import 'package:foo/foo.dart' as foo`.
|
|
55
|
+
- Prefer relative imports within the same package.
|
|
56
|
+
|
|
57
|
+
## Formatting
|
|
58
|
+
- Use `dart format` (line length 80) for consistent formatting.
|
|
59
|
+
- Use `dart analyze` for static analysis with default lint rules.
|
|
60
|
+
- Use `analysis_options.yaml` with recommended lints: `flutter_lints` or `lints`.
|
|
61
|
+
- Use trailing commas in multi-line argument lists for cleaner diffs.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: dart
|
|
3
|
+
category: frameworks
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dart Frameworks
|
|
8
|
+
|
|
9
|
+
## Flutter
|
|
10
|
+
- Use `StatelessWidget` by default. Use `StatefulWidget` only for local state.
|
|
11
|
+
- Use `const` constructors and `const` widgets for build optimization.
|
|
12
|
+
- Use `Key` parameters for widgets in lists for correct diffing.
|
|
13
|
+
- Extract large `build()` methods into smaller widget classes (not methods).
|
|
14
|
+
- Use `Theme.of(context)` and `TextTheme` for consistent styling.
|
|
15
|
+
|
|
16
|
+
## Navigation
|
|
17
|
+
- Use `GoRouter` for declarative, type-safe routing.
|
|
18
|
+
- Define routes as constants: `static const String home = '/home'`.
|
|
19
|
+
- Use `ShellRoute` for persistent navigation bars across routes.
|
|
20
|
+
- Use `context.go()` for navigation, `context.push()` for stacking.
|
|
21
|
+
- Pass arguments via path parameters or `extra` for complex objects.
|
|
22
|
+
|
|
23
|
+
## Networking
|
|
24
|
+
- Use `dio` for HTTP with interceptors, retry, and cancellation.
|
|
25
|
+
- Use `retrofit` (code gen) for type-safe REST client definitions.
|
|
26
|
+
- Use interceptors for auth token injection and refresh logic.
|
|
27
|
+
- Set timeouts on every request: `connectTimeout`, `receiveTimeout`.
|
|
28
|
+
- Use `CancelToken` for cancelling in-flight requests on navigation.
|
|
29
|
+
|
|
30
|
+
## Local Storage
|
|
31
|
+
- Use `shared_preferences` for simple key-value persistence.
|
|
32
|
+
- Use `drift` (formerly Moor) for type-safe SQLite with reactive queries.
|
|
33
|
+
- Use `hive` for fast, lightweight NoSQL local storage.
|
|
34
|
+
- Use `flutter_secure_storage` for sensitive data (tokens, passwords).
|
|
35
|
+
- Never store secrets in `shared_preferences` (not encrypted).
|
|
36
|
+
|
|
37
|
+
## Dependency Injection
|
|
38
|
+
- Use `get_it` for service locator pattern. Register at app startup.
|
|
39
|
+
- Use `injectable` (code gen) for automatic registration from annotations.
|
|
40
|
+
- Use Riverpod providers as DI containers for testable architecture.
|
|
41
|
+
- Register singletons for services, factories for per-use instances.
|
|
42
|
+
|
|
43
|
+
## Platform Channels
|
|
44
|
+
- Use `MethodChannel` for invoking native (iOS/Android) code.
|
|
45
|
+
- Use `EventChannel` for streaming data from native to Dart.
|
|
46
|
+
- Use `Pigeon` (code gen) for type-safe platform channel definitions.
|
|
47
|
+
- Handle `MissingPluginException` gracefully on unsupported platforms.
|
|
48
|
+
|
|
49
|
+
## Testing Frameworks
|
|
50
|
+
- Use `flutter_test` for widget tests with `WidgetTester`.
|
|
51
|
+
- Use `integration_test` package for full app integration tests.
|
|
52
|
+
- Use `patrol` for native-aware integration testing (permissions, notifications).
|
|
53
|
+
- Use `golden_toolkit` for advanced visual regression testing.
|
|
54
|
+
|
|
55
|
+
## Build and CI
|
|
56
|
+
- Use `flutter build` with `--release` and `--dart-define` for env configuration.
|
|
57
|
+
- Use flavors (`--flavor`) for dev/staging/prod build variants.
|
|
58
|
+
- Use `flutter analyze` in CI for static analysis enforcement.
|
|
59
|
+
- Use `flutter test --coverage` with `lcov` for coverage reporting.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: dart
|
|
3
|
+
category: patterns
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dart Patterns
|
|
8
|
+
|
|
9
|
+
## Error Handling
|
|
10
|
+
- Use typed exceptions for domain errors: `class UserNotFoundException implements Exception`.
|
|
11
|
+
- Use `try-catch` with specific exception types. Avoid bare `catch (e)`.
|
|
12
|
+
- Use `rethrow` to preserve stack trace when re-raising exceptions.
|
|
13
|
+
- Use `Result<T, E>` pattern (e.g., `dartz` Either) for expected failures.
|
|
14
|
+
- Use `Future.catchError()` only when `async/await` is not applicable.
|
|
15
|
+
|
|
16
|
+
## State Management (Flutter)
|
|
17
|
+
- Use Riverpod for compile-safe, testable state management.
|
|
18
|
+
- Use BLoC pattern for event-driven state with clear input/output.
|
|
19
|
+
- Use `ChangeNotifier` / `ValueNotifier` for simple local state.
|
|
20
|
+
- Use `StateNotifier` (Riverpod) for immutable state transitions.
|
|
21
|
+
- Keep state classes immutable. Use `copyWith()` for updates.
|
|
22
|
+
|
|
23
|
+
## Riverpod
|
|
24
|
+
- Use `@riverpod` annotation (code gen) for provider definitions.
|
|
25
|
+
- Use `ref.watch()` for reactive dependencies. Use `ref.read()` for one-time access.
|
|
26
|
+
- Use `AsyncNotifier` for async state management.
|
|
27
|
+
- Use `autoDispose` for providers that should clean up when unused.
|
|
28
|
+
- Use `family` modifier for parameterized providers.
|
|
29
|
+
|
|
30
|
+
## BLoC Pattern
|
|
31
|
+
- Separate events (input), states (output), and logic (bloc).
|
|
32
|
+
- Use `sealed class` for events and states (exhaustive `switch`).
|
|
33
|
+
- Use `Emitter<State>` for emitting state transitions.
|
|
34
|
+
- Use `transformEvents()` for debouncing search inputs.
|
|
35
|
+
- Use `BlocObserver` for global logging and error tracking.
|
|
36
|
+
|
|
37
|
+
## Repository Pattern
|
|
38
|
+
- Abstract data sources behind repository interfaces.
|
|
39
|
+
- Repositories return domain models, not DTOs or raw data.
|
|
40
|
+
- Use `Future<T>` for single values, `Stream<T>` for real-time updates.
|
|
41
|
+
- Cache data in repository layer when appropriate.
|
|
42
|
+
- Inject repositories via constructor. Use Riverpod/GetIt for DI.
|
|
43
|
+
|
|
44
|
+
## Freezed (Code Generation)
|
|
45
|
+
- Use `@freezed` for immutable data classes with `copyWith`, equality, `toString`.
|
|
46
|
+
- Use `@freezed` sealed unions for state modeling: `factory State.loading()`.
|
|
47
|
+
- Use `when()` / `map()` for exhaustive pattern matching on freezed unions.
|
|
48
|
+
- Run `dart run build_runner build` after modifying freezed classes.
|
|
49
|
+
|
|
50
|
+
## Async Patterns
|
|
51
|
+
- Use `Stream.asyncMap()` for transforming streams with async operations.
|
|
52
|
+
- Use `StreamController<T>` for custom streams. Close in `dispose()`.
|
|
53
|
+
- Use `Completer<T>` to bridge callback APIs to Future-based APIs.
|
|
54
|
+
- Use `Timer.periodic()` for polling. Cancel in `dispose()`.
|
|
55
|
+
- Use `compute()` (Flutter) for CPU-intensive work on isolates.
|
|
56
|
+
|
|
57
|
+
## Anti-Patterns
|
|
58
|
+
- Using `dynamic` type: defeats type safety. Use `Object?` or generics.
|
|
59
|
+
- Not disposing controllers/subscriptions: causes memory leaks.
|
|
60
|
+
- Putting business logic in widgets: extract to services/blocs.
|
|
61
|
+
- Using `setState()` for global state: use proper state management.
|
|
62
|
+
- Deep widget nesting: extract sub-widgets as separate classes.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: dart
|
|
3
|
+
category: security
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dart Security
|
|
8
|
+
|
|
9
|
+
## Input Validation
|
|
10
|
+
- Validate all user input in form fields with `TextFormField` validators.
|
|
11
|
+
- Use `RegExp` for pattern validation (email, phone, URL).
|
|
12
|
+
- Sanitize HTML content before rendering. Never use `Html` widget with raw user input.
|
|
13
|
+
- Validate deep link parameters before navigation or data loading.
|
|
14
|
+
- Limit text input length with `maxLength` on `TextFormField`.
|
|
15
|
+
|
|
16
|
+
## Network Security
|
|
17
|
+
- Use HTTPS exclusively. Configure `SecurityContext` for certificate pinning.
|
|
18
|
+
- Use `dio` interceptors for consistent auth header injection.
|
|
19
|
+
- Validate SSL certificates in production. Do not disable certificate checks.
|
|
20
|
+
- Set connection and read timeouts on all HTTP requests.
|
|
21
|
+
- Use `CancelToken` to abort requests when the user navigates away.
|
|
22
|
+
|
|
23
|
+
## Data Storage
|
|
24
|
+
- Use `flutter_secure_storage` for tokens, passwords, and API keys.
|
|
25
|
+
- Never store sensitive data in `shared_preferences` (stored in plaintext).
|
|
26
|
+
- Encrypt local databases (`drift` with `sqlcipher`, or `hive` with encryption).
|
|
27
|
+
- Clear secure storage on user logout.
|
|
28
|
+
- Use `kIsWeb` checks to handle web platform storage limitations.
|
|
29
|
+
|
|
30
|
+
## Authentication
|
|
31
|
+
- Use OAuth 2.0 / OIDC with PKCE flow for mobile authentication.
|
|
32
|
+
- Store refresh tokens in secure storage. Store access tokens in memory.
|
|
33
|
+
- Use `flutter_appauth` for standards-compliant OAuth flows.
|
|
34
|
+
- Implement biometric authentication with `local_auth` package.
|
|
35
|
+
- Never store credentials in Dart source code or asset files.
|
|
36
|
+
|
|
37
|
+
## Platform Channel Security
|
|
38
|
+
- Validate all data received from native code via platform channels.
|
|
39
|
+
- Do not pass sensitive data through `MethodChannel` logging-enabled calls.
|
|
40
|
+
- Use `Pigeon` for type-safe channel communication (prevents mismatched types).
|
|
41
|
+
- Handle `PlatformException` gracefully for missing native implementations.
|
|
42
|
+
|
|
43
|
+
## Obfuscation and Hardening
|
|
44
|
+
- Use `--obfuscate --split-debug-info=<dir>` for release builds.
|
|
45
|
+
- Use `--dart-define` for environment-specific configuration (not secrets).
|
|
46
|
+
- Do not embed API keys in the Dart source. Use server-side proxying.
|
|
47
|
+
- Use ProGuard rules (Android) and symbol stripping (iOS) for native code.
|
|
48
|
+
|
|
49
|
+
## WebView Security
|
|
50
|
+
- Use `webview_flutter` with JavaScript disabled unless explicitly needed.
|
|
51
|
+
- Restrict navigation to allowlisted domains with `NavigationDelegate`.
|
|
52
|
+
- Sanitize any data passed from WebView to Dart via JavaScript channels.
|
|
53
|
+
- Do not load untrusted URLs in WebViews.
|
|
54
|
+
|
|
55
|
+
## Dependency Security
|
|
56
|
+
- Run `dart pub outdated` regularly. Update dependencies promptly.
|
|
57
|
+
- Audit `pubspec.lock` for unexpected transitive dependencies.
|
|
58
|
+
- Use `dart pub audit` (when available) for vulnerability scanning.
|
|
59
|
+
- Prefer well-maintained packages with high pub.dev scores.
|
|
60
|
+
- Pin exact versions in `pubspec.yaml` for production apps.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: dart
|
|
3
|
+
category: testing
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Dart Testing
|
|
8
|
+
|
|
9
|
+
## Framework
|
|
10
|
+
- Use `package:test` for pure Dart unit tests.
|
|
11
|
+
- Use `package:flutter_test` for Flutter widget and integration tests.
|
|
12
|
+
- Use `package:mockito` with `@GenerateMocks` for mock generation.
|
|
13
|
+
- Use `package:mocktail` as a simpler alternative (no code generation).
|
|
14
|
+
|
|
15
|
+
## File Naming
|
|
16
|
+
- Test files: `foo_test.dart` in `test/` mirroring `lib/` structure.
|
|
17
|
+
- Widget tests: `test/widgets/` for Flutter widget tests.
|
|
18
|
+
- Integration tests: `integration_test/` directory (Flutter convention).
|
|
19
|
+
- Golden tests: `test/goldens/` for visual regression snapshots.
|
|
20
|
+
|
|
21
|
+
## Structure
|
|
22
|
+
- Use `group()` for organizing related tests.
|
|
23
|
+
- Use `setUp()` / `tearDown()` for per-test setup and cleanup.
|
|
24
|
+
- Use `setUpAll()` / `tearDownAll()` for expensive one-time setup.
|
|
25
|
+
- Name tests descriptively: `test('returns null when user is not found', ...)`.
|
|
26
|
+
|
|
27
|
+
## Assertions
|
|
28
|
+
- Use `expect(actual, matcher)` with built-in matchers.
|
|
29
|
+
- Use `equals()`, `isNull`, `isNotNull`, `isA<T>()` for type/value checks.
|
|
30
|
+
- Use `throwsA(isA<FormatException>())` for exception testing.
|
|
31
|
+
- Use `completion(expected)` for Future assertions.
|
|
32
|
+
- Use `emitsInOrder([...])` for Stream emission testing.
|
|
33
|
+
|
|
34
|
+
## Mocking (Mockito)
|
|
35
|
+
- Annotate: `@GenerateMocks([UserRepository])`. Run `build_runner`.
|
|
36
|
+
- Stub: `when(mock.getUser(any)).thenAnswer((_) async => user)`.
|
|
37
|
+
- Verify: `verify(mock.saveUser(captureAny)).called(1)`.
|
|
38
|
+
- Use `verifyNever()` to assert a method was not called.
|
|
39
|
+
- Use `throwOnMissingStub()` to catch unstubbed method calls.
|
|
40
|
+
|
|
41
|
+
## Widget Testing (Flutter)
|
|
42
|
+
- Use `testWidgets('description', (tester) async { ... })`.
|
|
43
|
+
- Use `tester.pumpWidget(MaterialApp(home: MyWidget()))` to render.
|
|
44
|
+
- Use `tester.pump()` to trigger rebuilds after state changes.
|
|
45
|
+
- Use `tester.pumpAndSettle()` to wait for animations to complete.
|
|
46
|
+
- Use `find.byType()`, `find.text()`, `find.byKey()` for widget lookups.
|
|
47
|
+
- Use `tester.tap()`, `tester.enterText()` for interaction simulation.
|
|
48
|
+
|
|
49
|
+
## Golden Tests
|
|
50
|
+
- Use `matchesGoldenFile('goldens/my_widget.png')` for visual comparison.
|
|
51
|
+
- Run `flutter test --update-goldens` to regenerate baseline images.
|
|
52
|
+
- Use golden tests for complex UI components, not simple widgets.
|
|
53
|
+
- Keep golden tests platform-specific (render output varies by OS).
|
|
54
|
+
|
|
55
|
+
## Best Practices
|
|
56
|
+
- Test public API behavior, not implementation details.
|
|
57
|
+
- Use `fake` classes (implementing interfaces) for simple test doubles.
|
|
58
|
+
- Use `addTearDown()` to register cleanup in the test body.
|
|
59
|
+
- Run `flutter test --coverage` and check `coverage/lcov.info`.
|
|
60
|
+
- Use `blocTest()` from `bloc_test` package for BLoC testing.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: golang
|
|
3
|
+
category: coding-style
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Go Coding Style
|
|
8
|
+
|
|
9
|
+
## Naming
|
|
10
|
+
- MixedCaps/mixedCaps only. No underscores in Go names (except test functions).
|
|
11
|
+
- Exported: `PascalCase`. Unexported: `camelCase`. Acronyms: `HTTPClient`, `userID`.
|
|
12
|
+
- Short variable names in small scopes: `i`, `r`, `w`, `ctx`, `err`.
|
|
13
|
+
- Descriptive names in larger scopes: `userRepository`, `requestTimeout`.
|
|
14
|
+
- Package names: short, lowercase, singular (`auth`, `user`, not `utils`, `helpers`).
|
|
15
|
+
|
|
16
|
+
## Packages
|
|
17
|
+
- One package per directory. Package name = directory name.
|
|
18
|
+
- Avoid `util`, `common`, `helpers` packages. Name by what it provides.
|
|
19
|
+
- Keep package APIs small. Export only what consumers need.
|
|
20
|
+
- Use `internal/` directory for packages not meant for external consumption.
|
|
21
|
+
|
|
22
|
+
## Functions
|
|
23
|
+
- Accept interfaces, return structs.
|
|
24
|
+
- First parameter `ctx context.Context` if the function does I/O or may be cancelled.
|
|
25
|
+
- Return `(result, error)` tuple. Error is always last return value.
|
|
26
|
+
- Use named return values only for documentation, not for naked returns.
|
|
27
|
+
- Keep functions short. If >40 lines, consider splitting.
|
|
28
|
+
|
|
29
|
+
## Error Handling
|
|
30
|
+
- Always check errors. Never use `_` to discard errors silently.
|
|
31
|
+
- Wrap errors with context: `fmt.Errorf("fetching user %s: %w", id, err)`.
|
|
32
|
+
- Use sentinel errors (`var ErrNotFound = errors.New(...)`) for expected conditions.
|
|
33
|
+
- Use `errors.Is()` and `errors.As()` for error checking, not type assertions.
|
|
34
|
+
|
|
35
|
+
## Formatting
|
|
36
|
+
- Use `gofmt` / `goimports`. No formatting debates in Go.
|
|
37
|
+
- Use `golangci-lint` with a `.golangci.yml` config in CI.
|
|
38
|
+
- Use `go vet` as minimum static analysis.
|
|
39
|
+
|
|
40
|
+
## Struct Design
|
|
41
|
+
- Use struct embedding for composition, not inheritance.
|
|
42
|
+
- Prefer value receivers for small structs, pointer receivers for large or mutable.
|
|
43
|
+
- Be consistent: all methods on a type use the same receiver type.
|
|
44
|
+
- Use struct literals with field names: `User{Name: "Ada", Age: 30}`.
|
|
45
|
+
|
|
46
|
+
## Concurrency
|
|
47
|
+
- Do not start goroutines without a plan to stop them.
|
|
48
|
+
- Use `sync.WaitGroup` or `errgroup.Group` to coordinate goroutines.
|
|
49
|
+
- Use channels for communication, mutexes for state protection.
|
|
50
|
+
- Prefer `context.Context` for cancellation and timeouts over manual signaling.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
language: golang
|
|
3
|
+
category: frameworks
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Go Frameworks
|
|
8
|
+
|
|
9
|
+
## Standard Library HTTP
|
|
10
|
+
- Use `http.NewServeMux()` (Go 1.22+ with method patterns) for simple APIs.
|
|
11
|
+
- Use `http.HandlerFunc` for handlers. Compose with middleware pattern.
|
|
12
|
+
- Use `context.Context` from `r.Context()` in all handlers.
|
|
13
|
+
- Use `http.TimeoutHandler` to prevent slow handlers from hanging.
|
|
14
|
+
|
|
15
|
+
## Chi / Gorilla Mux
|
|
16
|
+
- Use Chi for routing with middleware chains and URL params.
|
|
17
|
+
- Use `chi.URLParam(r, "id")` to extract path parameters.
|
|
18
|
+
- Use middleware groups: `r.Group(func(r chi.Router) { r.Use(authMiddleware) })`.
|
|
19
|
+
- Prefer Chi over Gorilla Mux (Gorilla was archived, Chi actively maintained).
|
|
20
|
+
|
|
21
|
+
## Gin / Echo
|
|
22
|
+
- Use Gin for high-performance APIs with built-in validation.
|
|
23
|
+
- Use binding tags: `binding:"required,email"` on struct fields.
|
|
24
|
+
- Use middleware for cross-cutting: logging, recovery, CORS, auth.
|
|
25
|
+
- Use `c.ShouldBindJSON()` over `c.BindJSON()` to handle errors yourself.
|
|
26
|
+
|
|
27
|
+
## GORM / sqlx / pgx
|
|
28
|
+
- Use `sqlx` for SQL-first with struct scanning (lightweight).
|
|
29
|
+
- Use `pgx` directly for PostgreSQL-specific features and performance.
|
|
30
|
+
- Use GORM only when rapid prototyping outweighs SQL control.
|
|
31
|
+
- Always use prepared statements or parameterized queries.
|
|
32
|
+
- Use `sqlx.In()` for dynamic IN clauses safely.
|
|
33
|
+
|
|
34
|
+
## gRPC
|
|
35
|
+
- Define services in `.proto` files. Generate Go code with `protoc`.
|
|
36
|
+
- Use interceptors for auth, logging, and tracing (equivalent to middleware).
|
|
37
|
+
- Use deadlines (context timeout) on every RPC call.
|
|
38
|
+
- Use streaming RPCs for real-time data, unary for request-response.
|
|
39
|
+
|
|
40
|
+
## Configuration
|
|
41
|
+
- Use `envconfig` or `viper` for configuration from env/files.
|
|
42
|
+
- Use struct tags for env mapping: `envconfig:"DATABASE_URL"`.
|
|
43
|
+
- Validate config at startup. Fail fast on invalid configuration.
|
|
44
|
+
- Use `flag` package for CLI arguments in tools and utilities.
|
|
45
|
+
|
|
46
|
+
## Observability
|
|
47
|
+
- Use `slog` (Go 1.21+) for structured logging. Replace `log` package.
|
|
48
|
+
- Use OpenTelemetry for distributed tracing and metrics.
|
|
49
|
+
- Export metrics via Prometheus endpoint.
|
|
50
|
+
- Use `pprof` for CPU and memory profiling in development.
|
|
51
|
+
|
|
52
|
+
## Project Layout
|
|
53
|
+
- Follow Standard Go Project Layout: `cmd/`, `internal/`, `pkg/`.
|
|
54
|
+
- Entry points in `cmd/appname/main.go`.
|
|
55
|
+
- Business logic in `internal/`. Shared libraries in `pkg/`.
|
|
56
|
+
- Use `Makefile` for common tasks: build, test, lint, run.
|