feat(usage-log): 增加请求 User-Agent 记录

在使用记录中添加 user_agent 字段,用于记录 API 请求的 User-Agent 头信息,
便于分析客户端类型和调试。

变更内容:
- 新增数据库迁移 028_add_usage_logs_user_agent.sql
- 更新 UsageLog 模型和 Ent Schema 添加 user_agent 字段
- 更新 Repository 层的 Create 和 scanUsageLog 方法
- 更新 RecordUsageInput 结构体支持传入 UserAgent
- 更新 Claude/OpenAI/Gemini 三个网关 Handler 传递 UserAgent

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Edric Li
2026-01-06 16:23:56 +08:00
parent f6dd4752e7
commit 1ada6cf768
17 changed files with 400 additions and 29 deletions

View File

@@ -175,6 +175,11 @@ func FirstTokenMs(v int) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEQ(FieldFirstTokenMs, v))
}
// UserAgent applies equality check predicate on the "user_agent" field. It's identical to UserAgentEQ.
func UserAgent(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEQ(FieldUserAgent, v))
}
// ImageCount applies equality check predicate on the "image_count" field. It's identical to ImageCountEQ.
func ImageCount(v int) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEQ(FieldImageCount, v))
@@ -1110,6 +1115,81 @@ func FirstTokenMsNotNil() predicate.UsageLog {
return predicate.UsageLog(sql.FieldNotNull(FieldFirstTokenMs))
}
// UserAgentEQ applies the EQ predicate on the "user_agent" field.
func UserAgentEQ(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEQ(FieldUserAgent, v))
}
// UserAgentNEQ applies the NEQ predicate on the "user_agent" field.
func UserAgentNEQ(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldNEQ(FieldUserAgent, v))
}
// UserAgentIn applies the In predicate on the "user_agent" field.
func UserAgentIn(vs ...string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldIn(FieldUserAgent, vs...))
}
// UserAgentNotIn applies the NotIn predicate on the "user_agent" field.
func UserAgentNotIn(vs ...string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldNotIn(FieldUserAgent, vs...))
}
// UserAgentGT applies the GT predicate on the "user_agent" field.
func UserAgentGT(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldGT(FieldUserAgent, v))
}
// UserAgentGTE applies the GTE predicate on the "user_agent" field.
func UserAgentGTE(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldGTE(FieldUserAgent, v))
}
// UserAgentLT applies the LT predicate on the "user_agent" field.
func UserAgentLT(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldLT(FieldUserAgent, v))
}
// UserAgentLTE applies the LTE predicate on the "user_agent" field.
func UserAgentLTE(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldLTE(FieldUserAgent, v))
}
// UserAgentContains applies the Contains predicate on the "user_agent" field.
func UserAgentContains(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldContains(FieldUserAgent, v))
}
// UserAgentHasPrefix applies the HasPrefix predicate on the "user_agent" field.
func UserAgentHasPrefix(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldHasPrefix(FieldUserAgent, v))
}
// UserAgentHasSuffix applies the HasSuffix predicate on the "user_agent" field.
func UserAgentHasSuffix(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldHasSuffix(FieldUserAgent, v))
}
// UserAgentIsNil applies the IsNil predicate on the "user_agent" field.
func UserAgentIsNil() predicate.UsageLog {
return predicate.UsageLog(sql.FieldIsNull(FieldUserAgent))
}
// UserAgentNotNil applies the NotNil predicate on the "user_agent" field.
func UserAgentNotNil() predicate.UsageLog {
return predicate.UsageLog(sql.FieldNotNull(FieldUserAgent))
}
// UserAgentEqualFold applies the EqualFold predicate on the "user_agent" field.
func UserAgentEqualFold(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEqualFold(FieldUserAgent, v))
}
// UserAgentContainsFold applies the ContainsFold predicate on the "user_agent" field.
func UserAgentContainsFold(v string) predicate.UsageLog {
return predicate.UsageLog(sql.FieldContainsFold(FieldUserAgent, v))
}
// ImageCountEQ applies the EQ predicate on the "image_count" field.
func ImageCountEQ(v int) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEQ(FieldImageCount, v))