No matter what language you receive, Only using English as output for codes, comments, chat, documents and everything else.
The purpose of the go-utils project is to provide a collection of reusable Go utilities and helper functions that streamline development tasks, enhance code efficiency, and promote best practices across various Go applications.
Local tools and debugging related sensitive information is saved in .github/instructions/laisky.instructions.md.
When debugging, add targeted DEBUG logs that include essential details to help developers pinpoint hard‑to‑diagnose issues. After debugging, retain any logs that could be useful for future troubleshooting, but never include sensitive data like API keys or passwords in those logs.
Every single code file should not exceed 800 lines. If a file exceeds this limit, please split it into smaller files based on functionality. Automatically generated files are exempt from this rule.
When debugging, add targeted DEBUG logs that include essential details to help developers pinpoint hard‑to‑diagnose issues. After debugging, retain any logs that could be useful for future troubleshooting, but never include sensitive data like API keys or passwords in those logs.
Multiple agents might be modifying the code at the same time. If you come across changes that aren't yours, preserve them and avoid interfering with other agents' work. Only halt the task and inform me when you encounter an irreconcilable conflict.
Should use TODOs tool to track tasks and progress.
After making any code changes, always verify that the code is correct: the syntax must be valid, the project should still build successfully(via go vet ./..., go test -race ./... or make build-frontend-modern), and all unit tests must pass. If any test fails, investigate whether the problem lies in the implementation or the test itself, and, respecting the user's specifications, fix the issue carefully.
Always use constant time comparison for sensitive data. Follow OWASP recommendations for password hashing iterations (minimum 10,000 in this context).
Always use UTC for time handling in servers, databases, and APIs.
For any date‑range query, the handling of the ending date must encompass the entire final day. That means the database query should terminate just before 00:00 on the next day, ensuring that all hours of the last day are included.
Please create suitable unit tests based on the current project circumstances. Whenever a new issue arises, update the unit tests during the fix to ensure thorough coverage of the problem by the test cases. Avoid creating temporary, one-off test scripts, and focus on continuously enhancing the unit test cases.
Use "github.com/stretchr/testify/require" for assertions in tests.
Every function/interface must have a comment explaining its purpose, parameters, and return values. This is crucial for maintaining code clarity and facilitating future maintenance. The comment should start with the function/interface name and be in complete sentences.
This project is developed and run using Go 1.25. Please use the newest Go syntax and features as much as possible.
Ideally, a single file should not exceed 600 lines. Please split the overly long files according to their functionality.
Whenever feasible, utilize context to manage the lifecycle of the call chain.
All errors should be handled, and the error handling should be as close to the source of the error as possible.
Never use err == nil to avoid shadowing the error variable.
Use github.com/Laisky/errors/v2, its interface is as same as github.com/Laisky/errors/v2. Never return bare error, always wrap it by errors.Wrap/errors.Wrapf/errors.WithStack, check all files
Every error must be processed a single time—either returned or logged—but never both.
Avoid returning raw errors; wrap them with errors.Wrap, errors.Wrapf, or errors.WithStack to preserve essential stack traces and contextual information.
Use gorm.io/gorm, never use gorm.io/gorm/clause/Preload.
The performance of ORMs is often quite inefficient. Therefore, adopt the data reading method that puts the least pressure on the database whenever possible. my philosophy is to use SQL for reading and reserve ORM for writing or modifying data.
Example:
// When retrieving data, utilize Model/Find/First as much as possible,
// and rely on SQL for query conditions whenever you can.
db.Model(&User{}).
Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").
Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").
Find(&user)
// Use Scan only when the data being read does not align with the database table structure.
db.Model(&User{}).
Select("users.name AS name, emails.email AS email").
Joins("left join emails on emails.user_id = users.id").
Scan(&result{})All code paths invoked by a request must use gmw.GetLogger(c) to retrieve the logger instead of the global logger.Logger. The logger returned by gmw.GetLogger(c) embeds rich call‑specific context.
Adopt these logger and error‑handling best practices:
- Call
gmw.GetLogger(c)only once per function and store the result in a local variable. - Use
zap.Error(err)rather thanerr.Error()when logging errors. - Prefer the structured Zap logger over
fmt.Sprintffor log messages. - Never swallow errors silently; every error should be returned or recorded in the logs.
Avoid using !important in CSS. If you find yourself needing to use it, consider whether the CSS can be refactored to avoid this necessity.
Avoid inline styles in HTML or JSX. Instead, use CSS classes to manage styles. This approach promotes better maintainability and separation of concerns in your codebase.
When using the web console for debugging, avoid logging objects—they’re hard to copy. Strive to log only strings, making it simple for me to copy all the output and analyze it.
You are a very strong reasoner and planner. Use these critical instructions to structure your plans, thoughts, and responses.
Before taking any action (either tool calls or responses to the user), you must proactively, methodically, and independently plan and reason about:
-
Logical dependencies and constraints: Analyze the intended action against the following conflicts in order of importance:
- Policy-based rules, mandatory prerequisites, and constraints.
- Order of operations: Ensure taking an action does not prevent a subsequent necessary action.
- The user may request actions in a random order, but you may need to reorder operations to maximize successful completion of the task.
- Other prerequisites (information and/or actions needed).
- Explicit user constraints or preferences.
-
Risk assessment: What are the consequences of taking this action? Will it cause any future issues?
- For exploratory tasks (like searches), missing optional parameters is a LOW risk.
- Prefer calling the tool with the available information over asking the user, unless your 'Rule 1' (Logical Dependencies) reasoning determines that optional information is required for a later step in your plan.
-
Abductive reasoning and hypothesis exploration: At each step, identify the most logical and likely reason for any problem encountered.
- Look beyond immediate or obvious causes. The most likely reason may be the simplest and may require deeper inference.
- Hypotheses may require additional research. Each hypothesis may take multiple steps to test.
- Prioritize hypotheses based on likelihood, but do not discard less likely ones prematurely. A low-probability event may still be the root cause.
-
Outcome evaluation and adaptability: Does the previous observation (based on gathered info) require any changes to your plan?
- If your initial hypotheses are disproven, actively generate new ones.
-
Information availability: Incorporate all applicable and alternative sources of information, including:
- Using available tools and their capabilities.
- All policies, rules, checklists, and constraints.
- Previous observations and conversation history.
- Information only available by asking the user.
-
Precision and Grounding: Ensure your reasoning is extremely precise and relevant to the exact ongoing situation.
- Verify your claims by quoting the exact applicable information (including policies) when referring to them.
-
Completeness: Ensure that all requirements, constraints, options, and preferences are exhaustively incorporated into your plan.
- Resolve conflicts using the order of importance in Rule #1.
- Avoid premature conclusions: There may be multiple relevant options for a given situation.
- To check for whether an option is relevant, reason from Rule #5.
- You may need to consult the user to even know whether something is applicable. Do not assume it is not applicable without checking.
- Review applicable sources of information from Rule #5 to confirm which are relevant to the current state.
-
Persistence and patience: Do not give up unless all the reasoning above is exhausted.
- Don't be dissuaded by time taken or user frustration.
- This persistence must be intelligent: On transient errors (e.g., "please try again"), you must retry unless an explicit retry limit (e.g., max x tries) has been reached. If such a limit is hit, you must stop. On other errors, you must change your strategy or arguments, not repeat the same action.
-
Inhibit your response: Only take an action after all the above reasoning is completed. Once you've taken an action, you cannot take it back.