Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
90bce60b
"backend/vscode:/vscode.git/clone" did not exist on "2491e9b5ad632f483ad5781d1b705616b0bad046"
Commit
90bce60b
authored
Jan 15, 2026
by
yangjianbo
Browse files
feat: merge dev
parent
a458e684
Changes
107
Show whitespace changes
Inline
Side-by-side
PR_DESCRIPTION.md
0 → 100644
View file @
90bce60b
## 概述
全面增强运维监控系统(Ops)的错误日志管理和告警静默功能,优化前端 UI 组件代码质量和用户体验。本次更新重构了核心服务层和数据访问层,提升系统可维护性和运维效率。
## 主要改动
### 1. 错误日志查询优化
**功能特性:**
-
新增 GetErrorLogByID 接口,支持按 ID 精确查询错误详情
-
优化错误日志过滤逻辑,支持多维度筛选(平台、阶段、来源、所有者等)
-
改进查询参数处理,简化代码结构
-
增强错误分类和标准化处理
-
支持错误解决状态追踪(resolved 字段)
**技术实现:**
-
`ops_handler.go`
- 新增单条错误日志查询接口
-
`ops_repo.go`
- 优化数据查询和过滤条件构建
-
`ops_models.go`
- 扩展错误日志数据模型
-
前端 API 接口同步更新
### 2. 告警静默功能
**功能特性:**
-
支持按规则、平台、分组、区域等维度静默告警
-
可设置静默时长和原因说明
-
静默记录可追溯,记录创建人和创建时间
-
自动过期机制,避免永久静默
**技术实现:**
-
`037_ops_alert_silences.sql`
- 新增告警静默表
-
`ops_alerts.go`
- 告警静默逻辑实现
-
`ops_alerts_handler.go`
- 告警静默 API 接口
-
`OpsAlertEventsCard.vue`
- 前端告警静默操作界面
**数据库结构:**
| 字段 | 类型 | 说明 |
|------|------|------|
| rule_id | BIGINT | 告警规则 ID |
| platform | VARCHAR(64) | 平台标识 |
| group_id | BIGINT | 分组 ID(可选) |
| region | VARCHAR(64) | 区域(可选) |
| until | TIMESTAMPTZ | 静默截止时间 |
| reason | TEXT | 静默原因 |
| created_by | BIGINT | 创建人 ID |
### 3. 错误分类标准化
**功能特性:**
-
统一错误阶段分类(request|auth|routing|upstream|network|internal)
-
规范错误归属分类(client|provider|platform)
-
标准化错误来源分类(client_request|upstream_http|gateway)
-
自动迁移历史数据到新分类体系
**技术实现:**
-
`038_ops_errors_resolution_retry_results_and_standardize_classification.sql`
- 分类标准化迁移
-
自动映射历史遗留分类到新标准
-
自动解决已恢复的上游错误(客户端状态码 < 400)
### 4. Gateway 服务集成
**功能特性:**
-
完善各 Gateway 服务的 Ops 集成
-
统一错误日志记录接口
-
增强上游错误追踪能力
**涉及服务:**
-
`antigravity_gateway_service.go`
- Antigravity 网关集成
-
`gateway_service.go`
- 通用网关集成
-
`gemini_messages_compat_service.go`
- Gemini 兼容层集成
-
`openai_gateway_service.go`
- OpenAI 网关集成
### 5. 前端 UI 优化
**代码重构:**
-
大幅简化错误详情模态框代码(从 828 行优化到 450 行)
-
优化错误日志表格组件,提升可读性
-
清理未使用的 i18n 翻译,减少冗余
-
统一组件代码风格和格式
-
优化骨架屏组件,更好匹配实际看板布局
**布局改进:**
-
修复模态框内容溢出和滚动问题
-
优化表格布局,使用 flex 布局确保正确显示
-
改进看板头部布局和交互
-
提升响应式体验
-
骨架屏支持全屏模式适配
**交互优化:**
-
优化告警事件卡片功能和展示
-
改进错误详情展示逻辑
-
增强请求详情模态框
-
完善运行时设置卡片
-
改进加载动画效果
### 6. 国际化完善
**文案补充:**
-
补充错误日志相关的英文翻译
-
添加告警静默功能的中英文文案
-
完善提示文本和错误信息
-
统一术语翻译标准
## 文件变更
**后端(26 个文件):**
-
`backend/internal/handler/admin/ops_alerts_handler.go`
- 告警接口增强
-
`backend/internal/handler/admin/ops_handler.go`
- 错误日志接口优化
-
`backend/internal/handler/ops_error_logger.go`
- 错误记录器增强
-
`backend/internal/repository/ops_repo.go`
- 数据访问层重构
-
`backend/internal/repository/ops_repo_alerts.go`
- 告警数据访问增强
-
`backend/internal/service/ops_*.go`
- 核心服务层重构(10 个文件)
-
`backend/internal/service/*_gateway_service.go`
- Gateway 集成(4 个文件)
-
`backend/internal/server/routes/admin.go`
- 路由配置更新
-
`backend/migrations/*.sql`
- 数据库迁移(2 个文件)
-
测试文件更新(5 个文件)
**前端(13 个文件):**
-
`frontend/src/views/admin/ops/OpsDashboard.vue`
- 看板主页优化
-
`frontend/src/views/admin/ops/components/*.vue`
- 组件重构(10 个文件)
-
`frontend/src/api/admin/ops.ts`
- API 接口扩展
-
`frontend/src/i18n/locales/*.ts`
- 国际化文本(2 个文件)
## 代码统计
-
44 个文件修改
-
3733 行新增
-
995 行删除
-
净增加 2738 行
## 核心改进
**可维护性提升:**
-
重构核心服务层,职责更清晰
-
简化前端组件代码,降低复杂度
-
统一代码风格和命名规范
-
清理冗余代码和未使用的翻译
-
标准化错误分类体系
**功能完善:**
-
告警静默功能,减少告警噪音
-
错误日志查询优化,提升运维效率
-
Gateway 服务集成完善,统一监控能力
-
错误解决状态追踪,便于问题管理
**用户体验优化:**
-
修复多个 UI 布局问题
-
优化交互流程
-
完善国际化支持
-
提升响应式体验
-
改进加载状态展示
## 测试验证
-
✅ 错误日志查询和过滤功能
-
✅ 告警静默创建和自动过期
-
✅ 错误分类标准化迁移
-
✅ Gateway 服务错误日志记录
-
✅ 前端组件布局和交互
-
✅ 骨架屏全屏模式适配
-
✅ 国际化文本完整性
-
✅ API 接口功能正确性
-
✅ 数据库迁移执行成功
backend/cmd/server/wire_gen.go
View file @
90bce60b
...
...
@@ -67,7 +67,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
userHandler
:=
handler
.
NewUserHandler
(
userService
)
apiKeyHandler
:=
handler
.
NewAPIKeyHandler
(
apiKeyService
)
usageLogRepository
:=
repository
.
NewUsageLogRepository
(
client
,
db
)
dashboardAggregationRepository
:=
repository
.
NewDashboardAggregationRepository
(
db
)
usageService
:=
service
.
NewUsageService
(
usageLogRepository
,
userRepository
,
client
,
apiKeyAuthCacheInvalidator
)
usageHandler
:=
handler
.
NewUsageHandler
(
usageService
,
apiKeyService
)
redeemCodeRepository
:=
repository
.
NewRedeemCodeRepository
(
client
)
...
...
@@ -76,15 +75,17 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
redeemService
:=
service
.
NewRedeemService
(
redeemCodeRepository
,
userRepository
,
subscriptionService
,
redeemCache
,
billingCacheService
,
client
,
apiKeyAuthCacheInvalidator
)
redeemHandler
:=
handler
.
NewRedeemHandler
(
redeemService
)
subscriptionHandler
:=
handler
.
NewSubscriptionHandler
(
subscriptionService
)
dashboardAggregationRepository
:=
repository
.
NewDashboardAggregationRepository
(
db
)
dashboardStatsCache
:=
repository
.
NewDashboardCache
(
redisClient
,
configConfig
)
dashboardService
:=
service
.
NewDashboardService
(
usageLogRepository
,
dashboardAggregationRepository
,
dashboardStatsCache
,
configConfig
)
timingWheelService
:=
service
.
ProvideTimingWheelService
()
dashboardAggregationService
:=
service
.
ProvideDashboardAggregationService
(
dashboardAggregationRepository
,
timingWheelService
,
configConfig
)
dashboardService
:=
service
.
NewDashboardService
(
usageLogRepository
,
dashboardAggregationRepository
,
dashboardStatsCache
,
configConfig
)
dashboardHandler
:=
admin
.
NewDashboardHandler
(
dashboardService
,
dashboardAggregationService
)
accountRepository
:=
repository
.
NewAccountRepository
(
client
,
db
)
proxyRepository
:=
repository
.
NewProxyRepository
(
client
,
db
)
proxyExitInfoProber
:=
repository
.
NewProxyExitInfoProber
(
configConfig
)
adminService
:=
service
.
NewAdminService
(
userRepository
,
groupRepository
,
accountRepository
,
proxyRepository
,
apiKeyRepository
,
redeemCodeRepository
,
billingCacheService
,
proxyExitInfoProber
,
apiKeyAuthCacheInvalidator
)
proxyLatencyCache
:=
repository
.
NewProxyLatencyCache
(
redisClient
)
adminService
:=
service
.
NewAdminService
(
userRepository
,
groupRepository
,
accountRepository
,
proxyRepository
,
apiKeyRepository
,
redeemCodeRepository
,
billingCacheService
,
proxyExitInfoProber
,
proxyLatencyCache
,
apiKeyAuthCacheInvalidator
)
adminUserHandler
:=
admin
.
NewUserHandler
(
adminService
)
groupHandler
:=
admin
.
NewGroupHandler
(
adminService
)
claudeOAuthClient
:=
repository
.
NewClaudeOAuthClient
()
...
...
@@ -113,9 +114,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
accountTestService
:=
service
.
NewAccountTestService
(
accountRepository
,
geminiTokenProvider
,
antigravityGatewayService
,
httpUpstream
,
configConfig
)
concurrencyCache
:=
repository
.
ProvideConcurrencyCache
(
redisClient
,
configConfig
)
concurrencyService
:=
service
.
ProvideConcurrencyService
(
concurrencyCache
,
accountRepository
,
configConfig
)
schedulerCache
:=
repository
.
NewSchedulerCache
(
redisClient
)
schedulerOutboxRepository
:=
repository
.
NewSchedulerOutboxRepository
(
db
)
schedulerSnapshotService
:=
service
.
ProvideSchedulerSnapshotService
(
schedulerCache
,
schedulerOutboxRepository
,
accountRepository
,
groupRepository
,
configConfig
)
crsSyncService
:=
service
.
NewCRSSyncService
(
accountRepository
,
proxyRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
configConfig
)
accountHandler
:=
admin
.
NewAccountHandler
(
adminService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
rateLimitService
,
accountUsageService
,
accountTestService
,
concurrencyService
,
crsSyncService
)
oAuthHandler
:=
admin
.
NewOAuthHandler
(
oAuthService
)
...
...
@@ -126,6 +124,9 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
adminRedeemHandler
:=
admin
.
NewRedeemHandler
(
adminService
)
promoHandler
:=
admin
.
NewPromoHandler
(
promoService
)
opsRepository
:=
repository
.
NewOpsRepository
(
db
)
schedulerCache
:=
repository
.
NewSchedulerCache
(
redisClient
)
schedulerOutboxRepository
:=
repository
.
NewSchedulerOutboxRepository
(
db
)
schedulerSnapshotService
:=
service
.
ProvideSchedulerSnapshotService
(
schedulerCache
,
schedulerOutboxRepository
,
accountRepository
,
groupRepository
,
configConfig
)
pricingRemoteClient
:=
repository
.
ProvidePricingRemoteClient
(
configConfig
)
pricingService
,
err
:=
service
.
ProvidePricingService
(
configConfig
,
pricingRemoteClient
)
if
err
!=
nil
{
...
...
backend/ent/account.go
View file @
90bce60b
...
...
@@ -43,6 +43,8 @@ type Account struct {
Concurrency
int
`json:"concurrency,omitempty"`
// Priority holds the value of the "priority" field.
Priority
int
`json:"priority,omitempty"`
// RateMultiplier holds the value of the "rate_multiplier" field.
RateMultiplier
float64
`json:"rate_multiplier,omitempty"`
// Status holds the value of the "status" field.
Status
string
`json:"status,omitempty"`
// ErrorMessage holds the value of the "error_message" field.
...
...
@@ -135,6 +137,8 @@ func (*Account) scanValues(columns []string) ([]any, error) {
values
[
i
]
=
new
([]
byte
)
case
account
.
FieldAutoPauseOnExpired
,
account
.
FieldSchedulable
:
values
[
i
]
=
new
(
sql
.
NullBool
)
case
account
.
FieldRateMultiplier
:
values
[
i
]
=
new
(
sql
.
NullFloat64
)
case
account
.
FieldID
,
account
.
FieldProxyID
,
account
.
FieldConcurrency
,
account
.
FieldPriority
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
case
account
.
FieldName
,
account
.
FieldNotes
,
account
.
FieldPlatform
,
account
.
FieldType
,
account
.
FieldStatus
,
account
.
FieldErrorMessage
,
account
.
FieldSessionWindowStatus
:
...
...
@@ -241,6 +245,12 @@ func (_m *Account) assignValues(columns []string, values []any) error {
}
else
if
value
.
Valid
{
_m
.
Priority
=
int
(
value
.
Int64
)
}
case
account
.
FieldRateMultiplier
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field rate_multiplier"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
RateMultiplier
=
value
.
Float64
}
case
account
.
FieldStatus
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullString
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field status"
,
values
[
i
])
...
...
@@ -420,6 +430,9 @@ func (_m *Account) String() string {
builder
.
WriteString
(
"priority="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Priority
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"rate_multiplier="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
RateMultiplier
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"status="
)
builder
.
WriteString
(
_m
.
Status
)
builder
.
WriteString
(
", "
)
...
...
backend/ent/account/account.go
View file @
90bce60b
...
...
@@ -39,6 +39,8 @@ const (
FieldConcurrency
=
"concurrency"
// FieldPriority holds the string denoting the priority field in the database.
FieldPriority
=
"priority"
// FieldRateMultiplier holds the string denoting the rate_multiplier field in the database.
FieldRateMultiplier
=
"rate_multiplier"
// FieldStatus holds the string denoting the status field in the database.
FieldStatus
=
"status"
// FieldErrorMessage holds the string denoting the error_message field in the database.
...
...
@@ -116,6 +118,7 @@ var Columns = []string{
FieldProxyID
,
FieldConcurrency
,
FieldPriority
,
FieldRateMultiplier
,
FieldStatus
,
FieldErrorMessage
,
FieldLastUsedAt
,
...
...
@@ -174,6 +177,8 @@ var (
DefaultConcurrency
int
// DefaultPriority holds the default value on creation for the "priority" field.
DefaultPriority
int
// DefaultRateMultiplier holds the default value on creation for the "rate_multiplier" field.
DefaultRateMultiplier
float64
// DefaultStatus holds the default value on creation for the "status" field.
DefaultStatus
string
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
...
...
@@ -244,6 +249,11 @@ func ByPriority(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldPriority
,
opts
...
)
.
ToFunc
()
}
// ByRateMultiplier orders the results by the rate_multiplier field.
func
ByRateMultiplier
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldRateMultiplier
,
opts
...
)
.
ToFunc
()
}
// ByStatus orders the results by the status field.
func
ByStatus
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldStatus
,
opts
...
)
.
ToFunc
()
...
...
backend/ent/account/where.go
View file @
90bce60b
...
...
@@ -105,6 +105,11 @@ func Priority(v int) predicate.Account {
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldPriority
,
v
))
}
// RateMultiplier applies equality check predicate on the "rate_multiplier" field. It's identical to RateMultiplierEQ.
func
RateMultiplier
(
v
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldRateMultiplier
,
v
))
}
// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
func
Status
(
v
string
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldStatus
,
v
))
...
...
@@ -675,6 +680,46 @@ func PriorityLTE(v int) predicate.Account {
return
predicate
.
Account
(
sql
.
FieldLTE
(
FieldPriority
,
v
))
}
// RateMultiplierEQ applies the EQ predicate on the "rate_multiplier" field.
func
RateMultiplierEQ
(
v
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldRateMultiplier
,
v
))
}
// RateMultiplierNEQ applies the NEQ predicate on the "rate_multiplier" field.
func
RateMultiplierNEQ
(
v
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNEQ
(
FieldRateMultiplier
,
v
))
}
// RateMultiplierIn applies the In predicate on the "rate_multiplier" field.
func
RateMultiplierIn
(
vs
...
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldIn
(
FieldRateMultiplier
,
vs
...
))
}
// RateMultiplierNotIn applies the NotIn predicate on the "rate_multiplier" field.
func
RateMultiplierNotIn
(
vs
...
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldNotIn
(
FieldRateMultiplier
,
vs
...
))
}
// RateMultiplierGT applies the GT predicate on the "rate_multiplier" field.
func
RateMultiplierGT
(
v
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldGT
(
FieldRateMultiplier
,
v
))
}
// RateMultiplierGTE applies the GTE predicate on the "rate_multiplier" field.
func
RateMultiplierGTE
(
v
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldGTE
(
FieldRateMultiplier
,
v
))
}
// RateMultiplierLT applies the LT predicate on the "rate_multiplier" field.
func
RateMultiplierLT
(
v
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldLT
(
FieldRateMultiplier
,
v
))
}
// RateMultiplierLTE applies the LTE predicate on the "rate_multiplier" field.
func
RateMultiplierLTE
(
v
float64
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldLTE
(
FieldRateMultiplier
,
v
))
}
// StatusEQ applies the EQ predicate on the "status" field.
func
StatusEQ
(
v
string
)
predicate
.
Account
{
return
predicate
.
Account
(
sql
.
FieldEQ
(
FieldStatus
,
v
))
...
...
backend/ent/account_create.go
View file @
90bce60b
...
...
@@ -153,6 +153,20 @@ func (_c *AccountCreate) SetNillablePriority(v *int) *AccountCreate {
return
_c
}
// SetRateMultiplier sets the "rate_multiplier" field.
func
(
_c
*
AccountCreate
)
SetRateMultiplier
(
v
float64
)
*
AccountCreate
{
_c
.
mutation
.
SetRateMultiplier
(
v
)
return
_c
}
// SetNillableRateMultiplier sets the "rate_multiplier" field if the given value is not nil.
func
(
_c
*
AccountCreate
)
SetNillableRateMultiplier
(
v
*
float64
)
*
AccountCreate
{
if
v
!=
nil
{
_c
.
SetRateMultiplier
(
*
v
)
}
return
_c
}
// SetStatus sets the "status" field.
func
(
_c
*
AccountCreate
)
SetStatus
(
v
string
)
*
AccountCreate
{
_c
.
mutation
.
SetStatus
(
v
)
...
...
@@ -429,6 +443,10 @@ func (_c *AccountCreate) defaults() error {
v
:=
account
.
DefaultPriority
_c
.
mutation
.
SetPriority
(
v
)
}
if
_
,
ok
:=
_c
.
mutation
.
RateMultiplier
();
!
ok
{
v
:=
account
.
DefaultRateMultiplier
_c
.
mutation
.
SetRateMultiplier
(
v
)
}
if
_
,
ok
:=
_c
.
mutation
.
Status
();
!
ok
{
v
:=
account
.
DefaultStatus
_c
.
mutation
.
SetStatus
(
v
)
...
...
@@ -488,6 +506,9 @@ func (_c *AccountCreate) check() error {
if
_
,
ok
:=
_c
.
mutation
.
Priority
();
!
ok
{
return
&
ValidationError
{
Name
:
"priority"
,
err
:
errors
.
New
(
`ent: missing required field "Account.priority"`
)}
}
if
_
,
ok
:=
_c
.
mutation
.
RateMultiplier
();
!
ok
{
return
&
ValidationError
{
Name
:
"rate_multiplier"
,
err
:
errors
.
New
(
`ent: missing required field "Account.rate_multiplier"`
)}
}
if
_
,
ok
:=
_c
.
mutation
.
Status
();
!
ok
{
return
&
ValidationError
{
Name
:
"status"
,
err
:
errors
.
New
(
`ent: missing required field "Account.status"`
)}
}
...
...
@@ -578,6 +599,10 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
_spec
.
SetField
(
account
.
FieldPriority
,
field
.
TypeInt
,
value
)
_node
.
Priority
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
RateMultiplier
();
ok
{
_spec
.
SetField
(
account
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
_node
.
RateMultiplier
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
Status
();
ok
{
_spec
.
SetField
(
account
.
FieldStatus
,
field
.
TypeString
,
value
)
_node
.
Status
=
value
...
...
@@ -893,6 +918,24 @@ func (u *AccountUpsert) AddPriority(v int) *AccountUpsert {
return
u
}
// SetRateMultiplier sets the "rate_multiplier" field.
func
(
u
*
AccountUpsert
)
SetRateMultiplier
(
v
float64
)
*
AccountUpsert
{
u
.
Set
(
account
.
FieldRateMultiplier
,
v
)
return
u
}
// UpdateRateMultiplier sets the "rate_multiplier" field to the value that was provided on create.
func
(
u
*
AccountUpsert
)
UpdateRateMultiplier
()
*
AccountUpsert
{
u
.
SetExcluded
(
account
.
FieldRateMultiplier
)
return
u
}
// AddRateMultiplier adds v to the "rate_multiplier" field.
func
(
u
*
AccountUpsert
)
AddRateMultiplier
(
v
float64
)
*
AccountUpsert
{
u
.
Add
(
account
.
FieldRateMultiplier
,
v
)
return
u
}
// SetStatus sets the "status" field.
func
(
u
*
AccountUpsert
)
SetStatus
(
v
string
)
*
AccountUpsert
{
u
.
Set
(
account
.
FieldStatus
,
v
)
...
...
@@ -1325,6 +1368,27 @@ func (u *AccountUpsertOne) UpdatePriority() *AccountUpsertOne {
})
}
// SetRateMultiplier sets the "rate_multiplier" field.
func
(
u
*
AccountUpsertOne
)
SetRateMultiplier
(
v
float64
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetRateMultiplier
(
v
)
})
}
// AddRateMultiplier adds v to the "rate_multiplier" field.
func
(
u
*
AccountUpsertOne
)
AddRateMultiplier
(
v
float64
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
AddRateMultiplier
(
v
)
})
}
// UpdateRateMultiplier sets the "rate_multiplier" field to the value that was provided on create.
func
(
u
*
AccountUpsertOne
)
UpdateRateMultiplier
()
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateRateMultiplier
()
})
}
// SetStatus sets the "status" field.
func
(
u
*
AccountUpsertOne
)
SetStatus
(
v
string
)
*
AccountUpsertOne
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
...
...
@@ -1956,6 +2020,27 @@ func (u *AccountUpsertBulk) UpdatePriority() *AccountUpsertBulk {
})
}
// SetRateMultiplier sets the "rate_multiplier" field.
func
(
u
*
AccountUpsertBulk
)
SetRateMultiplier
(
v
float64
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
SetRateMultiplier
(
v
)
})
}
// AddRateMultiplier adds v to the "rate_multiplier" field.
func
(
u
*
AccountUpsertBulk
)
AddRateMultiplier
(
v
float64
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
AddRateMultiplier
(
v
)
})
}
// UpdateRateMultiplier sets the "rate_multiplier" field to the value that was provided on create.
func
(
u
*
AccountUpsertBulk
)
UpdateRateMultiplier
()
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
s
.
UpdateRateMultiplier
()
})
}
// SetStatus sets the "status" field.
func
(
u
*
AccountUpsertBulk
)
SetStatus
(
v
string
)
*
AccountUpsertBulk
{
return
u
.
Update
(
func
(
s
*
AccountUpsert
)
{
...
...
backend/ent/account_update.go
View file @
90bce60b
...
...
@@ -193,6 +193,27 @@ func (_u *AccountUpdate) AddPriority(v int) *AccountUpdate {
return
_u
}
// SetRateMultiplier sets the "rate_multiplier" field.
func
(
_u
*
AccountUpdate
)
SetRateMultiplier
(
v
float64
)
*
AccountUpdate
{
_u
.
mutation
.
ResetRateMultiplier
()
_u
.
mutation
.
SetRateMultiplier
(
v
)
return
_u
}
// SetNillableRateMultiplier sets the "rate_multiplier" field if the given value is not nil.
func
(
_u
*
AccountUpdate
)
SetNillableRateMultiplier
(
v
*
float64
)
*
AccountUpdate
{
if
v
!=
nil
{
_u
.
SetRateMultiplier
(
*
v
)
}
return
_u
}
// AddRateMultiplier adds value to the "rate_multiplier" field.
func
(
_u
*
AccountUpdate
)
AddRateMultiplier
(
v
float64
)
*
AccountUpdate
{
_u
.
mutation
.
AddRateMultiplier
(
v
)
return
_u
}
// SetStatus sets the "status" field.
func
(
_u
*
AccountUpdate
)
SetStatus
(
v
string
)
*
AccountUpdate
{
_u
.
mutation
.
SetStatus
(
v
)
...
...
@@ -629,6 +650,12 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if
value
,
ok
:=
_u
.
mutation
.
AddedPriority
();
ok
{
_spec
.
AddField
(
account
.
FieldPriority
,
field
.
TypeInt
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
RateMultiplier
();
ok
{
_spec
.
SetField
(
account
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateMultiplier
();
ok
{
_spec
.
AddField
(
account
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Status
();
ok
{
_spec
.
SetField
(
account
.
FieldStatus
,
field
.
TypeString
,
value
)
}
...
...
@@ -1005,6 +1032,27 @@ func (_u *AccountUpdateOne) AddPriority(v int) *AccountUpdateOne {
return
_u
}
// SetRateMultiplier sets the "rate_multiplier" field.
func
(
_u
*
AccountUpdateOne
)
SetRateMultiplier
(
v
float64
)
*
AccountUpdateOne
{
_u
.
mutation
.
ResetRateMultiplier
()
_u
.
mutation
.
SetRateMultiplier
(
v
)
return
_u
}
// SetNillableRateMultiplier sets the "rate_multiplier" field if the given value is not nil.
func
(
_u
*
AccountUpdateOne
)
SetNillableRateMultiplier
(
v
*
float64
)
*
AccountUpdateOne
{
if
v
!=
nil
{
_u
.
SetRateMultiplier
(
*
v
)
}
return
_u
}
// AddRateMultiplier adds value to the "rate_multiplier" field.
func
(
_u
*
AccountUpdateOne
)
AddRateMultiplier
(
v
float64
)
*
AccountUpdateOne
{
_u
.
mutation
.
AddRateMultiplier
(
v
)
return
_u
}
// SetStatus sets the "status" field.
func
(
_u
*
AccountUpdateOne
)
SetStatus
(
v
string
)
*
AccountUpdateOne
{
_u
.
mutation
.
SetStatus
(
v
)
...
...
@@ -1471,6 +1519,12 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
if
value
,
ok
:=
_u
.
mutation
.
AddedPriority
();
ok
{
_spec
.
AddField
(
account
.
FieldPriority
,
field
.
TypeInt
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
RateMultiplier
();
ok
{
_spec
.
SetField
(
account
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateMultiplier
();
ok
{
_spec
.
AddField
(
account
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Status
();
ok
{
_spec
.
SetField
(
account
.
FieldStatus
,
field
.
TypeString
,
value
)
}
...
...
backend/ent/migrate/schema.go
View file @
90bce60b
...
...
@@ -79,6 +79,7 @@ var (
{
Name
:
"extra"
,
Type
:
field
.
TypeJSON
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"jsonb"
}},
{
Name
:
"concurrency"
,
Type
:
field
.
TypeInt
,
Default
:
3
},
{
Name
:
"priority"
,
Type
:
field
.
TypeInt
,
Default
:
50
},
{
Name
:
"rate_multiplier"
,
Type
:
field
.
TypeFloat64
,
Default
:
1
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(10,4)"
}},
{
Name
:
"status"
,
Type
:
field
.
TypeString
,
Size
:
20
,
Default
:
"active"
},
{
Name
:
"error_message"
,
Type
:
field
.
TypeString
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"text"
}},
{
Name
:
"last_used_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"timestamptz"
}},
...
...
@@ -101,7 +102,7 @@ var (
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
{
Symbol
:
"accounts_proxies_proxy"
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
4
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
5
]},
RefColumns
:
[]
*
schema
.
Column
{
ProxiesColumns
[
0
]},
OnDelete
:
schema
.
SetNull
,
},
...
...
@@ -120,12 +121,12 @@ var (
{
Name
:
"account_status"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
2
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
3
]},
},
{
Name
:
"account_proxy_id"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
4
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
5
]},
},
{
Name
:
"account_priority"
,
...
...
@@ -135,27 +136,27 @@ var (
{
Name
:
"account_last_used_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
4
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
5
]},
},
{
Name
:
"account_schedulable"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
7
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
8
]},
},
{
Name
:
"account_rate_limited_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
8
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
1
9
]},
},
{
Name
:
"account_rate_limit_reset_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
19
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
20
]},
},
{
Name
:
"account_overload_until"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
0
]},
Columns
:
[]
*
schema
.
Column
{
AccountsColumns
[
2
1
]},
},
{
Name
:
"account_deleted_at"
,
...
...
@@ -449,6 +450,7 @@ var (
{
Name
:
"total_cost"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,10)"
}},
{
Name
:
"actual_cost"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,10)"
}},
{
Name
:
"rate_multiplier"
,
Type
:
field
.
TypeFloat64
,
Default
:
1
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(10,4)"
}},
{
Name
:
"account_rate_multiplier"
,
Type
:
field
.
TypeFloat64
,
Nullable
:
true
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(10,4)"
}},
{
Name
:
"billing_type"
,
Type
:
field
.
TypeInt8
,
Default
:
0
},
{
Name
:
"stream"
,
Type
:
field
.
TypeBool
,
Default
:
false
},
{
Name
:
"duration_ms"
,
Type
:
field
.
TypeInt
,
Nullable
:
true
},
...
...
@@ -472,31 +474,31 @@ var (
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
{
Symbol
:
"usage_logs_api_keys_usage_logs"
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
5
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
6
]},
RefColumns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
0
]},
OnDelete
:
schema
.
NoAction
,
},
{
Symbol
:
"usage_logs_accounts_usage_logs"
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
6
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
7
]},
RefColumns
:
[]
*
schema
.
Column
{
AccountsColumns
[
0
]},
OnDelete
:
schema
.
NoAction
,
},
{
Symbol
:
"usage_logs_groups_usage_logs"
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
7
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
8
]},
RefColumns
:
[]
*
schema
.
Column
{
GroupsColumns
[
0
]},
OnDelete
:
schema
.
SetNull
,
},
{
Symbol
:
"usage_logs_users_usage_logs"
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
8
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
9
]},
RefColumns
:
[]
*
schema
.
Column
{
UsersColumns
[
0
]},
OnDelete
:
schema
.
NoAction
,
},
{
Symbol
:
"usage_logs_user_subscriptions_usage_logs"
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
29
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
30
]},
RefColumns
:
[]
*
schema
.
Column
{
UserSubscriptionsColumns
[
0
]},
OnDelete
:
schema
.
SetNull
,
},
...
...
@@ -505,32 +507,32 @@ var (
{
Name
:
"usagelog_user_id"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
8
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
9
]},
},
{
Name
:
"usagelog_api_key_id"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
5
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
6
]},
},
{
Name
:
"usagelog_account_id"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
6
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
7
]},
},
{
Name
:
"usagelog_group_id"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
7
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
8
]},
},
{
Name
:
"usagelog_subscription_id"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
29
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
30
]},
},
{
Name
:
"usagelog_created_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
4
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
5
]},
},
{
Name
:
"usagelog_model"
,
...
...
@@ -545,12 +547,12 @@ var (
{
Name
:
"usagelog_user_id_created_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
8
],
UsageLogsColumns
[
2
4
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
9
],
UsageLogsColumns
[
2
5
]},
},
{
Name
:
"usagelog_api_key_id_created_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
5
],
UsageLogsColumns
[
2
4
]},
Columns
:
[]
*
schema
.
Column
{
UsageLogsColumns
[
2
6
],
UsageLogsColumns
[
2
5
]},
},
},
}
...
...
backend/ent/mutation.go
View file @
90bce60b
...
...
@@ -1187,6 +1187,8 @@ type AccountMutation struct {
addconcurrency *int
priority *int
addpriority *int
rate_multiplier *float64
addrate_multiplier *float64
status *string
error_message *string
last_used_at *time.Time
...
...
@@ -1822,6 +1824,62 @@ func (m *AccountMutation) ResetPriority() {
m.addpriority = nil
}
// SetRateMultiplier sets the "rate_multiplier" field.
func (m *AccountMutation) SetRateMultiplier(f float64) {
m.rate_multiplier = &f
m.addrate_multiplier = nil
}
// RateMultiplier returns the value of the "rate_multiplier" field in the mutation.
func (m *AccountMutation) RateMultiplier() (r float64, exists bool) {
v := m.rate_multiplier
if v == nil {
return
}
return *v, true
}
// OldRateMultiplier returns the old "rate_multiplier" field's value of the Account entity.
// If the Account object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *AccountMutation) OldRateMultiplier(ctx context.Context) (v float64, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldRateMultiplier is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldRateMultiplier requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldRateMultiplier: %w", err)
}
return oldValue.RateMultiplier, nil
}
// AddRateMultiplier adds f to the "rate_multiplier" field.
func (m *AccountMutation) AddRateMultiplier(f float64) {
if m.addrate_multiplier != nil {
*m.addrate_multiplier += f
} else {
m.addrate_multiplier = &f
}
}
// AddedRateMultiplier returns the value that was added to the "rate_multiplier" field in this mutation.
func (m *AccountMutation) AddedRateMultiplier() (r float64, exists bool) {
v := m.addrate_multiplier
if v == nil {
return
}
return *v, true
}
// ResetRateMultiplier resets all changes to the "rate_multiplier" field.
func (m *AccountMutation) ResetRateMultiplier() {
m.rate_multiplier = nil
m.addrate_multiplier = nil
}
// SetStatus sets the "status" field.
func (m *AccountMutation) SetStatus(s string) {
m.status = &s
...
...
@@ -2540,7 +2598,7 @@ func (m *AccountMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *AccountMutation) Fields() []string {
fields := make([]string, 0, 2
4
)
fields := make([]string, 0, 2
5
)
if m.created_at != nil {
fields = append(fields, account.FieldCreatedAt)
}
...
...
@@ -2577,6 +2635,9 @@ func (m *AccountMutation) Fields() []string {
if m.priority != nil {
fields = append(fields, account.FieldPriority)
}
if m.rate_multiplier != nil {
fields = append(fields, account.FieldRateMultiplier)
}
if m.status != nil {
fields = append(fields, account.FieldStatus)
}
...
...
@@ -2645,6 +2706,8 @@ func (m *AccountMutation) Field(name string) (ent.Value, bool) {
return m.Concurrency()
case account.FieldPriority:
return m.Priority()
case account.FieldRateMultiplier:
return m.RateMultiplier()
case account.FieldStatus:
return m.Status()
case account.FieldErrorMessage:
...
...
@@ -2702,6 +2765,8 @@ func (m *AccountMutation) OldField(ctx context.Context, name string) (ent.Value,
return m.OldConcurrency(ctx)
case account.FieldPriority:
return m.OldPriority(ctx)
case account.FieldRateMultiplier:
return m.OldRateMultiplier(ctx)
case account.FieldStatus:
return m.OldStatus(ctx)
case account.FieldErrorMessage:
...
...
@@ -2819,6 +2884,13 @@ func (m *AccountMutation) SetField(name string, value ent.Value) error {
}
m.SetPriority(v)
return nil
case account.FieldRateMultiplier:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetRateMultiplier(v)
return nil
case account.FieldStatus:
v, ok := value.(string)
if !ok {
...
...
@@ -2917,6 +2989,9 @@ func (m *AccountMutation) AddedFields() []string {
if m.addpriority != nil {
fields = append(fields, account.FieldPriority)
}
if m.addrate_multiplier != nil {
fields = append(fields, account.FieldRateMultiplier)
}
return fields
}
...
...
@@ -2929,6 +3004,8 @@ func (m *AccountMutation) AddedField(name string) (ent.Value, bool) {
return m.AddedConcurrency()
case account.FieldPriority:
return m.AddedPriority()
case account.FieldRateMultiplier:
return m.AddedRateMultiplier()
}
return nil, false
}
...
...
@@ -2952,6 +3029,13 @@ func (m *AccountMutation) AddField(name string, value ent.Value) error {
}
m.AddPriority(v)
return nil
case account.FieldRateMultiplier:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.AddRateMultiplier(v)
return nil
}
return fmt.Errorf("unknown Account numeric field %s", name)
}
...
...
@@ -3090,6 +3174,9 @@ func (m *AccountMutation) ResetField(name string) error {
case account.FieldPriority:
m.ResetPriority()
return nil
case account.FieldRateMultiplier:
m.ResetRateMultiplier()
return nil
case account.FieldStatus:
m.ResetStatus()
return nil
...
...
@@ -10190,6 +10277,8 @@ type UsageLogMutation struct {
addactual_cost *float64
rate_multiplier *float64
addrate_multiplier *float64
account_rate_multiplier *float64
addaccount_rate_multiplier *float64
billing_type *int8
addbilling_type *int8
stream *bool
...
...
@@ -11323,6 +11412,76 @@ func (m *UsageLogMutation) ResetRateMultiplier() {
m.addrate_multiplier = nil
}
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
func (m *UsageLogMutation) SetAccountRateMultiplier(f float64) {
m.account_rate_multiplier = &f
m.addaccount_rate_multiplier = nil
}
// AccountRateMultiplier returns the value of the "account_rate_multiplier" field in the mutation.
func (m *UsageLogMutation) AccountRateMultiplier() (r float64, exists bool) {
v := m.account_rate_multiplier
if v == nil {
return
}
return *v, true
}
// OldAccountRateMultiplier returns the old "account_rate_multiplier" field's value of the UsageLog entity.
// If the UsageLog object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UsageLogMutation) OldAccountRateMultiplier(ctx context.Context) (v *float64, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldAccountRateMultiplier is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldAccountRateMultiplier requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldAccountRateMultiplier: %w", err)
}
return oldValue.AccountRateMultiplier, nil
}
// AddAccountRateMultiplier adds f to the "account_rate_multiplier" field.
func (m *UsageLogMutation) AddAccountRateMultiplier(f float64) {
if m.addaccount_rate_multiplier != nil {
*m.addaccount_rate_multiplier += f
} else {
m.addaccount_rate_multiplier = &f
}
}
// AddedAccountRateMultiplier returns the value that was added to the "account_rate_multiplier" field in this mutation.
func (m *UsageLogMutation) AddedAccountRateMultiplier() (r float64, exists bool) {
v := m.addaccount_rate_multiplier
if v == nil {
return
}
return *v, true
}
// ClearAccountRateMultiplier clears the value of the "account_rate_multiplier" field.
func (m *UsageLogMutation) ClearAccountRateMultiplier() {
m.account_rate_multiplier = nil
m.addaccount_rate_multiplier = nil
m.clearedFields[usagelog.FieldAccountRateMultiplier] = struct{}{}
}
// AccountRateMultiplierCleared returns if the "account_rate_multiplier" field was cleared in this mutation.
func (m *UsageLogMutation) AccountRateMultiplierCleared() bool {
_, ok := m.clearedFields[usagelog.FieldAccountRateMultiplier]
return ok
}
// ResetAccountRateMultiplier resets all changes to the "account_rate_multiplier" field.
func (m *UsageLogMutation) ResetAccountRateMultiplier() {
m.account_rate_multiplier = nil
m.addaccount_rate_multiplier = nil
delete(m.clearedFields, usagelog.FieldAccountRateMultiplier)
}
// SetBillingType sets the "billing_type" field.
func (m *UsageLogMutation) SetBillingType(i int8) {
m.billing_type = &i
...
...
@@ -11963,7 +12122,7 @@ func (m *UsageLogMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *UsageLogMutation) Fields() []string {
fields := make([]string, 0,
29
)
fields := make([]string, 0,
30
)
if m.user != nil {
fields = append(fields, usagelog.FieldUserID)
}
...
...
@@ -12024,6 +12183,9 @@ func (m *UsageLogMutation) Fields() []string {
if m.rate_multiplier != nil {
fields = append(fields, usagelog.FieldRateMultiplier)
}
if m.account_rate_multiplier != nil {
fields = append(fields, usagelog.FieldAccountRateMultiplier)
}
if m.billing_type != nil {
fields = append(fields, usagelog.FieldBillingType)
}
...
...
@@ -12099,6 +12261,8 @@ func (m *UsageLogMutation) Field(name string) (ent.Value, bool) {
return m.ActualCost()
case usagelog.FieldRateMultiplier:
return m.RateMultiplier()
case usagelog.FieldAccountRateMultiplier:
return m.AccountRateMultiplier()
case usagelog.FieldBillingType:
return m.BillingType()
case usagelog.FieldStream:
...
...
@@ -12166,6 +12330,8 @@ func (m *UsageLogMutation) OldField(ctx context.Context, name string) (ent.Value
return m.OldActualCost(ctx)
case usagelog.FieldRateMultiplier:
return m.OldRateMultiplier(ctx)
case usagelog.FieldAccountRateMultiplier:
return m.OldAccountRateMultiplier(ctx)
case usagelog.FieldBillingType:
return m.OldBillingType(ctx)
case usagelog.FieldStream:
...
...
@@ -12333,6 +12499,13 @@ func (m *UsageLogMutation) SetField(name string, value ent.Value) error {
}
m.SetRateMultiplier(v)
return nil
case usagelog.FieldAccountRateMultiplier:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetAccountRateMultiplier(v)
return nil
case usagelog.FieldBillingType:
v, ok := value.(int8)
if !ok {
...
...
@@ -12443,6 +12616,9 @@ func (m *UsageLogMutation) AddedFields() []string {
if m.addrate_multiplier != nil {
fields = append(fields, usagelog.FieldRateMultiplier)
}
if m.addaccount_rate_multiplier != nil {
fields = append(fields, usagelog.FieldAccountRateMultiplier)
}
if m.addbilling_type != nil {
fields = append(fields, usagelog.FieldBillingType)
}
...
...
@@ -12489,6 +12665,8 @@ func (m *UsageLogMutation) AddedField(name string) (ent.Value, bool) {
return m.AddedActualCost()
case usagelog.FieldRateMultiplier:
return m.AddedRateMultiplier()
case usagelog.FieldAccountRateMultiplier:
return m.AddedAccountRateMultiplier()
case usagelog.FieldBillingType:
return m.AddedBillingType()
case usagelog.FieldDurationMs:
...
...
@@ -12597,6 +12775,13 @@ func (m *UsageLogMutation) AddField(name string, value ent.Value) error {
}
m.AddRateMultiplier(v)
return nil
case usagelog.FieldAccountRateMultiplier:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.AddAccountRateMultiplier(v)
return nil
case usagelog.FieldBillingType:
v, ok := value.(int8)
if !ok {
...
...
@@ -12639,6 +12824,9 @@ func (m *UsageLogMutation) ClearedFields() []string {
if m.FieldCleared(usagelog.FieldSubscriptionID) {
fields = append(fields, usagelog.FieldSubscriptionID)
}
if m.FieldCleared(usagelog.FieldAccountRateMultiplier) {
fields = append(fields, usagelog.FieldAccountRateMultiplier)
}
if m.FieldCleared(usagelog.FieldDurationMs) {
fields = append(fields, usagelog.FieldDurationMs)
}
...
...
@@ -12674,6 +12862,9 @@ func (m *UsageLogMutation) ClearField(name string) error {
case usagelog.FieldSubscriptionID:
m.ClearSubscriptionID()
return nil
case usagelog.FieldAccountRateMultiplier:
m.ClearAccountRateMultiplier()
return nil
case usagelog.FieldDurationMs:
m.ClearDurationMs()
return nil
...
...
@@ -12757,6 +12948,9 @@ func (m *UsageLogMutation) ResetField(name string) error {
case usagelog.FieldRateMultiplier:
m.ResetRateMultiplier()
return nil
case usagelog.FieldAccountRateMultiplier:
m.ResetAccountRateMultiplier()
return nil
case usagelog.FieldBillingType:
m.ResetBillingType()
return nil
...
...
backend/ent/runtime/runtime.go
View file @
90bce60b
...
...
@@ -177,22 +177,26 @@ func init() {
accountDescPriority
:=
accountFields
[
8
]
.
Descriptor
()
// account.DefaultPriority holds the default value on creation for the priority field.
account
.
DefaultPriority
=
accountDescPriority
.
Default
.
(
int
)
// accountDescRateMultiplier is the schema descriptor for rate_multiplier field.
accountDescRateMultiplier
:=
accountFields
[
9
]
.
Descriptor
()
// account.DefaultRateMultiplier holds the default value on creation for the rate_multiplier field.
account
.
DefaultRateMultiplier
=
accountDescRateMultiplier
.
Default
.
(
float64
)
// accountDescStatus is the schema descriptor for status field.
accountDescStatus
:=
accountFields
[
9
]
.
Descriptor
()
accountDescStatus
:=
accountFields
[
10
]
.
Descriptor
()
// account.DefaultStatus holds the default value on creation for the status field.
account
.
DefaultStatus
=
accountDescStatus
.
Default
.
(
string
)
// account.StatusValidator is a validator for the "status" field. It is called by the builders before save.
account
.
StatusValidator
=
accountDescStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
// accountDescAutoPauseOnExpired is the schema descriptor for auto_pause_on_expired field.
accountDescAutoPauseOnExpired
:=
accountFields
[
1
3
]
.
Descriptor
()
accountDescAutoPauseOnExpired
:=
accountFields
[
1
4
]
.
Descriptor
()
// account.DefaultAutoPauseOnExpired holds the default value on creation for the auto_pause_on_expired field.
account
.
DefaultAutoPauseOnExpired
=
accountDescAutoPauseOnExpired
.
Default
.
(
bool
)
// accountDescSchedulable is the schema descriptor for schedulable field.
accountDescSchedulable
:=
accountFields
[
1
4
]
.
Descriptor
()
accountDescSchedulable
:=
accountFields
[
1
5
]
.
Descriptor
()
// account.DefaultSchedulable holds the default value on creation for the schedulable field.
account
.
DefaultSchedulable
=
accountDescSchedulable
.
Default
.
(
bool
)
// accountDescSessionWindowStatus is the schema descriptor for session_window_status field.
accountDescSessionWindowStatus
:=
accountFields
[
2
0
]
.
Descriptor
()
accountDescSessionWindowStatus
:=
accountFields
[
2
1
]
.
Descriptor
()
// account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
account
.
SessionWindowStatusValidator
=
accountDescSessionWindowStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
accountgroupFields
:=
schema
.
AccountGroup
{}
.
Fields
()
...
...
@@ -578,31 +582,31 @@ func init() {
// usagelog.DefaultRateMultiplier holds the default value on creation for the rate_multiplier field.
usagelog
.
DefaultRateMultiplier
=
usagelogDescRateMultiplier
.
Default
.
(
float64
)
// usagelogDescBillingType is the schema descriptor for billing_type field.
usagelogDescBillingType
:=
usagelogFields
[
2
0
]
.
Descriptor
()
usagelogDescBillingType
:=
usagelogFields
[
2
1
]
.
Descriptor
()
// usagelog.DefaultBillingType holds the default value on creation for the billing_type field.
usagelog
.
DefaultBillingType
=
usagelogDescBillingType
.
Default
.
(
int8
)
// usagelogDescStream is the schema descriptor for stream field.
usagelogDescStream
:=
usagelogFields
[
2
1
]
.
Descriptor
()
usagelogDescStream
:=
usagelogFields
[
2
2
]
.
Descriptor
()
// usagelog.DefaultStream holds the default value on creation for the stream field.
usagelog
.
DefaultStream
=
usagelogDescStream
.
Default
.
(
bool
)
// usagelogDescUserAgent is the schema descriptor for user_agent field.
usagelogDescUserAgent
:=
usagelogFields
[
2
4
]
.
Descriptor
()
usagelogDescUserAgent
:=
usagelogFields
[
2
5
]
.
Descriptor
()
// usagelog.UserAgentValidator is a validator for the "user_agent" field. It is called by the builders before save.
usagelog
.
UserAgentValidator
=
usagelogDescUserAgent
.
Validators
[
0
]
.
(
func
(
string
)
error
)
// usagelogDescIPAddress is the schema descriptor for ip_address field.
usagelogDescIPAddress
:=
usagelogFields
[
2
5
]
.
Descriptor
()
usagelogDescIPAddress
:=
usagelogFields
[
2
6
]
.
Descriptor
()
// usagelog.IPAddressValidator is a validator for the "ip_address" field. It is called by the builders before save.
usagelog
.
IPAddressValidator
=
usagelogDescIPAddress
.
Validators
[
0
]
.
(
func
(
string
)
error
)
// usagelogDescImageCount is the schema descriptor for image_count field.
usagelogDescImageCount
:=
usagelogFields
[
2
6
]
.
Descriptor
()
usagelogDescImageCount
:=
usagelogFields
[
2
7
]
.
Descriptor
()
// usagelog.DefaultImageCount holds the default value on creation for the image_count field.
usagelog
.
DefaultImageCount
=
usagelogDescImageCount
.
Default
.
(
int
)
// usagelogDescImageSize is the schema descriptor for image_size field.
usagelogDescImageSize
:=
usagelogFields
[
2
7
]
.
Descriptor
()
usagelogDescImageSize
:=
usagelogFields
[
2
8
]
.
Descriptor
()
// usagelog.ImageSizeValidator is a validator for the "image_size" field. It is called by the builders before save.
usagelog
.
ImageSizeValidator
=
usagelogDescImageSize
.
Validators
[
0
]
.
(
func
(
string
)
error
)
// usagelogDescCreatedAt is the schema descriptor for created_at field.
usagelogDescCreatedAt
:=
usagelogFields
[
2
8
]
.
Descriptor
()
usagelogDescCreatedAt
:=
usagelogFields
[
2
9
]
.
Descriptor
()
// usagelog.DefaultCreatedAt holds the default value on creation for the created_at field.
usagelog
.
DefaultCreatedAt
=
usagelogDescCreatedAt
.
Default
.
(
func
()
time
.
Time
)
userMixin
:=
schema
.
User
{}
.
Mixin
()
...
...
backend/ent/schema/account.go
View file @
90bce60b
...
...
@@ -102,6 +102,12 @@ func (Account) Fields() []ent.Field {
field
.
Int
(
"priority"
)
.
Default
(
50
),
// rate_multiplier: 账号计费倍率(>=0,允许 0 表示该账号计费为 0)
// 仅影响账号维度计费口径,不影响用户/API Key 扣费(分组倍率)
field
.
Float
(
"rate_multiplier"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(10,4)"
})
.
Default
(
1.0
),
// status: 账户状态,如 "active", "error", "disabled"
field
.
String
(
"status"
)
.
MaxLen
(
20
)
.
...
...
backend/ent/schema/usage_log.go
View file @
90bce60b
...
...
@@ -85,6 +85,12 @@ func (UsageLog) Fields() []ent.Field {
Default
(
1
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(10,4)"
}),
// account_rate_multiplier: 账号计费倍率快照(NULL 表示按 1.0 处理)
field
.
Float
(
"account_rate_multiplier"
)
.
Optional
()
.
Nillable
()
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(10,4)"
}),
// 其他字段
field
.
Int8
(
"billing_type"
)
.
Default
(
0
),
...
...
backend/ent/usagelog.go
View file @
90bce60b
...
...
@@ -62,6 +62,8 @@ type UsageLog struct {
ActualCost
float64
`json:"actual_cost,omitempty"`
// RateMultiplier holds the value of the "rate_multiplier" field.
RateMultiplier
float64
`json:"rate_multiplier,omitempty"`
// AccountRateMultiplier holds the value of the "account_rate_multiplier" field.
AccountRateMultiplier
*
float64
`json:"account_rate_multiplier,omitempty"`
// BillingType holds the value of the "billing_type" field.
BillingType
int8
`json:"billing_type,omitempty"`
// Stream holds the value of the "stream" field.
...
...
@@ -165,7 +167,7 @@ func (*UsageLog) scanValues(columns []string) ([]any, error) {
switch
columns
[
i
]
{
case
usagelog
.
FieldStream
:
values
[
i
]
=
new
(
sql
.
NullBool
)
case
usagelog
.
FieldInputCost
,
usagelog
.
FieldOutputCost
,
usagelog
.
FieldCacheCreationCost
,
usagelog
.
FieldCacheReadCost
,
usagelog
.
FieldTotalCost
,
usagelog
.
FieldActualCost
,
usagelog
.
FieldRateMultiplier
:
case
usagelog
.
FieldInputCost
,
usagelog
.
FieldOutputCost
,
usagelog
.
FieldCacheCreationCost
,
usagelog
.
FieldCacheReadCost
,
usagelog
.
FieldTotalCost
,
usagelog
.
FieldActualCost
,
usagelog
.
FieldRateMultiplier
,
usagelog
.
FieldAccountRateMultiplier
:
values
[
i
]
=
new
(
sql
.
NullFloat64
)
case
usagelog
.
FieldID
,
usagelog
.
FieldUserID
,
usagelog
.
FieldAPIKeyID
,
usagelog
.
FieldAccountID
,
usagelog
.
FieldGroupID
,
usagelog
.
FieldSubscriptionID
,
usagelog
.
FieldInputTokens
,
usagelog
.
FieldOutputTokens
,
usagelog
.
FieldCacheCreationTokens
,
usagelog
.
FieldCacheReadTokens
,
usagelog
.
FieldCacheCreation5mTokens
,
usagelog
.
FieldCacheCreation1hTokens
,
usagelog
.
FieldBillingType
,
usagelog
.
FieldDurationMs
,
usagelog
.
FieldFirstTokenMs
,
usagelog
.
FieldImageCount
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
...
...
@@ -316,6 +318,13 @@ func (_m *UsageLog) assignValues(columns []string, values []any) error {
}
else
if
value
.
Valid
{
_m
.
RateMultiplier
=
value
.
Float64
}
case
usagelog
.
FieldAccountRateMultiplier
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field account_rate_multiplier"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
AccountRateMultiplier
=
new
(
float64
)
*
_m
.
AccountRateMultiplier
=
value
.
Float64
}
case
usagelog
.
FieldBillingType
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field billing_type"
,
values
[
i
])
...
...
@@ -500,6 +509,11 @@ func (_m *UsageLog) String() string {
builder
.
WriteString
(
"rate_multiplier="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
RateMultiplier
))
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
AccountRateMultiplier
;
v
!=
nil
{
builder
.
WriteString
(
"account_rate_multiplier="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
*
v
))
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"billing_type="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
BillingType
))
builder
.
WriteString
(
", "
)
...
...
backend/ent/usagelog/usagelog.go
View file @
90bce60b
...
...
@@ -54,6 +54,8 @@ const (
FieldActualCost
=
"actual_cost"
// FieldRateMultiplier holds the string denoting the rate_multiplier field in the database.
FieldRateMultiplier
=
"rate_multiplier"
// FieldAccountRateMultiplier holds the string denoting the account_rate_multiplier field in the database.
FieldAccountRateMultiplier
=
"account_rate_multiplier"
// FieldBillingType holds the string denoting the billing_type field in the database.
FieldBillingType
=
"billing_type"
// FieldStream holds the string denoting the stream field in the database.
...
...
@@ -144,6 +146,7 @@ var Columns = []string{
FieldTotalCost
,
FieldActualCost
,
FieldRateMultiplier
,
FieldAccountRateMultiplier
,
FieldBillingType
,
FieldStream
,
FieldDurationMs
,
...
...
@@ -320,6 +323,11 @@ func ByRateMultiplier(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldRateMultiplier
,
opts
...
)
.
ToFunc
()
}
// ByAccountRateMultiplier orders the results by the account_rate_multiplier field.
func
ByAccountRateMultiplier
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldAccountRateMultiplier
,
opts
...
)
.
ToFunc
()
}
// ByBillingType orders the results by the billing_type field.
func
ByBillingType
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldBillingType
,
opts
...
)
.
ToFunc
()
...
...
backend/ent/usagelog/where.go
View file @
90bce60b
...
...
@@ -155,6 +155,11 @@ func RateMultiplier(v float64) predicate.UsageLog {
return
predicate
.
UsageLog
(
sql
.
FieldEQ
(
FieldRateMultiplier
,
v
))
}
// AccountRateMultiplier applies equality check predicate on the "account_rate_multiplier" field. It's identical to AccountRateMultiplierEQ.
func
AccountRateMultiplier
(
v
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldEQ
(
FieldAccountRateMultiplier
,
v
))
}
// BillingType applies equality check predicate on the "billing_type" field. It's identical to BillingTypeEQ.
func
BillingType
(
v
int8
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldEQ
(
FieldBillingType
,
v
))
...
...
@@ -970,6 +975,56 @@ func RateMultiplierLTE(v float64) predicate.UsageLog {
return
predicate
.
UsageLog
(
sql
.
FieldLTE
(
FieldRateMultiplier
,
v
))
}
// AccountRateMultiplierEQ applies the EQ predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierEQ
(
v
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldEQ
(
FieldAccountRateMultiplier
,
v
))
}
// AccountRateMultiplierNEQ applies the NEQ predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierNEQ
(
v
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldNEQ
(
FieldAccountRateMultiplier
,
v
))
}
// AccountRateMultiplierIn applies the In predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierIn
(
vs
...
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldIn
(
FieldAccountRateMultiplier
,
vs
...
))
}
// AccountRateMultiplierNotIn applies the NotIn predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierNotIn
(
vs
...
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldNotIn
(
FieldAccountRateMultiplier
,
vs
...
))
}
// AccountRateMultiplierGT applies the GT predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierGT
(
v
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldGT
(
FieldAccountRateMultiplier
,
v
))
}
// AccountRateMultiplierGTE applies the GTE predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierGTE
(
v
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldGTE
(
FieldAccountRateMultiplier
,
v
))
}
// AccountRateMultiplierLT applies the LT predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierLT
(
v
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldLT
(
FieldAccountRateMultiplier
,
v
))
}
// AccountRateMultiplierLTE applies the LTE predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierLTE
(
v
float64
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldLTE
(
FieldAccountRateMultiplier
,
v
))
}
// AccountRateMultiplierIsNil applies the IsNil predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierIsNil
()
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldIsNull
(
FieldAccountRateMultiplier
))
}
// AccountRateMultiplierNotNil applies the NotNil predicate on the "account_rate_multiplier" field.
func
AccountRateMultiplierNotNil
()
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldNotNull
(
FieldAccountRateMultiplier
))
}
// BillingTypeEQ applies the EQ predicate on the "billing_type" field.
func
BillingTypeEQ
(
v
int8
)
predicate
.
UsageLog
{
return
predicate
.
UsageLog
(
sql
.
FieldEQ
(
FieldBillingType
,
v
))
...
...
backend/ent/usagelog_create.go
View file @
90bce60b
...
...
@@ -267,6 +267,20 @@ func (_c *UsageLogCreate) SetNillableRateMultiplier(v *float64) *UsageLogCreate
return
_c
}
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
func
(
_c
*
UsageLogCreate
)
SetAccountRateMultiplier
(
v
float64
)
*
UsageLogCreate
{
_c
.
mutation
.
SetAccountRateMultiplier
(
v
)
return
_c
}
// SetNillableAccountRateMultiplier sets the "account_rate_multiplier" field if the given value is not nil.
func
(
_c
*
UsageLogCreate
)
SetNillableAccountRateMultiplier
(
v
*
float64
)
*
UsageLogCreate
{
if
v
!=
nil
{
_c
.
SetAccountRateMultiplier
(
*
v
)
}
return
_c
}
// SetBillingType sets the "billing_type" field.
func
(
_c
*
UsageLogCreate
)
SetBillingType
(
v
int8
)
*
UsageLogCreate
{
_c
.
mutation
.
SetBillingType
(
v
)
...
...
@@ -712,6 +726,10 @@ func (_c *UsageLogCreate) createSpec() (*UsageLog, *sqlgraph.CreateSpec) {
_spec
.
SetField
(
usagelog
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
_node
.
RateMultiplier
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
AccountRateMultiplier
();
ok
{
_spec
.
SetField
(
usagelog
.
FieldAccountRateMultiplier
,
field
.
TypeFloat64
,
value
)
_node
.
AccountRateMultiplier
=
&
value
}
if
value
,
ok
:=
_c
.
mutation
.
BillingType
();
ok
{
_spec
.
SetField
(
usagelog
.
FieldBillingType
,
field
.
TypeInt8
,
value
)
_node
.
BillingType
=
value
...
...
@@ -1215,6 +1233,30 @@ func (u *UsageLogUpsert) AddRateMultiplier(v float64) *UsageLogUpsert {
return
u
}
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsert
)
SetAccountRateMultiplier
(
v
float64
)
*
UsageLogUpsert
{
u
.
Set
(
usagelog
.
FieldAccountRateMultiplier
,
v
)
return
u
}
// UpdateAccountRateMultiplier sets the "account_rate_multiplier" field to the value that was provided on create.
func
(
u
*
UsageLogUpsert
)
UpdateAccountRateMultiplier
()
*
UsageLogUpsert
{
u
.
SetExcluded
(
usagelog
.
FieldAccountRateMultiplier
)
return
u
}
// AddAccountRateMultiplier adds v to the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsert
)
AddAccountRateMultiplier
(
v
float64
)
*
UsageLogUpsert
{
u
.
Add
(
usagelog
.
FieldAccountRateMultiplier
,
v
)
return
u
}
// ClearAccountRateMultiplier clears the value of the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsert
)
ClearAccountRateMultiplier
()
*
UsageLogUpsert
{
u
.
SetNull
(
usagelog
.
FieldAccountRateMultiplier
)
return
u
}
// SetBillingType sets the "billing_type" field.
func
(
u
*
UsageLogUpsert
)
SetBillingType
(
v
int8
)
*
UsageLogUpsert
{
u
.
Set
(
usagelog
.
FieldBillingType
,
v
)
...
...
@@ -1795,6 +1837,34 @@ func (u *UsageLogUpsertOne) UpdateRateMultiplier() *UsageLogUpsertOne {
})
}
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsertOne
)
SetAccountRateMultiplier
(
v
float64
)
*
UsageLogUpsertOne
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
SetAccountRateMultiplier
(
v
)
})
}
// AddAccountRateMultiplier adds v to the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsertOne
)
AddAccountRateMultiplier
(
v
float64
)
*
UsageLogUpsertOne
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
AddAccountRateMultiplier
(
v
)
})
}
// UpdateAccountRateMultiplier sets the "account_rate_multiplier" field to the value that was provided on create.
func
(
u
*
UsageLogUpsertOne
)
UpdateAccountRateMultiplier
()
*
UsageLogUpsertOne
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
UpdateAccountRateMultiplier
()
})
}
// ClearAccountRateMultiplier clears the value of the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsertOne
)
ClearAccountRateMultiplier
()
*
UsageLogUpsertOne
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
ClearAccountRateMultiplier
()
})
}
// SetBillingType sets the "billing_type" field.
func
(
u
*
UsageLogUpsertOne
)
SetBillingType
(
v
int8
)
*
UsageLogUpsertOne
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
...
...
@@ -2566,6 +2636,34 @@ func (u *UsageLogUpsertBulk) UpdateRateMultiplier() *UsageLogUpsertBulk {
})
}
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsertBulk
)
SetAccountRateMultiplier
(
v
float64
)
*
UsageLogUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
SetAccountRateMultiplier
(
v
)
})
}
// AddAccountRateMultiplier adds v to the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsertBulk
)
AddAccountRateMultiplier
(
v
float64
)
*
UsageLogUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
AddAccountRateMultiplier
(
v
)
})
}
// UpdateAccountRateMultiplier sets the "account_rate_multiplier" field to the value that was provided on create.
func
(
u
*
UsageLogUpsertBulk
)
UpdateAccountRateMultiplier
()
*
UsageLogUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
UpdateAccountRateMultiplier
()
})
}
// ClearAccountRateMultiplier clears the value of the "account_rate_multiplier" field.
func
(
u
*
UsageLogUpsertBulk
)
ClearAccountRateMultiplier
()
*
UsageLogUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
s
.
ClearAccountRateMultiplier
()
})
}
// SetBillingType sets the "billing_type" field.
func
(
u
*
UsageLogUpsertBulk
)
SetBillingType
(
v
int8
)
*
UsageLogUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UsageLogUpsert
)
{
...
...
backend/ent/usagelog_update.go
View file @
90bce60b
...
...
@@ -415,6 +415,33 @@ func (_u *UsageLogUpdate) AddRateMultiplier(v float64) *UsageLogUpdate {
return
_u
}
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
func
(
_u
*
UsageLogUpdate
)
SetAccountRateMultiplier
(
v
float64
)
*
UsageLogUpdate
{
_u
.
mutation
.
ResetAccountRateMultiplier
()
_u
.
mutation
.
SetAccountRateMultiplier
(
v
)
return
_u
}
// SetNillableAccountRateMultiplier sets the "account_rate_multiplier" field if the given value is not nil.
func
(
_u
*
UsageLogUpdate
)
SetNillableAccountRateMultiplier
(
v
*
float64
)
*
UsageLogUpdate
{
if
v
!=
nil
{
_u
.
SetAccountRateMultiplier
(
*
v
)
}
return
_u
}
// AddAccountRateMultiplier adds value to the "account_rate_multiplier" field.
func
(
_u
*
UsageLogUpdate
)
AddAccountRateMultiplier
(
v
float64
)
*
UsageLogUpdate
{
_u
.
mutation
.
AddAccountRateMultiplier
(
v
)
return
_u
}
// ClearAccountRateMultiplier clears the value of the "account_rate_multiplier" field.
func
(
_u
*
UsageLogUpdate
)
ClearAccountRateMultiplier
()
*
UsageLogUpdate
{
_u
.
mutation
.
ClearAccountRateMultiplier
()
return
_u
}
// SetBillingType sets the "billing_type" field.
func
(
_u
*
UsageLogUpdate
)
SetBillingType
(
v
int8
)
*
UsageLogUpdate
{
_u
.
mutation
.
ResetBillingType
()
...
...
@@ -807,6 +834,15 @@ func (_u *UsageLogUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if
value
,
ok
:=
_u
.
mutation
.
AddedRateMultiplier
();
ok
{
_spec
.
AddField
(
usagelog
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AccountRateMultiplier
();
ok
{
_spec
.
SetField
(
usagelog
.
FieldAccountRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedAccountRateMultiplier
();
ok
{
_spec
.
AddField
(
usagelog
.
FieldAccountRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
_u
.
mutation
.
AccountRateMultiplierCleared
()
{
_spec
.
ClearField
(
usagelog
.
FieldAccountRateMultiplier
,
field
.
TypeFloat64
)
}
if
value
,
ok
:=
_u
.
mutation
.
BillingType
();
ok
{
_spec
.
SetField
(
usagelog
.
FieldBillingType
,
field
.
TypeInt8
,
value
)
}
...
...
@@ -1406,6 +1442,33 @@ func (_u *UsageLogUpdateOne) AddRateMultiplier(v float64) *UsageLogUpdateOne {
return
_u
}
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
func
(
_u
*
UsageLogUpdateOne
)
SetAccountRateMultiplier
(
v
float64
)
*
UsageLogUpdateOne
{
_u
.
mutation
.
ResetAccountRateMultiplier
()
_u
.
mutation
.
SetAccountRateMultiplier
(
v
)
return
_u
}
// SetNillableAccountRateMultiplier sets the "account_rate_multiplier" field if the given value is not nil.
func
(
_u
*
UsageLogUpdateOne
)
SetNillableAccountRateMultiplier
(
v
*
float64
)
*
UsageLogUpdateOne
{
if
v
!=
nil
{
_u
.
SetAccountRateMultiplier
(
*
v
)
}
return
_u
}
// AddAccountRateMultiplier adds value to the "account_rate_multiplier" field.
func
(
_u
*
UsageLogUpdateOne
)
AddAccountRateMultiplier
(
v
float64
)
*
UsageLogUpdateOne
{
_u
.
mutation
.
AddAccountRateMultiplier
(
v
)
return
_u
}
// ClearAccountRateMultiplier clears the value of the "account_rate_multiplier" field.
func
(
_u
*
UsageLogUpdateOne
)
ClearAccountRateMultiplier
()
*
UsageLogUpdateOne
{
_u
.
mutation
.
ClearAccountRateMultiplier
()
return
_u
}
// SetBillingType sets the "billing_type" field.
func
(
_u
*
UsageLogUpdateOne
)
SetBillingType
(
v
int8
)
*
UsageLogUpdateOne
{
_u
.
mutation
.
ResetBillingType
()
...
...
@@ -1828,6 +1891,15 @@ func (_u *UsageLogUpdateOne) sqlSave(ctx context.Context) (_node *UsageLog, err
if
value
,
ok
:=
_u
.
mutation
.
AddedRateMultiplier
();
ok
{
_spec
.
AddField
(
usagelog
.
FieldRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AccountRateMultiplier
();
ok
{
_spec
.
SetField
(
usagelog
.
FieldAccountRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedAccountRateMultiplier
();
ok
{
_spec
.
AddField
(
usagelog
.
FieldAccountRateMultiplier
,
field
.
TypeFloat64
,
value
)
}
if
_u
.
mutation
.
AccountRateMultiplierCleared
()
{
_spec
.
ClearField
(
usagelog
.
FieldAccountRateMultiplier
,
field
.
TypeFloat64
)
}
if
value
,
ok
:=
_u
.
mutation
.
BillingType
();
ok
{
_spec
.
SetField
(
usagelog
.
FieldBillingType
,
field
.
TypeInt8
,
value
)
}
...
...
backend/internal/handler/admin/account_handler.go
View file @
90bce60b
...
...
@@ -84,6 +84,7 @@ type CreateAccountRequest struct {
ProxyID
*
int64
`json:"proxy_id"`
Concurrency
int
`json:"concurrency"`
Priority
int
`json:"priority"`
RateMultiplier
*
float64
`json:"rate_multiplier"`
GroupIDs
[]
int64
`json:"group_ids"`
ExpiresAt
*
int64
`json:"expires_at"`
AutoPauseOnExpired
*
bool
`json:"auto_pause_on_expired"`
...
...
@@ -101,6 +102,7 @@ type UpdateAccountRequest struct {
ProxyID
*
int64
`json:"proxy_id"`
Concurrency
*
int
`json:"concurrency"`
Priority
*
int
`json:"priority"`
RateMultiplier
*
float64
`json:"rate_multiplier"`
Status
string
`json:"status" binding:"omitempty,oneof=active inactive"`
GroupIDs
*
[]
int64
`json:"group_ids"`
ExpiresAt
*
int64
`json:"expires_at"`
...
...
@@ -115,6 +117,7 @@ type BulkUpdateAccountsRequest struct {
ProxyID
*
int64
`json:"proxy_id"`
Concurrency
*
int
`json:"concurrency"`
Priority
*
int
`json:"priority"`
RateMultiplier
*
float64
`json:"rate_multiplier"`
Status
string
`json:"status" binding:"omitempty,oneof=active inactive error"`
Schedulable
*
bool
`json:"schedulable"`
GroupIDs
*
[]
int64
`json:"group_ids"`
...
...
@@ -199,6 +202,10 @@ func (h *AccountHandler) Create(c *gin.Context) {
response
.
BadRequest
(
c
,
"Invalid request: "
+
err
.
Error
())
return
}
if
req
.
RateMultiplier
!=
nil
&&
*
req
.
RateMultiplier
<
0
{
response
.
BadRequest
(
c
,
"rate_multiplier must be >= 0"
)
return
}
// 确定是否跳过混合渠道检查
skipCheck
:=
req
.
ConfirmMixedChannelRisk
!=
nil
&&
*
req
.
ConfirmMixedChannelRisk
...
...
@@ -213,6 +220,7 @@ func (h *AccountHandler) Create(c *gin.Context) {
ProxyID
:
req
.
ProxyID
,
Concurrency
:
req
.
Concurrency
,
Priority
:
req
.
Priority
,
RateMultiplier
:
req
.
RateMultiplier
,
GroupIDs
:
req
.
GroupIDs
,
ExpiresAt
:
req
.
ExpiresAt
,
AutoPauseOnExpired
:
req
.
AutoPauseOnExpired
,
...
...
@@ -258,6 +266,10 @@ func (h *AccountHandler) Update(c *gin.Context) {
response
.
BadRequest
(
c
,
"Invalid request: "
+
err
.
Error
())
return
}
if
req
.
RateMultiplier
!=
nil
&&
*
req
.
RateMultiplier
<
0
{
response
.
BadRequest
(
c
,
"rate_multiplier must be >= 0"
)
return
}
// 确定是否跳过混合渠道检查
skipCheck
:=
req
.
ConfirmMixedChannelRisk
!=
nil
&&
*
req
.
ConfirmMixedChannelRisk
...
...
@@ -271,6 +283,7 @@ func (h *AccountHandler) Update(c *gin.Context) {
ProxyID
:
req
.
ProxyID
,
Concurrency
:
req
.
Concurrency
,
// 指针类型,nil 表示未提供
Priority
:
req
.
Priority
,
// 指针类型,nil 表示未提供
RateMultiplier
:
req
.
RateMultiplier
,
Status
:
req
.
Status
,
GroupIDs
:
req
.
GroupIDs
,
ExpiresAt
:
req
.
ExpiresAt
,
...
...
@@ -652,6 +665,10 @@ func (h *AccountHandler) BulkUpdate(c *gin.Context) {
response
.
BadRequest
(
c
,
"Invalid request: "
+
err
.
Error
())
return
}
if
req
.
RateMultiplier
!=
nil
&&
*
req
.
RateMultiplier
<
0
{
response
.
BadRequest
(
c
,
"rate_multiplier must be >= 0"
)
return
}
// 确定是否跳过混合渠道检查
skipCheck
:=
req
.
ConfirmMixedChannelRisk
!=
nil
&&
*
req
.
ConfirmMixedChannelRisk
...
...
@@ -660,6 +677,7 @@ func (h *AccountHandler) BulkUpdate(c *gin.Context) {
req
.
ProxyID
!=
nil
||
req
.
Concurrency
!=
nil
||
req
.
Priority
!=
nil
||
req
.
RateMultiplier
!=
nil
||
req
.
Status
!=
""
||
req
.
Schedulable
!=
nil
||
req
.
GroupIDs
!=
nil
||
...
...
@@ -677,6 +695,7 @@ func (h *AccountHandler) BulkUpdate(c *gin.Context) {
ProxyID
:
req
.
ProxyID
,
Concurrency
:
req
.
Concurrency
,
Priority
:
req
.
Priority
,
RateMultiplier
:
req
.
RateMultiplier
,
Status
:
req
.
Status
,
Schedulable
:
req
.
Schedulable
,
GroupIDs
:
req
.
GroupIDs
,
...
...
backend/internal/handler/admin/dashboard_handler.go
View file @
90bce60b
...
...
@@ -186,13 +186,16 @@ func (h *DashboardHandler) GetRealtimeMetrics(c *gin.Context) {
// GetUsageTrend handles getting usage trend data
// GET /api/v1/admin/dashboard/trend
// Query params: start_date, end_date (YYYY-MM-DD), granularity (day/hour), user_id, api_key_id
// Query params: start_date, end_date (YYYY-MM-DD), granularity (day/hour), user_id, api_key_id
, model, account_id, group_id, stream
func
(
h
*
DashboardHandler
)
GetUsageTrend
(
c
*
gin
.
Context
)
{
startTime
,
endTime
:=
parseTimeRange
(
c
)
granularity
:=
c
.
DefaultQuery
(
"granularity"
,
"day"
)
// Parse optional filter params
var
userID
,
apiKeyID
int64
var
userID
,
apiKeyID
,
accountID
,
groupID
int64
var
model
string
var
stream
*
bool
if
userIDStr
:=
c
.
Query
(
"user_id"
);
userIDStr
!=
""
{
if
id
,
err
:=
strconv
.
ParseInt
(
userIDStr
,
10
,
64
);
err
==
nil
{
userID
=
id
...
...
@@ -203,8 +206,26 @@ func (h *DashboardHandler) GetUsageTrend(c *gin.Context) {
apiKeyID
=
id
}
}
if
accountIDStr
:=
c
.
Query
(
"account_id"
);
accountIDStr
!=
""
{
if
id
,
err
:=
strconv
.
ParseInt
(
accountIDStr
,
10
,
64
);
err
==
nil
{
accountID
=
id
}
}
if
groupIDStr
:=
c
.
Query
(
"group_id"
);
groupIDStr
!=
""
{
if
id
,
err
:=
strconv
.
ParseInt
(
groupIDStr
,
10
,
64
);
err
==
nil
{
groupID
=
id
}
}
if
modelStr
:=
c
.
Query
(
"model"
);
modelStr
!=
""
{
model
=
modelStr
}
if
streamStr
:=
c
.
Query
(
"stream"
);
streamStr
!=
""
{
if
streamVal
,
err
:=
strconv
.
ParseBool
(
streamStr
);
err
==
nil
{
stream
=
&
streamVal
}
}
trend
,
err
:=
h
.
dashboardService
.
GetUsageTrendWithFilters
(
c
.
Request
.
Context
(),
startTime
,
endTime
,
granularity
,
userID
,
apiKeyID
)
trend
,
err
:=
h
.
dashboardService
.
GetUsageTrendWithFilters
(
c
.
Request
.
Context
(),
startTime
,
endTime
,
granularity
,
userID
,
apiKeyID
,
accountID
,
groupID
,
model
,
stream
)
if
err
!=
nil
{
response
.
Error
(
c
,
500
,
"Failed to get usage trend"
)
return
...
...
@@ -220,12 +241,14 @@ func (h *DashboardHandler) GetUsageTrend(c *gin.Context) {
// GetModelStats handles getting model usage statistics
// GET /api/v1/admin/dashboard/models
// Query params: start_date, end_date (YYYY-MM-DD), user_id, api_key_id
// Query params: start_date, end_date (YYYY-MM-DD), user_id, api_key_id
, account_id, group_id, stream
func
(
h
*
DashboardHandler
)
GetModelStats
(
c
*
gin
.
Context
)
{
startTime
,
endTime
:=
parseTimeRange
(
c
)
// Parse optional filter params
var
userID
,
apiKeyID
int64
var
userID
,
apiKeyID
,
accountID
,
groupID
int64
var
stream
*
bool
if
userIDStr
:=
c
.
Query
(
"user_id"
);
userIDStr
!=
""
{
if
id
,
err
:=
strconv
.
ParseInt
(
userIDStr
,
10
,
64
);
err
==
nil
{
userID
=
id
...
...
@@ -236,8 +259,23 @@ func (h *DashboardHandler) GetModelStats(c *gin.Context) {
apiKeyID
=
id
}
}
if
accountIDStr
:=
c
.
Query
(
"account_id"
);
accountIDStr
!=
""
{
if
id
,
err
:=
strconv
.
ParseInt
(
accountIDStr
,
10
,
64
);
err
==
nil
{
accountID
=
id
}
}
if
groupIDStr
:=
c
.
Query
(
"group_id"
);
groupIDStr
!=
""
{
if
id
,
err
:=
strconv
.
ParseInt
(
groupIDStr
,
10
,
64
);
err
==
nil
{
groupID
=
id
}
}
if
streamStr
:=
c
.
Query
(
"stream"
);
streamStr
!=
""
{
if
streamVal
,
err
:=
strconv
.
ParseBool
(
streamStr
);
err
==
nil
{
stream
=
&
streamVal
}
}
stats
,
err
:=
h
.
dashboardService
.
GetModelStatsWithFilters
(
c
.
Request
.
Context
(),
startTime
,
endTime
,
userID
,
apiKeyID
)
stats
,
err
:=
h
.
dashboardService
.
GetModelStatsWithFilters
(
c
.
Request
.
Context
(),
startTime
,
endTime
,
userID
,
apiKeyID
,
accountID
,
groupID
,
stream
)
if
err
!=
nil
{
response
.
Error
(
c
,
500
,
"Failed to get model statistics"
)
return
...
...
backend/internal/handler/admin/ops_alerts_handler.go
View file @
90bce60b
...
...
@@ -7,8 +7,10 @@ import (
"net/http"
"strconv"
"strings"
"time"
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
"github.com/Wei-Shaw/sub2api/internal/server/middleware"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
...
...
@@ -18,8 +20,6 @@ var validOpsAlertMetricTypes = []string{
"success_rate"
,
"error_rate"
,
"upstream_error_rate"
,
"p95_latency_ms"
,
"p99_latency_ms"
,
"cpu_usage_percent"
,
"memory_usage_percent"
,
"concurrency_queue_depth"
,
...
...
@@ -372,8 +372,135 @@ func (h *OpsHandler) DeleteAlertRule(c *gin.Context) {
response
.
Success
(
c
,
gin
.
H
{
"deleted"
:
true
})
}
// GetAlertEvent returns a single ops alert event.
// GET /api/v1/admin/ops/alert-events/:id
func
(
h
*
OpsHandler
)
GetAlertEvent
(
c
*
gin
.
Context
)
{
if
h
.
opsService
==
nil
{
response
.
Error
(
c
,
http
.
StatusServiceUnavailable
,
"Ops service not available"
)
return
}
if
err
:=
h
.
opsService
.
RequireMonitoringEnabled
(
c
.
Request
.
Context
());
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
id
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
||
id
<=
0
{
response
.
BadRequest
(
c
,
"Invalid event ID"
)
return
}
ev
,
err
:=
h
.
opsService
.
GetAlertEventByID
(
c
.
Request
.
Context
(),
id
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
ev
)
}
// UpdateAlertEventStatus updates an ops alert event status.
// PUT /api/v1/admin/ops/alert-events/:id/status
func
(
h
*
OpsHandler
)
UpdateAlertEventStatus
(
c
*
gin
.
Context
)
{
if
h
.
opsService
==
nil
{
response
.
Error
(
c
,
http
.
StatusServiceUnavailable
,
"Ops service not available"
)
return
}
if
err
:=
h
.
opsService
.
RequireMonitoringEnabled
(
c
.
Request
.
Context
());
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
id
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
||
id
<=
0
{
response
.
BadRequest
(
c
,
"Invalid event ID"
)
return
}
var
payload
struct
{
Status
string
`json:"status"`
}
if
err
:=
c
.
ShouldBindJSON
(
&
payload
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid request body"
)
return
}
payload
.
Status
=
strings
.
TrimSpace
(
payload
.
Status
)
if
payload
.
Status
==
""
{
response
.
BadRequest
(
c
,
"Invalid status"
)
return
}
if
payload
.
Status
!=
service
.
OpsAlertStatusResolved
&&
payload
.
Status
!=
service
.
OpsAlertStatusManualResolved
{
response
.
BadRequest
(
c
,
"Invalid status"
)
return
}
var
resolvedAt
*
time
.
Time
if
payload
.
Status
==
service
.
OpsAlertStatusResolved
||
payload
.
Status
==
service
.
OpsAlertStatusManualResolved
{
now
:=
time
.
Now
()
.
UTC
()
resolvedAt
=
&
now
}
if
err
:=
h
.
opsService
.
UpdateAlertEventStatus
(
c
.
Request
.
Context
(),
id
,
payload
.
Status
,
resolvedAt
);
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
gin
.
H
{
"updated"
:
true
})
}
// ListAlertEvents lists recent ops alert events.
// GET /api/v1/admin/ops/alert-events
// CreateAlertSilence creates a scoped silence for ops alerts.
// POST /api/v1/admin/ops/alert-silences
func
(
h
*
OpsHandler
)
CreateAlertSilence
(
c
*
gin
.
Context
)
{
if
h
.
opsService
==
nil
{
response
.
Error
(
c
,
http
.
StatusServiceUnavailable
,
"Ops service not available"
)
return
}
if
err
:=
h
.
opsService
.
RequireMonitoringEnabled
(
c
.
Request
.
Context
());
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
var
payload
struct
{
RuleID
int64
`json:"rule_id"`
Platform
string
`json:"platform"`
GroupID
*
int64
`json:"group_id"`
Region
*
string
`json:"region"`
Until
string
`json:"until"`
Reason
string
`json:"reason"`
}
if
err
:=
c
.
ShouldBindJSON
(
&
payload
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid request body"
)
return
}
until
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
strings
.
TrimSpace
(
payload
.
Until
))
if
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid until"
)
return
}
createdBy
:=
(
*
int64
)(
nil
)
if
subject
,
ok
:=
middleware
.
GetAuthSubjectFromContext
(
c
);
ok
{
uid
:=
subject
.
UserID
createdBy
=
&
uid
}
silence
:=
&
service
.
OpsAlertSilence
{
RuleID
:
payload
.
RuleID
,
Platform
:
strings
.
TrimSpace
(
payload
.
Platform
),
GroupID
:
payload
.
GroupID
,
Region
:
payload
.
Region
,
Until
:
until
,
Reason
:
strings
.
TrimSpace
(
payload
.
Reason
),
CreatedBy
:
createdBy
,
}
created
,
err
:=
h
.
opsService
.
CreateAlertSilence
(
c
.
Request
.
Context
(),
silence
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
created
)
}
func
(
h
*
OpsHandler
)
ListAlertEvents
(
c
*
gin
.
Context
)
{
if
h
.
opsService
==
nil
{
response
.
Error
(
c
,
http
.
StatusServiceUnavailable
,
"Ops service not available"
)
...
...
@@ -384,7 +511,7 @@ func (h *OpsHandler) ListAlertEvents(c *gin.Context) {
return
}
limit
:=
10
0
limit
:=
2
0
if
raw
:=
strings
.
TrimSpace
(
c
.
Query
(
"limit"
));
raw
!=
""
{
n
,
err
:=
strconv
.
Atoi
(
raw
)
if
err
!=
nil
||
n
<=
0
{
...
...
@@ -400,6 +527,49 @@ func (h *OpsHandler) ListAlertEvents(c *gin.Context) {
Severity
:
strings
.
TrimSpace
(
c
.
Query
(
"severity"
)),
}
if
v
:=
strings
.
TrimSpace
(
c
.
Query
(
"email_sent"
));
v
!=
""
{
vv
:=
strings
.
ToLower
(
v
)
switch
vv
{
case
"true"
,
"1"
:
b
:=
true
filter
.
EmailSent
=
&
b
case
"false"
,
"0"
:
b
:=
false
filter
.
EmailSent
=
&
b
default
:
response
.
BadRequest
(
c
,
"Invalid email_sent"
)
return
}
}
// Cursor pagination: both params must be provided together.
rawTS
:=
strings
.
TrimSpace
(
c
.
Query
(
"before_fired_at"
))
rawID
:=
strings
.
TrimSpace
(
c
.
Query
(
"before_id"
))
if
(
rawTS
==
""
)
!=
(
rawID
==
""
)
{
response
.
BadRequest
(
c
,
"before_fired_at and before_id must be provided together"
)
return
}
if
rawTS
!=
""
{
ts
,
err
:=
time
.
Parse
(
time
.
RFC3339Nano
,
rawTS
)
if
err
!=
nil
{
if
t2
,
err2
:=
time
.
Parse
(
time
.
RFC3339
,
rawTS
);
err2
==
nil
{
ts
=
t2
}
else
{
response
.
BadRequest
(
c
,
"Invalid before_fired_at"
)
return
}
}
filter
.
BeforeFiredAt
=
&
ts
}
if
rawID
!=
""
{
id
,
err
:=
strconv
.
ParseInt
(
rawID
,
10
,
64
)
if
err
!=
nil
||
id
<=
0
{
response
.
BadRequest
(
c
,
"Invalid before_id"
)
return
}
filter
.
BeforeID
=
&
id
}
// Optional global filter support (platform/group/time range).
if
platform
:=
strings
.
TrimSpace
(
c
.
Query
(
"platform"
));
platform
!=
""
{
filter
.
Platform
=
platform
...
...
Prev
1
2
3
4
5
6
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment