gorig-cli 1.0.14 → 1.0.23

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 CHANGED
@@ -72,6 +72,33 @@ npx gorig-cli@latest doc user
72
72
  After generating the documentation, you can access it through:
73
73
  http://127.0.0.1:8080/redoc.html
74
74
 
75
+ ### Install Gorig Skill
76
+
77
+ Use the `skill` command to install the bundled `gorig-backend` skill for Codex or Claude:
78
+
79
+ ```sh
80
+ # Install both Codex and Claude user-level skills
81
+ gorig-cli skill install all
82
+
83
+ # Install only the Codex skill
84
+ gorig-cli skill install codex
85
+
86
+ # Install Claude user-level skill
87
+ gorig-cli skill install claude user
88
+
89
+ # Install Claude project-level skill into the current repository
90
+ gorig-cli skill install claude project
91
+ ```
92
+
93
+ Or use npx:
94
+
95
+ ```sh
96
+ npx gorig-cli@latest skill install all
97
+ npx gorig-cli@latest skill install codex
98
+ npx gorig-cli@latest skill install claude user
99
+ npx gorig-cli@latest skill install claude project
100
+ ```
101
+
75
102
  ### Run the Project
76
103
 
77
104
  After entering the project directory, you can run the project using the following commands:
@@ -86,4 +113,3 @@ Or run it after building:
86
113
  ```sh
87
114
  go build -o my-new-project _cmd/main.go && ./my-new-project
88
115
  ```
89
-
package/bin/cli.js CHANGED
@@ -3,53 +3,62 @@
3
3
  import chalk from 'chalk';
4
4
  import path from 'path';
5
5
 
6
- // 获取命令行参数
6
+ // Get command line arguments
7
7
  const args = process.argv.slice(2);
8
8
 
9
- // 验证是否提供了命令
9
+ // Validate if a command is provided
10
10
  if (args.length < 1) {
11
- console.error(chalk.red('请提供一个有效的命令,例如: create init'));
11
+ console.error(chalk.red('Please provide a valid command, e.g.: create, init, doc, or skill'));
12
12
  process.exit(1);
13
13
  }
14
14
 
15
- // 提取命令
15
+ // Extract command
16
16
  const command = args[0];
17
17
 
18
- // 获取当前文件的目录
18
+ // Get current file directory
19
19
  const __dirname = path.dirname(new URL(import.meta.url).pathname);
20
20
 
21
- // 根据命令执行不同的逻辑
21
+ // Execute different logic based on command
22
22
  switch (command) {
23
23
  case 'create':
24
- // 动态导入 create.js,命令放在 commands 目录下
24
+ // Dynamically import create.js, commands are placed in the commands directory
25
25
  import(path.join(__dirname, '../commands/create.js')).then(module => {
26
26
  const createModule = module.default;
27
- createModule(args.slice(1)); // 将命令行的其他参数传递给 create.js
27
+ createModule(args.slice(1)); // Pass other command line arguments to create.js
28
28
  }).catch(error => {
29
- console.error(chalk.red('无法加载 create 命令模块:', error.message));
29
+ console.error(chalk.red('Failed to load create command module:', error.message));
30
30
  });
31
31
  break;
32
32
 
33
33
  case 'init':
34
- // 动态导入 init.js
34
+ // Dynamically import init.js
35
35
  import(path.join(__dirname, '../commands/init.js')).then(module => {
36
36
  const initModule = module.default;
37
- initModule(args.slice(1)); // 将命令行的其他参数传递给 init.js
37
+ initModule(args.slice(1)); // Pass other command line arguments to init.js
38
38
  }).catch(error => {
39
- console.error(chalk.red('无法加载 init 命令模块:', error.message));
39
+ console.error(chalk.red('Failed to load init command module:', error.message));
40
40
  });
41
41
  break;
42
42
  case 'doc':
43
43
  import(path.join(__dirname, '../commands/doc.js')).then(module => {
44
44
  const docModule = module.default;
45
- docModule(); // 执行 doc 命令
45
+ docModule(); // Execute doc command
46
46
  }).catch(error => {
47
- console.error(chalk.red('无法加载 doc 命令模块:', error.message));
47
+ console.error(chalk.red('Failed to load doc command module:', error.message));
48
+ });
49
+ break;
50
+
51
+ case 'skill':
52
+ import(path.join(__dirname, '../commands/skill.js')).then(module => {
53
+ const skillModule = module.default;
54
+ skillModule(args.slice(1));
55
+ }).catch(error => {
56
+ console.error(chalk.red('Failed to load skill command module:', error.message));
48
57
  });
49
58
  break;
50
59
 
51
60
  default:
52
- console.error(chalk.red(`未知的命令: ${command}`));
53
- console.error(chalk.yellow('可用的命令: create, init'));
61
+ console.error(chalk.red(`Unknown command: ${command}`));
62
+ console.error(chalk.yellow('Available commands: create, init, doc, skill'));
54
63
  process.exit(1);
55
64
  }
@@ -0,0 +1,92 @@
1
+ import fs from 'fs-extra';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import chalk from 'chalk';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ const SKILL_NAME = 'gorig-backend';
11
+ const VALID_TARGETS = new Set(['codex', 'claude', 'all']);
12
+ const VALID_SCOPES = new Set(['user', 'project']);
13
+
14
+ const printUsage = () => {
15
+ console.log(chalk.yellow('Usage: gorig-cli skill install <codex|claude|all> [user|project]'));
16
+ };
17
+
18
+ const installSkill = async (target, scope) => {
19
+ const templateRoot = path.join(__dirname, '../templates/skills');
20
+ const installs = [];
21
+
22
+ if (target === 'codex' || target === 'all') {
23
+ const codexHome = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
24
+ installs.push({
25
+ label: 'Codex',
26
+ source: path.join(templateRoot, 'codex', SKILL_NAME),
27
+ destination: path.join(codexHome, 'skills', SKILL_NAME),
28
+ });
29
+ }
30
+
31
+ if (target === 'claude' || target === 'all') {
32
+ const claudeBase = scope === 'project'
33
+ ? path.join(process.cwd(), '.claude')
34
+ : path.join(os.homedir(), '.claude');
35
+
36
+ installs.push({
37
+ label: `Claude (${scope})`,
38
+ source: path.join(templateRoot, 'claude', SKILL_NAME),
39
+ destination: path.join(claudeBase, 'skills', SKILL_NAME),
40
+ });
41
+ }
42
+
43
+ for (const install of installs) {
44
+ const exists = await fs.pathExists(install.source);
45
+ if (!exists) {
46
+ throw new Error(`Skill template not found: ${install.source}`);
47
+ }
48
+
49
+ await fs.ensureDir(path.dirname(install.destination));
50
+ await fs.copy(install.source, install.destination, { overwrite: true });
51
+ console.log(chalk.green(`Installed ${install.label} skill to ${install.destination}`));
52
+ }
53
+ };
54
+
55
+ const skillModule = async (args) => {
56
+ const action = args[0];
57
+
58
+ if (!action) {
59
+ printUsage();
60
+ process.exit(1);
61
+ }
62
+
63
+ if (action !== 'install') {
64
+ console.error(chalk.red(`Unknown skill action: ${action}`));
65
+ printUsage();
66
+ process.exit(1);
67
+ }
68
+
69
+ const target = args[1] || 'all';
70
+ const scope = args[2] || 'user';
71
+
72
+ if (!VALID_TARGETS.has(target)) {
73
+ console.error(chalk.red(`Unknown skill target: ${target}`));
74
+ printUsage();
75
+ process.exit(1);
76
+ }
77
+
78
+ if (!VALID_SCOPES.has(scope)) {
79
+ console.error(chalk.red(`Unknown skill scope: ${scope}`));
80
+ printUsage();
81
+ process.exit(1);
82
+ }
83
+
84
+ try {
85
+ await installSkill(target, scope);
86
+ } catch (error) {
87
+ console.error(chalk.red('Failed to install skill:'), chalk.redBright(error.message));
88
+ process.exit(1);
89
+ }
90
+ };
91
+
92
+ export default skillModule;
@@ -0,0 +1,65 @@
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 "脚本执行完成。"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gorig-cli",
3
- "version": "1.0.14",
3
+ "version": "1.0.23",
4
4
  "type": "module",
5
5
  "description": "gorig build tool",
6
6
  "main": "bin/cli.js",
@@ -1,16 +1,17 @@
1
1
  package cron
2
2
 
3
3
  import (
4
+ "context"
4
5
  "fmt"
5
6
  "github.com/jom-io/gorig/cronx"
6
7
  "github.com/jom-io/gorig/utils/logger"
7
8
  "time"
8
9
  )
9
10
 
10
- func test() {
11
- logger.Info(nil, fmt.Sprintf("hello, now is %s", time.Now().Format("2006-01-02 15:04:05")))
11
+ func test(ctx context.Context) {
12
+ logger.Info(ctx, fmt.Sprintf("hello, now is %s", time.Now().Format("2006-01-02 15:04:05")))
12
13
  }
13
14
 
14
15
  func init() {
15
- cronx.AddTask("*/10 * * * * *", test)
16
+ cronx.AddCronTask("*/10 * * * * *", test, 0)
16
17
  }
@@ -2,6 +2,7 @@ package domain
2
2
 
3
3
  import (
4
4
  "github.com/gin-gonic/gin"
5
+ "github.com/jom-io/gorig/apix/response"
5
6
  "github.com/jom-io/gorig/httpx"
6
7
  "github.com/jom-io/gorig/serv"
7
8
  configure "github.com/jom-io/gorig/utils/cofigure"
@@ -11,7 +12,7 @@ import (
11
12
  func init() {
12
13
  httpx.RegisterRouter(func(groupRouter *gin.RouterGroup) {
13
14
  groupRouter.GET("/", func(ctx *gin.Context) {
14
- httpx.Success(ctx, "hello world, this is <%= projectNameUpper %> project generated by gorig-cli")
15
+ response.Success(ctx, "Hello world, this is <%= projectNameUpper %> project generated by gorig-cli", nil)
15
16
  })
16
17
  })
17
18
  err := serv.RegisterService(
@@ -0,0 +1,189 @@
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.
@@ -0,0 +1,50 @@
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
+ | | | |
@@ -0,0 +1,46 @@
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
+ - 文档更新规则:
@@ -0,0 +1,38 @@
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.