feat: 修改合并bug
This commit is contained in:
parent
f768613509
commit
456bf10352
@ -1,6 +0,0 @@
|
||||
[mcp_servers.code-review-graph]
|
||||
command = "uvx"
|
||||
args = [
|
||||
"code-review-graph",
|
||||
"serve",
|
||||
]
|
||||
@ -1,28 +0,0 @@
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write|Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "git rev-parse --git-dir >/dev/null 2>&1 && code-review-graph update --skip-flows --repo \"/Users/liulujian/Documents/code/TopFansByGithub\" || true",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "git rev-parse --git-dir >/dev/null 2>&1 && code-review-graph status --repo \"/Users/liulujian/Documents/code/TopFansByGithub\" || echo 'Not a git repo, skipping'",
|
||||
"timeout": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
---
|
||||
name: "karpathy-guidelines"
|
||||
description: "Karpathy 启发的编码行为指南,包含四大原则:编码前思考、简洁优先、精准修改、目标驱动执行。适用于所有编码任务,自动引导模型减少常见 LLM 编码错误。"
|
||||
---
|
||||
|
||||
# Karpathy 编码行为指南
|
||||
|
||||
源自 [Andrej Karpathy 的观察](https://x.com/karpathy/status/2015883857489522876) 关于 LLM 编码陷阱的总结。
|
||||
|
||||
**权衡说明:** 这些指南倾向于谨慎而非速度。对于琐碎任务(简单拼写错误修复、显而易见的一行修改),请自行判断。
|
||||
|
||||
## 1. 编码前思考
|
||||
|
||||
**不要假设。不要隐藏困惑。呈现权衡。**
|
||||
|
||||
在实现之前:
|
||||
- 明确陈述你的假设。如果不确定,询问。
|
||||
- 如果存在多种解释,呈现它们 —— 不要默默选择。
|
||||
- 如果存在更简单的方法,说出来。适时提出异议。
|
||||
- 如果有不清楚的地方,停下来。指出困惑之处。询问。
|
||||
|
||||
## 2. 简洁优先
|
||||
|
||||
**用最少的代码解决问题。不要过度推测。**
|
||||
|
||||
- 不添加要求之外的功能。
|
||||
- 不为一次性代码创建抽象。
|
||||
- 不添加未要求的"灵活性"或"可配置性"。
|
||||
- 不为不可能发生的场景做错误处理。
|
||||
- 如果你写了 200 行代码,而 50 行就能搞定,重写它。
|
||||
|
||||
**自问:** "资深工程师会觉得这过于复杂吗?" 如果是,简化。
|
||||
|
||||
## 3. 精准修改
|
||||
|
||||
**只碰必须碰的。只清理自己造成的混乱。**
|
||||
|
||||
编辑现有代码时:
|
||||
- 不要"改进"相邻的代码、注释或格式。
|
||||
- 不要重构没坏的东西。
|
||||
- 匹配现有风格,即使你更倾向于不同的写法。
|
||||
- 如果注意到无关的死代码,提一下 —— 不要删除它。
|
||||
|
||||
当你的改动产生孤儿代码时:
|
||||
- 删除因你的改动而变得无用的导入/变量/函数。
|
||||
- 不要删除预先存在的死代码,除非被要求。
|
||||
|
||||
**检验标准:** 每一行修改都应该能直接追溯到用户的请求。
|
||||
|
||||
## 4. 目标驱动执行
|
||||
|
||||
**定义成功标准。循环验证直到达成。**
|
||||
|
||||
将指令式任务转化为可验证的目标:
|
||||
- "添加验证" → "为无效输入编写测试,然后让它们通过"
|
||||
- "修复 bug" → "编写重现 bug 的测试,然后让它通过"
|
||||
- "重构 X" → "确保重构前后测试都能通过"
|
||||
|
||||
对于多步骤任务,说明一个简短的计划:
|
||||
```
|
||||
1. [步骤] → 验证: [检查]
|
||||
2. [步骤] → 验证: [检查]
|
||||
3. [步骤] → 验证: [检查]
|
||||
```
|
||||
|
||||
强有力的成功标准让你能够独立循环执行。弱标准("让它工作")需要不断澄清。
|
||||
|
||||
---
|
||||
|
||||
**这些指南在起作用的标志:** diff 中不必要的改动更少、因过度复杂而导致的重写更少、澄清问题在实现之前提出而不是在犯错之后。
|
||||
@ -8,17 +8,18 @@ import (
|
||||
|
||||
// Config 网关配置
|
||||
type Config struct {
|
||||
Server ServerConfig
|
||||
Dubbo DubboConfig
|
||||
JWT JWTConfig
|
||||
OSS OSSConfig
|
||||
Segment SegmentConfig
|
||||
Dify DifyConfig
|
||||
Minimax MinimaxConfig
|
||||
Server ServerConfig
|
||||
Dubbo DubboConfig
|
||||
JWT JWTConfig
|
||||
OSS OSSConfig
|
||||
Segment SegmentConfig
|
||||
Dify DifyConfig
|
||||
Minimax MinimaxConfig
|
||||
LaserCompositor LaserCompositorConfig
|
||||
Redis RedisConfig
|
||||
DB DBConfig
|
||||
Root string
|
||||
Redis RedisConfig
|
||||
DB DBConfig
|
||||
WebSocket WebSocketConfig
|
||||
Root string
|
||||
}
|
||||
|
||||
// MinimaxConfig MiniMax 图像生成配置
|
||||
@ -36,13 +37,6 @@ type LaserCompositorConfig struct {
|
||||
type DifyConfig struct {
|
||||
APIBase string
|
||||
APIKey string
|
||||
Server ServerConfig
|
||||
Dubbo DubboConfig
|
||||
JWT JWTConfig
|
||||
OSS OSSConfig
|
||||
Redis RedisConfig
|
||||
WebSocket WebSocketConfig
|
||||
Root string
|
||||
}
|
||||
|
||||
// RedisConfig Redis 配置
|
||||
@ -175,6 +169,15 @@ func Load() *Config {
|
||||
Password: getEnv("REDIS_PASSWORD", ""),
|
||||
DB: getEnvInt("REDIS_DB", 0),
|
||||
},
|
||||
DB: DBConfig{
|
||||
Host: getEnv("DB_HOST", "localhost"),
|
||||
Port: getEnvInt("DB_PORT", 5432),
|
||||
User: getEnv("DB_USER", "postgres"),
|
||||
Password: getEnv("DB_PASSWORD", ""),
|
||||
DBName: getEnv("DB_NAME", "top-fans"),
|
||||
SSLMode: getEnv("DB_SSLMODE", "disable"),
|
||||
TimeZone: getEnv("DB_TIMEZONE", "Asia/Shanghai"),
|
||||
},
|
||||
WebSocket: WebSocketConfig{
|
||||
AIChatPath: getEnv("WS_AI_CHAT_PATH", "/ws/ai-chat"),
|
||||
},
|
||||
|
||||
@ -1046,16 +1046,10 @@ func (ctrl *AssetController) generateOSSPolicyTokenWithKey(
|
||||
date := utcTime.Format("20060102")
|
||||
expiration := utcTime.Add(time.Duration(ossConfig.TokenExpireTime) * time.Second)
|
||||
|
||||
baseDir := ossConfig.GetUploadDir(uploadType)
|
||||
uploadDir := baseDir
|
||||
if userID != nil && starID != nil {
|
||||
uploadDir = fmt.Sprintf("%s%d/%d/", baseDir, userID, starID)
|
||||
}
|
||||
|
||||
// 尝试 STS AssumeRole,失败则降级到永久 AccessKey 直连
|
||||
var accessKeyID, accessKeySecret, securityToken string
|
||||
useSTS := false
|
||||
|
||||
// 尝试 STS AssumeRole,失败则降级到永久 AccessKey 直连
|
||||
// 1. 创建 STS 凭证提供器
|
||||
credConfig := new(credentials.Config).
|
||||
SetType("ram_role_arn").
|
||||
@ -1079,32 +1073,23 @@ func (ctrl *AssetController) generateOSSPolicyTokenWithKey(
|
||||
logger.Logger.Warn("STS credential provider failed, falling back to direct AK/SK", zap.Error(err))
|
||||
}
|
||||
|
||||
|
||||
if !useSTS {
|
||||
accessKeyID = ossConfig.AccessKeyID
|
||||
accessKeySecret = ossConfig.AccessKeySecret
|
||||
}
|
||||
// 2. 获取临时凭证
|
||||
cred, err := provider.GetCredential()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取临时凭证失败: %w", err)
|
||||
}
|
||||
|
||||
// 3. 构建 Policy
|
||||
utcTime := time.Now().UTC()
|
||||
date := utcTime.Format("20060102")
|
||||
expiration := utcTime.Add(time.Duration(ossConfig.TokenExpireTime) * time.Second)
|
||||
|
||||
// 构建 Policy 条件
|
||||
// 2. 构建 Policy 条件
|
||||
conditions := []interface{}{
|
||||
map[string]string{"bucket": ossConfig.BucketName},
|
||||
// 限制 key 必须等于指定完整 key(更严:前端只能写到该路径)
|
||||
[]interface{}{"eq", "$key", uploadKey},
|
||||
map[string]string{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
|
||||
map[string]string{"x-oss-credential": fmt.Sprintf("%s/%s/%s/%s/aliyun_v4_request",
|
||||
*cred.AccessKeyId, date, ossConfig.Region, "oss")},
|
||||
accessKeyID, date, ossConfig.Region, "oss")},
|
||||
map[string]string{"x-oss-date": utcTime.Format("20060102T150405Z")},
|
||||
map[string]string{"x-oss-security-token": *cred.SecurityToken},
|
||||
}
|
||||
if useSTS && securityToken != "" {
|
||||
conditions = append(conditions, map[string]string{"x-oss-security-token": securityToken})
|
||||
}
|
||||
|
||||
policyMap := map[string]interface{}{
|
||||
@ -1112,33 +1097,36 @@ func (ctrl *AssetController) generateOSSPolicyTokenWithKey(
|
||||
"conditions": conditions,
|
||||
}
|
||||
|
||||
// 4. 生成 Policy 的 Base64 编码
|
||||
// 3. 生成 Policy 的 Base64 编码
|
||||
policyJSON, err := json.Marshal(policyMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("序列化 policy 失败: %w", err)
|
||||
}
|
||||
policyBase64 := base64.StdEncoding.EncodeToString(policyJSON)
|
||||
|
||||
// 5. 计算签名
|
||||
signingKey := buildSigningKey(*cred.AccessKeySecret, date, ossConfig.Region, "oss")
|
||||
// 4. 计算签名
|
||||
signingKey := buildSigningKey(accessKeySecret, date, ossConfig.Region, "oss")
|
||||
signature := calculateSignature(signingKey, policyBase64)
|
||||
|
||||
// 6. 构建返回数据
|
||||
// 5. 构建返回数据
|
||||
host := fmt.Sprintf("https://%s.oss-%s.aliyuncs.com", ossConfig.BucketName, ossConfig.Region)
|
||||
|
||||
return map[string]interface{}{
|
||||
result := map[string]interface{}{
|
||||
"policy": policyBase64,
|
||||
"security_token": *cred.SecurityToken,
|
||||
"x_oss_signature_version": "OSS4-HMAC-SHA256",
|
||||
"x_oss_credential": fmt.Sprintf("%s/%s/%s/%s/aliyun_v4_request",
|
||||
*cred.AccessKeyId, date, ossConfig.Region, "oss"),
|
||||
accessKeyID, date, ossConfig.Region, "oss"),
|
||||
"x_oss_date": utcTime.Format("20060102T150405Z"),
|
||||
"signature": signature,
|
||||
"host": host,
|
||||
"dir": dirFromKey(uploadKey),
|
||||
"key": uploadKey,
|
||||
"expire_time": expiration.Unix(),
|
||||
}, nil
|
||||
}
|
||||
if useSTS && securityToken != "" {
|
||||
result["security_token"] = securityToken
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// generateOSSPolicyTokenWithDir 按显式目录生成 OSS 上传策略和签名
|
||||
@ -1157,15 +1145,26 @@ func (ctrl *AssetController) generateOSSPolicyTokenWithDir(
|
||||
SetPolicy("").
|
||||
SetRoleSessionExpiration(ossConfig.TokenExpireTime)
|
||||
|
||||
provider, err := credentials.NewCredential(credConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建凭证提供器失败: %w", err)
|
||||
// 尝试 STS AssumeRole,失败则降级到永久 AccessKey 直连
|
||||
var accessKeyID, accessKeySecret, securityToken string
|
||||
useSTS := false
|
||||
|
||||
if provider, err := credentials.NewCredential(credConfig); err == nil {
|
||||
if cred, err := provider.GetCredential(); err == nil {
|
||||
accessKeyID = *cred.AccessKeyId
|
||||
accessKeySecret = *cred.AccessKeySecret
|
||||
securityToken = *cred.SecurityToken
|
||||
useSTS = true
|
||||
} else {
|
||||
logger.Logger.Warn("STS AssumeRole failed for WithDir, falling back to direct AK/SK", zap.Error(err))
|
||||
}
|
||||
} else {
|
||||
logger.Logger.Warn("STS credential provider failed for WithDir, falling back to direct AK/SK", zap.Error(err))
|
||||
}
|
||||
|
||||
// 2. 获取临时凭证
|
||||
cred, err := provider.GetCredential()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取临时凭证失败: %w", err)
|
||||
if !useSTS {
|
||||
accessKeyID = ossConfig.AccessKeyID
|
||||
accessKeySecret = ossConfig.AccessKeySecret
|
||||
}
|
||||
|
||||
// 3. 构建 Policy
|
||||
|
||||
Loading…
Reference in New Issue
Block a user