Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions asynclogger/.cursor/rules/global/golang/code-quality.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
description: "Guidelines for maintaining code quality, clarity, and consistency across imports, function usage, and documentation"
globs:
alwaysApply: false
---

### Import statements quality
1. Do not change the import order of existing import files and packages, just add the new ones
2. Avoid wild card imports

### Functions usage
1. Do not change the private functions to public unless we want other packages to use it
2. If the same package is using the function then keep it private

### Code comments and documentation
1. Add comments only when necessary, do not add comments when the code itself gives the understanding
2. Add comments for architectural decision
36 changes: 36 additions & 0 deletions asynclogger/.cursor/rules/global/golang/compliance.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
description: "Provide the list of rules which are obeyed in every response"
globs:
alwaysApply: true
---

# Rule Compliance Tracking

## Response Format Requirement
When responding to user queries about code patterns, architecture, or implementation examples:

1. **Always List Obeyed Rules**: At the end of your response, include a section titled "**Rules Followed:**" that lists the specific rules from the codebase that are being obeyed or demonstrated in your response.

2. **Rule Identification**: Identify rules from the following files:
- `.cursor/rules/unit-testing.mdc`
- `.cursor/rules/requirement-planning.mdc`
- `.cursor/rules/code-quality.mdc`
- `.cursor/rules/compliance.mdc`

3. **Example Format**:
```
**Rules Followed:**
- Dependency Injection Pattern
- Configuration Management
- Interface Design
```

4. **Context Awareness**: Only list rules that are actually relevant to the specific response or examples provided.

5. **Rule Verification**: When analyzing code examples, verify which rule categories are being followed and explicitly mention the rule headings.

## Implementation Guidelines
- Scan the codebase for examples that demonstrate rule compliance
- Provide concrete code examples when possible
- Explain how the examples follow the specific rule categories
- Use the rule headings/categories from the source files when listing them
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
description: These rules cover data shapes, allocation, interface design, and safe concurrency/error handlingβ€”areas where AI can subtly violate idioms or introduce leaks and races.
alwaysApply: false
globs: *.go
---

### Effective Go Rules: Data, Allocation, Interfaces, Concurrency, Errors

These rules cover data shapes, allocation, interface design, and safe concurrency/error handlingβ€”areas where AI can subtly violate idioms or introduce leaks and races.

## Arrays, Slices, Maps
- Reassign the result of `append`; capacity may change.
- Preallocate capacity when known; use `copy` for duplication.
- If copying a slice or map, the pointers nested in these will not be copied.
- Maps: missing keys yield zero values; use comma-ok to test presence.

Example:
```go
v, ok := m[key]
if !ok { /* handle missing */ }
```

## Variadics & Append
- Use `...T` for flexible APIs; forward with `f(v...)`.
- Concatenate slices with `append(dst, src...)`.


## Methods: Pointer vs Value
- Pointer receivers for mutation/big copies.

## Interfaces
- Define small, behavior-driven interfaces near use sites.
- Constructors should return the narrowest interface needed.
- Convert types to reuse method sets (e.g., `sort.IntSlice(s).Sort()`).


## Concurrency Basics
- Start goroutines only when beneficial; ensure they can terminate.
- Use channels for synchronization/communication; avoid shared memory without coordination.

Use Worker pool at appropriate places:
```go
jobs := make(chan Job)
for i := 0; i < N; i++ { go func() { for j := range jobs { handle(j) } }() }
```

Channel ownership:
- Close channels only from the sender/owner.

## Context & Cancellation
- Accept `context.Context` and honor `Done()` for long-lived operations.
- Avoid `time.Sleep` polling; use timers/tickers with `select`.

## Panic, Recover, Errors
- Prefer `error` returns; reserve `panic` for unrecoverable programmer errors.
- At boundaries, `defer` + `recover` to convert internal panics to errors; type-assert expected panic values.
- Structure error strings without caps/punctuation; prefix with operation or package when helpful.
- Avoid double-reporting (log and return); choose a single owner.
- Use rich error types (ex: `*os.PathError`) and `%w` wrapping.
- Always try to return a meaningfull error code and message, client should be able to find out the failure reason without exposing internal details.
- Either log or return - not both. If you're returning an API response, then log it as well.
34 changes: 34 additions & 0 deletions asynclogger/.cursor/rules/global/golang/formatting-control.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
description: These rules focus on the places where AI often drifts from idiomatic Go,, naming that avoids stutter, brace placement, early-returns, and minimalistic control flow. Follow these to produce idiomatic, readable Go.
alwaysApply: false
globs: *.go
---

### Effective Go Rules: Formatting, Comments, Naming, Semicolons, Control Flow

These rules focus on the places where AI often drifts from idiomatic Go: formatting handled by tools, naming that avoids stutter, brace placement, early-returns, and minimalistic control flow. Follow these to produce idiomatic, readable Go.


## Naming
- Do not prefix getters with `Get`; prefer `Owner()` over `GetOwner()`; setters as `SetOwner(x)`.

## Control Flow Essentials
- Prefer early returns for errors; let the success path flow downward.
- Omit `else` when the `if` body ends in `return/break/continue`.
- Use `if`/`switch` init statements to scope locals.
- Prefer `switch` over long `if-else` chains; avoid implicit fallthrough.

## `defer` and Resources
- Place `defer` immediately after acquiring a resource; args evaluated at `defer` time.
- Deferred calls run LIFO. Avoid deferring inside hot loops.

## Printing and Diagnostics
- Prefer `%v` for values, `%+v` to include field names, `%#v` for Go syntax, `%T` for type.

## Shadowing and Short Decls
- Reuse `err` with `:=` when at least one new variable exists; avoid accidental shadowing across scopes.
- Declare variables at first use; avoid predeclaring far from usage.


## Extra
- Prefer `const` for stable magic numbers; otherwise localize and comment literals.
12 changes: 12 additions & 0 deletions asynclogger/.cursor/rules/global/golang/requirement-planning.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
description: "Promotes thorough requirement analysis, careful planning, and implementation of robust, general-purpose solutions."
alwaysApply: false
---
### Requirement Understanding

Before creating a plan you MUST ask questions from the user to get clarity on the problem statement

1. Break down a problem statement into smaller problem statements
2. Please write a high quality, general purpose solution. Implement a solution that works correctly for all valid inputs, not just the test cases. Do not hard-code values or create solutions that only work for specific test inputs. Instead, implement the actual logic that solves the problem generally.
3. Focus on understanding the problem requirements and implementing the correct algorithm. Tests are there to verify correctness, not to define the solution. Provide a principled implementation that follows best practices and software design principles.
4. If the task is unreasonable or infeasible, or if any of the tests are incorrect, please tell me. The solution should be robust, maintainable, and extendable.
108 changes: 108 additions & 0 deletions asynclogger/.cursor/rules/global/golang/unit-testing.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
description: "Go testing patterns including test structure, mocking, test data, assertions and more"
globs: *.go
alwaysApply: false
---

# Go Testing Patterns

## Instructions

### Test Plan Creation

When writing unit tests, get clarity on the system under test and come up with a list of what all cases can be possible within that system. Generate the unit test for all those cases

### Coverage Guidelines
- MUST run `go test -cover` to measure coverage, instead of calculating yourself and aim for 80%+ code coverage for critical business logic
- Focus on testing behavior, not just coverage percentage
- Test error paths and edge cases

## Test Structure and Organization

### Test File Organization
- Group related tests using subtests with `t.Run()`
- If there is a single test, then don't use `t.Run()`
- Generate Go tests using testify's suite package for structure wherever applicable

### Test Naming Conventions
Use descriptive test names that clearly indicate the scenario:

```go
// βœ… Good - Clear scenario description
func TestConfigService_GetConfig_ReturnsConfigWhenFound(t *testing.T) {}
func TestConfigService_GetConfig_ReturnsErrorWhenNotFound(t *testing.T) {}
func TestConfigService_ValidateConfig_ReturnsErrorOnInvalidData(t *testing.T) {}

// ❌ Avoid - Vague test names
func TestGetConfig(t *testing.T) {}
func TestValidation(t *testing.T) {}
```

## Mocking and Dependencies

### Interface-Based Mocking
Use interfaces for dependencies to enable easy mocking

### Mock Setup Patterns
mockRepo := mocks.NewMockRepository(ctrl)
mockRepo.EXPECT().
GetConfig("test-id").
Return(&Config{ID: "test-id"}, nil).
Times(1)

## Test Data and Fixtures

### Test Data Creation
Create helper functions for building test data where the test data is common

### Table-Driven Tests
Use table-driven tests for testing multiple scenarios

## Assertion Patterns

### Using testify/assert
Prefer testify/assert for better error messages

```go
// βœ… Good - Clear assertions with testify
assert.NoError(t, err)
assert.Equal(t, expectedValue, actualValue)
assert.Contains(t, slice, element)
assert.Len(t, collection, expectedLength)

// ❌ Avoid - Basic Go testing with poor error messages
if err != nil {
t.Errorf("expected no error, got %v", err)
}
```

### Error Testing
```go
// Testing specific error types
assert.ErrorIs(t, err, ErrConfigNotFound)
assert.ErrorAs(t, err, &validationErr)
assert.NoError(t, err)

// Testing error messages
assert.EqualError(t, err, "expected error message")
assert.Contains(t, err.Error(), "partial error message")
```

## HTTP Handler Testing

### Testing HTTP Handlers
Use `httptest` for testing HTTP handlers

## Test Quality

### Test Organization
- Use setup/teardown functions for complex test scenarios
- Keep tests independent - one test should not depend on another
- Use parallel tests where appropriate: `t.Parallel()`

### Common Pitfalls to Avoid
1. **Testing Implementation Details**: Focus on behavior, not internal implementation
2. **Ignoring Error Cases**: Always test both success and error scenarios
3. **Flaky Tests**: Avoid time-dependent tests, use deterministic test data
4. **Over-Mocking**: Don't mock everything, test real integrations where valuable
5. **Poor Test Data**: Use realistic test data that reflects production scenarios
Loading