Skip to content
Merged
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
72 changes: 72 additions & 0 deletions .cursor/rules/bugsnag/fix-bugsnag-issues.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
description: Describes how to handle a request to fix a bugsnag issue
globs:
alwaysApply: false
---
# Bugsnag Ticket Workflow

When a user provides a Bugsnag error URL or asks to fix a Bugsnag issue, follow this systematic approach:

## 1. **Root Cause Analysis**

### Error Investigation
- Use `mcp_bugsnag-mcp_list-error-events` to get recent events for the error
- Use `mcp_bugsnag-mcp_get-stacktrace` with `include_code: true` and `show_all_frames: true` to get the complete stacktrace
- Analyze the stacktrace to identify:
- The exact line and file where the error occurs
- The call stack that leads to the error
- The error message and context

### Codebase Investigation
- Read the relevant files identified in the stacktrace
- Search for related code patterns or similar implementations
- Identify the data flow that leads to the problematic state
- Look for edge cases or missing null/undefined checks

## 2. **Suggest Fixes (No Code Changes)**

### Analysis Summary
- Provide a clear explanation of what's causing the error
- Identify the specific conditions that trigger the issue
- Explain the impact and severity of the error
- If you can't figure out what is going on, just say so and ask the user for more context

### Proposed Solutions
- Present 1-3 potential fix approaches with pros/cons
- Suggest relevant tests to prevent regression
- Try to be tactical with your suggestions, avoid large refactors when possible

### Implementation Recommendations
- Specify which files need to be modified
- Outline the exact changes needed (but don't make them yet)
- Mention any dependencies or related changes required
- Highlight potential breaking changes or compatibility concerns

## 3. **User Confirmation & Implementation**

### Get Approval
- Wait for user confirmation on the proposed approach
- Allow for discussion and refinement of the solution
- Clarify any ambiguous requirements or edge cases

### Implementation & PR Creation
Once the user confirms the approach:
- Follow the below process:
- Making code changes
- Adding tests if needed

---

**Example Workflow:**

- User: "Fix this Bugsnag issue: https://app.bugsnag.com/<ticket>"
- Assistant:
1. Fetches error events and stacktrace from Bugsnag
2. Analyzes the code to identify root cause
3. Proposes specific fix approach with explanation
4. Waits for user confirmation
5. Making code changes and tests if needed

---

**Note:** This workflow ensures thorough analysis before making changes, reducing the risk of incomplete fixes or introducing new issues while maintaining the systematic approach for PR creation.
19 changes: 19 additions & 0 deletions .cursor/rules/coding-workflow.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
description: Coding workflow cursor must follow
globs:
alwaysApply: false
---
# Coding workflow preferences
- Focus on the areas of code relevant to the task
- Do not touch code that is unrelated to the task
- Avoid making major changes to the patterns and architecture of how a feature works, after it has shown to work well, unless explicitly instructed
- Always think about what other methods and areas of code might be affected by code changes
- Keep code simple and readable
- Write thorough tests for all functionalities you wrote

Follow this sequential workflow:
1. Write or update existing code
2. Write the incremental unit-test to cover code logic you wrote
3. Test unit-test pass
4. Verify it passes all the tests by running `make test` command
5. Ensue your unit-test has good code coverage for the code you have written
59 changes: 59 additions & 0 deletions .cursor/rules/github/pr-template-format.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
description:
globs:
alwaysApply: false
---
---
description: Follow PR template format from .github/pull_request_template.md when creating pull request descriptions
globs: "**/*"
alwaysApply: false
---

# GitHub Pull Request Template Format

When creating pull request descriptions, you **must** follow the format specified in `.github/pull_request_template.md` if it exists in the repository.

## Rule Requirements

1. **Check for Template**: Always check if `.github/pull_request_template.md` exists in the repository root before creating PR descriptions.

2. **Use Template Structure**: If the template exists:
- Follow the exact section structure defined in the template
- Include all required sections from the template
- Maintain the same heading levels and formatting style
- Preserve any placeholder text guidelines or instructions
- Fill in the template sections with relevant information for the specific PR

3. **Template Sections**: Common sections that should be preserved if present in the template include:
- **Summary/Description**: Brief overview of the changes
- **Changes Made**: Detailed list of modifications
- **Testing**: How the changes were tested
- **Type of Change**: Bug fix, feature, documentation, etc.
- **Checklist**: Action items or verification steps
- **Breaking Changes**: Any backward compatibility concerns
- **Related Issues**: Links to related issues or tickets

4. **Fallback Behavior**: If no template exists, create a well-structured PR description with:
- Clear summary of changes
- Bullet points for key modifications
- Testing information if applicable
- Any relevant context or notes

## Implementation Guidelines

- **Read Template First**: Use tools to read the `.github/pull_request_template.md` file content before generating PR descriptions
- **Preserve Formatting**: Maintain markdown formatting, comments, and structure from the template
- **Fill Appropriately**: Replace template placeholders with actual, relevant information
- **Be Comprehensive**: Ensure all template sections are addressed, even if briefly
- **Stay Consistent**: Use the same tone and style as indicated by the template

## Example Usage

When creating a PR:
1. Check for `.github/pull_request_template.md`
2. If found, read the template content
3. Generate PR description following the template structure
4. Fill in each section with relevant information
5. Ensure all required sections are included

This rule ensures consistency across all pull requests in repositories that have established PR templates, while providing a sensible fallback for repositories without templates.
27 changes: 27 additions & 0 deletions .cursor/rules/golang/coding-rules.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
description: Rules to follow when writing code
globs: *.go
---
You are Staff Software Engineer expert in Golang, Protobuff, GRPC. You write clean and properly docummented code. You ensure code written works, and you always write corresponding Unit-tests.
You are an expert in writing Unit-test, and specialised in updating existing unit-test to fit missing use-cases.

# Coding pattern preferences
- Always prefer simple solutions.
- Keep the codebase very clean and organized.
- Avoid duplication of code whenever possible, which means checking for other areas of the codebase that might already have similar code and functionality.
- Write code that takes into account the different environments: development, staging, and production.
- You are careful to only make changes that are requested or you are confident are well understood and related to the change being requested.
- When fixing an issue or bug, do not introduce a new pattern or technology without first exhausting all options for the existing implementation. And if you finally do this, make sure to remove the old ipmlementation afterwards so we don't have duplicate logic.
- Avoid having files over 200-300 lines of code. Refactor at that point.
- Mocking data is only needed for tests, never mock data for dev or prod.
- Avoid writing scripts in files if possible, especially if the script is likely only to be run once.
- Never add stubbing or fake data patterns to code that affects the dev or prod environments.
- Never overwrite config *.yml (Yaml) files without first asking and confirming.
- It is acceptable to say you do not know.
- Do not write your own mocks in testing. Follow this sequence:
1. Update Makefile to generate the mock needed.
Following the example for internal packages
`mockgen -source=internal/client/users_service.go -destination=internal/dao/mocks/mock_users_service.go -package=mockdao`
and for external packages follow this:
` mockgen -destination=mocks/eth_client_mock.go -mock_names EthClient=MockEthClient -package=mocks github.cbhq.net/intl/rip7755-fulfiller/internal/client EthClientmockgen`
2. Update testing code to use the generated mock
49 changes: 49 additions & 0 deletions .cursor/rules/golang/english-and-comments-std.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
description: Make sure to always add clear comments within the codebase
globs: *.go
alwaysApply: true
---
# Standard: Language, Comments, and Documentation

This rule defines the standards for language use and commenting within the codebase, prioritizing clarity and developer experience for engineers familiar with the project.

**1. Language:**

* **All** code artifacts, including variable names, function names, comments, documentation, commit messages, and generated rules, **must** be written in **simple, clear, friendly and idiomatic English**.

**2. Comments:**

* **Target Audience:** Assume the reader is an experienced developer familiar with Go and the general project context.
* **Prioritize Readability:** Code should be self-documenting whenever possible through clear naming and structure.
* **Avoid Redundant Comments:** Do **not** add comments that merely restate what the code clearly does. For example:
```go
// Bad: Comment explains the obvious
// Increment count
count++

// Good: Comment starts with the function name
// GetUserByID finds a user by their ID
func GetUserByID(id string) (*User, error) { ... }
```
* **Focus on the "Why", Not Just the "What":** Prioritize comments that explain *why* a particular approach was taken, especially if it's non-obvious, involves trade-offs, or relates to external factors or historical context.
* Explain complex logic or algorithms briefly.
* Clarify the purpose of seemingly arbitrary values or constants.
* Document known limitations, potential issues, or future work (`TODO`, `FIXME`).
* Add comments when fixing subtle bugs to explain the reasoning.
```go
// Good: Explains the rationale for a non-obvious choice
// Use FNV-1a hash for Redis hash tags to optimize for speed and key length,
// as cryptographic security is not required for slot assignment.
func hashUserIDForTag(userID string) string { ... }

// Good: Explains a workaround or limitation
// TODO(GH-123): Refactor this when the upstream API supports batch requests.
for _, item := range items { ... }
```
* **Placement:** Place comments on the line *before* the code they refer to, or sometimes at the end of a line for very short clarifications.

**3. Documentation (e.g., READMEs, Design Docs):**

* Maintain clarity and conciseness.
* Keep documentation up-to-date with significant code changes.
* Use diagrams or examples where appropriate to illustrate complex concepts.
69 changes: 69 additions & 0 deletions .cursor/rules/golang/golang-naming-std.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
description: Avoid package prefix redundancy when naming
globs: *.go
alwaysApply: false
---
# Go Standard: Naming Conventions - Avoid Package Prefix Redundancy

This rule outlines the standard Go practice for naming exported identifiers to avoid redundancy with the package name.

**The Standard:**

When naming exported identifiers (types, functions, variables, constants), **avoid repeating the package name** if the context provided by the package itself makes the identifier clear.

**Rationale:**

* **Readability:** Code that imports the package becomes cleaner and less verbose. For example, `store.New()` is more idiomatic and readable than `store.NewStore()`.
* **Conciseness:** Reduces unnecessary stuttering in code (e.g., `store.StoreType` vs. `store.Type`).
* **Idiomatic Go:** Follows the common practice seen in the Go standard library and many popular Go projects.

**Examples:**

```go
// --- Package: store ---

// BAD: Repeats "store"
package store

type StoreConfig struct { ... }
func NewStore(cfg StoreConfig) (*Store, error) { ... }
var DefaultStoreOptions StoreOptions

// GOOD: Avoids repeating "store"
package store

type Config struct { ... } // Type name is clear within package 'store'
func New(cfg Config) (*Store, error) { ... } // Function name 'New' is clear
var DefaultOptions Options // Variable name is clear

type Store struct { ... } // OK: Identifier itself IS the package name conceptually
```

When importing and using the "good" example:

```go
import "path/to/store"

// ...
cfg := store.Config{ ... }
activityStore, err := store.New(cfg)
opts := store.DefaultOptions
var s store.Store
```

This reads much better than:

```go
import "path/to/store"

// ...
cfg := store.StoreConfig{ ... }
activityStore, err := store.NewStore(cfg)
opts := store.DefaultStoreOptions
var s store.Store
```

**Exceptions:**

* It is acceptable if the identifier itself essentially *is* the package name (e.g., `package http; type Client`, `package store; type Store`).
* Sometimes repeating a part of the package name is necessary for clarity if the package has many distinct concepts.
53 changes: 53 additions & 0 deletions .cursor/rules/golang/golang-use-getters.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
description: Prefer getter methods over direct field access
globs: *.go
alwaysApply: false
---
# Go Standard: Prefer Getter Methods (Especially for Protobuf)

This rule encourages the use of getter methods over direct field access, particularly when working with structs generated from Protobuf definitions.

**The Standard:**

**Prefer using generated getter methods (e.g., `myProto.GetMyField()`) over direct field access (e.g., `myProto.MyField`) when such getters are available.** This is especially relevant for structs generated by the Protobuf compiler (`protoc-gen-go`).

**Rationale:**

* **Encapsulation and Nil Safety:** Getters often provide a layer of abstraction. For Protobuf messages, getters automatically handle `nil` checks for pointer fields (like optional message fields or fields within a `oneof`), returning a zero value instead of causing a panic. This significantly improves robustness.
* **Consistency:** Using getters consistently makes the code easier to read and maintain, aligning with common Go practices for Protobuf.
* **Future-Proofing:** Relying on the getter method decouples the calling code from the exact internal representation of the field. If the underlying field changes in a backward-compatible way (e.g., how a default value is handled), code using the getter is less likely to break.
* **Helper Logic:** Getters might potentially include minor logic (though less common in basic Protobuf getters beyond nil checks).

**Example (Protobuf):**

```protobuf
// -- Example.proto --
message UserProfile {
optional string name = 1;
optional int32 age = 2;
}
```

```go
// -- Go code --
import "path/to/gen/go/examplepb"

func processProfile(profile *examplepb.UserProfile) {
// GOOD: Uses getter, safe even if profile or profile.Name is nil.
name := profile.GetName()
age := profile.GetAge() // Also handles potential nil receiver safely.

// BAD: Direct access risks nil pointer dereference if profile is non-nil
// but profile.Name is nil (for optional fields).
// nameDirect := *profile.Name // PANICS if profile.Name is nil!
// ageDirect := *profile.Age // PANICS if profile.Age is nil!

fmt.Printf("Name: %s, Age: %d\n", name, age)
}
```

**Exceptions:**

* **No Getter Available:** If a struct field does not have a corresponding getter method, direct access is necessary.
* **Performance Critical Code:** In extremely rare, performance-critical sections where profiling has demonstrably shown the function call overhead of the getter to be a bottleneck, direct access *might* be considered cautiously. This should be well-documented and justified.
* **Setting Values:** This rule applies to *reading* values. Setting struct fields typically involves direct assignment.
17 changes: 17 additions & 0 deletions .cursor/rules/golang/grpcclient.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
description: Creating a new grpc connection should use csf's grpcclient, not golang/grpc
globs: *.go
alwaysApply: false
---
Pull in the package from github.cbhq.net/engineering/csf/grpcclient

Here is an example of how you should implement it
```
manager := csf.New()
ctx := manager.ServiceContext()
conn, err := grpcclient.Dial(
ctx,
endpoint,
grpcclient.WithDialOpt(grpc.WithBlock()),
)
```
Loading