Skip to content

Instantly share code, notes, and snippets.

@Lucho00Cuba
Created October 30, 2025 22:46
Show Gist options
  • Select an option

  • Save Lucho00Cuba/d2667277d4572659a7aef07f052fdcb0 to your computer and use it in GitHub Desktop.

Select an option

Save Lucho00Cuba/d2667277d4572659a7aef07f052fdcb0 to your computer and use it in GitHub Desktop.
Cursor Rules
---
name: Commit Message Generation Rules
description: Commit message generation rules for the project
---
## Format
`<type>[(scope)]: <description>`
- Keep `<description>` imperative, present tense, and ≤ 72 chars.
- Use body for motivation, context, and trade-offs.
- Use footer for BREAKING CHANGES, issue refs, and co-authors.
## Type (required)
Specifies the kind of change:
- `feat`: add a new feature
- `fix`: fix a bug
- `docs`: documentation only changes
- `style`: formatting or style changes (no code meaning changes)
- `refactor`: code change that is not a fix or feature
- `perf`: improve performance
- `test`: add or correct tests
- `build`: changes to build system or dependencies
- `ci`: CI configuration or script changes
- `chore`: other changes not affecting src or tests
- `revert`: revert a previous commit
## Scope (optional)
Indicate the impacted area for quick scanning. Prefer paths or domains:
- Examples: `api/users`, `application/orders`, `domain/billing`, `infrastructure/persistence`, `docs`, `scripts`, `docker`, `build`.
- Derive from `git status` or the directory touched when precise.
- Omit when change is cross-cutting.
## Description (required)
- Use imperative mood: “add”, “fix”, “remove”.
- Be specific: what changed and why it matters (in the body if lengthy).
- Avoid noise words like “update”, “stuff”.
## Body (optional but recommended)
Explain motivation, context, alternatives considered, and side-effects.
- Wrap at 72 chars per line.
- Reference design docs or ADRs if relevant.
## Footer (optional)
- `BREAKING CHANGE:` one-line summary, then details on migration.
- `Closes #123`, `Refs #456`.
- `Co-authored-by: Name <email>`.
## Examples
### Single File Change (derived scope)
```markdown
fix(api/users): return 404 when user not found
```
### Multi-Module Feature
```markdown
feat(application,api): add password reset flow
- application: add ResetPassword command + handler
- api: expose POST /v1/auth/reset with email throttle
- test: cover token expiry + invalid payloads
```
### Build/CI Change
```markdown
ci(github-actions): cache NuGet and testcontainers layers
```
### Breaking Change
```markdown
feat(api): rename /v1/orders to /v1/purchases
BREAKING CHANGE: client routes must switch to /v1/purchases.
Closes #842
```
### Revert
```markdown
revert: feat(api): add experimental timeline endpoint
Reverts commit abcdef1 due to performance regression.
```
## Commit Hygiene
- One logical change per commit; avoid mixed refactor + feature.
- Keep diffs focused and reviewable; large refactors split by area.
- Ensure code compiles and tests pass locally before commit.
- Run linters/analyzers; fix warnings or justify in body.
## Branch Naming
- `feature/<short-kebab-summary>`
- `fix/<ticket-or-bug-summary>`
- `chore/<task>`
- `perf/<area>`
- `refactor/<area>`
- `docs/<topic>`
- `ci/<pipeline-part>`
## Conventional Commits → Semantic Versioning
- `feat` → minor, `fix` → patch, `BREAKING CHANGE` → major.
- Release notes are generated from types/scopes. Keep consistent.
## Squash vs Merge
- Prefer **squash merge** for feature branches to keep a clean history.
- Preserve meaningful bodies and footers in the final squashed commit.
## When Auto-Generating Commits (e.g., tools)
- Ensure the first line follows the exact format.
- Include scopes from changed paths when clear.
- Add `Refs #<id>` if tied to tracker issues.
---
name: General Code and Documentation Rules
description: Cross-cutting engineering rules for .NET 8 projects (code quality, SOLID, architecture, docs, testing, security, performance, and ops).
---
## Goals
- Prioritize readability, explicitness, and testability over cleverness.
- Enforce SOLID, hexagonal/clean architecture, and clear boundaries.
- Optimize for maintainability, observability, and secure-by-default.
## Project Structure
- Root folders:
- `src/` (production code), `tests/` (unit/integration), `tools/`, `build/`, `docs/`, `scripts/`.
- Solution layout:
- Prefer vertical-slice or bounded contexts over giant shared libraries.
- Common layers (when applicable): `Api`, `Application`, `Domain`, `Infrastructure`, `Common`.
- Keep public surface area minimal; internal by default.
## Language & Framework (C# / .NET 8)
- Enable nullable reference types: `<Nullable>enable</Nullable>`.
- Treat warnings as errors in CI: `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>`.
- Use **file-scoped namespaces**, **primary constructors** where suitable.
- Favor `record`/`readonly struct` when semantics fit.
- Avoid `async void` (except top-level event handlers).
- Suffix async methods with `Async`.
- Cancellation tokens:
- Accept `CancellationToken` in async public methods; pass it downstream.
- Do not block async (no `.Result`/`.Wait()`).
- Libraries: consider `ConfigureAwait(false)`; **not** needed in ASP.NET Core apps.
## SOLID & Design
- Single Responsibility: one reason to change per class/module.
- Open/Closed: extend via composition or strategy; avoid switch-on-type antipatterns.
- Liskov Substitution: substitute without surprises; no throwing `NotImplementedException` in derived overrides.
- Interface Segregation: granular interfaces; no “fat” contracts.
- Dependency Inversion: depend on abstractions; wire in composition root (DI).
## Architecture & Boundaries
- Domain model independent from frameworks (no EF Core types in domain).
- Application layer orchestrates use cases (e.g., MediatR handlers).
- Infrastructure handles I/O (EF Core, HTTP, queues, cache).
- API layer maps HTTP ↔ DTOs; no domain leakage.
- Use Options Pattern for configuration (`IOptions<T>`), validate at startup.
## Error Handling & Contracts
- Fail fast on misconfiguration; validate `IOptions<T>` using `ValidateDataAnnotations()`.
- Domain errors via Result/Either or domain exceptions — be consistent.
- Map errors to proper HTTP codes. Never expose stack traces to clients.
## Logging & Observability
- Use structured logging (e.g., Serilog) with consistent properties:
- `CorrelationId`, `UserId`, `TenantId`, `RequestPath`, `Feature`.
- Emit **metrics** (counters, histograms) and **traces** (OpenTelemetry).
- No logging of secrets, tokens, or PII. Use log levels correctly (Debug/Info/Warn/Error).
## Configuration & Secrets
- No secrets in repo. Source from env vars, Secret Manager (dev), or vault (prod).
- Hierarchy: defaults (`appsettings.json`) → env-specific → env vars → KeyVault.
- Document required settings in `docs/configuration.md` with examples.
## Data & Persistence
- EF Core:
- Migrations per bounded context; **no** seeding in migrations beyond reference data.
- Use `AsNoTracking()` for read-only queries.
- Prefer projection at query time (DTO/select) to avoid over-fetching.
- Repositories should be thin; push complex queries to `IQueryable` projections or dedicated read-models.
## API Guidelines (ASP.NET Core)
- Use minimal APIs or controllers consistently within the project.
- Request/Response DTOs:
- Explicit contracts; avoid leaking domain entities.
- Validate with `FluentValidation` or `DataAnnotations`.
- Versioning: header or URL-based (e.g., `/api/v1/...`).
- Idempotency for POST where relevant (idempotency keys).
- Pagination: use `limit`, `offset` (or `cursor`) and return total counts when feasible.
- OpenAPI:
- Always generate Swagger; document auth flows and error schemas.
## Caching
- Prefer **output caching** or **response caching** at API edges where safe.
- Use distributed caches (e.g., Memcached/Redis) behind interfaces.
- Define TTLs explicitly; avoid infinite caches unless immutable.
## Security
- Enforce HTTPS; use HSTS in production.
- Authentication/Authorization:
- JWT or tokens validated server-side; short-lived access tokens, long-lived refresh with rotation.
- Use policy-based authorization.
- Input validation & output encoding.
- CORS: explicit origins; avoid `*` in prod.
- Rate limiting for public endpoints.
## Performance
- Measure first: add benchmarks or profiling before micro-optimizing.
- Async I/O everywhere; avoid sync-over-async.
- Consider `IAsyncEnumerable<T>` for streams; paginate large sets.
- Pooling and `Span<T>` only when justified and encapsulated.
## Code Style & Analyzers
- Use `.editorconfig` to codify style (naming, spacing, imports).
- Analyzers: Microsoft Code Analysis + (optionally) StyleCop, Sonar.
- Naming:
- **PascalCase**: classes, methods, public properties.
- **camelCase**: locals, parameters, private fields (prefix `_` allowed: `_logger`).
- Interfaces start with `I`.
- Async suffix `Async`.
- Avoid magic numbers; extract constants.
## Documentation
- C# public APIs documented with **XML docs**.
- Architectural docs in `docs/`:
- ADRs (`docs/ADRs/`), diagrams, sequence/flow, deployment.
- When writing TypeScript/JS in the repo, document with **TSDoc**.
- README at root with quickstart, stack, make targets, CI status.
## Testing Strategy
- **Unit tests**: xUnit (preferred), AAA pattern, single assertion rule (soft).
- **Integration tests**: `WebApplicationFactory`, testcontainers or docker-compose.
- Naming: `MethodName_ShouldExpectedBehavior_WhenCondition`.
- Coverage thresholds: 80% unit, critical paths ≥90%.
- Deterministic tests; no external calls—mock or fake.
- Include contract tests for adapters (e.g., external APIs).
## Git, Branching, and PRs (Summary)
- Branch naming: `feature/…`, `fix/…`, `chore/…`, `docs/…`, `perf/…`, `refactor/…`.
- Keep PRs small (< 400 LOC diff when possible); include context, screenshots for UI.
- Require green CI (build, tests, linters, analyzers) before merge.
- Code review: focus on correctness, security, readability, and testability.
## Example
```charp
/// <summary>
/// Calculate monthly repayment using the annuity formula.
/// </summary>
/// <param name="principal">Total loan amount.</param>
/// <param name="annualRate">Annual interest rate (e.g., 0.05 for 5%).</param>
/// <param name="months">Total number of months.</param>
/// <returns>Monthly repayment value.</returns>
/// <throws>Error if inputs are out of range.</throws>
/// </summary>
void int calcMonthlyRepayment(int principal, int annualRate, int months){
if (principal <= 0 || annualRate < 0 || months <= 0) throw new Error("Invalid inputs");
const r = annualRate / 12;
return r === 0 ? principal / months : (principal * r) / (1 - Math.pow(1 + r, -months));
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment