gorig-cli 1.0.23 → 1.0.25
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/README.md +112 -22
- package/commands/create.js +267 -112
- package/commands/doc.js +21 -8
- package/commands/init.js +316 -255
- package/commands/skill.js +55 -17
- package/package.json +1 -1
- package/templates/config.go.ejs +6 -5
- package/templates/config.yaml.ejs +3 -38
- package/templates/controller.go.ejs +11 -42
- package/templates/crud.controller.go.ejs +71 -0
- package/templates/crud.doc.md.ejs +60 -0
- package/templates/crud.dto.go.ejs +103 -0
- package/templates/crud.integration.init_test.go.ejs +17 -0
- package/templates/crud.integration_test.go.ejs +66 -0
- package/templates/crud.model.go.ejs +25 -0
- package/templates/crud.module.README.md.ejs +70 -0
- package/templates/crud.mongo.config.yaml.ejs +19 -0
- package/templates/crud.mysql.config.yaml.ejs +14 -0
- package/templates/crud.router.go.ejs +18 -0
- package/templates/crud.service.go.ejs +179 -0
- package/templates/crud.test.go.ejs +52 -0
- package/templates/dto.go.ejs +16 -0
- package/templates/gitignore.ejs +18 -49
- package/templates/hello.controller.go.ejs +19 -0
- package/templates/hello.router.go.ejs +12 -0
- package/templates/hello.service.go.ejs +31 -0
- package/templates/hello.test.go.ejs +34 -0
- package/templates/init.go.ejs +1 -27
- package/templates/main.go.ejs +2 -5
- package/templates/model.go.ejs +3 -4
- package/templates/project.README.md.ejs +35 -0
- package/templates/router.go.ejs +4 -8
- package/templates/service.go.ejs +25 -77
- package/templates/skills/gorig-backend/SKILL.md +89 -0
- package/templates/skills/gorig-backend/agents/openai.yaml +4 -0
- package/templates/skills/gorig-backend/assets/api-doc-template.md +59 -0
- package/templates/skills/gorig-backend/assets/gorig.gitignore +65 -0
- package/templates/skills/gorig-backend/assets/module-readme-template.md +58 -0
- package/templates/skills/gorig-backend/references/advanced-data-access.md +275 -0
- package/templates/skills/gorig-backend/references/auth-security.md +194 -0
- package/templates/skills/gorig-backend/references/business-scenarios.md +155 -0
- package/templates/skills/gorig-backend/references/cache.md +301 -0
- package/templates/skills/gorig-backend/references/capability-matrix.md +37 -0
- package/templates/skills/gorig-backend/references/configuration.md +48 -0
- package/templates/skills/gorig-backend/references/framework-api.md +190 -0
- package/templates/skills/gorig-backend/references/messaging.md +143 -0
- package/templates/skills/gorig-backend/references/onboarding-files.md +46 -0
- package/templates/skills/gorig-backend/references/outbound-http.md +162 -0
- package/templates/skills/gorig-backend/references/persistent-crud.md +332 -0
- package/templates/skills/gorig-backend/references/project-bootstrap.md +128 -0
- package/templates/skills/gorig-backend/references/scheduled-tasks.md +231 -0
- package/templates/skills/gorig-backend/references/service-lifecycle.md +51 -0
- package/templates/skills/gorig-backend/references/source-map.md +43 -0
- package/templates/skills/gorig-backend/references/source-policy.md +58 -0
- package/templates/skills/gorig-backend/references/sse.md +121 -0
- package/templates/skills/gorig-backend/references/testing.md +171 -0
- package/templates/skills/gorig-backend/scripts/check-source-links.sh +48 -0
- package/templates/skills/gorig-backend/scripts/detect-gorig-context.sh +67 -0
- package/templates/skills/gorig-backend/scripts/verify-basic-project.sh +108 -0
- package/npm_publish copy.sh +0 -65
- package/templates/internal.go.ejs +0 -49
- package/templates/req.go.ejs +0 -8
- package/templates/resp.go.ejs +0 -8
- package/templates/service.pub.go.ejs +0 -22
- package/templates/skills/claude/gorig-backend/SKILL.md +0 -189
- package/templates/skills/claude/gorig-backend/assets/api-doc-template.md +0 -50
- package/templates/skills/claude/gorig-backend/assets/module-readme-template.md +0 -46
- package/templates/skills/claude/gorig-backend/references/onboarding-files.md +0 -38
- package/templates/skills/codex/gorig-backend/SKILL.md +0 -189
- package/templates/skills/codex/gorig-backend/agents/openai.yaml +0 -4
- package/templates/skills/codex/gorig-backend/assets/api-doc-template.md +0 -50
- package/templates/skills/codex/gorig-backend/assets/module-readme-template.md +0 -46
- package/templates/skills/codex/gorig-backend/references/onboarding-files.md +0 -38
package/npm_publish copy.sh
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# 确保脚本有执行权限
|
|
4
|
-
# chmod +x npm_publish.sh
|
|
5
|
-
|
|
6
|
-
# 设置官方源地址和原仓库源地址
|
|
7
|
-
NPM_OFFICIAL_REGISTRY="https://registry.npmjs.org/"
|
|
8
|
-
CUSTOM_REGISTRY=$(npm config get registry)
|
|
9
|
-
|
|
10
|
-
# 检查原始仓库源是否为官方源
|
|
11
|
-
if [ "$CUSTOM_REGISTRY" = "$NPM_OFFICIAL_REGISTRY" ]; then
|
|
12
|
-
echo "当前已经是官方源,不需要切换。"
|
|
13
|
-
else
|
|
14
|
-
echo "当前仓库源为: $CUSTOM_REGISTRY"
|
|
15
|
-
echo "正在切换为官方源: $NPM_OFFICIAL_REGISTRY"
|
|
16
|
-
npm config set registry $NPM_OFFICIAL_REGISTRY
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
# 验证是否成功切换到官方源
|
|
20
|
-
CURRENT_REGISTRY=$(npm config get registry)
|
|
21
|
-
if [ "$CURRENT_REGISTRY" = "$NPM_OFFICIAL_REGISTRY" ]; then
|
|
22
|
-
echo "仓库源已成功切换为官方源。"
|
|
23
|
-
else
|
|
24
|
-
echo "切换仓库源失败,请检查。"
|
|
25
|
-
exit 1
|
|
26
|
-
fi
|
|
27
|
-
|
|
28
|
-
# 登录 npm 账户
|
|
29
|
-
echo "开始登录 npm,请根据提示输入用户名、密码和邮箱地址。"
|
|
30
|
-
npm login
|
|
31
|
-
if [ $? -ne 0 ]; then
|
|
32
|
-
echo "npm 登录失败,请检查用户名、密码和邮箱是否正确。"
|
|
33
|
-
exit 1
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
# 执行 yarn publish 或 npm publish
|
|
37
|
-
echo "请选择使用 yarn 还是 npm 发布包(输入 y 表示使用 yarn,输入 n 表示使用 npm):"
|
|
38
|
-
read -p "[y/n]: " CHOICE
|
|
39
|
-
|
|
40
|
-
if [ "$CHOICE" = "y" ]; then
|
|
41
|
-
yarn publish
|
|
42
|
-
elif [ "$CHOICE" = "n" ]; then
|
|
43
|
-
npm publish
|
|
44
|
-
else
|
|
45
|
-
echo "无效输入,请重新运行脚本并选择 y 或 n。"
|
|
46
|
-
exit 1
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
if [ $? -ne 0 ]; then
|
|
50
|
-
echo "发布失败,请检查日志。"
|
|
51
|
-
exit 1
|
|
52
|
-
else
|
|
53
|
-
echo "发布成功!"
|
|
54
|
-
fi
|
|
55
|
-
|
|
56
|
-
# 恢复原始仓库源
|
|
57
|
-
if [ "$CUSTOM_REGISTRY" != "$NPM_OFFICIAL_REGISTRY" ]; then
|
|
58
|
-
echo "正在恢复原始仓库源: $CUSTOM_REGISTRY"
|
|
59
|
-
npm config set registry $CUSTOM_REGISTRY
|
|
60
|
-
echo "仓库源已恢复为: $(npm config get registry)"
|
|
61
|
-
else
|
|
62
|
-
echo "仓库源保持为官方源,无需恢复。"
|
|
63
|
-
fi
|
|
64
|
-
|
|
65
|
-
echo "脚本执行完成。"
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
package internal
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"github.com/jom-io/gorig/domainx"
|
|
5
|
-
"github.com/jom-io/gorig/global/variable"
|
|
6
|
-
"<%= projectName %>/domain/<%= moduleName %>/api/req"
|
|
7
|
-
"<%= projectName %>/domain/<%= moduleName %>/model"
|
|
8
|
-
"<%= projectName %>/global"
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
func <%= ModuleName %>() *<%= ModuleName %>M {
|
|
12
|
-
return &<%= ModuleName %>M{Complex: domainx.UseComplex[model.<%= ModuleName %>D](domainx.Mysql, global.DBDef, "<%= moduleName %>")}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
type <%= ModuleName %>M struct {
|
|
16
|
-
*domainx.Complex[model.<%= ModuleName %>D]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
func (u *<%= ModuleName %>M) TableName() string {
|
|
20
|
-
return variable.TBPrefix +"<%= moduleName %>"
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
func init() {
|
|
24
|
-
domainx.AutoMigrate(func() (value domainx.ConTable) {
|
|
25
|
-
return <%= ModuleName %>()
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
func (u *<%= ModuleName %>M) ParseReq(req *req.<%= ModuleName %>Req) {
|
|
30
|
-
u.Data = &req.<%= ModuleName %>D
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
func (u *<%= ModuleName %>M) ToResp() *req.<%= ModuleName %>Resp {
|
|
34
|
-
if u.Data == nil {
|
|
35
|
-
return nil
|
|
36
|
-
}
|
|
37
|
-
return &req.<%= ModuleName %>Resp{
|
|
38
|
-
ID: u.ID,
|
|
39
|
-
<%= ModuleName %>D: *u.Data,
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
func (u *<%= ModuleName %>M) ToRespList(list *[]<%= ModuleName %>M) []*req.<%= ModuleName %>Resp {
|
|
44
|
-
respList := make([]*req.<%= ModuleName %>Resp, 0)
|
|
45
|
-
for _, v := range *list {
|
|
46
|
-
respList = append(respList, v.ToResp())
|
|
47
|
-
}
|
|
48
|
-
return respList
|
|
49
|
-
}
|
package/templates/req.go.ejs
DELETED
package/templates/resp.go.ejs
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
package <%= moduleName %>
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"github.com/gin-gonic/gin"
|
|
5
|
-
"github.com/jom-io/gorig/apix/load"
|
|
6
|
-
"github.com/jom-io/gorig/utils/errors"
|
|
7
|
-
"<%= projectName %>/domain/<%= moduleName %>/api/req"
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
var GService <%= moduleName %>Service
|
|
11
|
-
|
|
12
|
-
func setService(s <%= moduleName %>Service) {
|
|
13
|
-
GService = s
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type <%= moduleName %>Service interface {
|
|
17
|
-
Save<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>(ctx *gin.Context, req *req.<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>Req) *errors.Error
|
|
18
|
-
Page<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>(ctx *gin.Context, pageReq *load.Page, filter *req.<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>Req) (*load.PageResp, *errors.Error)
|
|
19
|
-
List<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>(ctx *gin.Context, filter *req.<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>Req) ([]*req.<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>Resp, *errors.Error)
|
|
20
|
-
Get<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>(ctx *gin.Context, id int64) (*req.<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>Resp, *errors.Error)
|
|
21
|
-
Delete<%= moduleName.charAt(0).toUpperCase() + moduleName.slice(1) %>(ctx *gin.Context, id int64) *errors.Error
|
|
22
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gorig-backend
|
|
3
|
-
description: Senior Go backend development expert for the gorig framework. Use when tasks involve implementing or reviewing gorig services, routers, controllers, services, models, domain modules, dx-based data access, API contract changes, test additions, or module documentation updates. Apply this skill when strict adherence to local gorig/news code patterns and real API behavior is required.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Gorig Backend
|
|
7
|
-
|
|
8
|
-
Implement backend work in gorig with strict framework conventions, deterministic workflow, and mandatory confirmation before coding.
|
|
9
|
-
|
|
10
|
-
## Load Context First
|
|
11
|
-
Read `references/onboarding-files.md`.
|
|
12
|
-
Build a concrete mental model from local code before proposing changes.
|
|
13
|
-
Treat code behavior as the source of truth for all framework APIs and helper methods.
|
|
14
|
-
State uncertainty explicitly and ask focused questions instead of guessing.
|
|
15
|
-
|
|
16
|
-
## Confirm Change Plan Before Coding
|
|
17
|
-
Provide a concise plan and wait for explicit user confirmation before editing code.
|
|
18
|
-
Include:
|
|
19
|
-
- Business objective and boundary.
|
|
20
|
-
- Data structures and persistence impact.
|
|
21
|
-
- Route list with request/response and error code shape.
|
|
22
|
-
- File-level change list in `Router -> Controller -> Service -> Model/Domainx`.
|
|
23
|
-
- Test and documentation update plan.
|
|
24
|
-
|
|
25
|
-
Do not start implementation until confirmation is received.
|
|
26
|
-
|
|
27
|
-
## Implement With Framework Rules
|
|
28
|
-
Follow these hard constraints:
|
|
29
|
-
- Register services with `serv.RegisterService`; start with `bootstrap.StartUp()`.
|
|
30
|
-
- Register routes with `httpx.RegisterRouter`; reuse existing `httpx` middleware.
|
|
31
|
-
- Add `defer apix.HandlePanic(ctx)` in controllers.
|
|
32
|
-
- Parse request params with `apix.BindParams` or `apix.GetParam*`.
|
|
33
|
-
- Return responses with `apix.HandleData`.
|
|
34
|
-
- Keep business logic in service layer.
|
|
35
|
-
- Use `utils/errors` for errors.
|
|
36
|
-
- Use `utils/logger` or global logger helpers for logging.
|
|
37
|
-
- Do not use `fmt.Println` for runtime logging.
|
|
38
|
-
- Prefer `domainx/dx` APIs for DB operations; align usage with `test/dx_test.go`.
|
|
39
|
-
- Keep names short and clear; avoid long camel-case identifiers.
|
|
40
|
-
- Use snake_case for storage fields and CamelCase for model fields.
|
|
41
|
-
- Keep module layout under `domain/<module>/{router.go, controller.go, service.go, model/*.go}`.
|
|
42
|
-
- Put shared logic in `domain/common`.
|
|
43
|
-
- When a route should bypass the built-in 429 debounce middleware, add it in `router.go` with `httpx.DebouceAw(...)` before `httpx.RegisterRouter(...)`. Example: `httpx.DebouceAw("/api/catalog/markets", "/api/catalog/agents")`.
|
|
44
|
-
|
|
45
|
-
## Data Access Patterns
|
|
46
|
-
|
|
47
|
-
### Model layer - minimal structure
|
|
48
|
-
The model `D` struct only needs fields and `DConfig()`. Do NOT add `M` type alias or `NewM()` factory:
|
|
49
|
-
```go
|
|
50
|
-
// CORRECT
|
|
51
|
-
type D struct {
|
|
52
|
-
AgentID string `bson:"agent_id" json:"agent_id"`
|
|
53
|
-
// ...
|
|
54
|
-
}
|
|
55
|
-
func (d *D) DConfig() (domainx.ConType, string, string) {
|
|
56
|
-
return domainx.Mongo, global.QuantSageDB, Table
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// WRONG - do not add these
|
|
60
|
-
type M = domainx.Complex[D]
|
|
61
|
-
func NewM() *M { return domainx.UseComplex[D](...) }
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Index registration - always in service.go init()
|
|
65
|
-
Indexes are registered in `service.go` via `domainx.AutoMigrate`, never in the model file.
|
|
66
|
-
Fields are automatically prefixed with `data.` by the framework - pass bare field names:
|
|
67
|
-
```go
|
|
68
|
-
func init() {
|
|
69
|
-
domainx.AutoMigrate(
|
|
70
|
-
func() domainx.ConTable { return domainx.UseComplex[model.D](domainx.Mongo, global.DB, model.Table) },
|
|
71
|
-
domainx.CtIdx(domainx.Idx, "field_a", "field_b", "field_c"), // compound index
|
|
72
|
-
domainx.CtIdx(domainx.Unique, "unique_field"), // unique index
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### dx query API
|
|
78
|
-
```go
|
|
79
|
-
// Find multiple records
|
|
80
|
-
result, err := dx.On[model.D](ctx).
|
|
81
|
-
Eq("agent_id", agentID).
|
|
82
|
-
Gte("date", startDate).
|
|
83
|
-
Sort("id", true). // true=desc, false=asc
|
|
84
|
-
Find() // returns domainx.ComplexList[D] = []*domainx.Complex[D]
|
|
85
|
-
if err != nil { return nil, err }
|
|
86
|
-
for i := range result {
|
|
87
|
-
if result[i] != nil && result[i].Data != nil {
|
|
88
|
-
// use result[i].Data
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Get single record
|
|
93
|
-
item, err := dx.On[model.D](ctx).Eq("agent_id", agentID).Sort("id", true).Get()
|
|
94
|
-
|
|
95
|
-
// Save (create or update)
|
|
96
|
-
_, err := dx.On[model.D](ctx, &d).Save()
|
|
97
|
-
|
|
98
|
-
// Update single field
|
|
99
|
-
err := dx.On[model.D](ctx).WithID(id).Update("field", value)
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Execution Strategy
|
|
103
|
-
|
|
104
|
-
For small changes (< ~20 lines, 1-2 files): implement directly.
|
|
105
|
-
|
|
106
|
-
For larger or pattern-repeatable changes (3+ files, bulk updates): delegate only when it helps the agent move work in parallel.
|
|
107
|
-
- Keep the critical path local when the next step depends on the result.
|
|
108
|
-
- Give delegated workers disjoint file ownership and keep `gorig-backend` conventions in scope.
|
|
109
|
-
- Verify with `go build ./...` and `go test ./...` after delegated work lands.
|
|
110
|
-
|
|
111
|
-
## Maintain Documentation
|
|
112
|
-
When API changes exist, create or update `doc/<module>.md` using `assets/api-doc-template.md`.
|
|
113
|
-
When module behavior changes, update `domain/<module>/README.md` using `assets/module-readme-template.md`.
|
|
114
|
-
|
|
115
|
-
## Go Test Convention
|
|
116
|
-
|
|
117
|
-
**All tests live in `go/test/`, `package test`. Never place test files inside domain packages.**
|
|
118
|
-
|
|
119
|
-
```text
|
|
120
|
-
go/test/
|
|
121
|
-
|-- init.go <- Shared MongoDB init - DO NOT modify
|
|
122
|
-
|-- _bin/local.yaml <- Test DB config - DO NOT modify
|
|
123
|
-
`-- {feature}_test.go <- Add new test files here
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
`init.go` starts MongoDB before any test runs. Tests that bypass this package lose the DB connection.
|
|
127
|
-
|
|
128
|
-
**New test file boilerplate:**
|
|
129
|
-
|
|
130
|
-
```go
|
|
131
|
-
package test
|
|
132
|
-
|
|
133
|
-
import (
|
|
134
|
-
"testing"
|
|
135
|
-
|
|
136
|
-
"quantsage/domain/{module}" // import target domain
|
|
137
|
-
{module}model "quantsage/domain/{module}/model" // if model types needed
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
func TestXxx_场景描述(t *testing.T) {
|
|
141
|
-
// arrange
|
|
142
|
-
input := ...
|
|
143
|
-
|
|
144
|
-
// act - only exported functions are accessible from package test
|
|
145
|
-
got := {module}.ExportedFunction(input)
|
|
146
|
-
|
|
147
|
-
// assert
|
|
148
|
-
if got != want {
|
|
149
|
-
t.Fatalf("ExportedFunction() = %v, want %v", got, want)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
**Rules:**
|
|
155
|
-
- Functions under test must be **exported** (capitalized) - `package test` cannot access unexported symbols.
|
|
156
|
-
- Use standard `testing` only. No testify or other assertion libraries.
|
|
157
|
-
- Use `t.Fatalf` / `t.Errorf` for assertions.
|
|
158
|
-
- Hardcode test data inline; do not read external files.
|
|
159
|
-
|
|
160
|
-
**Run commands:**
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
cd go
|
|
164
|
-
go test ./test/... -v # all tests
|
|
165
|
-
go test ./test/... -run TestXxx -v # single test
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## Validate and Deliver
|
|
169
|
-
Run `go build ./... && go test ./test/... -v` after every change.
|
|
170
|
-
If tests cannot run, explain the exact blocker and provide a minimal verification plan.
|
|
171
|
-
Deliver results in concise engineering format:
|
|
172
|
-
- Change summary.
|
|
173
|
-
- Key file paths.
|
|
174
|
-
- Test status and suggestions.
|
|
175
|
-
- Unknowns plus minimal assumptions.
|
|
176
|
-
|
|
177
|
-
## Provide Database Recommendation
|
|
178
|
-
When asked to choose storage, recommend based on:
|
|
179
|
-
- Existing dependencies and `dx` compatibility.
|
|
180
|
-
- Read/write pattern and query complexity.
|
|
181
|
-
- Transaction consistency requirements.
|
|
182
|
-
- Operational cost and team familiarity.
|
|
183
|
-
|
|
184
|
-
Present recommendation with clear rationale and trade-offs.
|
|
185
|
-
|
|
186
|
-
## Resources
|
|
187
|
-
- `references/onboarding-files.md`: Required code-reading checklist for gorig and news.
|
|
188
|
-
- `assets/api-doc-template.md`: API documentation template.
|
|
189
|
-
- `assets/module-readme-template.md`: Module README template.
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# <module> API 文档
|
|
2
|
-
|
|
3
|
-
## 1. 模块说明
|
|
4
|
-
- 模块名:
|
|
5
|
-
- 业务目标:
|
|
6
|
-
- 依赖服务/存储:
|
|
7
|
-
|
|
8
|
-
## 2. 接口清单
|
|
9
|
-
| 名称 | 方法 | 路径 | 鉴权 | 说明 |
|
|
10
|
-
| --- | --- | --- | --- | --- |
|
|
11
|
-
| | | | | |
|
|
12
|
-
|
|
13
|
-
## 3. 接口详情
|
|
14
|
-
|
|
15
|
-
### 3.1 <接口名>
|
|
16
|
-
- 方法与路径:
|
|
17
|
-
- Controller:
|
|
18
|
-
- Service:
|
|
19
|
-
- 说明:
|
|
20
|
-
|
|
21
|
-
#### 请求参数
|
|
22
|
-
| 字段 | 类型 | 必填 | 说明 |
|
|
23
|
-
| --- | --- | --- | --- |
|
|
24
|
-
| | | | |
|
|
25
|
-
|
|
26
|
-
#### 响应示例
|
|
27
|
-
```json
|
|
28
|
-
{
|
|
29
|
-
"code": 0,
|
|
30
|
-
"msg": "ok",
|
|
31
|
-
"data": {}
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
#### 错误码
|
|
36
|
-
| code | 含义 | 触发场景 |
|
|
37
|
-
| --- | --- | --- |
|
|
38
|
-
| | | |
|
|
39
|
-
|
|
40
|
-
## 4. 调用样例
|
|
41
|
-
```bash
|
|
42
|
-
curl -X POST 'http://<host>/<path>' \
|
|
43
|
-
-H 'Content-Type: application/json' \
|
|
44
|
-
-d '{}'
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## 5. 变更记录
|
|
48
|
-
| 日期 | 变更人 | 说明 |
|
|
49
|
-
| --- | --- | --- |
|
|
50
|
-
| | | |
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# <module> 模块说明
|
|
2
|
-
|
|
3
|
-
## 1. 模块职责
|
|
4
|
-
- 目标:
|
|
5
|
-
- 边界:
|
|
6
|
-
- 非目标:
|
|
7
|
-
|
|
8
|
-
## 2. 目录结构
|
|
9
|
-
```text
|
|
10
|
-
domain/<module>/
|
|
11
|
-
├── router.go
|
|
12
|
-
├── controller.go
|
|
13
|
-
├── service.go
|
|
14
|
-
└── model/
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## 3. 请求处理流程
|
|
18
|
-
1. Router 注册入口与中间件。
|
|
19
|
-
2. Controller 参数处理、panic 保护、返回封装。
|
|
20
|
-
3. Service 业务逻辑与错误处理。
|
|
21
|
-
4. Model 或 dx 数据访问。
|
|
22
|
-
|
|
23
|
-
## 4. 数据模型
|
|
24
|
-
| 结构体 | 说明 | 关键字段 |
|
|
25
|
-
| --- | --- | --- |
|
|
26
|
-
| | | |
|
|
27
|
-
|
|
28
|
-
## 5. 对外接口
|
|
29
|
-
| 名称 | 方法 | 路径 | 说明 |
|
|
30
|
-
| --- | --- | --- | --- |
|
|
31
|
-
| | | | |
|
|
32
|
-
|
|
33
|
-
## 6. 错误与日志
|
|
34
|
-
- 错误定义位置:
|
|
35
|
-
- 常见错误码:
|
|
36
|
-
- 日志关键字段:
|
|
37
|
-
|
|
38
|
-
## 7. 测试与验证
|
|
39
|
-
- 单测:
|
|
40
|
-
- 集成测试:
|
|
41
|
-
- 手工验证步骤:
|
|
42
|
-
|
|
43
|
-
## 8. 维护约定
|
|
44
|
-
- 命名:
|
|
45
|
-
- 兼容性:
|
|
46
|
-
- 文档更新规则:
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Onboarding File Checklist
|
|
2
|
-
|
|
3
|
-
Read these files before implementation.
|
|
4
|
-
|
|
5
|
-
## gorig (target project)
|
|
6
|
-
- `AGENTS.md`
|
|
7
|
-
- `README.md`
|
|
8
|
-
- `bootstrap/startup.go`
|
|
9
|
-
- `httpx/serv.go`
|
|
10
|
-
- `httpx/tool.go`
|
|
11
|
-
- `apix/handle.go`
|
|
12
|
-
- `apix/params.go`
|
|
13
|
-
- `domainx/*`
|
|
14
|
-
- `domainx/dx/*`
|
|
15
|
-
- `serv/serv.go`
|
|
16
|
-
- `utils/errors/*`
|
|
17
|
-
- `utils/logger/*`
|
|
18
|
-
- `test/dx_test.go`
|
|
19
|
-
|
|
20
|
-
## news (reference project, do not modify)
|
|
21
|
-
- `_cmd/api/main.go`
|
|
22
|
-
- `domain/init.go`
|
|
23
|
-
- `domain/**/router.go`
|
|
24
|
-
- `domain/**/controller.go`
|
|
25
|
-
- `domain/**/service.go`
|
|
26
|
-
- `domain/**/model/*.go`
|
|
27
|
-
- `test/*`
|
|
28
|
-
|
|
29
|
-
## Working Paths
|
|
30
|
-
- Target to modify: `/Users/doz/Desktop/project/open/gorig`
|
|
31
|
-
- Reference only: `/Users/doz/Desktop/project/personal/news`
|
|
32
|
-
|
|
33
|
-
## Reading Strategy
|
|
34
|
-
1. Trace startup and service registration.
|
|
35
|
-
2. Trace a complete request path: router -> controller -> service -> model/dx.
|
|
36
|
-
3. Confirm panic handling, param binding, and response helpers in real code.
|
|
37
|
-
4. Confirm error and logger usage from existing modules.
|
|
38
|
-
5. Reuse existing patterns before introducing new abstractions.
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gorig-backend
|
|
3
|
-
description: Senior Go backend development expert for the gorig framework. Use when tasks involve implementing or reviewing gorig services, routers, controllers, services, models, domain modules, dx-based data access, API contract changes, test additions, or module documentation updates. Apply this skill when strict adherence to local gorig/news code patterns and real API behavior is required.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Gorig Backend
|
|
7
|
-
|
|
8
|
-
Implement backend work in gorig with strict framework conventions, deterministic workflow, and mandatory confirmation before coding.
|
|
9
|
-
|
|
10
|
-
## Load Context First
|
|
11
|
-
Read `~/.codex/skills/gorig-backend/references/onboarding-files.md`.
|
|
12
|
-
Build a concrete mental model from local code before proposing changes.
|
|
13
|
-
Treat code behavior as the source of truth for all framework APIs and helper methods.
|
|
14
|
-
State uncertainty explicitly and ask focused questions instead of guessing.
|
|
15
|
-
|
|
16
|
-
## Confirm Change Plan Before Coding
|
|
17
|
-
Provide a concise plan and wait for explicit user confirmation before editing code.
|
|
18
|
-
Include:
|
|
19
|
-
- Business objective and boundary.
|
|
20
|
-
- Data structures and persistence impact.
|
|
21
|
-
- Route list with request/response and error code shape.
|
|
22
|
-
- File-level change list in `Router -> Controller -> Service -> Model/Domainx`.
|
|
23
|
-
- Test and documentation update plan.
|
|
24
|
-
|
|
25
|
-
Do not start implementation until confirmation is received.
|
|
26
|
-
|
|
27
|
-
## Implement With Framework Rules
|
|
28
|
-
Follow these hard constraints:
|
|
29
|
-
- Register services with `serv.RegisterService`; start with `bootstrap.StartUp()`.
|
|
30
|
-
- Register routes with `httpx.RegisterRouter`; reuse existing `httpx` middleware.
|
|
31
|
-
- Add `defer apix.HandlePanic(ctx)` in controllers.
|
|
32
|
-
- Parse request params with `apix.BindParams` or `apix.GetParam*`.
|
|
33
|
-
- Return responses with `apix.HandleData`.
|
|
34
|
-
- Keep business logic in service layer.
|
|
35
|
-
- Use `utils/errors` for errors.
|
|
36
|
-
- Use `utils/logger` or global logger helpers for logging.
|
|
37
|
-
- Do not use `fmt.Println` for runtime logging.
|
|
38
|
-
- Prefer `domainx/dx` APIs for DB operations; align usage with `test/dx_test.go`.
|
|
39
|
-
- Keep names short and clear; avoid long camel-case identifiers.
|
|
40
|
-
- Use snake_case for storage fields and CamelCase for model fields.
|
|
41
|
-
- Keep module layout under `domain/<module>/{router.go, controller.go, service.go, model/*.go}`.
|
|
42
|
-
- Put shared logic in `domain/common`.
|
|
43
|
-
- When a route should bypass the built-in 429 debounce middleware, add it in `router.go` with `httpx.DebouceAw(...)` before `httpx.RegisterRouter(...)`. Example: `httpx.DebouceAw("/api/catalog/markets", "/api/catalog/agents")`.
|
|
44
|
-
|
|
45
|
-
## Data Access Patterns
|
|
46
|
-
|
|
47
|
-
### Model layer - minimal structure
|
|
48
|
-
The model `D` struct only needs fields and `DConfig()`. Do NOT add `M` type alias or `NewM()` factory:
|
|
49
|
-
```go
|
|
50
|
-
// CORRECT
|
|
51
|
-
type D struct {
|
|
52
|
-
AgentID string `bson:"agent_id" json:"agent_id"`
|
|
53
|
-
// ...
|
|
54
|
-
}
|
|
55
|
-
func (d *D) DConfig() (domainx.ConType, string, string) {
|
|
56
|
-
return domainx.Mongo, global.QuantSageDB, Table
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// WRONG - do not add these
|
|
60
|
-
type M = domainx.Complex[D]
|
|
61
|
-
func NewM() *M { return domainx.UseComplex[D](...) }
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Index registration - always in service.go init()
|
|
65
|
-
Indexes are registered in `service.go` via `domainx.AutoMigrate`, never in the model file.
|
|
66
|
-
Fields are automatically prefixed with `data.` by the framework - pass bare field names:
|
|
67
|
-
```go
|
|
68
|
-
func init() {
|
|
69
|
-
domainx.AutoMigrate(
|
|
70
|
-
func() domainx.ConTable { return domainx.UseComplex[model.D](domainx.Mongo, global.DB, model.Table) },
|
|
71
|
-
domainx.CtIdx(domainx.Idx, "field_a", "field_b", "field_c"), // compound index
|
|
72
|
-
domainx.CtIdx(domainx.Unique, "unique_field"), // unique index
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### dx query API
|
|
78
|
-
```go
|
|
79
|
-
// Find multiple records
|
|
80
|
-
result, err := dx.On[model.D](ctx).
|
|
81
|
-
Eq("agent_id", agentID).
|
|
82
|
-
Gte("date", startDate).
|
|
83
|
-
Sort("id", true). // true=desc, false=asc
|
|
84
|
-
Find() // returns domainx.ComplexList[D] = []*domainx.Complex[D]
|
|
85
|
-
if err != nil { return nil, err }
|
|
86
|
-
for i := range result {
|
|
87
|
-
if result[i] != nil && result[i].Data != nil {
|
|
88
|
-
// use result[i].Data
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Get single record
|
|
93
|
-
item, err := dx.On[model.D](ctx).Eq("agent_id", agentID).Sort("id", true).Get()
|
|
94
|
-
|
|
95
|
-
// Save (create or update)
|
|
96
|
-
_, err := dx.On[model.D](ctx, &d).Save()
|
|
97
|
-
|
|
98
|
-
// Update single field
|
|
99
|
-
err := dx.On[model.D](ctx).WithID(id).Update("field", value)
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Execution Strategy
|
|
103
|
-
|
|
104
|
-
For small changes (< ~20 lines, 1-2 files): implement directly.
|
|
105
|
-
|
|
106
|
-
For larger or pattern-repeatable changes (3+ files, bulk updates): delegate only when it helps Codex move work in parallel.
|
|
107
|
-
- Keep the critical path local when the next step depends on the result.
|
|
108
|
-
- Give delegated workers disjoint file ownership and keep `gorig-backend` conventions in scope.
|
|
109
|
-
- Verify with `go build ./...` and `go test ./...` after delegated work lands.
|
|
110
|
-
|
|
111
|
-
## Maintain Documentation
|
|
112
|
-
When API changes exist, create or update `doc/<module>.md` using `~/.codex/skills/gorig-backend/assets/api-doc-template.md`.
|
|
113
|
-
When module behavior changes, update `domain/<module>/README.md` using `~/.codex/skills/gorig-backend/assets/module-readme-template.md`.
|
|
114
|
-
|
|
115
|
-
## Go Test Convention
|
|
116
|
-
|
|
117
|
-
**All tests live in `go/test/`, `package test`. Never place test files inside domain packages.**
|
|
118
|
-
|
|
119
|
-
```text
|
|
120
|
-
go/test/
|
|
121
|
-
|-- init.go <- Shared MongoDB init - DO NOT modify
|
|
122
|
-
|-- _bin/local.yaml <- Test DB config - DO NOT modify
|
|
123
|
-
`-- {feature}_test.go <- Add new test files here
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
`init.go` starts MongoDB before any test runs. Tests that bypass this package lose the DB connection.
|
|
127
|
-
|
|
128
|
-
**New test file boilerplate:**
|
|
129
|
-
|
|
130
|
-
```go
|
|
131
|
-
package test
|
|
132
|
-
|
|
133
|
-
import (
|
|
134
|
-
"testing"
|
|
135
|
-
|
|
136
|
-
"quantsage/domain/{module}" // import target domain
|
|
137
|
-
{module}model "quantsage/domain/{module}/model" // if model types needed
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
func TestXxx_场景描述(t *testing.T) {
|
|
141
|
-
// arrange
|
|
142
|
-
input := ...
|
|
143
|
-
|
|
144
|
-
// act - only exported functions are accessible from package test
|
|
145
|
-
got := {module}.ExportedFunction(input)
|
|
146
|
-
|
|
147
|
-
// assert
|
|
148
|
-
if got != want {
|
|
149
|
-
t.Fatalf("ExportedFunction() = %v, want %v", got, want)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
**Rules:**
|
|
155
|
-
- Functions under test must be **exported** (capitalized) - `package test` cannot access unexported symbols.
|
|
156
|
-
- Use standard `testing` only. No testify or other assertion libraries.
|
|
157
|
-
- Use `t.Fatalf` / `t.Errorf` for assertions.
|
|
158
|
-
- Hardcode test data inline; do not read external files.
|
|
159
|
-
|
|
160
|
-
**Run commands:**
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
cd go
|
|
164
|
-
go test ./test/... -v # all tests
|
|
165
|
-
go test ./test/... -run TestXxx -v # single test
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## Validate and Deliver
|
|
169
|
-
Run `go build ./... && go test ./test/... -v` after every change.
|
|
170
|
-
If tests cannot run, explain the exact blocker and provide a minimal verification plan.
|
|
171
|
-
Deliver results in concise engineering format:
|
|
172
|
-
- Change summary.
|
|
173
|
-
- Key file paths.
|
|
174
|
-
- Test status and suggestions.
|
|
175
|
-
- Unknowns plus minimal assumptions.
|
|
176
|
-
|
|
177
|
-
## Provide Database Recommendation
|
|
178
|
-
When asked to choose storage, recommend based on:
|
|
179
|
-
- Existing dependencies and `dx` compatibility.
|
|
180
|
-
- Read/write pattern and query complexity.
|
|
181
|
-
- Transaction consistency requirements.
|
|
182
|
-
- Operational cost and team familiarity.
|
|
183
|
-
|
|
184
|
-
Present recommendation with clear rationale and trade-offs.
|
|
185
|
-
|
|
186
|
-
## Resources
|
|
187
|
-
- `~/.codex/skills/gorig-backend/references/onboarding-files.md`: Required code-reading checklist for gorig and news.
|
|
188
|
-
- `~/.codex/skills/gorig-backend/assets/api-doc-template.md`: API documentation template.
|
|
189
|
-
- `~/.codex/skills/gorig-backend/assets/module-readme-template.md`: Module README template.
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
interface:
|
|
2
|
-
display_name: "Gorig Backend"
|
|
3
|
-
short_description: "Go backend execution for gorig framework"
|
|
4
|
-
default_prompt: "Act as a senior Go backend engineer in gorig. Read required local files first, propose a change plan and wait for confirmation, then implement Router-Controller-Service-Model changes with tests and docs."
|