skills/goframe-v2/SKILL.md
GoFrame v2 development skill. Use only when the target Go project uses or is explicitly adopting GoFrame v2: the nearest go.mod requires github.com/gogf/gf/v2, existing Go files import github.com/gogf/gf/v2 or any github.com/gogf/gf/v2/... component package, or the user asks to scaffold, migrate, or build with GoFrame. Trigger for GoFrame-backed Go work such as APIs/controllers/services, middleware, routing/config, ORM/DAO/DO/entity/database operations, gf CLI/codegen, HTTP/gRPC services, and microservice conventions. Do not trigger for generic Go projects without GoFrame evidence, frontend-only work, shell scripts, or unrelated infrastructure tasks.
npx skillsauth add gogf/skills goframe-v2Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
gf init to create project scaffolding. See Project Creation - init for details.logic/ directory for business logic. Implement business logic directly in the service/ directory.gerror component for all error handling to ensure complete stack traces for traceability.internal/model/do/), never g.Map or map[string]interface{}. DO struct fields are interface{}; unset fields remain nil and are automatically ignored by the ORM:
// Good - use DO object
dao.Users.Ctx(ctx).Where(cols.Id, id).Data(do.User{Uid: uid}).Update()
// Good - conditional fields, unset fields are nil and ignored
data := do.User{}
if password != "" { data.PasswordHash = hash }
if isAdmin != nil { data.IsAdmin = *isAdmin }
dao.Users.Ctx(ctx).Where(cols.Id, id).Data(data).Update()
// Good - explicitly set a column to NULL using gdb.Raw
dao.Instances.Ctx(ctx).Where(cols.Id, id).Data(do.Instance{IdleSince: gdb.Raw("NULL")}).Update()
// Bad - never use g.Map for database operations
dao.Users.Ctx(ctx).Data(g.Map{cols.Uid: uid}).Update()
var block to group them for better alignment and readability:
// Good - aligned and clean
var (
authSvc *auth.Service
bizCtxSvc *bizctx.Service
k8sSvc *svcK8s.Service
notebookSvc *notebook.Service
middlewareSvc *middleware.Service
)
// Avoid - scattered declarations
authSvc := auth.New()
bizCtxSvc := bizctx.New()
k8sSvc := svcK8s.New()
GoFrame provides automatic soft delete and time maintenance features. When a table contains created_at, updated_at, or deleted_at fields, the ORM handles these automatically.
| Field | Auto Behavior |
|-------|---------------|
| created_at | Auto-written on Insert/InsertAndGetId, never modified afterward |
| updated_at | Auto-written on Insert/Update/Save |
| deleted_at | Auto-written on Delete (soft delete), auto-filtered on queries |
1. NEVER manually set time fields - GoFrame handles these automatically:
// WRONG - redundant manual time setting
dao.User.Ctx(ctx).Data(do.User{
Name: "john",
CreatedAt: gtime.Now(), // REDUNDANT! Framework handles this
UpdatedAt: gtime.Now(), // REDUNDANT! Framework handles this
}).Insert()
// CORRECT - let framework handle time fields
dao.User.Ctx(ctx).Data(do.User{
Name: "john",
}).Insert()
2. NEVER manually add WhereNull(cols.DeletedAt) - GoFrame auto-adds soft delete filter:
// WRONG - redundant soft delete condition
dao.User.Ctx(ctx).
Where(do.User{Status: 1}).
WhereNull(cols.DeletedAt). // REDUNDANT! Framework auto-adds this
Scan(&list)
// CORRECT - framework auto-adds deleted_at IS NULL
dao.User.Ctx(ctx).
Where(do.User{Status: 1}).
Scan(&list)
3. Use Delete() for soft delete - Framework converts to UPDATE SET deleted_at = NOW():
// CORRECT - use Delete(), framework handles soft delete
dao.User.Ctx(ctx).Where(do.User{Id: id}).Delete()
// Actual SQL: UPDATE `sys_user` SET `deleted_at`=NOW() WHERE `id`=?
// WRONG - manual Update with deleted_at
dao.User.Ctx(ctx).
Where(do.User{Id: id}).
Data(do.User{DeletedAt: gtime.Now()}). // REDUNDANT!
Update()
The deleted_at field supports multiple types:
Time field names can be customized in config.yaml:
database:
default:
createdAt: "created_at" # Custom field name
updatedAt: "updated_at"
deletedAt: "deleted_at"
timeMaintainDisabled: false # Set true to disable this feature
Complete GoFrame development resources covering component design, usage, best practices, and considerations: GoFrame Documentation
Rich practical code examples covering HTTP services, gRPC services, and various project types: GoFrame Examples
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
A CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.