@abarcenas/ai-workflow-template 1.1.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/.github/agents/implementation-plan.agent.md +192 -0
- package/.github/agents/plan.agent.md +135 -0
- package/.github/agents/research-spike.agent.md +204 -0
- package/.github/instructions/agent-safety.instructions.md +98 -0
- package/.github/instructions/agent-skill.instructions.md +272 -0
- package/.github/instructions/agent.instructions.md +1068 -0
- package/.github/instructions/ai-prompt-engineering-safety.instructions.md +991 -0
- package/.github/instructions/angular.instructions.md +116 -0
- package/.github/instructions/context7.instructions.md +109 -0
- package/.github/instructions/go.instructions.md +374 -0
- package/.github/instructions/html-to-css-guide.instructions.md +104 -0
- package/.github/instructions/instructions.instructions.md +264 -0
- package/.github/instructions/markdown.instructions.md +51 -0
- package/.github/instructions/memory-bank.instructions.md +322 -0
- package/.github/instructions/nodejs-vitest.instructions.md +34 -0
- package/.github/instructions/playwright-typescript.instructions.md +88 -0
- package/.github/instructions/prompt.instructions.md +99 -0
- package/.github/instructions/security-owasp.instructions.md +59 -0
- package/.github/instructions/shell.instructions.md +132 -0
- package/.github/instructions/task-implementation.instructions.md +203 -0
- package/.github/instructions/typescript.instructions.md +114 -0
- package/.github/prompts/copilot-instructions-blueprint-generator.prompt.md +317 -0
- package/.github/prompts/documentation-writer.prompt.md +46 -0
- package/.github/prompts/editconfig.prompt.md +64 -0
- package/.github/prompts/playwright-explore.prompt.md +39 -0
- package/.github/prompts/playwright-generate-test.prompt.md +39 -0
- package/.github/skills/agent-governance/SKILL.md +572 -0
- package/.github/skills/boost-prompt/SKILL.md +25 -0
- package/.github/skills/chrome-devtools/SKILL.md +97 -0
- package/.github/skills/context-map/SKILL.md +57 -0
- package/.github/skills/conventional-commit/SKILL.md +72 -0
- package/.github/skills/create-readme/SKILL.md +21 -0
- package/.github/skills/editorconfig/SKILL.md +63 -0
- package/.github/skills/gh-cli/SKILL.md +2188 -0
- package/.github/skills/git-commit/SKILL.md +124 -0
- package/.github/skills/github-issues/SKILL.md +134 -0
- package/.github/skills/github-issues/references/templates.md +110 -0
- package/.github/skills/microsoft-docs/SKILL.md +114 -0
- package/.github/skills/playwright-explore-website/SKILL.md +17 -0
- package/.github/skills/playwright-generate-test/SKILL.md +17 -0
- package/.github/skills/polygot-test-agent/SKILL.md +171 -0
- package/.github/skills/polygot-test-agent/unit-test-genearation.prompt.md +155 -0
- package/.github/skills/prompt-builder/SKILL.md +159 -0
- package/.github/workflows/npm-publish.yml +25 -0
- package/README.md +111 -0
- package/package.json +32 -0
- package/scripts/bump-version.js +29 -0
- package/scripts/sync.js +122 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Angular-specific coding standards and best practices"
|
|
3
|
+
applyTo: "**/*.ts, **/*.html, **/*.scss, **/*.css"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Angular Development Instructions
|
|
7
|
+
|
|
8
|
+
Instructions for generating high-quality Angular applications with TypeScript, using Angular Signals for state management, adhering to Angular best practices as outlined at https://angular.dev.
|
|
9
|
+
|
|
10
|
+
## Project Context
|
|
11
|
+
|
|
12
|
+
- Latest Angular version (use standalone components by default)
|
|
13
|
+
- TypeScript for type safety
|
|
14
|
+
- Angular CLI for project setup and scaffolding
|
|
15
|
+
- Follow Angular Style Guide (https://angular.dev/style-guide)
|
|
16
|
+
- Use Angular Material or other modern UI libraries for consistent styling (if specified)
|
|
17
|
+
|
|
18
|
+
## Development Standards
|
|
19
|
+
|
|
20
|
+
### Architecture
|
|
21
|
+
|
|
22
|
+
- Use standalone components unless modules are explicitly required
|
|
23
|
+
- Organize code by standalone feature modules or domains for scalability
|
|
24
|
+
- Implement lazy loading for feature modules to optimize performance
|
|
25
|
+
- Use Angular's built-in dependency injection system effectively
|
|
26
|
+
- Structure components with a clear separation of concerns (smart vs. presentational components)
|
|
27
|
+
|
|
28
|
+
### TypeScript
|
|
29
|
+
|
|
30
|
+
- Enable strict mode in `tsconfig.json` for type safety
|
|
31
|
+
- Define clear interfaces and types for components, services, and models
|
|
32
|
+
- Use type guards and union types for robust type checking
|
|
33
|
+
- Implement proper error handling with RxJS operators (e.g., `catchError`)
|
|
34
|
+
- Use typed forms (e.g., `FormGroup`, `FormControl`) for reactive forms
|
|
35
|
+
|
|
36
|
+
### Component Design
|
|
37
|
+
|
|
38
|
+
- Follow Angular's component lifecycle hooks best practices
|
|
39
|
+
- When using Angular >= 19, Use `input()` `output()`, `viewChild()`, `viewChildren()`, `contentChild()` and `contentChildren()` functions instead of decorators; otherwise use decorators
|
|
40
|
+
- Leverage Angular's change detection strategy (default or `OnPush` for performance)
|
|
41
|
+
- Keep templates clean and logic in component classes or services
|
|
42
|
+
- Use Angular directives and pipes for reusable functionality
|
|
43
|
+
|
|
44
|
+
### Styling
|
|
45
|
+
|
|
46
|
+
- Use Angular's component-level CSS encapsulation (default: ViewEncapsulation.Emulated)
|
|
47
|
+
- Prefer SCSS for styling with consistent theming
|
|
48
|
+
- Implement responsive design using CSS Grid, Flexbox, or Angular CDK Layout utilities
|
|
49
|
+
- Follow Angular Material's theming guidelines if used
|
|
50
|
+
- Maintain accessibility (a11y) with ARIA attributes and semantic HTML
|
|
51
|
+
|
|
52
|
+
### State Management
|
|
53
|
+
|
|
54
|
+
- Use Angular Signals for reactive state management in components and services
|
|
55
|
+
- Leverage `signal()`, `computed()`, and `effect()` for reactive state updates
|
|
56
|
+
- Use writable signals for mutable state and computed signals for derived state
|
|
57
|
+
- Handle loading and error states with signals and proper UI feedback
|
|
58
|
+
- Use Angular's `AsyncPipe` to handle observables in templates when combining signals with RxJS
|
|
59
|
+
|
|
60
|
+
### Data Fetching
|
|
61
|
+
|
|
62
|
+
- Use Angular's `HttpClient` for API calls with proper typing
|
|
63
|
+
- Implement RxJS operators for data transformation and error handling
|
|
64
|
+
- Use Angular's `inject()` function for dependency injection in standalone components
|
|
65
|
+
- Implement caching strategies (e.g., `shareReplay` for observables)
|
|
66
|
+
- Store API response data in signals for reactive updates
|
|
67
|
+
- Handle API errors with global interceptors for consistent error handling
|
|
68
|
+
|
|
69
|
+
### Security
|
|
70
|
+
|
|
71
|
+
- Sanitize user inputs using Angular's built-in sanitization
|
|
72
|
+
- Implement route guards for authentication and authorization
|
|
73
|
+
- Use Angular's `HttpInterceptor` for CSRF protection and API authentication headers
|
|
74
|
+
- Validate form inputs with Angular's reactive forms and custom validators
|
|
75
|
+
- Follow Angular's security best practices (e.g., avoid direct DOM manipulation)
|
|
76
|
+
|
|
77
|
+
### Performance
|
|
78
|
+
|
|
79
|
+
- Enable production builds with `ng build --prod` for optimization
|
|
80
|
+
- Use lazy loading for routes to reduce initial bundle size
|
|
81
|
+
- Optimize change detection with `OnPush` strategy and signals for fine-grained reactivity
|
|
82
|
+
- Use trackBy in `ngFor` loops to improve rendering performance
|
|
83
|
+
- Implement server-side rendering (SSR) or static site generation (SSG) with Angular Universal (if specified)
|
|
84
|
+
|
|
85
|
+
### Testing
|
|
86
|
+
|
|
87
|
+
- Write unit tests for components, services, and pipes using Jasmine and Karma
|
|
88
|
+
- Use Angular's `TestBed` for component testing with mocked dependencies
|
|
89
|
+
- Test signal-based state updates using Angular's testing utilities
|
|
90
|
+
- Write end-to-end tests with Cypress or Playwright (if specified)
|
|
91
|
+
- Mock HTTP requests using `provideHttpClientTesting`
|
|
92
|
+
- Ensure high test coverage for critical functionality
|
|
93
|
+
|
|
94
|
+
## Implementation Process
|
|
95
|
+
|
|
96
|
+
1. Plan project structure and feature modules
|
|
97
|
+
2. Define TypeScript interfaces and models
|
|
98
|
+
3. Scaffold components, services, and pipes using Angular CLI
|
|
99
|
+
4. Implement data services and API integrations with signal-based state
|
|
100
|
+
5. Build reusable components with clear inputs and outputs
|
|
101
|
+
6. Add reactive forms and validation
|
|
102
|
+
7. Apply styling with SCSS and responsive design
|
|
103
|
+
8. Implement lazy-loaded routes and guards
|
|
104
|
+
9. Add error handling and loading states using signals
|
|
105
|
+
10. Write unit and end-to-end tests
|
|
106
|
+
11. Optimize performance and bundle size
|
|
107
|
+
|
|
108
|
+
## Additional Guidelines
|
|
109
|
+
|
|
110
|
+
- Follow the Angular Style Guide for file naming conventions (see https://angular.dev/style-guide), e.g., use `feature.ts` for components and `feature-service.ts` for services. For legacy codebases, maintain consistency with existing pattern.
|
|
111
|
+
- Use Angular CLI commands for generating boilerplate code
|
|
112
|
+
- Document components and services with clear JSDoc comments
|
|
113
|
+
- Ensure accessibility compliance (WCAG 2.1) where applicable
|
|
114
|
+
- Use Angular's built-in i18n for internationalization (if specified)
|
|
115
|
+
- Keep code DRY by creating reusable utilities and shared modules
|
|
116
|
+
- Use signals consistently for state management to ensure reactive updates
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Use Context7 for authoritative external docs and API references when local context is insufficient"
|
|
3
|
+
applyTo: "**"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Context7-aware development
|
|
7
|
+
|
|
8
|
+
Use Context7 proactively whenever the task depends on **authoritative, current, version-specific external documentation** that is not present in the workspace context.
|
|
9
|
+
|
|
10
|
+
This instruction exists so you **do not require the user to type** “use context7” to get up-to-date docs.
|
|
11
|
+
|
|
12
|
+
## When to use Context7
|
|
13
|
+
|
|
14
|
+
Use Context7 before making decisions or writing code when you need any of the following:
|
|
15
|
+
|
|
16
|
+
- **Framework/library API details** (method signatures, configuration keys, expected behaviors).
|
|
17
|
+
- **Version-sensitive guidance** (breaking changes, deprecations, new defaults).
|
|
18
|
+
- **Correctness or security-critical patterns** (auth flows, crypto usage, deserialization rules).
|
|
19
|
+
- **Interpreting unfamiliar error messages** that likely come from third-party tools.
|
|
20
|
+
- **Best-practice implementation constraints** (rate limits, quotas, required headers, supported formats).
|
|
21
|
+
|
|
22
|
+
Also use Context7 when:
|
|
23
|
+
|
|
24
|
+
- The user references **a specific framework/library version** (e.g., “Next.js 15”, “React 19”, “AWS SDK v3”).
|
|
25
|
+
- You’re about to recommend **non-trivial configuration** (CLI flags, config files, auth flows).
|
|
26
|
+
- You’re unsure whether an API exists, changed names, or got deprecated.
|
|
27
|
+
|
|
28
|
+
Skip Context7 for:
|
|
29
|
+
|
|
30
|
+
- Purely local refactors, formatting, naming, or logic that is fully derivable from the repo.
|
|
31
|
+
- Language fundamentals (no external APIs involved).
|
|
32
|
+
|
|
33
|
+
## What to fetch
|
|
34
|
+
|
|
35
|
+
When using Context7, prefer **primary sources** and narrow queries:
|
|
36
|
+
|
|
37
|
+
- Official docs (vendor/framework documentation)
|
|
38
|
+
- Reference/API pages
|
|
39
|
+
- Release notes / migration guides
|
|
40
|
+
- Security advisories (when relevant)
|
|
41
|
+
|
|
42
|
+
Gather only what you need to proceed. If multiple candidates exist, pick the most authoritative/current.
|
|
43
|
+
|
|
44
|
+
Prefer fetching:
|
|
45
|
+
|
|
46
|
+
- The exact method/type/option you will use
|
|
47
|
+
- The minimal surrounding context needed to avoid misuse (constraints, default behaviors, migration notes)
|
|
48
|
+
|
|
49
|
+
## How to incorporate results
|
|
50
|
+
|
|
51
|
+
- Translate findings into concrete code/config changes.
|
|
52
|
+
- **Cite sources** with title + URL when the decision relies on external facts.
|
|
53
|
+
- If docs conflict or are ambiguous, present the tradeoffs briefly and choose the safest default.
|
|
54
|
+
|
|
55
|
+
When the answer requires specific values (flags, config keys, headers), prefer:
|
|
56
|
+
|
|
57
|
+
- stating the exact value from docs
|
|
58
|
+
- calling out defaults and caveats
|
|
59
|
+
- providing a quick validation step (e.g., “run `--help`”, or a minimal smoke test)
|
|
60
|
+
|
|
61
|
+
## How to use Context7 MCP tools (auto)
|
|
62
|
+
|
|
63
|
+
When Context7 is available as an MCP server, use it automatically as follows.
|
|
64
|
+
|
|
65
|
+
### Tool workflow
|
|
66
|
+
|
|
67
|
+
1. **If the user provides a library ID**, use it directly.
|
|
68
|
+
|
|
69
|
+
- Valid forms: `/owner/repo` or `/owner/repo/version` (for pinned versions).
|
|
70
|
+
|
|
71
|
+
2. Otherwise, **resolve the library ID** using:
|
|
72
|
+
|
|
73
|
+
- Tool: `resolve-library-id`
|
|
74
|
+
- Inputs:
|
|
75
|
+
- `libraryName`: the library/framework name (e.g., “next.js”, “supabase”, “prisma”)
|
|
76
|
+
- `query`: the user’s task (used to rank matches)
|
|
77
|
+
|
|
78
|
+
3. **Fetch relevant documentation** using:
|
|
79
|
+
|
|
80
|
+
- Tool: `query-docs`
|
|
81
|
+
- Inputs:
|
|
82
|
+
- `libraryId`: the resolved (or user-supplied) library ID
|
|
83
|
+
- `query`: the exact task/question you are answering
|
|
84
|
+
|
|
85
|
+
4. Only after docs are retrieved: **write the code/steps** based on those docs.
|
|
86
|
+
|
|
87
|
+
### Efficiency limits
|
|
88
|
+
|
|
89
|
+
- Do **not** call `resolve-library-id` more than **3 times** per user question.
|
|
90
|
+
- Do **not** call `query-docs` more than **3 times** per user question.
|
|
91
|
+
- If multiple good matches exist, pick the best one and proceed; ask a clarification question only when the choice materially affects the implementation.
|
|
92
|
+
|
|
93
|
+
### Version behavior
|
|
94
|
+
|
|
95
|
+
- If the user names a version, reflect it in the library ID when possible (e.g., `/vercel/next.js/v15.1.8`).
|
|
96
|
+
- If you need reproducibility (CI/builds), prefer pinning to a specific version in examples.
|
|
97
|
+
|
|
98
|
+
## Failure handling
|
|
99
|
+
|
|
100
|
+
If Context7 cannot find a reliable source:
|
|
101
|
+
|
|
102
|
+
1. Say what you tried to verify.
|
|
103
|
+
2. Proceed with a conservative, well-labeled assumption.
|
|
104
|
+
3. Suggest a quick validation step (e.g., run a command, check a file, or consult a specific official page).
|
|
105
|
+
|
|
106
|
+
## Security & privacy
|
|
107
|
+
|
|
108
|
+
- Never request or echo API keys. If configuration requires a key, instruct storing it in environment variables.
|
|
109
|
+
- Treat retrieved docs as **helpful but not infallible**; for security-sensitive code, prefer official vendor docs and add an explicit verification step.
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Instructions for writing Go code following idiomatic Go practices and community standards"
|
|
3
|
+
applyTo: "**/*.go,**/go.mod,**/go.sum"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Go Development Instructions
|
|
7
|
+
|
|
8
|
+
Follow idiomatic Go practices and community standards when writing Go code. These instructions are based on [Effective Go](https://go.dev/doc/effective_go), [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments), and [Google's Go Style Guide](https://google.github.io/styleguide/go/).
|
|
9
|
+
|
|
10
|
+
## General Instructions
|
|
11
|
+
|
|
12
|
+
- Write simple, clear, and idiomatic Go code
|
|
13
|
+
- Favor clarity and simplicity over cleverness
|
|
14
|
+
- Follow the principle of least surprise
|
|
15
|
+
- Keep the happy path left-aligned (minimize indentation)
|
|
16
|
+
- Return early to reduce nesting
|
|
17
|
+
- Prefer early return over if-else chains; use `if condition { return }` pattern to avoid else blocks
|
|
18
|
+
- Make the zero value useful
|
|
19
|
+
- Write self-documenting code with clear, descriptive names
|
|
20
|
+
- Document exported types, functions, methods, and packages
|
|
21
|
+
- Use Go modules for dependency management
|
|
22
|
+
- Leverage the Go standard library instead of reinventing the wheel (e.g., use `strings.Builder` for string concatenation, `filepath.Join` for path construction)
|
|
23
|
+
- Prefer standard library solutions over custom implementations when functionality exists
|
|
24
|
+
- Write comments in English by default; translate only upon user request
|
|
25
|
+
- Avoid using emoji in code and comments
|
|
26
|
+
|
|
27
|
+
## Naming Conventions
|
|
28
|
+
|
|
29
|
+
### Packages
|
|
30
|
+
|
|
31
|
+
- Use lowercase, single-word package names
|
|
32
|
+
- Avoid underscores, hyphens, or mixedCaps
|
|
33
|
+
- Choose names that describe what the package provides, not what it contains
|
|
34
|
+
- Avoid generic names like `util`, `common`, or `base`
|
|
35
|
+
- Package names should be singular, not plural
|
|
36
|
+
|
|
37
|
+
#### Package Declaration Rules (CRITICAL):
|
|
38
|
+
|
|
39
|
+
- **NEVER duplicate `package` declarations** - each Go file must have exactly ONE `package` line
|
|
40
|
+
- When editing an existing `.go` file:
|
|
41
|
+
- **PRESERVE** the existing `package` declaration - do not add another one
|
|
42
|
+
- If you need to replace the entire file content, start with the existing package name
|
|
43
|
+
- When creating a new `.go` file:
|
|
44
|
+
- **BEFORE writing any code**, check what package name other `.go` files in the same directory use
|
|
45
|
+
- Use the SAME package name as existing files in that directory
|
|
46
|
+
- If it's a new directory, use the directory name as the package name
|
|
47
|
+
- Write **exactly one** `package <name>` line at the very top of the file
|
|
48
|
+
- When using file creation or replacement tools:
|
|
49
|
+
- **ALWAYS verify** the target file doesn't already have a `package` declaration before adding one
|
|
50
|
+
- If replacing file content, include only ONE `package` declaration in the new content
|
|
51
|
+
- **NEVER** create files with multiple `package` lines or duplicate declarations
|
|
52
|
+
|
|
53
|
+
### Variables and Functions
|
|
54
|
+
|
|
55
|
+
- Use mixedCaps or MixedCaps (camelCase) rather than underscores
|
|
56
|
+
- Keep names short but descriptive
|
|
57
|
+
- Use single-letter variables only for very short scopes (like loop indices)
|
|
58
|
+
- Exported names start with a capital letter
|
|
59
|
+
- Unexported names start with a lowercase letter
|
|
60
|
+
- Avoid stuttering (e.g., avoid `http.HTTPServer`, prefer `http.Server`)
|
|
61
|
+
|
|
62
|
+
### Interfaces
|
|
63
|
+
|
|
64
|
+
- Name interfaces with -er suffix when possible (e.g., `Reader`, `Writer`, `Formatter`)
|
|
65
|
+
- Single-method interfaces should be named after the method (e.g., `Read` → `Reader`)
|
|
66
|
+
- Keep interfaces small and focused
|
|
67
|
+
|
|
68
|
+
### Constants
|
|
69
|
+
|
|
70
|
+
- Use MixedCaps for exported constants
|
|
71
|
+
- Use mixedCaps for unexported constants
|
|
72
|
+
- Group related constants using `const` blocks
|
|
73
|
+
- Consider using typed constants for better type safety
|
|
74
|
+
|
|
75
|
+
## Code Style and Formatting
|
|
76
|
+
|
|
77
|
+
### Formatting
|
|
78
|
+
|
|
79
|
+
- Always use `gofmt` to format code
|
|
80
|
+
- Use `goimports` to manage imports automatically
|
|
81
|
+
- Keep line length reasonable (no hard limit, but consider readability)
|
|
82
|
+
- Add blank lines to separate logical groups of code
|
|
83
|
+
|
|
84
|
+
### Comments
|
|
85
|
+
|
|
86
|
+
- Strive for self-documenting code; prefer clear variable names, function names, and code structure over comments
|
|
87
|
+
- Write comments only when necessary to explain complex logic, business rules, or non-obvious behavior
|
|
88
|
+
- Write comments in complete sentences in English by default
|
|
89
|
+
- Translate comments to other languages only upon specific user request
|
|
90
|
+
- Start sentences with the name of the thing being described
|
|
91
|
+
- Package comments should start with "Package [name]"
|
|
92
|
+
- Use line comments (`//`) for most comments
|
|
93
|
+
- Use block comments (`/* */`) sparingly, mainly for package documentation
|
|
94
|
+
- Document why, not what, unless the what is complex
|
|
95
|
+
- Avoid emoji in comments and code
|
|
96
|
+
|
|
97
|
+
### Error Handling
|
|
98
|
+
|
|
99
|
+
- Check errors immediately after the function call
|
|
100
|
+
- Don't ignore errors using `_` unless you have a good reason (document why)
|
|
101
|
+
- Wrap errors with context using `fmt.Errorf` with `%w` verb
|
|
102
|
+
- Create custom error types when you need to check for specific errors
|
|
103
|
+
- Place error returns as the last return value
|
|
104
|
+
- Name error variables `err`
|
|
105
|
+
- Keep error messages lowercase and don't end with punctuation
|
|
106
|
+
|
|
107
|
+
## Architecture and Project Structure
|
|
108
|
+
|
|
109
|
+
### Package Organization
|
|
110
|
+
|
|
111
|
+
- Follow standard Go project layout conventions
|
|
112
|
+
- Keep `main` packages in `cmd/` directory
|
|
113
|
+
- Put reusable packages in `pkg/` or `internal/`
|
|
114
|
+
- Use `internal/` for packages that shouldn't be imported by external projects
|
|
115
|
+
- Group related functionality into packages
|
|
116
|
+
- Avoid circular dependencies
|
|
117
|
+
|
|
118
|
+
### Dependency Management
|
|
119
|
+
|
|
120
|
+
- Use Go modules (`go.mod` and `go.sum`)
|
|
121
|
+
- Keep dependencies minimal
|
|
122
|
+
- Regularly update dependencies for security patches
|
|
123
|
+
- Use `go mod tidy` to clean up unused dependencies
|
|
124
|
+
- Vendor dependencies only when necessary
|
|
125
|
+
|
|
126
|
+
## Type Safety and Language Features
|
|
127
|
+
|
|
128
|
+
### Type Definitions
|
|
129
|
+
|
|
130
|
+
- Define types to add meaning and type safety
|
|
131
|
+
- Use struct tags for JSON, XML, database mappings
|
|
132
|
+
- Prefer explicit type conversions
|
|
133
|
+
- Use type assertions carefully and check the second return value
|
|
134
|
+
- Prefer generics over unconstrained types; when an unconstrained type is truly needed, use the predeclared alias `any` instead of `interface{}` (Go 1.18+)
|
|
135
|
+
|
|
136
|
+
### Pointers vs Values
|
|
137
|
+
|
|
138
|
+
- Use pointer receivers for large structs or when you need to modify the receiver
|
|
139
|
+
- Use value receivers for small structs and when immutability is desired
|
|
140
|
+
- Use pointer parameters when you need to modify the argument or for large structs
|
|
141
|
+
- Use value parameters for small structs and when you want to prevent modification
|
|
142
|
+
- Be consistent within a type's method set
|
|
143
|
+
- Consider the zero value when choosing pointer vs value receivers
|
|
144
|
+
|
|
145
|
+
### Interfaces and Composition
|
|
146
|
+
|
|
147
|
+
- Accept interfaces, return concrete types
|
|
148
|
+
- Keep interfaces small (1-3 methods is ideal)
|
|
149
|
+
- Use embedding for composition
|
|
150
|
+
- Define interfaces close to where they're used, not where they're implemented
|
|
151
|
+
- Don't export interfaces unless necessary
|
|
152
|
+
|
|
153
|
+
## Concurrency
|
|
154
|
+
|
|
155
|
+
### Goroutines
|
|
156
|
+
|
|
157
|
+
- Be cautious about creating goroutines in libraries; prefer letting the caller control concurrency
|
|
158
|
+
- If you must create goroutines in libraries, provide clear documentation and cleanup mechanisms
|
|
159
|
+
- Always know how a goroutine will exit
|
|
160
|
+
- Use `sync.WaitGroup` or channels to wait for goroutines
|
|
161
|
+
- Avoid goroutine leaks by ensuring cleanup
|
|
162
|
+
|
|
163
|
+
### Channels
|
|
164
|
+
|
|
165
|
+
- Use channels to communicate between goroutines
|
|
166
|
+
- Don't communicate by sharing memory; share memory by communicating
|
|
167
|
+
- Close channels from the sender side, not the receiver
|
|
168
|
+
- Use buffered channels when you know the capacity
|
|
169
|
+
- Use `select` for non-blocking operations
|
|
170
|
+
|
|
171
|
+
### Synchronization
|
|
172
|
+
|
|
173
|
+
- Use `sync.Mutex` for protecting shared state
|
|
174
|
+
- Keep critical sections small
|
|
175
|
+
- Use `sync.RWMutex` when you have many readers
|
|
176
|
+
- Choose between channels and mutexes based on the use case: use channels for communication, mutexes for protecting state
|
|
177
|
+
- Use `sync.Once` for one-time initialization
|
|
178
|
+
- WaitGroup usage by Go version:
|
|
179
|
+
- If `go >= 1.25` in `go.mod`, use the new `WaitGroup.Go` method ([documentation](https://pkg.go.dev/sync#WaitGroup)):
|
|
180
|
+
```go
|
|
181
|
+
var wg sync.WaitGroup
|
|
182
|
+
wg.Go(task1)
|
|
183
|
+
wg.Go(task2)
|
|
184
|
+
wg.Wait()
|
|
185
|
+
```
|
|
186
|
+
- If `go < 1.25`, use the classic `Add`/`Done` pattern
|
|
187
|
+
|
|
188
|
+
## Error Handling Patterns
|
|
189
|
+
|
|
190
|
+
### Creating Errors
|
|
191
|
+
|
|
192
|
+
- Use `errors.New` for simple static errors
|
|
193
|
+
- Use `fmt.Errorf` for dynamic errors
|
|
194
|
+
- Create custom error types for domain-specific errors
|
|
195
|
+
- Export error variables for sentinel errors
|
|
196
|
+
- Use `errors.Is` and `errors.As` for error checking
|
|
197
|
+
|
|
198
|
+
### Error Propagation
|
|
199
|
+
|
|
200
|
+
- Add context when propagating errors up the stack
|
|
201
|
+
- Don't log and return errors (choose one)
|
|
202
|
+
- Handle errors at the appropriate level
|
|
203
|
+
- Consider using structured errors for better debugging
|
|
204
|
+
|
|
205
|
+
## API Design
|
|
206
|
+
|
|
207
|
+
### HTTP Handlers
|
|
208
|
+
|
|
209
|
+
- Use `http.HandlerFunc` for simple handlers
|
|
210
|
+
- Implement `http.Handler` for handlers that need state
|
|
211
|
+
- Use middleware for cross-cutting concerns
|
|
212
|
+
- Set appropriate status codes and headers
|
|
213
|
+
- Handle errors gracefully and return appropriate error responses
|
|
214
|
+
- Router usage by Go version:
|
|
215
|
+
- If `go >= 1.22`, prefer the enhanced `net/http` `ServeMux` with pattern-based routing and method matching
|
|
216
|
+
- If `go < 1.22`, use the classic `ServeMux` and handle methods/paths manually (or use a third-party router when justified)
|
|
217
|
+
|
|
218
|
+
### JSON APIs
|
|
219
|
+
|
|
220
|
+
- Use struct tags to control JSON marshaling
|
|
221
|
+
- Validate input data
|
|
222
|
+
- Use pointers for optional fields
|
|
223
|
+
- Consider using `json.RawMessage` for delayed parsing
|
|
224
|
+
- Handle JSON errors appropriately
|
|
225
|
+
|
|
226
|
+
### HTTP Clients
|
|
227
|
+
|
|
228
|
+
- Keep the client struct focused on configuration and dependencies only (e.g., base URL, `*http.Client`, auth, default headers). It must not store per-request state
|
|
229
|
+
- Do not store or cache `*http.Request` inside the client struct, and do not persist request-specific state across calls; instead, construct a fresh request per method invocation
|
|
230
|
+
- Methods should accept `context.Context` and input parameters, assemble the `*http.Request` locally (or via a short-lived builder/helper created per call), then call `c.httpClient.Do(req)`
|
|
231
|
+
- If request-building logic is reused, factor it into unexported helper functions or a per-call builder type; never keep `http.Request` (URL params, body, headers) as fields on the long-lived client
|
|
232
|
+
- Ensure the underlying `*http.Client` is configured (timeouts, transport) and is safe for concurrent use; avoid mutating `Transport` after first use
|
|
233
|
+
- Always set headers on the request instance you’re sending, and close response bodies (`defer resp.Body.Close()`), handling errors appropriately
|
|
234
|
+
|
|
235
|
+
## Performance Optimization
|
|
236
|
+
|
|
237
|
+
### Memory Management
|
|
238
|
+
|
|
239
|
+
- Minimize allocations in hot paths
|
|
240
|
+
- Reuse objects when possible (consider `sync.Pool`)
|
|
241
|
+
- Use value receivers for small structs
|
|
242
|
+
- Preallocate slices when size is known
|
|
243
|
+
- Avoid unnecessary string conversions
|
|
244
|
+
|
|
245
|
+
### I/O: Readers and Buffers
|
|
246
|
+
|
|
247
|
+
- Most `io.Reader` streams are consumable once; reading advances state. Do not assume a reader can be re-read without special handling
|
|
248
|
+
- If you must read data multiple times, buffer it once and recreate readers on demand:
|
|
249
|
+
- Use `io.ReadAll` (or a limited read) to obtain `[]byte`, then create fresh readers via `bytes.NewReader(buf)` or `bytes.NewBuffer(buf)` for each reuse
|
|
250
|
+
- For strings, use `strings.NewReader(s)`; you can `Seek(0, io.SeekStart)` on `*bytes.Reader` to rewind
|
|
251
|
+
- For HTTP requests, do not reuse a consumed `req.Body`. Instead:
|
|
252
|
+
- Keep the original payload as `[]byte` and set `req.Body = io.NopCloser(bytes.NewReader(buf))` before each send
|
|
253
|
+
- Prefer configuring `req.GetBody` so the transport can recreate the body for redirects/retries: `req.GetBody = func() (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(buf)), nil }`
|
|
254
|
+
- To duplicate a stream while reading, use `io.TeeReader` (copy to a buffer while passing through) or write to multiple sinks with `io.MultiWriter`
|
|
255
|
+
- Reusing buffered readers: call `(*bufio.Reader).Reset(r)` to attach to a new underlying reader; do not expect it to “rewind” unless the source supports seeking
|
|
256
|
+
- For large payloads, avoid unbounded buffering; consider streaming, `io.LimitReader`, or on-disk temporary storage to control memory
|
|
257
|
+
|
|
258
|
+
- Use `io.Pipe` to stream without buffering the whole payload:
|
|
259
|
+
- Write to `*io.PipeWriter` in a separate goroutine while the reader consumes
|
|
260
|
+
- Always close the writer; use `CloseWithError(err)` on failures
|
|
261
|
+
- `io.Pipe` is for streaming, not rewinding or making readers reusable
|
|
262
|
+
|
|
263
|
+
- **Warning:** When using `io.Pipe` (especially with multipart writers), all writes must be performed in strict, sequential order. Do not write concurrently or out of order—multipart boundaries and chunk order must be preserved. Out-of-order or parallel writes can corrupt the stream and result in errors.
|
|
264
|
+
|
|
265
|
+
- Streaming multipart/form-data with `io.Pipe`:
|
|
266
|
+
- `pr, pw := io.Pipe()`; `mw := multipart.NewWriter(pw)`; use `pr` as the HTTP request body
|
|
267
|
+
- Set `Content-Type` to `mw.FormDataContentType()`
|
|
268
|
+
- In a goroutine: write all parts to `mw` in the correct order; on error `pw.CloseWithError(err)`; on success `mw.Close()` then `pw.Close()`
|
|
269
|
+
- Do not store request/in-flight form state on a long-lived client; build per call
|
|
270
|
+
- Streamed bodies are not rewindable; for retries/redirects, buffer small payloads or provide `GetBody`
|
|
271
|
+
|
|
272
|
+
### Profiling
|
|
273
|
+
|
|
274
|
+
- Use built-in profiling tools (`pprof`)
|
|
275
|
+
- Benchmark critical code paths
|
|
276
|
+
- Profile before optimizing
|
|
277
|
+
- Focus on algorithmic improvements first
|
|
278
|
+
- Consider using `testing.B` for benchmarks
|
|
279
|
+
|
|
280
|
+
## Testing
|
|
281
|
+
|
|
282
|
+
### Test Organization
|
|
283
|
+
|
|
284
|
+
- Keep tests in the same package (white-box testing)
|
|
285
|
+
- Use `_test` package suffix for black-box testing
|
|
286
|
+
- Name test files with `_test.go` suffix
|
|
287
|
+
- Place test files next to the code they test
|
|
288
|
+
|
|
289
|
+
### Writing Tests
|
|
290
|
+
|
|
291
|
+
- Use table-driven tests for multiple test cases
|
|
292
|
+
- Name tests descriptively using `Test_functionName_scenario`
|
|
293
|
+
- Use subtests with `t.Run` for better organization
|
|
294
|
+
- Test both success and error cases
|
|
295
|
+
- Consider using `testify` or similar libraries when they add value, but don't over-complicate simple tests
|
|
296
|
+
|
|
297
|
+
### Test Helpers
|
|
298
|
+
|
|
299
|
+
- Mark helper functions with `t.Helper()`
|
|
300
|
+
- Create test fixtures for complex setup
|
|
301
|
+
- Use `testing.TB` interface for functions used in tests and benchmarks
|
|
302
|
+
- Clean up resources using `t.Cleanup()`
|
|
303
|
+
|
|
304
|
+
## Security Best Practices
|
|
305
|
+
|
|
306
|
+
### Input Validation
|
|
307
|
+
|
|
308
|
+
- Validate all external input
|
|
309
|
+
- Use strong typing to prevent invalid states
|
|
310
|
+
- Sanitize data before using in SQL queries
|
|
311
|
+
- Be careful with file paths from user input
|
|
312
|
+
- Validate and escape data for different contexts (HTML, SQL, shell)
|
|
313
|
+
|
|
314
|
+
### Cryptography
|
|
315
|
+
|
|
316
|
+
- Use standard library crypto packages
|
|
317
|
+
- Don't implement your own cryptography
|
|
318
|
+
- Use crypto/rand for random number generation
|
|
319
|
+
- Store passwords using bcrypt, scrypt, or argon2 (consider golang.org/x/crypto for additional options)
|
|
320
|
+
- Use TLS for network communication
|
|
321
|
+
|
|
322
|
+
## Documentation
|
|
323
|
+
|
|
324
|
+
### Code Documentation
|
|
325
|
+
|
|
326
|
+
- Prioritize self-documenting code through clear naming and structure
|
|
327
|
+
- Document all exported symbols with clear, concise explanations
|
|
328
|
+
- Start documentation with the symbol name
|
|
329
|
+
- Write documentation in English by default
|
|
330
|
+
- Use examples in documentation when helpful
|
|
331
|
+
- Keep documentation close to code
|
|
332
|
+
- Update documentation when code changes
|
|
333
|
+
- Avoid emoji in documentation and comments
|
|
334
|
+
|
|
335
|
+
### README and Documentation Files
|
|
336
|
+
|
|
337
|
+
- Include clear setup instructions
|
|
338
|
+
- Document dependencies and requirements
|
|
339
|
+
- Provide usage examples
|
|
340
|
+
- Document configuration options
|
|
341
|
+
- Include troubleshooting section
|
|
342
|
+
|
|
343
|
+
## Tools and Development Workflow
|
|
344
|
+
|
|
345
|
+
### Essential Tools
|
|
346
|
+
|
|
347
|
+
- `go fmt`: Format code
|
|
348
|
+
- `go vet`: Find suspicious constructs
|
|
349
|
+
- `golangci-lint`: Additional linting (golint is deprecated)
|
|
350
|
+
- `go test`: Run tests
|
|
351
|
+
- `go mod`: Manage dependencies
|
|
352
|
+
- `go generate`: Code generation
|
|
353
|
+
|
|
354
|
+
### Development Practices
|
|
355
|
+
|
|
356
|
+
- Run tests before committing
|
|
357
|
+
- Use pre-commit hooks for formatting and linting
|
|
358
|
+
- Keep commits focused and atomic
|
|
359
|
+
- Write meaningful commit messages
|
|
360
|
+
- Review diffs before committing
|
|
361
|
+
|
|
362
|
+
## Common Pitfalls to Avoid
|
|
363
|
+
|
|
364
|
+
- Not checking errors
|
|
365
|
+
- Ignoring race conditions
|
|
366
|
+
- Creating goroutine leaks
|
|
367
|
+
- Not using defer for cleanup
|
|
368
|
+
- Modifying maps concurrently
|
|
369
|
+
- Not understanding nil interfaces vs nil pointers
|
|
370
|
+
- Forgetting to close resources (files, connections)
|
|
371
|
+
- Using global variables unnecessarily
|
|
372
|
+
- Over-using unconstrained types (e.g., `any`); prefer specific types or generic type parameters with constraints. If an unconstrained type is required, use `any` rather than `interface{}`
|
|
373
|
+
- Not considering the zero value of types
|
|
374
|
+
- **Creating duplicate `package` declarations** - this is a compile error; always check existing files before adding package declarations
|