diff --git a/_parse_upstream.py b/_parse_upstream.py new file mode 100644 index 00000000..807d1cac --- /dev/null +++ b/_parse_upstream.py @@ -0,0 +1,78 @@ +""" +严格按模型拆分 upstream 的 token 和 quota;并按【我们的定价表】重算每个模型的 token 应得金额。 +对比 upstream provider-side (/group_ratio) 与我们 Anthropic 官方价的计算结果。 +""" +import re +import json +from collections import defaultdict + +# 按账号(token_name) + 模型拆 +by_key = defaultdict(lambda: { + 'count': 0, + 'prompt': 0, + 'completion': 0, + 'cache_create': 0, + 'cache_read': 0, + 'quota_pre_group_sum': 0.0, + 'flat_price_reqs': 0, + 'flat_price_value': 0.0, + 'model_ratios': set(), + 'model_prices': set(), +}) + +with open(r"C:\Users\16790\xwechat_files\wxid_8tc8tfooo5rs22_fef8\msg\file\2026-04\asakifeng_consume.txt", 'r', encoding='utf-8') as f: + for line in f: + m = re.match(r'\[INFO\] (\d{4}/\d{2}/\d{2} - \d{2}:\d{2}:\d{2}) \|.*params=(\{.*\})\s*$', line.strip()) + if not m: continue + try: p = json.loads(m.group(2)) + except Exception: continue + tn = p.get('token_name', '') + model = p.get('model_name', '') + other = p.get('other') or {} + gr = other.get('group_ratio', 1.0) or 1.0 + q = p.get('quota', 0) or 0 + k = (tn, model) + d = by_key[k] + d['count'] += 1 + d['prompt'] += p.get('prompt_tokens', 0) or 0 + d['completion'] += p.get('completion_tokens', 0) or 0 + d['cache_create'] += other.get('cache_creation_tokens', 0) or 0 + d['cache_read'] += other.get('cache_tokens', 0) or 0 + d['quota_pre_group_sum'] += q / gr if gr else q + mp = other.get('model_price') or 0 + mr = other.get('model_ratio') + if mr is not None: d['model_ratios'].add(mr) + d['model_prices'].add(mp) + if mp and mp > 0: + d['flat_price_reqs'] += 1 + d['flat_price_value'] += mp # flat $ per request + +# 我们定价表(从 backend/resources/.../model_prices_and_context_window.json 读的真实值) +OUR_PRICE = { + 'claude-haiku-4-5-20251001': {'input': 1e-6, 'output': 5e-6, 'cc5m': 1.25e-6, 'cr': 1e-7}, + 'claude-sonnet-4-6': {'input': 3e-6, 'output': 1.5e-5, 'cc5m': 3.75e-6, 'cr': 3e-7}, + 'claude-sonnet-4-5-20250929': {'input': 3e-6, 'output': 1.5e-5, 'cc5m': 3.75e-6, 'cr': 3e-7}, + 'claude-opus-4-6': {'input': 5e-6, 'output': 2.5e-5, 'cc5m': 6.25e-6, 'cr': 5e-7}, + 'claude-opus-4-5-20251101': {'input': 5e-6, 'output': 2.5e-5, 'cc5m': 6.25e-6, 'cr': 5e-7}, + 'claude-opus-4-7': {'input': 5e-6, 'output': 2.5e-5, 'cc5m': 6.25e-6, 'cr': 5e-7}, # 我们回退到 opus-4-6 价 +} + +print("%-40s %-28s %5s %12s %12s %12s %12s" % ("TOKEN", "MODEL", "req", "upstream$", "our_calc$", "diff$", "note")) +print("-" * 150) +total_up = 0.0; total_ours = 0.0 +for (tn, model), d in sorted(by_key.items()): + up = d['quota_pre_group_sum'] / 500000 + p = OUR_PRICE.get(model) + if p: + ours = (d['prompt']*p['input'] + d['completion']*p['output'] + + d['cache_create']*p['cc5m'] + d['cache_read']*p['cr']) + else: + ours = 0.0 + diff = up - ours + note = "" + if d['flat_price_reqs']: + note = f"flat_price {d['flat_price_reqs']}/{d['count']}" + total_up += up; total_ours += ours + print("%-40s %-28s %5d %12.4f %12.4f %+12.4f %s" % (tn[:40], model, d['count'], up, ours, diff, note)) +print("-" * 150) +print("%-40s %-28s %5s %12.4f %12.4f %+12.4f" % ("TOTAL", "", "", total_up, total_ours, total_up - total_ours)) diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index a878ea68..4e95035a 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -215,6 +215,9 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { return nil, err } channelMonitorRepository := repository.NewChannelMonitorRepository(client, sqlDB) + channelMonitorRequestTemplateRepository := repository.NewChannelMonitorRequestTemplateRepository(client, sqlDB) + channelMonitorRequestTemplateService := service.NewChannelMonitorRequestTemplateService(channelMonitorRequestTemplateRepository) + channelMonitorRequestTemplateHandler := admin.NewChannelMonitorRequestTemplateHandler(channelMonitorRequestTemplateService) channelMonitorService := service.ProvideChannelMonitorService(channelMonitorRepository, secretEncryptor) channelMonitorHandler := admin.NewChannelMonitorHandler(channelMonitorService) channelMonitorUserHandler := handler.NewChannelMonitorUserHandler(channelMonitorService, settingService) @@ -231,7 +234,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { settingHandler := admin.NewSettingHandler(settingService, emailService, turnstileService, opsService, paymentConfigService, paymentService) paymentOrderExpiryService := service.ProvidePaymentOrderExpiryService(paymentService) paymentHandler := admin.NewPaymentHandler(paymentService, paymentConfigService) - adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, adminAnnouncementHandler, dataManagementHandler, backupHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, promoHandler, settingHandler, opsHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler, errorPassthroughHandler, tlsFingerprintProfileHandler, adminAPIKeyHandler, scheduledTestHandler, channelHandler, channelMonitorHandler, paymentHandler) + adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, adminAnnouncementHandler, dataManagementHandler, backupHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, promoHandler, settingHandler, opsHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler, errorPassthroughHandler, tlsFingerprintProfileHandler, adminAPIKeyHandler, scheduledTestHandler, channelHandler, channelMonitorHandler, channelMonitorRequestTemplateHandler, paymentHandler) usageRecordWorkerPool := service.NewUsageRecordWorkerPool(configConfig) userMsgQueueCache := repository.NewUserMsgQueueCache(redisClient) userMessageQueueService := service.ProvideUserMessageQueueService(userMsgQueueCache, rpmCache, configConfig) diff --git a/backend/ent/channelmonitor.go b/backend/ent/channelmonitor.go index 58886884..dbb73362 100644 --- a/backend/ent/channelmonitor.go +++ b/backend/ent/channelmonitor.go @@ -11,6 +11,7 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/Wei-Shaw/sub2api/ent/channelmonitor" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" ) // ChannelMonitor is the model entity for the ChannelMonitor schema. @@ -44,6 +45,14 @@ type ChannelMonitor struct { LastCheckedAt *time.Time `json:"last_checked_at,omitempty"` // CreatedBy holds the value of the "created_by" field. CreatedBy int64 `json:"created_by,omitempty"` + // TemplateID holds the value of the "template_id" field. + TemplateID *int64 `json:"template_id,omitempty"` + // ExtraHeaders holds the value of the "extra_headers" field. + ExtraHeaders map[string]string `json:"extra_headers,omitempty"` + // BodyOverrideMode holds the value of the "body_override_mode" field. + BodyOverrideMode string `json:"body_override_mode,omitempty"` + // BodyOverride holds the value of the "body_override" field. + BodyOverride map[string]interface{} `json:"body_override,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the ChannelMonitorQuery when eager-loading is set. Edges ChannelMonitorEdges `json:"edges"` @@ -56,9 +65,11 @@ type ChannelMonitorEdges struct { History []*ChannelMonitorHistory `json:"history,omitempty"` // DailyRollups holds the value of the daily_rollups edge. DailyRollups []*ChannelMonitorDailyRollup `json:"daily_rollups,omitempty"` + // RequestTemplate holds the value of the request_template edge. + RequestTemplate *ChannelMonitorRequestTemplate `json:"request_template,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [2]bool + loadedTypes [3]bool } // HistoryOrErr returns the History value or an error if the edge @@ -79,18 +90,29 @@ func (e ChannelMonitorEdges) DailyRollupsOrErr() ([]*ChannelMonitorDailyRollup, return nil, &NotLoadedError{edge: "daily_rollups"} } +// RequestTemplateOrErr returns the RequestTemplate value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e ChannelMonitorEdges) RequestTemplateOrErr() (*ChannelMonitorRequestTemplate, error) { + if e.RequestTemplate != nil { + return e.RequestTemplate, nil + } else if e.loadedTypes[2] { + return nil, &NotFoundError{label: channelmonitorrequesttemplate.Label} + } + return nil, &NotLoadedError{edge: "request_template"} +} + // scanValues returns the types for scanning values from sql.Rows. func (*ChannelMonitor) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case channelmonitor.FieldExtraModels: + case channelmonitor.FieldExtraModels, channelmonitor.FieldExtraHeaders, channelmonitor.FieldBodyOverride: values[i] = new([]byte) case channelmonitor.FieldEnabled: values[i] = new(sql.NullBool) - case channelmonitor.FieldID, channelmonitor.FieldIntervalSeconds, channelmonitor.FieldCreatedBy: + case channelmonitor.FieldID, channelmonitor.FieldIntervalSeconds, channelmonitor.FieldCreatedBy, channelmonitor.FieldTemplateID: values[i] = new(sql.NullInt64) - case channelmonitor.FieldName, channelmonitor.FieldProvider, channelmonitor.FieldEndpoint, channelmonitor.FieldAPIKeyEncrypted, channelmonitor.FieldPrimaryModel, channelmonitor.FieldGroupName: + case channelmonitor.FieldName, channelmonitor.FieldProvider, channelmonitor.FieldEndpoint, channelmonitor.FieldAPIKeyEncrypted, channelmonitor.FieldPrimaryModel, channelmonitor.FieldGroupName, channelmonitor.FieldBodyOverrideMode: values[i] = new(sql.NullString) case channelmonitor.FieldCreatedAt, channelmonitor.FieldUpdatedAt, channelmonitor.FieldLastCheckedAt: values[i] = new(sql.NullTime) @@ -196,6 +218,35 @@ func (_m *ChannelMonitor) assignValues(columns []string, values []any) error { } else if value.Valid { _m.CreatedBy = value.Int64 } + case channelmonitor.FieldTemplateID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field template_id", values[i]) + } else if value.Valid { + _m.TemplateID = new(int64) + *_m.TemplateID = value.Int64 + } + case channelmonitor.FieldExtraHeaders: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field extra_headers", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &_m.ExtraHeaders); err != nil { + return fmt.Errorf("unmarshal field extra_headers: %w", err) + } + } + case channelmonitor.FieldBodyOverrideMode: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field body_override_mode", values[i]) + } else if value.Valid { + _m.BodyOverrideMode = value.String + } + case channelmonitor.FieldBodyOverride: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field body_override", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &_m.BodyOverride); err != nil { + return fmt.Errorf("unmarshal field body_override: %w", err) + } + } default: _m.selectValues.Set(columns[i], values[i]) } @@ -219,6 +270,11 @@ func (_m *ChannelMonitor) QueryDailyRollups() *ChannelMonitorDailyRollupQuery { return NewChannelMonitorClient(_m.config).QueryDailyRollups(_m) } +// QueryRequestTemplate queries the "request_template" edge of the ChannelMonitor entity. +func (_m *ChannelMonitor) QueryRequestTemplate() *ChannelMonitorRequestTemplateQuery { + return NewChannelMonitorClient(_m.config).QueryRequestTemplate(_m) +} + // Update returns a builder for updating this ChannelMonitor. // Note that you need to call ChannelMonitor.Unwrap() before calling this method if this ChannelMonitor // was returned from a transaction, and the transaction was committed or rolled back. @@ -281,6 +337,20 @@ func (_m *ChannelMonitor) String() string { builder.WriteString(", ") builder.WriteString("created_by=") builder.WriteString(fmt.Sprintf("%v", _m.CreatedBy)) + builder.WriteString(", ") + if v := _m.TemplateID; v != nil { + builder.WriteString("template_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + builder.WriteString(", ") + builder.WriteString("extra_headers=") + builder.WriteString(fmt.Sprintf("%v", _m.ExtraHeaders)) + builder.WriteString(", ") + builder.WriteString("body_override_mode=") + builder.WriteString(_m.BodyOverrideMode) + builder.WriteString(", ") + builder.WriteString("body_override=") + builder.WriteString(fmt.Sprintf("%v", _m.BodyOverride)) builder.WriteByte(')') return builder.String() } diff --git a/backend/ent/channelmonitor/channelmonitor.go b/backend/ent/channelmonitor/channelmonitor.go index ff6d7105..e5a6bfe7 100644 --- a/backend/ent/channelmonitor/channelmonitor.go +++ b/backend/ent/channelmonitor/channelmonitor.go @@ -41,10 +41,20 @@ const ( FieldLastCheckedAt = "last_checked_at" // FieldCreatedBy holds the string denoting the created_by field in the database. FieldCreatedBy = "created_by" + // FieldTemplateID holds the string denoting the template_id field in the database. + FieldTemplateID = "template_id" + // FieldExtraHeaders holds the string denoting the extra_headers field in the database. + FieldExtraHeaders = "extra_headers" + // FieldBodyOverrideMode holds the string denoting the body_override_mode field in the database. + FieldBodyOverrideMode = "body_override_mode" + // FieldBodyOverride holds the string denoting the body_override field in the database. + FieldBodyOverride = "body_override" // EdgeHistory holds the string denoting the history edge name in mutations. EdgeHistory = "history" // EdgeDailyRollups holds the string denoting the daily_rollups edge name in mutations. EdgeDailyRollups = "daily_rollups" + // EdgeRequestTemplate holds the string denoting the request_template edge name in mutations. + EdgeRequestTemplate = "request_template" // Table holds the table name of the channelmonitor in the database. Table = "channel_monitors" // HistoryTable is the table that holds the history relation/edge. @@ -61,6 +71,13 @@ const ( DailyRollupsInverseTable = "channel_monitor_daily_rollups" // DailyRollupsColumn is the table column denoting the daily_rollups relation/edge. DailyRollupsColumn = "monitor_id" + // RequestTemplateTable is the table that holds the request_template relation/edge. + RequestTemplateTable = "channel_monitors" + // RequestTemplateInverseTable is the table name for the ChannelMonitorRequestTemplate entity. + // It exists in this package in order to avoid circular dependency with the "channelmonitorrequesttemplate" package. + RequestTemplateInverseTable = "channel_monitor_request_templates" + // RequestTemplateColumn is the table column denoting the request_template relation/edge. + RequestTemplateColumn = "template_id" ) // Columns holds all SQL columns for channelmonitor fields. @@ -79,6 +96,10 @@ var Columns = []string{ FieldIntervalSeconds, FieldLastCheckedAt, FieldCreatedBy, + FieldTemplateID, + FieldExtraHeaders, + FieldBodyOverrideMode, + FieldBodyOverride, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -116,6 +137,12 @@ var ( DefaultEnabled bool // IntervalSecondsValidator is a validator for the "interval_seconds" field. It is called by the builders before save. IntervalSecondsValidator func(int) error + // DefaultExtraHeaders holds the default value on creation for the "extra_headers" field. + DefaultExtraHeaders map[string]string + // DefaultBodyOverrideMode holds the default value on creation for the "body_override_mode" field. + DefaultBodyOverrideMode string + // BodyOverrideModeValidator is a validator for the "body_override_mode" field. It is called by the builders before save. + BodyOverrideModeValidator func(string) error ) // Provider defines the type for the "provider" enum field. @@ -210,6 +237,16 @@ func ByCreatedBy(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldCreatedBy, opts...).ToFunc() } +// ByTemplateID orders the results by the template_id field. +func ByTemplateID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldTemplateID, opts...).ToFunc() +} + +// ByBodyOverrideMode orders the results by the body_override_mode field. +func ByBodyOverrideMode(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBodyOverrideMode, opts...).ToFunc() +} + // ByHistoryCount orders the results by history count. func ByHistoryCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { @@ -237,6 +274,13 @@ func ByDailyRollups(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { sqlgraph.OrderByNeighborTerms(s, newDailyRollupsStep(), append([]sql.OrderTerm{term}, terms...)...) } } + +// ByRequestTemplateField orders the results by request_template field. +func ByRequestTemplateField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newRequestTemplateStep(), sql.OrderByField(field, opts...)) + } +} func newHistoryStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), @@ -251,3 +295,10 @@ func newDailyRollupsStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.O2M, false, DailyRollupsTable, DailyRollupsColumn), ) } +func newRequestTemplateStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(RequestTemplateInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, RequestTemplateTable, RequestTemplateColumn), + ) +} diff --git a/backend/ent/channelmonitor/where.go b/backend/ent/channelmonitor/where.go index abb8484d..755d83a3 100644 --- a/backend/ent/channelmonitor/where.go +++ b/backend/ent/channelmonitor/where.go @@ -110,6 +110,16 @@ func CreatedBy(v int64) predicate.ChannelMonitor { return predicate.ChannelMonitor(sql.FieldEQ(FieldCreatedBy, v)) } +// TemplateID applies equality check predicate on the "template_id" field. It's identical to TemplateIDEQ. +func TemplateID(v int64) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldEQ(FieldTemplateID, v)) +} + +// BodyOverrideMode applies equality check predicate on the "body_override_mode" field. It's identical to BodyOverrideModeEQ. +func BodyOverrideMode(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldEQ(FieldBodyOverrideMode, v)) +} + // CreatedAtEQ applies the EQ predicate on the "created_at" field. func CreatedAtEQ(v time.Time) predicate.ChannelMonitor { return predicate.ChannelMonitor(sql.FieldEQ(FieldCreatedAt, v)) @@ -685,6 +695,111 @@ func CreatedByLTE(v int64) predicate.ChannelMonitor { return predicate.ChannelMonitor(sql.FieldLTE(FieldCreatedBy, v)) } +// TemplateIDEQ applies the EQ predicate on the "template_id" field. +func TemplateIDEQ(v int64) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldEQ(FieldTemplateID, v)) +} + +// TemplateIDNEQ applies the NEQ predicate on the "template_id" field. +func TemplateIDNEQ(v int64) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldNEQ(FieldTemplateID, v)) +} + +// TemplateIDIn applies the In predicate on the "template_id" field. +func TemplateIDIn(vs ...int64) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldIn(FieldTemplateID, vs...)) +} + +// TemplateIDNotIn applies the NotIn predicate on the "template_id" field. +func TemplateIDNotIn(vs ...int64) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldNotIn(FieldTemplateID, vs...)) +} + +// TemplateIDIsNil applies the IsNil predicate on the "template_id" field. +func TemplateIDIsNil() predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldIsNull(FieldTemplateID)) +} + +// TemplateIDNotNil applies the NotNil predicate on the "template_id" field. +func TemplateIDNotNil() predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldNotNull(FieldTemplateID)) +} + +// BodyOverrideModeEQ applies the EQ predicate on the "body_override_mode" field. +func BodyOverrideModeEQ(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldEQ(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeNEQ applies the NEQ predicate on the "body_override_mode" field. +func BodyOverrideModeNEQ(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldNEQ(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeIn applies the In predicate on the "body_override_mode" field. +func BodyOverrideModeIn(vs ...string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldIn(FieldBodyOverrideMode, vs...)) +} + +// BodyOverrideModeNotIn applies the NotIn predicate on the "body_override_mode" field. +func BodyOverrideModeNotIn(vs ...string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldNotIn(FieldBodyOverrideMode, vs...)) +} + +// BodyOverrideModeGT applies the GT predicate on the "body_override_mode" field. +func BodyOverrideModeGT(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldGT(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeGTE applies the GTE predicate on the "body_override_mode" field. +func BodyOverrideModeGTE(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldGTE(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeLT applies the LT predicate on the "body_override_mode" field. +func BodyOverrideModeLT(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldLT(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeLTE applies the LTE predicate on the "body_override_mode" field. +func BodyOverrideModeLTE(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldLTE(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeContains applies the Contains predicate on the "body_override_mode" field. +func BodyOverrideModeContains(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldContains(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeHasPrefix applies the HasPrefix predicate on the "body_override_mode" field. +func BodyOverrideModeHasPrefix(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldHasPrefix(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeHasSuffix applies the HasSuffix predicate on the "body_override_mode" field. +func BodyOverrideModeHasSuffix(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldHasSuffix(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeEqualFold applies the EqualFold predicate on the "body_override_mode" field. +func BodyOverrideModeEqualFold(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldEqualFold(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeContainsFold applies the ContainsFold predicate on the "body_override_mode" field. +func BodyOverrideModeContainsFold(v string) predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldContainsFold(FieldBodyOverrideMode, v)) +} + +// BodyOverrideIsNil applies the IsNil predicate on the "body_override" field. +func BodyOverrideIsNil() predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldIsNull(FieldBodyOverride)) +} + +// BodyOverrideNotNil applies the NotNil predicate on the "body_override" field. +func BodyOverrideNotNil() predicate.ChannelMonitor { + return predicate.ChannelMonitor(sql.FieldNotNull(FieldBodyOverride)) +} + // HasHistory applies the HasEdge predicate on the "history" edge. func HasHistory() predicate.ChannelMonitor { return predicate.ChannelMonitor(func(s *sql.Selector) { @@ -731,6 +846,29 @@ func HasDailyRollupsWith(preds ...predicate.ChannelMonitorDailyRollup) predicate }) } +// HasRequestTemplate applies the HasEdge predicate on the "request_template" edge. +func HasRequestTemplate() predicate.ChannelMonitor { + return predicate.ChannelMonitor(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, RequestTemplateTable, RequestTemplateColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasRequestTemplateWith applies the HasEdge predicate on the "request_template" edge with a given conditions (other predicates). +func HasRequestTemplateWith(preds ...predicate.ChannelMonitorRequestTemplate) predicate.ChannelMonitor { + return predicate.ChannelMonitor(func(s *sql.Selector) { + step := newRequestTemplateStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // And groups predicates with the AND operator between them. func And(predicates ...predicate.ChannelMonitor) predicate.ChannelMonitor { return predicate.ChannelMonitor(sql.AndPredicates(predicates...)) diff --git a/backend/ent/channelmonitor_create.go b/backend/ent/channelmonitor_create.go index 30a7b40d..2f70c300 100644 --- a/backend/ent/channelmonitor_create.go +++ b/backend/ent/channelmonitor_create.go @@ -14,6 +14,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" ) // ChannelMonitorCreate is the builder for creating a ChannelMonitor entity. @@ -142,6 +143,46 @@ func (_c *ChannelMonitorCreate) SetCreatedBy(v int64) *ChannelMonitorCreate { return _c } +// SetTemplateID sets the "template_id" field. +func (_c *ChannelMonitorCreate) SetTemplateID(v int64) *ChannelMonitorCreate { + _c.mutation.SetTemplateID(v) + return _c +} + +// SetNillableTemplateID sets the "template_id" field if the given value is not nil. +func (_c *ChannelMonitorCreate) SetNillableTemplateID(v *int64) *ChannelMonitorCreate { + if v != nil { + _c.SetTemplateID(*v) + } + return _c +} + +// SetExtraHeaders sets the "extra_headers" field. +func (_c *ChannelMonitorCreate) SetExtraHeaders(v map[string]string) *ChannelMonitorCreate { + _c.mutation.SetExtraHeaders(v) + return _c +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (_c *ChannelMonitorCreate) SetBodyOverrideMode(v string) *ChannelMonitorCreate { + _c.mutation.SetBodyOverrideMode(v) + return _c +} + +// SetNillableBodyOverrideMode sets the "body_override_mode" field if the given value is not nil. +func (_c *ChannelMonitorCreate) SetNillableBodyOverrideMode(v *string) *ChannelMonitorCreate { + if v != nil { + _c.SetBodyOverrideMode(*v) + } + return _c +} + +// SetBodyOverride sets the "body_override" field. +func (_c *ChannelMonitorCreate) SetBodyOverride(v map[string]interface{}) *ChannelMonitorCreate { + _c.mutation.SetBodyOverride(v) + return _c +} + // AddHistoryIDs adds the "history" edge to the ChannelMonitorHistory entity by IDs. func (_c *ChannelMonitorCreate) AddHistoryIDs(ids ...int64) *ChannelMonitorCreate { _c.mutation.AddHistoryIDs(ids...) @@ -172,6 +213,25 @@ func (_c *ChannelMonitorCreate) AddDailyRollups(v ...*ChannelMonitorDailyRollup) return _c.AddDailyRollupIDs(ids...) } +// SetRequestTemplateID sets the "request_template" edge to the ChannelMonitorRequestTemplate entity by ID. +func (_c *ChannelMonitorCreate) SetRequestTemplateID(id int64) *ChannelMonitorCreate { + _c.mutation.SetRequestTemplateID(id) + return _c +} + +// SetNillableRequestTemplateID sets the "request_template" edge to the ChannelMonitorRequestTemplate entity by ID if the given value is not nil. +func (_c *ChannelMonitorCreate) SetNillableRequestTemplateID(id *int64) *ChannelMonitorCreate { + if id != nil { + _c = _c.SetRequestTemplateID(*id) + } + return _c +} + +// SetRequestTemplate sets the "request_template" edge to the ChannelMonitorRequestTemplate entity. +func (_c *ChannelMonitorCreate) SetRequestTemplate(v *ChannelMonitorRequestTemplate) *ChannelMonitorCreate { + return _c.SetRequestTemplateID(v.ID) +} + // Mutation returns the ChannelMonitorMutation object of the builder. func (_c *ChannelMonitorCreate) Mutation() *ChannelMonitorMutation { return _c.mutation @@ -227,6 +287,14 @@ func (_c *ChannelMonitorCreate) defaults() { v := channelmonitor.DefaultEnabled _c.mutation.SetEnabled(v) } + if _, ok := _c.mutation.ExtraHeaders(); !ok { + v := channelmonitor.DefaultExtraHeaders + _c.mutation.SetExtraHeaders(v) + } + if _, ok := _c.mutation.BodyOverrideMode(); !ok { + v := channelmonitor.DefaultBodyOverrideMode + _c.mutation.SetBodyOverrideMode(v) + } } // check runs all checks and user-defined validators on the builder. @@ -299,6 +367,17 @@ func (_c *ChannelMonitorCreate) check() error { if _, ok := _c.mutation.CreatedBy(); !ok { return &ValidationError{Name: "created_by", err: errors.New(`ent: missing required field "ChannelMonitor.created_by"`)} } + if _, ok := _c.mutation.ExtraHeaders(); !ok { + return &ValidationError{Name: "extra_headers", err: errors.New(`ent: missing required field "ChannelMonitor.extra_headers"`)} + } + if _, ok := _c.mutation.BodyOverrideMode(); !ok { + return &ValidationError{Name: "body_override_mode", err: errors.New(`ent: missing required field "ChannelMonitor.body_override_mode"`)} + } + if v, ok := _c.mutation.BodyOverrideMode(); ok { + if err := channelmonitor.BodyOverrideModeValidator(v); err != nil { + return &ValidationError{Name: "body_override_mode", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitor.body_override_mode": %w`, err)} + } + } return nil } @@ -378,6 +457,18 @@ func (_c *ChannelMonitorCreate) createSpec() (*ChannelMonitor, *sqlgraph.CreateS _spec.SetField(channelmonitor.FieldCreatedBy, field.TypeInt64, value) _node.CreatedBy = value } + if value, ok := _c.mutation.ExtraHeaders(); ok { + _spec.SetField(channelmonitor.FieldExtraHeaders, field.TypeJSON, value) + _node.ExtraHeaders = value + } + if value, ok := _c.mutation.BodyOverrideMode(); ok { + _spec.SetField(channelmonitor.FieldBodyOverrideMode, field.TypeString, value) + _node.BodyOverrideMode = value + } + if value, ok := _c.mutation.BodyOverride(); ok { + _spec.SetField(channelmonitor.FieldBodyOverride, field.TypeJSON, value) + _node.BodyOverride = value + } if nodes := _c.mutation.HistoryIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -410,6 +501,23 @@ func (_c *ChannelMonitorCreate) createSpec() (*ChannelMonitor, *sqlgraph.CreateS } _spec.Edges = append(_spec.Edges, edge) } + if nodes := _c.mutation.RequestTemplateIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: channelmonitor.RequestTemplateTable, + Columns: []string{channelmonitor.RequestTemplateColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.TemplateID = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } return _node, _spec } @@ -630,6 +738,66 @@ func (u *ChannelMonitorUpsert) AddCreatedBy(v int64) *ChannelMonitorUpsert { return u } +// SetTemplateID sets the "template_id" field. +func (u *ChannelMonitorUpsert) SetTemplateID(v int64) *ChannelMonitorUpsert { + u.Set(channelmonitor.FieldTemplateID, v) + return u +} + +// UpdateTemplateID sets the "template_id" field to the value that was provided on create. +func (u *ChannelMonitorUpsert) UpdateTemplateID() *ChannelMonitorUpsert { + u.SetExcluded(channelmonitor.FieldTemplateID) + return u +} + +// ClearTemplateID clears the value of the "template_id" field. +func (u *ChannelMonitorUpsert) ClearTemplateID() *ChannelMonitorUpsert { + u.SetNull(channelmonitor.FieldTemplateID) + return u +} + +// SetExtraHeaders sets the "extra_headers" field. +func (u *ChannelMonitorUpsert) SetExtraHeaders(v map[string]string) *ChannelMonitorUpsert { + u.Set(channelmonitor.FieldExtraHeaders, v) + return u +} + +// UpdateExtraHeaders sets the "extra_headers" field to the value that was provided on create. +func (u *ChannelMonitorUpsert) UpdateExtraHeaders() *ChannelMonitorUpsert { + u.SetExcluded(channelmonitor.FieldExtraHeaders) + return u +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (u *ChannelMonitorUpsert) SetBodyOverrideMode(v string) *ChannelMonitorUpsert { + u.Set(channelmonitor.FieldBodyOverrideMode, v) + return u +} + +// UpdateBodyOverrideMode sets the "body_override_mode" field to the value that was provided on create. +func (u *ChannelMonitorUpsert) UpdateBodyOverrideMode() *ChannelMonitorUpsert { + u.SetExcluded(channelmonitor.FieldBodyOverrideMode) + return u +} + +// SetBodyOverride sets the "body_override" field. +func (u *ChannelMonitorUpsert) SetBodyOverride(v map[string]interface{}) *ChannelMonitorUpsert { + u.Set(channelmonitor.FieldBodyOverride, v) + return u +} + +// UpdateBodyOverride sets the "body_override" field to the value that was provided on create. +func (u *ChannelMonitorUpsert) UpdateBodyOverride() *ChannelMonitorUpsert { + u.SetExcluded(channelmonitor.FieldBodyOverride) + return u +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (u *ChannelMonitorUpsert) ClearBodyOverride() *ChannelMonitorUpsert { + u.SetNull(channelmonitor.FieldBodyOverride) + return u +} + // UpdateNewValues updates the mutable fields using the new values that were set on create. // Using this option is equivalent to using: // @@ -871,6 +1039,76 @@ func (u *ChannelMonitorUpsertOne) UpdateCreatedBy() *ChannelMonitorUpsertOne { }) } +// SetTemplateID sets the "template_id" field. +func (u *ChannelMonitorUpsertOne) SetTemplateID(v int64) *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetTemplateID(v) + }) +} + +// UpdateTemplateID sets the "template_id" field to the value that was provided on create. +func (u *ChannelMonitorUpsertOne) UpdateTemplateID() *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateTemplateID() + }) +} + +// ClearTemplateID clears the value of the "template_id" field. +func (u *ChannelMonitorUpsertOne) ClearTemplateID() *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.ClearTemplateID() + }) +} + +// SetExtraHeaders sets the "extra_headers" field. +func (u *ChannelMonitorUpsertOne) SetExtraHeaders(v map[string]string) *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetExtraHeaders(v) + }) +} + +// UpdateExtraHeaders sets the "extra_headers" field to the value that was provided on create. +func (u *ChannelMonitorUpsertOne) UpdateExtraHeaders() *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateExtraHeaders() + }) +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (u *ChannelMonitorUpsertOne) SetBodyOverrideMode(v string) *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetBodyOverrideMode(v) + }) +} + +// UpdateBodyOverrideMode sets the "body_override_mode" field to the value that was provided on create. +func (u *ChannelMonitorUpsertOne) UpdateBodyOverrideMode() *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateBodyOverrideMode() + }) +} + +// SetBodyOverride sets the "body_override" field. +func (u *ChannelMonitorUpsertOne) SetBodyOverride(v map[string]interface{}) *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetBodyOverride(v) + }) +} + +// UpdateBodyOverride sets the "body_override" field to the value that was provided on create. +func (u *ChannelMonitorUpsertOne) UpdateBodyOverride() *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateBodyOverride() + }) +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (u *ChannelMonitorUpsertOne) ClearBodyOverride() *ChannelMonitorUpsertOne { + return u.Update(func(s *ChannelMonitorUpsert) { + s.ClearBodyOverride() + }) +} + // Exec executes the query. func (u *ChannelMonitorUpsertOne) Exec(ctx context.Context) error { if len(u.create.conflict) == 0 { @@ -1278,6 +1516,76 @@ func (u *ChannelMonitorUpsertBulk) UpdateCreatedBy() *ChannelMonitorUpsertBulk { }) } +// SetTemplateID sets the "template_id" field. +func (u *ChannelMonitorUpsertBulk) SetTemplateID(v int64) *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetTemplateID(v) + }) +} + +// UpdateTemplateID sets the "template_id" field to the value that was provided on create. +func (u *ChannelMonitorUpsertBulk) UpdateTemplateID() *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateTemplateID() + }) +} + +// ClearTemplateID clears the value of the "template_id" field. +func (u *ChannelMonitorUpsertBulk) ClearTemplateID() *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.ClearTemplateID() + }) +} + +// SetExtraHeaders sets the "extra_headers" field. +func (u *ChannelMonitorUpsertBulk) SetExtraHeaders(v map[string]string) *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetExtraHeaders(v) + }) +} + +// UpdateExtraHeaders sets the "extra_headers" field to the value that was provided on create. +func (u *ChannelMonitorUpsertBulk) UpdateExtraHeaders() *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateExtraHeaders() + }) +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (u *ChannelMonitorUpsertBulk) SetBodyOverrideMode(v string) *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetBodyOverrideMode(v) + }) +} + +// UpdateBodyOverrideMode sets the "body_override_mode" field to the value that was provided on create. +func (u *ChannelMonitorUpsertBulk) UpdateBodyOverrideMode() *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateBodyOverrideMode() + }) +} + +// SetBodyOverride sets the "body_override" field. +func (u *ChannelMonitorUpsertBulk) SetBodyOverride(v map[string]interface{}) *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.SetBodyOverride(v) + }) +} + +// UpdateBodyOverride sets the "body_override" field to the value that was provided on create. +func (u *ChannelMonitorUpsertBulk) UpdateBodyOverride() *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.UpdateBodyOverride() + }) +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (u *ChannelMonitorUpsertBulk) ClearBodyOverride() *ChannelMonitorUpsertBulk { + return u.Update(func(s *ChannelMonitorUpsert) { + s.ClearBodyOverride() + }) +} + // Exec executes the query. func (u *ChannelMonitorUpsertBulk) Exec(ctx context.Context) error { if u.create.err != nil { diff --git a/backend/ent/channelmonitor_query.go b/backend/ent/channelmonitor_query.go index 2ebd95bb..b6722e78 100644 --- a/backend/ent/channelmonitor_query.go +++ b/backend/ent/channelmonitor_query.go @@ -16,19 +16,21 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" "github.com/Wei-Shaw/sub2api/ent/predicate" ) // ChannelMonitorQuery is the builder for querying ChannelMonitor entities. type ChannelMonitorQuery struct { config - ctx *QueryContext - order []channelmonitor.OrderOption - inters []Interceptor - predicates []predicate.ChannelMonitor - withHistory *ChannelMonitorHistoryQuery - withDailyRollups *ChannelMonitorDailyRollupQuery - modifiers []func(*sql.Selector) + ctx *QueryContext + order []channelmonitor.OrderOption + inters []Interceptor + predicates []predicate.ChannelMonitor + withHistory *ChannelMonitorHistoryQuery + withDailyRollups *ChannelMonitorDailyRollupQuery + withRequestTemplate *ChannelMonitorRequestTemplateQuery + modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -109,6 +111,28 @@ func (_q *ChannelMonitorQuery) QueryDailyRollups() *ChannelMonitorDailyRollupQue return query } +// QueryRequestTemplate chains the current query on the "request_template" edge. +func (_q *ChannelMonitorQuery) QueryRequestTemplate() *ChannelMonitorRequestTemplateQuery { + query := (&ChannelMonitorRequestTemplateClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(channelmonitor.Table, channelmonitor.FieldID, selector), + sqlgraph.To(channelmonitorrequesttemplate.Table, channelmonitorrequesttemplate.FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, channelmonitor.RequestTemplateTable, channelmonitor.RequestTemplateColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + // First returns the first ChannelMonitor entity from the query. // Returns a *NotFoundError when no ChannelMonitor was found. func (_q *ChannelMonitorQuery) First(ctx context.Context) (*ChannelMonitor, error) { @@ -296,13 +320,14 @@ func (_q *ChannelMonitorQuery) Clone() *ChannelMonitorQuery { return nil } return &ChannelMonitorQuery{ - config: _q.config, - ctx: _q.ctx.Clone(), - order: append([]channelmonitor.OrderOption{}, _q.order...), - inters: append([]Interceptor{}, _q.inters...), - predicates: append([]predicate.ChannelMonitor{}, _q.predicates...), - withHistory: _q.withHistory.Clone(), - withDailyRollups: _q.withDailyRollups.Clone(), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]channelmonitor.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.ChannelMonitor{}, _q.predicates...), + withHistory: _q.withHistory.Clone(), + withDailyRollups: _q.withDailyRollups.Clone(), + withRequestTemplate: _q.withRequestTemplate.Clone(), // clone intermediate query. sql: _q.sql.Clone(), path: _q.path, @@ -331,6 +356,17 @@ func (_q *ChannelMonitorQuery) WithDailyRollups(opts ...func(*ChannelMonitorDail return _q } +// WithRequestTemplate tells the query-builder to eager-load the nodes that are connected to +// the "request_template" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *ChannelMonitorQuery) WithRequestTemplate(opts ...func(*ChannelMonitorRequestTemplateQuery)) *ChannelMonitorQuery { + query := (&ChannelMonitorRequestTemplateClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withRequestTemplate = query + return _q +} + // GroupBy is used to group vertices by one or more fields/columns. // It is often used with aggregate functions, like: count, max, mean, min, sum. // @@ -409,9 +445,10 @@ func (_q *ChannelMonitorQuery) sqlAll(ctx context.Context, hooks ...queryHook) ( var ( nodes = []*ChannelMonitor{} _spec = _q.querySpec() - loadedTypes = [2]bool{ + loadedTypes = [3]bool{ _q.withHistory != nil, _q.withDailyRollups != nil, + _q.withRequestTemplate != nil, } ) _spec.ScanValues = func(columns []string) ([]any, error) { @@ -451,6 +488,12 @@ func (_q *ChannelMonitorQuery) sqlAll(ctx context.Context, hooks ...queryHook) ( return nil, err } } + if query := _q.withRequestTemplate; query != nil { + if err := _q.loadRequestTemplate(ctx, query, nodes, nil, + func(n *ChannelMonitor, e *ChannelMonitorRequestTemplate) { n.Edges.RequestTemplate = e }); err != nil { + return nil, err + } + } return nodes, nil } @@ -514,6 +557,38 @@ func (_q *ChannelMonitorQuery) loadDailyRollups(ctx context.Context, query *Chan } return nil } +func (_q *ChannelMonitorQuery) loadRequestTemplate(ctx context.Context, query *ChannelMonitorRequestTemplateQuery, nodes []*ChannelMonitor, init func(*ChannelMonitor), assign func(*ChannelMonitor, *ChannelMonitorRequestTemplate)) error { + ids := make([]int64, 0, len(nodes)) + nodeids := make(map[int64][]*ChannelMonitor) + for i := range nodes { + if nodes[i].TemplateID == nil { + continue + } + fk := *nodes[i].TemplateID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(channelmonitorrequesttemplate.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "template_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} func (_q *ChannelMonitorQuery) sqlCount(ctx context.Context) (int, error) { _spec := _q.querySpec() @@ -543,6 +618,9 @@ func (_q *ChannelMonitorQuery) querySpec() *sqlgraph.QuerySpec { _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) } } + if _q.withRequestTemplate != nil { + _spec.Node.AddColumnOnce(channelmonitor.FieldTemplateID) + } } if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { diff --git a/backend/ent/channelmonitor_update.go b/backend/ent/channelmonitor_update.go index 7ba4e449..4bbcd564 100644 --- a/backend/ent/channelmonitor_update.go +++ b/backend/ent/channelmonitor_update.go @@ -15,6 +15,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" "github.com/Wei-Shaw/sub2api/ent/predicate" ) @@ -215,6 +216,58 @@ func (_u *ChannelMonitorUpdate) AddCreatedBy(v int64) *ChannelMonitorUpdate { return _u } +// SetTemplateID sets the "template_id" field. +func (_u *ChannelMonitorUpdate) SetTemplateID(v int64) *ChannelMonitorUpdate { + _u.mutation.SetTemplateID(v) + return _u +} + +// SetNillableTemplateID sets the "template_id" field if the given value is not nil. +func (_u *ChannelMonitorUpdate) SetNillableTemplateID(v *int64) *ChannelMonitorUpdate { + if v != nil { + _u.SetTemplateID(*v) + } + return _u +} + +// ClearTemplateID clears the value of the "template_id" field. +func (_u *ChannelMonitorUpdate) ClearTemplateID() *ChannelMonitorUpdate { + _u.mutation.ClearTemplateID() + return _u +} + +// SetExtraHeaders sets the "extra_headers" field. +func (_u *ChannelMonitorUpdate) SetExtraHeaders(v map[string]string) *ChannelMonitorUpdate { + _u.mutation.SetExtraHeaders(v) + return _u +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (_u *ChannelMonitorUpdate) SetBodyOverrideMode(v string) *ChannelMonitorUpdate { + _u.mutation.SetBodyOverrideMode(v) + return _u +} + +// SetNillableBodyOverrideMode sets the "body_override_mode" field if the given value is not nil. +func (_u *ChannelMonitorUpdate) SetNillableBodyOverrideMode(v *string) *ChannelMonitorUpdate { + if v != nil { + _u.SetBodyOverrideMode(*v) + } + return _u +} + +// SetBodyOverride sets the "body_override" field. +func (_u *ChannelMonitorUpdate) SetBodyOverride(v map[string]interface{}) *ChannelMonitorUpdate { + _u.mutation.SetBodyOverride(v) + return _u +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (_u *ChannelMonitorUpdate) ClearBodyOverride() *ChannelMonitorUpdate { + _u.mutation.ClearBodyOverride() + return _u +} + // AddHistoryIDs adds the "history" edge to the ChannelMonitorHistory entity by IDs. func (_u *ChannelMonitorUpdate) AddHistoryIDs(ids ...int64) *ChannelMonitorUpdate { _u.mutation.AddHistoryIDs(ids...) @@ -245,6 +298,25 @@ func (_u *ChannelMonitorUpdate) AddDailyRollups(v ...*ChannelMonitorDailyRollup) return _u.AddDailyRollupIDs(ids...) } +// SetRequestTemplateID sets the "request_template" edge to the ChannelMonitorRequestTemplate entity by ID. +func (_u *ChannelMonitorUpdate) SetRequestTemplateID(id int64) *ChannelMonitorUpdate { + _u.mutation.SetRequestTemplateID(id) + return _u +} + +// SetNillableRequestTemplateID sets the "request_template" edge to the ChannelMonitorRequestTemplate entity by ID if the given value is not nil. +func (_u *ChannelMonitorUpdate) SetNillableRequestTemplateID(id *int64) *ChannelMonitorUpdate { + if id != nil { + _u = _u.SetRequestTemplateID(*id) + } + return _u +} + +// SetRequestTemplate sets the "request_template" edge to the ChannelMonitorRequestTemplate entity. +func (_u *ChannelMonitorUpdate) SetRequestTemplate(v *ChannelMonitorRequestTemplate) *ChannelMonitorUpdate { + return _u.SetRequestTemplateID(v.ID) +} + // Mutation returns the ChannelMonitorMutation object of the builder. func (_u *ChannelMonitorUpdate) Mutation() *ChannelMonitorMutation { return _u.mutation @@ -292,6 +364,12 @@ func (_u *ChannelMonitorUpdate) RemoveDailyRollups(v ...*ChannelMonitorDailyRoll return _u.RemoveDailyRollupIDs(ids...) } +// ClearRequestTemplate clears the "request_template" edge to the ChannelMonitorRequestTemplate entity. +func (_u *ChannelMonitorUpdate) ClearRequestTemplate() *ChannelMonitorUpdate { + _u.mutation.ClearRequestTemplate() + return _u +} + // Save executes the query and returns the number of nodes affected by the update operation. func (_u *ChannelMonitorUpdate) Save(ctx context.Context) (int, error) { _u.defaults() @@ -365,6 +443,11 @@ func (_u *ChannelMonitorUpdate) check() error { return &ValidationError{Name: "interval_seconds", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitor.interval_seconds": %w`, err)} } } + if v, ok := _u.mutation.BodyOverrideMode(); ok { + if err := channelmonitor.BodyOverrideModeValidator(v); err != nil { + return &ValidationError{Name: "body_override_mode", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitor.body_override_mode": %w`, err)} + } + } return nil } @@ -433,6 +516,18 @@ func (_u *ChannelMonitorUpdate) sqlSave(ctx context.Context) (_node int, err err if value, ok := _u.mutation.AddedCreatedBy(); ok { _spec.AddField(channelmonitor.FieldCreatedBy, field.TypeInt64, value) } + if value, ok := _u.mutation.ExtraHeaders(); ok { + _spec.SetField(channelmonitor.FieldExtraHeaders, field.TypeJSON, value) + } + if value, ok := _u.mutation.BodyOverrideMode(); ok { + _spec.SetField(channelmonitor.FieldBodyOverrideMode, field.TypeString, value) + } + if value, ok := _u.mutation.BodyOverride(); ok { + _spec.SetField(channelmonitor.FieldBodyOverride, field.TypeJSON, value) + } + if _u.mutation.BodyOverrideCleared() { + _spec.ClearField(channelmonitor.FieldBodyOverride, field.TypeJSON) + } if _u.mutation.HistoryCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -523,6 +618,35 @@ func (_u *ChannelMonitorUpdate) sqlSave(ctx context.Context) (_node int, err err } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.RequestTemplateCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: channelmonitor.RequestTemplateTable, + Columns: []string{channelmonitor.RequestTemplateColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RequestTemplateIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: channelmonitor.RequestTemplateTable, + Columns: []string{channelmonitor.RequestTemplateColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{channelmonitor.Label} @@ -727,6 +851,58 @@ func (_u *ChannelMonitorUpdateOne) AddCreatedBy(v int64) *ChannelMonitorUpdateOn return _u } +// SetTemplateID sets the "template_id" field. +func (_u *ChannelMonitorUpdateOne) SetTemplateID(v int64) *ChannelMonitorUpdateOne { + _u.mutation.SetTemplateID(v) + return _u +} + +// SetNillableTemplateID sets the "template_id" field if the given value is not nil. +func (_u *ChannelMonitorUpdateOne) SetNillableTemplateID(v *int64) *ChannelMonitorUpdateOne { + if v != nil { + _u.SetTemplateID(*v) + } + return _u +} + +// ClearTemplateID clears the value of the "template_id" field. +func (_u *ChannelMonitorUpdateOne) ClearTemplateID() *ChannelMonitorUpdateOne { + _u.mutation.ClearTemplateID() + return _u +} + +// SetExtraHeaders sets the "extra_headers" field. +func (_u *ChannelMonitorUpdateOne) SetExtraHeaders(v map[string]string) *ChannelMonitorUpdateOne { + _u.mutation.SetExtraHeaders(v) + return _u +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (_u *ChannelMonitorUpdateOne) SetBodyOverrideMode(v string) *ChannelMonitorUpdateOne { + _u.mutation.SetBodyOverrideMode(v) + return _u +} + +// SetNillableBodyOverrideMode sets the "body_override_mode" field if the given value is not nil. +func (_u *ChannelMonitorUpdateOne) SetNillableBodyOverrideMode(v *string) *ChannelMonitorUpdateOne { + if v != nil { + _u.SetBodyOverrideMode(*v) + } + return _u +} + +// SetBodyOverride sets the "body_override" field. +func (_u *ChannelMonitorUpdateOne) SetBodyOverride(v map[string]interface{}) *ChannelMonitorUpdateOne { + _u.mutation.SetBodyOverride(v) + return _u +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (_u *ChannelMonitorUpdateOne) ClearBodyOverride() *ChannelMonitorUpdateOne { + _u.mutation.ClearBodyOverride() + return _u +} + // AddHistoryIDs adds the "history" edge to the ChannelMonitorHistory entity by IDs. func (_u *ChannelMonitorUpdateOne) AddHistoryIDs(ids ...int64) *ChannelMonitorUpdateOne { _u.mutation.AddHistoryIDs(ids...) @@ -757,6 +933,25 @@ func (_u *ChannelMonitorUpdateOne) AddDailyRollups(v ...*ChannelMonitorDailyRoll return _u.AddDailyRollupIDs(ids...) } +// SetRequestTemplateID sets the "request_template" edge to the ChannelMonitorRequestTemplate entity by ID. +func (_u *ChannelMonitorUpdateOne) SetRequestTemplateID(id int64) *ChannelMonitorUpdateOne { + _u.mutation.SetRequestTemplateID(id) + return _u +} + +// SetNillableRequestTemplateID sets the "request_template" edge to the ChannelMonitorRequestTemplate entity by ID if the given value is not nil. +func (_u *ChannelMonitorUpdateOne) SetNillableRequestTemplateID(id *int64) *ChannelMonitorUpdateOne { + if id != nil { + _u = _u.SetRequestTemplateID(*id) + } + return _u +} + +// SetRequestTemplate sets the "request_template" edge to the ChannelMonitorRequestTemplate entity. +func (_u *ChannelMonitorUpdateOne) SetRequestTemplate(v *ChannelMonitorRequestTemplate) *ChannelMonitorUpdateOne { + return _u.SetRequestTemplateID(v.ID) +} + // Mutation returns the ChannelMonitorMutation object of the builder. func (_u *ChannelMonitorUpdateOne) Mutation() *ChannelMonitorMutation { return _u.mutation @@ -804,6 +999,12 @@ func (_u *ChannelMonitorUpdateOne) RemoveDailyRollups(v ...*ChannelMonitorDailyR return _u.RemoveDailyRollupIDs(ids...) } +// ClearRequestTemplate clears the "request_template" edge to the ChannelMonitorRequestTemplate entity. +func (_u *ChannelMonitorUpdateOne) ClearRequestTemplate() *ChannelMonitorUpdateOne { + _u.mutation.ClearRequestTemplate() + return _u +} + // Where appends a list predicates to the ChannelMonitorUpdate builder. func (_u *ChannelMonitorUpdateOne) Where(ps ...predicate.ChannelMonitor) *ChannelMonitorUpdateOne { _u.mutation.Where(ps...) @@ -890,6 +1091,11 @@ func (_u *ChannelMonitorUpdateOne) check() error { return &ValidationError{Name: "interval_seconds", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitor.interval_seconds": %w`, err)} } } + if v, ok := _u.mutation.BodyOverrideMode(); ok { + if err := channelmonitor.BodyOverrideModeValidator(v); err != nil { + return &ValidationError{Name: "body_override_mode", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitor.body_override_mode": %w`, err)} + } + } return nil } @@ -975,6 +1181,18 @@ func (_u *ChannelMonitorUpdateOne) sqlSave(ctx context.Context) (_node *ChannelM if value, ok := _u.mutation.AddedCreatedBy(); ok { _spec.AddField(channelmonitor.FieldCreatedBy, field.TypeInt64, value) } + if value, ok := _u.mutation.ExtraHeaders(); ok { + _spec.SetField(channelmonitor.FieldExtraHeaders, field.TypeJSON, value) + } + if value, ok := _u.mutation.BodyOverrideMode(); ok { + _spec.SetField(channelmonitor.FieldBodyOverrideMode, field.TypeString, value) + } + if value, ok := _u.mutation.BodyOverride(); ok { + _spec.SetField(channelmonitor.FieldBodyOverride, field.TypeJSON, value) + } + if _u.mutation.BodyOverrideCleared() { + _spec.ClearField(channelmonitor.FieldBodyOverride, field.TypeJSON) + } if _u.mutation.HistoryCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -1065,6 +1283,35 @@ func (_u *ChannelMonitorUpdateOne) sqlSave(ctx context.Context) (_node *ChannelM } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if _u.mutation.RequestTemplateCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: channelmonitor.RequestTemplateTable, + Columns: []string{channelmonitor.RequestTemplateColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RequestTemplateIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: false, + Table: channelmonitor.RequestTemplateTable, + Columns: []string{channelmonitor.RequestTemplateColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } _node = &ChannelMonitor{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/backend/ent/channelmonitorrequesttemplate.go b/backend/ent/channelmonitorrequesttemplate.go new file mode 100644 index 00000000..b8429a4d --- /dev/null +++ b/backend/ent/channelmonitorrequesttemplate.go @@ -0,0 +1,216 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" +) + +// ChannelMonitorRequestTemplate is the model entity for the ChannelMonitorRequestTemplate schema. +type ChannelMonitorRequestTemplate struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` + // Name holds the value of the "name" field. + Name string `json:"name,omitempty"` + // Provider holds the value of the "provider" field. + Provider channelmonitorrequesttemplate.Provider `json:"provider,omitempty"` + // Description holds the value of the "description" field. + Description string `json:"description,omitempty"` + // ExtraHeaders holds the value of the "extra_headers" field. + ExtraHeaders map[string]string `json:"extra_headers,omitempty"` + // BodyOverrideMode holds the value of the "body_override_mode" field. + BodyOverrideMode string `json:"body_override_mode,omitempty"` + // BodyOverride holds the value of the "body_override" field. + BodyOverride map[string]interface{} `json:"body_override,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the ChannelMonitorRequestTemplateQuery when eager-loading is set. + Edges ChannelMonitorRequestTemplateEdges `json:"edges"` + selectValues sql.SelectValues +} + +// ChannelMonitorRequestTemplateEdges holds the relations/edges for other nodes in the graph. +type ChannelMonitorRequestTemplateEdges struct { + // Monitors holds the value of the monitors edge. + Monitors []*ChannelMonitor `json:"monitors,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// MonitorsOrErr returns the Monitors value or an error if the edge +// was not loaded in eager-loading. +func (e ChannelMonitorRequestTemplateEdges) MonitorsOrErr() ([]*ChannelMonitor, error) { + if e.loadedTypes[0] { + return e.Monitors, nil + } + return nil, &NotLoadedError{edge: "monitors"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*ChannelMonitorRequestTemplate) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case channelmonitorrequesttemplate.FieldExtraHeaders, channelmonitorrequesttemplate.FieldBodyOverride: + values[i] = new([]byte) + case channelmonitorrequesttemplate.FieldID: + values[i] = new(sql.NullInt64) + case channelmonitorrequesttemplate.FieldName, channelmonitorrequesttemplate.FieldProvider, channelmonitorrequesttemplate.FieldDescription, channelmonitorrequesttemplate.FieldBodyOverrideMode: + values[i] = new(sql.NullString) + case channelmonitorrequesttemplate.FieldCreatedAt, channelmonitorrequesttemplate.FieldUpdatedAt: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the ChannelMonitorRequestTemplate fields. +func (_m *ChannelMonitorRequestTemplate) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case channelmonitorrequesttemplate.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case channelmonitorrequesttemplate.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + _m.CreatedAt = value.Time + } + case channelmonitorrequesttemplate.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + _m.UpdatedAt = value.Time + } + case channelmonitorrequesttemplate.FieldName: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field name", values[i]) + } else if value.Valid { + _m.Name = value.String + } + case channelmonitorrequesttemplate.FieldProvider: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field provider", values[i]) + } else if value.Valid { + _m.Provider = channelmonitorrequesttemplate.Provider(value.String) + } + case channelmonitorrequesttemplate.FieldDescription: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field description", values[i]) + } else if value.Valid { + _m.Description = value.String + } + case channelmonitorrequesttemplate.FieldExtraHeaders: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field extra_headers", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &_m.ExtraHeaders); err != nil { + return fmt.Errorf("unmarshal field extra_headers: %w", err) + } + } + case channelmonitorrequesttemplate.FieldBodyOverrideMode: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field body_override_mode", values[i]) + } else if value.Valid { + _m.BodyOverrideMode = value.String + } + case channelmonitorrequesttemplate.FieldBodyOverride: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field body_override", values[i]) + } else if value != nil && len(*value) > 0 { + if err := json.Unmarshal(*value, &_m.BodyOverride); err != nil { + return fmt.Errorf("unmarshal field body_override: %w", err) + } + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the ChannelMonitorRequestTemplate. +// This includes values selected through modifiers, order, etc. +func (_m *ChannelMonitorRequestTemplate) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// QueryMonitors queries the "monitors" edge of the ChannelMonitorRequestTemplate entity. +func (_m *ChannelMonitorRequestTemplate) QueryMonitors() *ChannelMonitorQuery { + return NewChannelMonitorRequestTemplateClient(_m.config).QueryMonitors(_m) +} + +// Update returns a builder for updating this ChannelMonitorRequestTemplate. +// Note that you need to call ChannelMonitorRequestTemplate.Unwrap() before calling this method if this ChannelMonitorRequestTemplate +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *ChannelMonitorRequestTemplate) Update() *ChannelMonitorRequestTemplateUpdateOne { + return NewChannelMonitorRequestTemplateClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the ChannelMonitorRequestTemplate entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *ChannelMonitorRequestTemplate) Unwrap() *ChannelMonitorRequestTemplate { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: ChannelMonitorRequestTemplate is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *ChannelMonitorRequestTemplate) String() string { + var builder strings.Builder + builder.WriteString("ChannelMonitorRequestTemplate(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("created_at=") + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(_m.UpdatedAt.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("name=") + builder.WriteString(_m.Name) + builder.WriteString(", ") + builder.WriteString("provider=") + builder.WriteString(fmt.Sprintf("%v", _m.Provider)) + builder.WriteString(", ") + builder.WriteString("description=") + builder.WriteString(_m.Description) + builder.WriteString(", ") + builder.WriteString("extra_headers=") + builder.WriteString(fmt.Sprintf("%v", _m.ExtraHeaders)) + builder.WriteString(", ") + builder.WriteString("body_override_mode=") + builder.WriteString(_m.BodyOverrideMode) + builder.WriteString(", ") + builder.WriteString("body_override=") + builder.WriteString(fmt.Sprintf("%v", _m.BodyOverride)) + builder.WriteByte(')') + return builder.String() +} + +// ChannelMonitorRequestTemplates is a parsable slice of ChannelMonitorRequestTemplate. +type ChannelMonitorRequestTemplates []*ChannelMonitorRequestTemplate diff --git a/backend/ent/channelmonitorrequesttemplate/channelmonitorrequesttemplate.go b/backend/ent/channelmonitorrequesttemplate/channelmonitorrequesttemplate.go new file mode 100644 index 00000000..65b8d641 --- /dev/null +++ b/backend/ent/channelmonitorrequesttemplate/channelmonitorrequesttemplate.go @@ -0,0 +1,172 @@ +// Code generated by ent, DO NOT EDIT. + +package channelmonitorrequesttemplate + +import ( + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" +) + +const ( + // Label holds the string label denoting the channelmonitorrequesttemplate type in the database. + Label = "channel_monitor_request_template" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // FieldName holds the string denoting the name field in the database. + FieldName = "name" + // FieldProvider holds the string denoting the provider field in the database. + FieldProvider = "provider" + // FieldDescription holds the string denoting the description field in the database. + FieldDescription = "description" + // FieldExtraHeaders holds the string denoting the extra_headers field in the database. + FieldExtraHeaders = "extra_headers" + // FieldBodyOverrideMode holds the string denoting the body_override_mode field in the database. + FieldBodyOverrideMode = "body_override_mode" + // FieldBodyOverride holds the string denoting the body_override field in the database. + FieldBodyOverride = "body_override" + // EdgeMonitors holds the string denoting the monitors edge name in mutations. + EdgeMonitors = "monitors" + // Table holds the table name of the channelmonitorrequesttemplate in the database. + Table = "channel_monitor_request_templates" + // MonitorsTable is the table that holds the monitors relation/edge. + MonitorsTable = "channel_monitors" + // MonitorsInverseTable is the table name for the ChannelMonitor entity. + // It exists in this package in order to avoid circular dependency with the "channelmonitor" package. + MonitorsInverseTable = "channel_monitors" + // MonitorsColumn is the table column denoting the monitors relation/edge. + MonitorsColumn = "template_id" +) + +// Columns holds all SQL columns for channelmonitorrequesttemplate fields. +var Columns = []string{ + FieldID, + FieldCreatedAt, + FieldUpdatedAt, + FieldName, + FieldProvider, + FieldDescription, + FieldExtraHeaders, + FieldBodyOverrideMode, + FieldBodyOverride, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time + // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. + UpdateDefaultUpdatedAt func() time.Time + // NameValidator is a validator for the "name" field. It is called by the builders before save. + NameValidator func(string) error + // DefaultDescription holds the default value on creation for the "description" field. + DefaultDescription string + // DescriptionValidator is a validator for the "description" field. It is called by the builders before save. + DescriptionValidator func(string) error + // DefaultExtraHeaders holds the default value on creation for the "extra_headers" field. + DefaultExtraHeaders map[string]string + // DefaultBodyOverrideMode holds the default value on creation for the "body_override_mode" field. + DefaultBodyOverrideMode string + // BodyOverrideModeValidator is a validator for the "body_override_mode" field. It is called by the builders before save. + BodyOverrideModeValidator func(string) error +) + +// Provider defines the type for the "provider" enum field. +type Provider string + +// Provider values. +const ( + ProviderOpenai Provider = "openai" + ProviderAnthropic Provider = "anthropic" + ProviderGemini Provider = "gemini" +) + +func (pr Provider) String() string { + return string(pr) +} + +// ProviderValidator is a validator for the "provider" field enum values. It is called by the builders before save. +func ProviderValidator(pr Provider) error { + switch pr { + case ProviderOpenai, ProviderAnthropic, ProviderGemini: + return nil + default: + return fmt.Errorf("channelmonitorrequesttemplate: invalid enum value for provider field: %q", pr) + } +} + +// OrderOption defines the ordering options for the ChannelMonitorRequestTemplate queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByProvider orders the results by the provider field. +func ByProvider(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldProvider, opts...).ToFunc() +} + +// ByDescription orders the results by the description field. +func ByDescription(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDescription, opts...).ToFunc() +} + +// ByBodyOverrideMode orders the results by the body_override_mode field. +func ByBodyOverrideMode(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldBodyOverrideMode, opts...).ToFunc() +} + +// ByMonitorsCount orders the results by monitors count. +func ByMonitorsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newMonitorsStep(), opts...) + } +} + +// ByMonitors orders the results by monitors terms. +func ByMonitors(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newMonitorsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} +func newMonitorsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(MonitorsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, true, MonitorsTable, MonitorsColumn), + ) +} diff --git a/backend/ent/channelmonitorrequesttemplate/where.go b/backend/ent/channelmonitorrequesttemplate/where.go new file mode 100644 index 00000000..b95e5df0 --- /dev/null +++ b/backend/ent/channelmonitorrequesttemplate/where.go @@ -0,0 +1,434 @@ +// Code generated by ent, DO NOT EDIT. + +package channelmonitorrequesttemplate + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLTE(FieldID, id)) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldCreatedAt, v)) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// Name applies equality check predicate on the "name" field. It's identical to NameEQ. +func Name(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldName, v)) +} + +// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. +func Description(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldDescription, v)) +} + +// BodyOverrideMode applies equality check predicate on the "body_override_mode" field. It's identical to BodyOverrideModeEQ. +func BodyOverrideMode(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldBodyOverrideMode, v)) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldCreatedAt, v)) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNEQ(FieldCreatedAt, v)) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIn(FieldCreatedAt, vs...)) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotIn(FieldCreatedAt, vs...)) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGT(FieldCreatedAt, v)) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGTE(FieldCreatedAt, v)) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLT(FieldCreatedAt, v)) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLTE(FieldCreatedAt, v)) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLTE(FieldUpdatedAt, v)) +} + +// NameEQ applies the EQ predicate on the "name" field. +func NameEQ(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldName, v)) +} + +// NameNEQ applies the NEQ predicate on the "name" field. +func NameNEQ(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNEQ(FieldName, v)) +} + +// NameIn applies the In predicate on the "name" field. +func NameIn(vs ...string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIn(FieldName, vs...)) +} + +// NameNotIn applies the NotIn predicate on the "name" field. +func NameNotIn(vs ...string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotIn(FieldName, vs...)) +} + +// NameGT applies the GT predicate on the "name" field. +func NameGT(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGT(FieldName, v)) +} + +// NameGTE applies the GTE predicate on the "name" field. +func NameGTE(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGTE(FieldName, v)) +} + +// NameLT applies the LT predicate on the "name" field. +func NameLT(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLT(FieldName, v)) +} + +// NameLTE applies the LTE predicate on the "name" field. +func NameLTE(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLTE(FieldName, v)) +} + +// NameContains applies the Contains predicate on the "name" field. +func NameContains(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldContains(FieldName, v)) +} + +// NameHasPrefix applies the HasPrefix predicate on the "name" field. +func NameHasPrefix(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldHasPrefix(FieldName, v)) +} + +// NameHasSuffix applies the HasSuffix predicate on the "name" field. +func NameHasSuffix(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldHasSuffix(FieldName, v)) +} + +// NameEqualFold applies the EqualFold predicate on the "name" field. +func NameEqualFold(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEqualFold(FieldName, v)) +} + +// NameContainsFold applies the ContainsFold predicate on the "name" field. +func NameContainsFold(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldContainsFold(FieldName, v)) +} + +// ProviderEQ applies the EQ predicate on the "provider" field. +func ProviderEQ(v Provider) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldProvider, v)) +} + +// ProviderNEQ applies the NEQ predicate on the "provider" field. +func ProviderNEQ(v Provider) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNEQ(FieldProvider, v)) +} + +// ProviderIn applies the In predicate on the "provider" field. +func ProviderIn(vs ...Provider) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIn(FieldProvider, vs...)) +} + +// ProviderNotIn applies the NotIn predicate on the "provider" field. +func ProviderNotIn(vs ...Provider) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotIn(FieldProvider, vs...)) +} + +// DescriptionEQ applies the EQ predicate on the "description" field. +func DescriptionEQ(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldDescription, v)) +} + +// DescriptionNEQ applies the NEQ predicate on the "description" field. +func DescriptionNEQ(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNEQ(FieldDescription, v)) +} + +// DescriptionIn applies the In predicate on the "description" field. +func DescriptionIn(vs ...string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIn(FieldDescription, vs...)) +} + +// DescriptionNotIn applies the NotIn predicate on the "description" field. +func DescriptionNotIn(vs ...string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotIn(FieldDescription, vs...)) +} + +// DescriptionGT applies the GT predicate on the "description" field. +func DescriptionGT(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGT(FieldDescription, v)) +} + +// DescriptionGTE applies the GTE predicate on the "description" field. +func DescriptionGTE(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGTE(FieldDescription, v)) +} + +// DescriptionLT applies the LT predicate on the "description" field. +func DescriptionLT(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLT(FieldDescription, v)) +} + +// DescriptionLTE applies the LTE predicate on the "description" field. +func DescriptionLTE(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLTE(FieldDescription, v)) +} + +// DescriptionContains applies the Contains predicate on the "description" field. +func DescriptionContains(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldContains(FieldDescription, v)) +} + +// DescriptionHasPrefix applies the HasPrefix predicate on the "description" field. +func DescriptionHasPrefix(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldHasPrefix(FieldDescription, v)) +} + +// DescriptionHasSuffix applies the HasSuffix predicate on the "description" field. +func DescriptionHasSuffix(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldHasSuffix(FieldDescription, v)) +} + +// DescriptionIsNil applies the IsNil predicate on the "description" field. +func DescriptionIsNil() predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIsNull(FieldDescription)) +} + +// DescriptionNotNil applies the NotNil predicate on the "description" field. +func DescriptionNotNil() predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotNull(FieldDescription)) +} + +// DescriptionEqualFold applies the EqualFold predicate on the "description" field. +func DescriptionEqualFold(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEqualFold(FieldDescription, v)) +} + +// DescriptionContainsFold applies the ContainsFold predicate on the "description" field. +func DescriptionContainsFold(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldContainsFold(FieldDescription, v)) +} + +// BodyOverrideModeEQ applies the EQ predicate on the "body_override_mode" field. +func BodyOverrideModeEQ(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEQ(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeNEQ applies the NEQ predicate on the "body_override_mode" field. +func BodyOverrideModeNEQ(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNEQ(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeIn applies the In predicate on the "body_override_mode" field. +func BodyOverrideModeIn(vs ...string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIn(FieldBodyOverrideMode, vs...)) +} + +// BodyOverrideModeNotIn applies the NotIn predicate on the "body_override_mode" field. +func BodyOverrideModeNotIn(vs ...string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotIn(FieldBodyOverrideMode, vs...)) +} + +// BodyOverrideModeGT applies the GT predicate on the "body_override_mode" field. +func BodyOverrideModeGT(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGT(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeGTE applies the GTE predicate on the "body_override_mode" field. +func BodyOverrideModeGTE(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldGTE(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeLT applies the LT predicate on the "body_override_mode" field. +func BodyOverrideModeLT(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLT(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeLTE applies the LTE predicate on the "body_override_mode" field. +func BodyOverrideModeLTE(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldLTE(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeContains applies the Contains predicate on the "body_override_mode" field. +func BodyOverrideModeContains(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldContains(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeHasPrefix applies the HasPrefix predicate on the "body_override_mode" field. +func BodyOverrideModeHasPrefix(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldHasPrefix(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeHasSuffix applies the HasSuffix predicate on the "body_override_mode" field. +func BodyOverrideModeHasSuffix(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldHasSuffix(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeEqualFold applies the EqualFold predicate on the "body_override_mode" field. +func BodyOverrideModeEqualFold(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldEqualFold(FieldBodyOverrideMode, v)) +} + +// BodyOverrideModeContainsFold applies the ContainsFold predicate on the "body_override_mode" field. +func BodyOverrideModeContainsFold(v string) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldContainsFold(FieldBodyOverrideMode, v)) +} + +// BodyOverrideIsNil applies the IsNil predicate on the "body_override" field. +func BodyOverrideIsNil() predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldIsNull(FieldBodyOverride)) +} + +// BodyOverrideNotNil applies the NotNil predicate on the "body_override" field. +func BodyOverrideNotNil() predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.FieldNotNull(FieldBodyOverride)) +} + +// HasMonitors applies the HasEdge predicate on the "monitors" edge. +func HasMonitors() predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, true, MonitorsTable, MonitorsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasMonitorsWith applies the HasEdge predicate on the "monitors" edge with a given conditions (other predicates). +func HasMonitorsWith(preds ...predicate.ChannelMonitor) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(func(s *sql.Selector) { + step := newMonitorsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.ChannelMonitorRequestTemplate) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.ChannelMonitorRequestTemplate) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.ChannelMonitorRequestTemplate) predicate.ChannelMonitorRequestTemplate { + return predicate.ChannelMonitorRequestTemplate(sql.NotPredicates(p)) +} diff --git a/backend/ent/channelmonitorrequesttemplate_create.go b/backend/ent/channelmonitorrequesttemplate_create.go new file mode 100644 index 00000000..1ba842cd --- /dev/null +++ b/backend/ent/channelmonitorrequesttemplate_create.go @@ -0,0 +1,942 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/channelmonitor" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" +) + +// ChannelMonitorRequestTemplateCreate is the builder for creating a ChannelMonitorRequestTemplate entity. +type ChannelMonitorRequestTemplateCreate struct { + config + mutation *ChannelMonitorRequestTemplateMutation + hooks []Hook + conflict []sql.ConflictOption +} + +// SetCreatedAt sets the "created_at" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetCreatedAt(v time.Time) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetCreatedAt(v) + return _c +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (_c *ChannelMonitorRequestTemplateCreate) SetNillableCreatedAt(v *time.Time) *ChannelMonitorRequestTemplateCreate { + if v != nil { + _c.SetCreatedAt(*v) + } + return _c +} + +// SetUpdatedAt sets the "updated_at" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetUpdatedAt(v time.Time) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetUpdatedAt(v) + return _c +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (_c *ChannelMonitorRequestTemplateCreate) SetNillableUpdatedAt(v *time.Time) *ChannelMonitorRequestTemplateCreate { + if v != nil { + _c.SetUpdatedAt(*v) + } + return _c +} + +// SetName sets the "name" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetName(v string) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetName(v) + return _c +} + +// SetProvider sets the "provider" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetProvider(v channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetProvider(v) + return _c +} + +// SetDescription sets the "description" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetDescription(v string) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetDescription(v) + return _c +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_c *ChannelMonitorRequestTemplateCreate) SetNillableDescription(v *string) *ChannelMonitorRequestTemplateCreate { + if v != nil { + _c.SetDescription(*v) + } + return _c +} + +// SetExtraHeaders sets the "extra_headers" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetExtraHeaders(v map[string]string) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetExtraHeaders(v) + return _c +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetBodyOverrideMode(v string) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetBodyOverrideMode(v) + return _c +} + +// SetNillableBodyOverrideMode sets the "body_override_mode" field if the given value is not nil. +func (_c *ChannelMonitorRequestTemplateCreate) SetNillableBodyOverrideMode(v *string) *ChannelMonitorRequestTemplateCreate { + if v != nil { + _c.SetBodyOverrideMode(*v) + } + return _c +} + +// SetBodyOverride sets the "body_override" field. +func (_c *ChannelMonitorRequestTemplateCreate) SetBodyOverride(v map[string]interface{}) *ChannelMonitorRequestTemplateCreate { + _c.mutation.SetBodyOverride(v) + return _c +} + +// AddMonitorIDs adds the "monitors" edge to the ChannelMonitor entity by IDs. +func (_c *ChannelMonitorRequestTemplateCreate) AddMonitorIDs(ids ...int64) *ChannelMonitorRequestTemplateCreate { + _c.mutation.AddMonitorIDs(ids...) + return _c +} + +// AddMonitors adds the "monitors" edges to the ChannelMonitor entity. +func (_c *ChannelMonitorRequestTemplateCreate) AddMonitors(v ...*ChannelMonitor) *ChannelMonitorRequestTemplateCreate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _c.AddMonitorIDs(ids...) +} + +// Mutation returns the ChannelMonitorRequestTemplateMutation object of the builder. +func (_c *ChannelMonitorRequestTemplateCreate) Mutation() *ChannelMonitorRequestTemplateMutation { + return _c.mutation +} + +// Save creates the ChannelMonitorRequestTemplate in the database. +func (_c *ChannelMonitorRequestTemplateCreate) Save(ctx context.Context) (*ChannelMonitorRequestTemplate, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *ChannelMonitorRequestTemplateCreate) SaveX(ctx context.Context) *ChannelMonitorRequestTemplate { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *ChannelMonitorRequestTemplateCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *ChannelMonitorRequestTemplateCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_c *ChannelMonitorRequestTemplateCreate) defaults() { + if _, ok := _c.mutation.CreatedAt(); !ok { + v := channelmonitorrequesttemplate.DefaultCreatedAt() + _c.mutation.SetCreatedAt(v) + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + v := channelmonitorrequesttemplate.DefaultUpdatedAt() + _c.mutation.SetUpdatedAt(v) + } + if _, ok := _c.mutation.Description(); !ok { + v := channelmonitorrequesttemplate.DefaultDescription + _c.mutation.SetDescription(v) + } + if _, ok := _c.mutation.ExtraHeaders(); !ok { + v := channelmonitorrequesttemplate.DefaultExtraHeaders + _c.mutation.SetExtraHeaders(v) + } + if _, ok := _c.mutation.BodyOverrideMode(); !ok { + v := channelmonitorrequesttemplate.DefaultBodyOverrideMode + _c.mutation.SetBodyOverrideMode(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *ChannelMonitorRequestTemplateCreate) check() error { + if _, ok := _c.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "ChannelMonitorRequestTemplate.created_at"`)} + } + if _, ok := _c.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "ChannelMonitorRequestTemplate.updated_at"`)} + } + if _, ok := _c.mutation.Name(); !ok { + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "ChannelMonitorRequestTemplate.name"`)} + } + if v, ok := _c.mutation.Name(); ok { + if err := channelmonitorrequesttemplate.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.name": %w`, err)} + } + } + if _, ok := _c.mutation.Provider(); !ok { + return &ValidationError{Name: "provider", err: errors.New(`ent: missing required field "ChannelMonitorRequestTemplate.provider"`)} + } + if v, ok := _c.mutation.Provider(); ok { + if err := channelmonitorrequesttemplate.ProviderValidator(v); err != nil { + return &ValidationError{Name: "provider", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.provider": %w`, err)} + } + } + if v, ok := _c.mutation.Description(); ok { + if err := channelmonitorrequesttemplate.DescriptionValidator(v); err != nil { + return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.description": %w`, err)} + } + } + if _, ok := _c.mutation.ExtraHeaders(); !ok { + return &ValidationError{Name: "extra_headers", err: errors.New(`ent: missing required field "ChannelMonitorRequestTemplate.extra_headers"`)} + } + if _, ok := _c.mutation.BodyOverrideMode(); !ok { + return &ValidationError{Name: "body_override_mode", err: errors.New(`ent: missing required field "ChannelMonitorRequestTemplate.body_override_mode"`)} + } + if v, ok := _c.mutation.BodyOverrideMode(); ok { + if err := channelmonitorrequesttemplate.BodyOverrideModeValidator(v); err != nil { + return &ValidationError{Name: "body_override_mode", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.body_override_mode": %w`, err)} + } + } + return nil +} + +func (_c *ChannelMonitorRequestTemplateCreate) sqlSave(ctx context.Context) (*ChannelMonitorRequestTemplate, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *ChannelMonitorRequestTemplateCreate) createSpec() (*ChannelMonitorRequestTemplate, *sqlgraph.CreateSpec) { + var ( + _node = &ChannelMonitorRequestTemplate{config: _c.config} + _spec = sqlgraph.NewCreateSpec(channelmonitorrequesttemplate.Table, sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64)) + ) + _spec.OnConflict = _c.conflict + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldCreatedAt, field.TypeTime, value) + _node.CreatedAt = value + } + if value, ok := _c.mutation.UpdatedAt(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } + if value, ok := _c.mutation.Name(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldName, field.TypeString, value) + _node.Name = value + } + if value, ok := _c.mutation.Provider(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldProvider, field.TypeEnum, value) + _node.Provider = value + } + if value, ok := _c.mutation.Description(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldDescription, field.TypeString, value) + _node.Description = value + } + if value, ok := _c.mutation.ExtraHeaders(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldExtraHeaders, field.TypeJSON, value) + _node.ExtraHeaders = value + } + if value, ok := _c.mutation.BodyOverrideMode(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldBodyOverrideMode, field.TypeString, value) + _node.BodyOverrideMode = value + } + if value, ok := _c.mutation.BodyOverride(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldBodyOverride, field.TypeJSON, value) + _node.BodyOverride = value + } + if nodes := _c.mutation.MonitorsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: true, + Table: channelmonitorrequesttemplate.MonitorsTable, + Columns: []string{channelmonitorrequesttemplate.MonitorsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitor.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.ChannelMonitorRequestTemplate.Create(). +// SetCreatedAt(v). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.ChannelMonitorRequestTemplateUpsert) { +// SetCreatedAt(v+v). +// }). +// Exec(ctx) +func (_c *ChannelMonitorRequestTemplateCreate) OnConflict(opts ...sql.ConflictOption) *ChannelMonitorRequestTemplateUpsertOne { + _c.conflict = opts + return &ChannelMonitorRequestTemplateUpsertOne{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.ChannelMonitorRequestTemplate.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *ChannelMonitorRequestTemplateCreate) OnConflictColumns(columns ...string) *ChannelMonitorRequestTemplateUpsertOne { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &ChannelMonitorRequestTemplateUpsertOne{ + create: _c, + } +} + +type ( + // ChannelMonitorRequestTemplateUpsertOne is the builder for "upsert"-ing + // one ChannelMonitorRequestTemplate node. + ChannelMonitorRequestTemplateUpsertOne struct { + create *ChannelMonitorRequestTemplateCreate + } + + // ChannelMonitorRequestTemplateUpsert is the "OnConflict" setter. + ChannelMonitorRequestTemplateUpsert struct { + *sql.UpdateSet + } +) + +// SetUpdatedAt sets the "updated_at" field. +func (u *ChannelMonitorRequestTemplateUpsert) SetUpdatedAt(v time.Time) *ChannelMonitorRequestTemplateUpsert { + u.Set(channelmonitorrequesttemplate.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsert) UpdateUpdatedAt() *ChannelMonitorRequestTemplateUpsert { + u.SetExcluded(channelmonitorrequesttemplate.FieldUpdatedAt) + return u +} + +// SetName sets the "name" field. +func (u *ChannelMonitorRequestTemplateUpsert) SetName(v string) *ChannelMonitorRequestTemplateUpsert { + u.Set(channelmonitorrequesttemplate.FieldName, v) + return u +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsert) UpdateName() *ChannelMonitorRequestTemplateUpsert { + u.SetExcluded(channelmonitorrequesttemplate.FieldName) + return u +} + +// SetProvider sets the "provider" field. +func (u *ChannelMonitorRequestTemplateUpsert) SetProvider(v channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateUpsert { + u.Set(channelmonitorrequesttemplate.FieldProvider, v) + return u +} + +// UpdateProvider sets the "provider" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsert) UpdateProvider() *ChannelMonitorRequestTemplateUpsert { + u.SetExcluded(channelmonitorrequesttemplate.FieldProvider) + return u +} + +// SetDescription sets the "description" field. +func (u *ChannelMonitorRequestTemplateUpsert) SetDescription(v string) *ChannelMonitorRequestTemplateUpsert { + u.Set(channelmonitorrequesttemplate.FieldDescription, v) + return u +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsert) UpdateDescription() *ChannelMonitorRequestTemplateUpsert { + u.SetExcluded(channelmonitorrequesttemplate.FieldDescription) + return u +} + +// ClearDescription clears the value of the "description" field. +func (u *ChannelMonitorRequestTemplateUpsert) ClearDescription() *ChannelMonitorRequestTemplateUpsert { + u.SetNull(channelmonitorrequesttemplate.FieldDescription) + return u +} + +// SetExtraHeaders sets the "extra_headers" field. +func (u *ChannelMonitorRequestTemplateUpsert) SetExtraHeaders(v map[string]string) *ChannelMonitorRequestTemplateUpsert { + u.Set(channelmonitorrequesttemplate.FieldExtraHeaders, v) + return u +} + +// UpdateExtraHeaders sets the "extra_headers" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsert) UpdateExtraHeaders() *ChannelMonitorRequestTemplateUpsert { + u.SetExcluded(channelmonitorrequesttemplate.FieldExtraHeaders) + return u +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (u *ChannelMonitorRequestTemplateUpsert) SetBodyOverrideMode(v string) *ChannelMonitorRequestTemplateUpsert { + u.Set(channelmonitorrequesttemplate.FieldBodyOverrideMode, v) + return u +} + +// UpdateBodyOverrideMode sets the "body_override_mode" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsert) UpdateBodyOverrideMode() *ChannelMonitorRequestTemplateUpsert { + u.SetExcluded(channelmonitorrequesttemplate.FieldBodyOverrideMode) + return u +} + +// SetBodyOverride sets the "body_override" field. +func (u *ChannelMonitorRequestTemplateUpsert) SetBodyOverride(v map[string]interface{}) *ChannelMonitorRequestTemplateUpsert { + u.Set(channelmonitorrequesttemplate.FieldBodyOverride, v) + return u +} + +// UpdateBodyOverride sets the "body_override" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsert) UpdateBodyOverride() *ChannelMonitorRequestTemplateUpsert { + u.SetExcluded(channelmonitorrequesttemplate.FieldBodyOverride) + return u +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (u *ChannelMonitorRequestTemplateUpsert) ClearBodyOverride() *ChannelMonitorRequestTemplateUpsert { + u.SetNull(channelmonitorrequesttemplate.FieldBodyOverride) + return u +} + +// UpdateNewValues updates the mutable fields using the new values that were set on create. +// Using this option is equivalent to using: +// +// client.ChannelMonitorRequestTemplate.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateNewValues() *ChannelMonitorRequestTemplateUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + if _, exists := u.create.mutation.CreatedAt(); exists { + s.SetIgnore(channelmonitorrequesttemplate.FieldCreatedAt) + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.ChannelMonitorRequestTemplate.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *ChannelMonitorRequestTemplateUpsertOne) Ignore() *ChannelMonitorRequestTemplateUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *ChannelMonitorRequestTemplateUpsertOne) DoNothing() *ChannelMonitorRequestTemplateUpsertOne { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the ChannelMonitorRequestTemplateCreate.OnConflict +// documentation for more info. +func (u *ChannelMonitorRequestTemplateUpsertOne) Update(set func(*ChannelMonitorRequestTemplateUpsert)) *ChannelMonitorRequestTemplateUpsertOne { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&ChannelMonitorRequestTemplateUpsert{UpdateSet: update}) + })) + return u +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) SetUpdatedAt(v time.Time) *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateUpdatedAt() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateUpdatedAt() + }) +} + +// SetName sets the "name" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) SetName(v string) *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetName(v) + }) +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateName() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateName() + }) +} + +// SetProvider sets the "provider" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) SetProvider(v channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetProvider(v) + }) +} + +// UpdateProvider sets the "provider" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateProvider() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateProvider() + }) +} + +// SetDescription sets the "description" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) SetDescription(v string) *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetDescription(v) + }) +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateDescription() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateDescription() + }) +} + +// ClearDescription clears the value of the "description" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) ClearDescription() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.ClearDescription() + }) +} + +// SetExtraHeaders sets the "extra_headers" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) SetExtraHeaders(v map[string]string) *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetExtraHeaders(v) + }) +} + +// UpdateExtraHeaders sets the "extra_headers" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateExtraHeaders() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateExtraHeaders() + }) +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) SetBodyOverrideMode(v string) *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetBodyOverrideMode(v) + }) +} + +// UpdateBodyOverrideMode sets the "body_override_mode" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateBodyOverrideMode() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateBodyOverrideMode() + }) +} + +// SetBodyOverride sets the "body_override" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) SetBodyOverride(v map[string]interface{}) *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetBodyOverride(v) + }) +} + +// UpdateBodyOverride sets the "body_override" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertOne) UpdateBodyOverride() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateBodyOverride() + }) +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (u *ChannelMonitorRequestTemplateUpsertOne) ClearBodyOverride() *ChannelMonitorRequestTemplateUpsertOne { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.ClearBodyOverride() + }) +} + +// Exec executes the query. +func (u *ChannelMonitorRequestTemplateUpsertOne) Exec(ctx context.Context) error { + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for ChannelMonitorRequestTemplateCreate.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *ChannelMonitorRequestTemplateUpsertOne) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} + +// Exec executes the UPSERT query and returns the inserted/updated ID. +func (u *ChannelMonitorRequestTemplateUpsertOne) ID(ctx context.Context) (id int64, err error) { + node, err := u.create.Save(ctx) + if err != nil { + return id, err + } + return node.ID, nil +} + +// IDX is like ID, but panics if an error occurs. +func (u *ChannelMonitorRequestTemplateUpsertOne) IDX(ctx context.Context) int64 { + id, err := u.ID(ctx) + if err != nil { + panic(err) + } + return id +} + +// ChannelMonitorRequestTemplateCreateBulk is the builder for creating many ChannelMonitorRequestTemplate entities in bulk. +type ChannelMonitorRequestTemplateCreateBulk struct { + config + err error + builders []*ChannelMonitorRequestTemplateCreate + conflict []sql.ConflictOption +} + +// Save creates the ChannelMonitorRequestTemplate entities in the database. +func (_c *ChannelMonitorRequestTemplateCreateBulk) Save(ctx context.Context) ([]*ChannelMonitorRequestTemplate, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*ChannelMonitorRequestTemplate, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ChannelMonitorRequestTemplateMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.OnConflict = _c.conflict + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *ChannelMonitorRequestTemplateCreateBulk) SaveX(ctx context.Context) []*ChannelMonitorRequestTemplate { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *ChannelMonitorRequestTemplateCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *ChannelMonitorRequestTemplateCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause +// of the `INSERT` statement. For example: +// +// client.ChannelMonitorRequestTemplate.CreateBulk(builders...). +// OnConflict( +// // Update the row with the new values +// // the was proposed for insertion. +// sql.ResolveWithNewValues(), +// ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.ChannelMonitorRequestTemplateUpsert) { +// SetCreatedAt(v+v). +// }). +// Exec(ctx) +func (_c *ChannelMonitorRequestTemplateCreateBulk) OnConflict(opts ...sql.ConflictOption) *ChannelMonitorRequestTemplateUpsertBulk { + _c.conflict = opts + return &ChannelMonitorRequestTemplateUpsertBulk{ + create: _c, + } +} + +// OnConflictColumns calls `OnConflict` and configures the columns +// as conflict target. Using this option is equivalent to using: +// +// client.ChannelMonitorRequestTemplate.Create(). +// OnConflict(sql.ConflictColumns(columns...)). +// Exec(ctx) +func (_c *ChannelMonitorRequestTemplateCreateBulk) OnConflictColumns(columns ...string) *ChannelMonitorRequestTemplateUpsertBulk { + _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) + return &ChannelMonitorRequestTemplateUpsertBulk{ + create: _c, + } +} + +// ChannelMonitorRequestTemplateUpsertBulk is the builder for "upsert"-ing +// a bulk of ChannelMonitorRequestTemplate nodes. +type ChannelMonitorRequestTemplateUpsertBulk struct { + create *ChannelMonitorRequestTemplateCreateBulk +} + +// UpdateNewValues updates the mutable fields using the new values that +// were set on create. Using this option is equivalent to using: +// +// client.ChannelMonitorRequestTemplate.Create(). +// OnConflict( +// sql.ResolveWithNewValues(), +// ). +// Exec(ctx) +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateNewValues() *ChannelMonitorRequestTemplateUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { + for _, b := range u.create.builders { + if _, exists := b.mutation.CreatedAt(); exists { + s.SetIgnore(channelmonitorrequesttemplate.FieldCreatedAt) + } + } + })) + return u +} + +// Ignore sets each column to itself in case of conflict. +// Using this option is equivalent to using: +// +// client.ChannelMonitorRequestTemplate.Create(). +// OnConflict(sql.ResolveWithIgnore()). +// Exec(ctx) +func (u *ChannelMonitorRequestTemplateUpsertBulk) Ignore() *ChannelMonitorRequestTemplateUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) + return u +} + +// DoNothing configures the conflict_action to `DO NOTHING`. +// Supported only by SQLite and PostgreSQL. +func (u *ChannelMonitorRequestTemplateUpsertBulk) DoNothing() *ChannelMonitorRequestTemplateUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.DoNothing()) + return u +} + +// Update allows overriding fields `UPDATE` values. See the ChannelMonitorRequestTemplateCreateBulk.OnConflict +// documentation for more info. +func (u *ChannelMonitorRequestTemplateUpsertBulk) Update(set func(*ChannelMonitorRequestTemplateUpsert)) *ChannelMonitorRequestTemplateUpsertBulk { + u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { + set(&ChannelMonitorRequestTemplateUpsert{UpdateSet: update}) + })) + return u +} + +// SetUpdatedAt sets the "updated_at" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) SetUpdatedAt(v time.Time) *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateUpdatedAt() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateUpdatedAt() + }) +} + +// SetName sets the "name" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) SetName(v string) *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetName(v) + }) +} + +// UpdateName sets the "name" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateName() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateName() + }) +} + +// SetProvider sets the "provider" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) SetProvider(v channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetProvider(v) + }) +} + +// UpdateProvider sets the "provider" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateProvider() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateProvider() + }) +} + +// SetDescription sets the "description" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) SetDescription(v string) *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetDescription(v) + }) +} + +// UpdateDescription sets the "description" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateDescription() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateDescription() + }) +} + +// ClearDescription clears the value of the "description" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) ClearDescription() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.ClearDescription() + }) +} + +// SetExtraHeaders sets the "extra_headers" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) SetExtraHeaders(v map[string]string) *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetExtraHeaders(v) + }) +} + +// UpdateExtraHeaders sets the "extra_headers" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateExtraHeaders() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateExtraHeaders() + }) +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) SetBodyOverrideMode(v string) *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetBodyOverrideMode(v) + }) +} + +// UpdateBodyOverrideMode sets the "body_override_mode" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateBodyOverrideMode() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateBodyOverrideMode() + }) +} + +// SetBodyOverride sets the "body_override" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) SetBodyOverride(v map[string]interface{}) *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.SetBodyOverride(v) + }) +} + +// UpdateBodyOverride sets the "body_override" field to the value that was provided on create. +func (u *ChannelMonitorRequestTemplateUpsertBulk) UpdateBodyOverride() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.UpdateBodyOverride() + }) +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (u *ChannelMonitorRequestTemplateUpsertBulk) ClearBodyOverride() *ChannelMonitorRequestTemplateUpsertBulk { + return u.Update(func(s *ChannelMonitorRequestTemplateUpsert) { + s.ClearBodyOverride() + }) +} + +// Exec executes the query. +func (u *ChannelMonitorRequestTemplateUpsertBulk) Exec(ctx context.Context) error { + if u.create.err != nil { + return u.create.err + } + for i, b := range u.create.builders { + if len(b.conflict) != 0 { + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the ChannelMonitorRequestTemplateCreateBulk instead", i) + } + } + if len(u.create.conflict) == 0 { + return errors.New("ent: missing options for ChannelMonitorRequestTemplateCreateBulk.OnConflict") + } + return u.create.Exec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (u *ChannelMonitorRequestTemplateUpsertBulk) ExecX(ctx context.Context) { + if err := u.create.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/channelmonitorrequesttemplate_delete.go b/backend/ent/channelmonitorrequesttemplate_delete.go new file mode 100644 index 00000000..98d365c8 --- /dev/null +++ b/backend/ent/channelmonitorrequesttemplate_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ChannelMonitorRequestTemplateDelete is the builder for deleting a ChannelMonitorRequestTemplate entity. +type ChannelMonitorRequestTemplateDelete struct { + config + hooks []Hook + mutation *ChannelMonitorRequestTemplateMutation +} + +// Where appends a list predicates to the ChannelMonitorRequestTemplateDelete builder. +func (_d *ChannelMonitorRequestTemplateDelete) Where(ps ...predicate.ChannelMonitorRequestTemplate) *ChannelMonitorRequestTemplateDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *ChannelMonitorRequestTemplateDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *ChannelMonitorRequestTemplateDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *ChannelMonitorRequestTemplateDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(channelmonitorrequesttemplate.Table, sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64)) + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// ChannelMonitorRequestTemplateDeleteOne is the builder for deleting a single ChannelMonitorRequestTemplate entity. +type ChannelMonitorRequestTemplateDeleteOne struct { + _d *ChannelMonitorRequestTemplateDelete +} + +// Where appends a list predicates to the ChannelMonitorRequestTemplateDelete builder. +func (_d *ChannelMonitorRequestTemplateDeleteOne) Where(ps ...predicate.ChannelMonitorRequestTemplate) *ChannelMonitorRequestTemplateDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *ChannelMonitorRequestTemplateDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{channelmonitorrequesttemplate.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *ChannelMonitorRequestTemplateDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/backend/ent/channelmonitorrequesttemplate_query.go b/backend/ent/channelmonitorrequesttemplate_query.go new file mode 100644 index 00000000..6491ea60 --- /dev/null +++ b/backend/ent/channelmonitorrequesttemplate_query.go @@ -0,0 +1,648 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/channelmonitor" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ChannelMonitorRequestTemplateQuery is the builder for querying ChannelMonitorRequestTemplate entities. +type ChannelMonitorRequestTemplateQuery struct { + config + ctx *QueryContext + order []channelmonitorrequesttemplate.OrderOption + inters []Interceptor + predicates []predicate.ChannelMonitorRequestTemplate + withMonitors *ChannelMonitorQuery + modifiers []func(*sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the ChannelMonitorRequestTemplateQuery builder. +func (_q *ChannelMonitorRequestTemplateQuery) Where(ps ...predicate.ChannelMonitorRequestTemplate) *ChannelMonitorRequestTemplateQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *ChannelMonitorRequestTemplateQuery) Limit(limit int) *ChannelMonitorRequestTemplateQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *ChannelMonitorRequestTemplateQuery) Offset(offset int) *ChannelMonitorRequestTemplateQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *ChannelMonitorRequestTemplateQuery) Unique(unique bool) *ChannelMonitorRequestTemplateQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *ChannelMonitorRequestTemplateQuery) Order(o ...channelmonitorrequesttemplate.OrderOption) *ChannelMonitorRequestTemplateQuery { + _q.order = append(_q.order, o...) + return _q +} + +// QueryMonitors chains the current query on the "monitors" edge. +func (_q *ChannelMonitorRequestTemplateQuery) QueryMonitors() *ChannelMonitorQuery { + query := (&ChannelMonitorClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(channelmonitorrequesttemplate.Table, channelmonitorrequesttemplate.FieldID, selector), + sqlgraph.To(channelmonitor.Table, channelmonitor.FieldID), + sqlgraph.Edge(sqlgraph.O2M, true, channelmonitorrequesttemplate.MonitorsTable, channelmonitorrequesttemplate.MonitorsColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first ChannelMonitorRequestTemplate entity from the query. +// Returns a *NotFoundError when no ChannelMonitorRequestTemplate was found. +func (_q *ChannelMonitorRequestTemplateQuery) First(ctx context.Context) (*ChannelMonitorRequestTemplate, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{channelmonitorrequesttemplate.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) FirstX(ctx context.Context) *ChannelMonitorRequestTemplate { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first ChannelMonitorRequestTemplate ID from the query. +// Returns a *NotFoundError when no ChannelMonitorRequestTemplate ID was found. +func (_q *ChannelMonitorRequestTemplateQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{channelmonitorrequesttemplate.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single ChannelMonitorRequestTemplate entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one ChannelMonitorRequestTemplate entity is found. +// Returns a *NotFoundError when no ChannelMonitorRequestTemplate entities are found. +func (_q *ChannelMonitorRequestTemplateQuery) Only(ctx context.Context) (*ChannelMonitorRequestTemplate, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{channelmonitorrequesttemplate.Label} + default: + return nil, &NotSingularError{channelmonitorrequesttemplate.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) OnlyX(ctx context.Context) *ChannelMonitorRequestTemplate { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only ChannelMonitorRequestTemplate ID in the query. +// Returns a *NotSingularError when more than one ChannelMonitorRequestTemplate ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *ChannelMonitorRequestTemplateQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{channelmonitorrequesttemplate.Label} + default: + err = &NotSingularError{channelmonitorrequesttemplate.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of ChannelMonitorRequestTemplates. +func (_q *ChannelMonitorRequestTemplateQuery) All(ctx context.Context) ([]*ChannelMonitorRequestTemplate, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*ChannelMonitorRequestTemplate, *ChannelMonitorRequestTemplateQuery]() + return withInterceptors[[]*ChannelMonitorRequestTemplate](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) AllX(ctx context.Context) []*ChannelMonitorRequestTemplate { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of ChannelMonitorRequestTemplate IDs. +func (_q *ChannelMonitorRequestTemplateQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(channelmonitorrequesttemplate.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *ChannelMonitorRequestTemplateQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*ChannelMonitorRequestTemplateQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *ChannelMonitorRequestTemplateQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *ChannelMonitorRequestTemplateQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the ChannelMonitorRequestTemplateQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *ChannelMonitorRequestTemplateQuery) Clone() *ChannelMonitorRequestTemplateQuery { + if _q == nil { + return nil + } + return &ChannelMonitorRequestTemplateQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]channelmonitorrequesttemplate.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.ChannelMonitorRequestTemplate{}, _q.predicates...), + withMonitors: _q.withMonitors.Clone(), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// WithMonitors tells the query-builder to eager-load the nodes that are connected to +// the "monitors" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *ChannelMonitorRequestTemplateQuery) WithMonitors(opts ...func(*ChannelMonitorQuery)) *ChannelMonitorRequestTemplateQuery { + query := (&ChannelMonitorClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withMonitors = query + return _q +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// CreatedAt time.Time `json:"created_at,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.ChannelMonitorRequestTemplate.Query(). +// GroupBy(channelmonitorrequesttemplate.FieldCreatedAt). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *ChannelMonitorRequestTemplateQuery) GroupBy(field string, fields ...string) *ChannelMonitorRequestTemplateGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &ChannelMonitorRequestTemplateGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = channelmonitorrequesttemplate.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// CreatedAt time.Time `json:"created_at,omitempty"` +// } +// +// client.ChannelMonitorRequestTemplate.Query(). +// Select(channelmonitorrequesttemplate.FieldCreatedAt). +// Scan(ctx, &v) +func (_q *ChannelMonitorRequestTemplateQuery) Select(fields ...string) *ChannelMonitorRequestTemplateSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &ChannelMonitorRequestTemplateSelect{ChannelMonitorRequestTemplateQuery: _q} + sbuild.label = channelmonitorrequesttemplate.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a ChannelMonitorRequestTemplateSelect configured with the given aggregations. +func (_q *ChannelMonitorRequestTemplateQuery) Aggregate(fns ...AggregateFunc) *ChannelMonitorRequestTemplateSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *ChannelMonitorRequestTemplateQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !channelmonitorrequesttemplate.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *ChannelMonitorRequestTemplateQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*ChannelMonitorRequestTemplate, error) { + var ( + nodes = []*ChannelMonitorRequestTemplate{} + _spec = _q.querySpec() + loadedTypes = [1]bool{ + _q.withMonitors != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*ChannelMonitorRequestTemplate).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &ChannelMonitorRequestTemplate{config: _q.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := _q.withMonitors; query != nil { + if err := _q.loadMonitors(ctx, query, nodes, + func(n *ChannelMonitorRequestTemplate) { n.Edges.Monitors = []*ChannelMonitor{} }, + func(n *ChannelMonitorRequestTemplate, e *ChannelMonitor) { + n.Edges.Monitors = append(n.Edges.Monitors, e) + }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (_q *ChannelMonitorRequestTemplateQuery) loadMonitors(ctx context.Context, query *ChannelMonitorQuery, nodes []*ChannelMonitorRequestTemplate, init func(*ChannelMonitorRequestTemplate), assign func(*ChannelMonitorRequestTemplate, *ChannelMonitor)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int64]*ChannelMonitorRequestTemplate) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(channelmonitor.FieldTemplateID) + } + query.Where(predicate.ChannelMonitor(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(channelmonitorrequesttemplate.MonitorsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.TemplateID + if fk == nil { + return fmt.Errorf(`foreign-key "template_id" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "template_id" returned %v for node %v`, *fk, n.ID) + } + assign(node, n) + } + return nil +} + +func (_q *ChannelMonitorRequestTemplateQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + if len(_q.modifiers) > 0 { + _spec.Modifiers = _q.modifiers + } + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *ChannelMonitorRequestTemplateQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(channelmonitorrequesttemplate.Table, channelmonitorrequesttemplate.Columns, sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, channelmonitorrequesttemplate.FieldID) + for i := range fields { + if fields[i] != channelmonitorrequesttemplate.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *ChannelMonitorRequestTemplateQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(channelmonitorrequesttemplate.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = channelmonitorrequesttemplate.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, m := range _q.modifiers { + m(selector) + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (_q *ChannelMonitorRequestTemplateQuery) ForUpdate(opts ...sql.LockOption) *ChannelMonitorRequestTemplateQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return _q +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (_q *ChannelMonitorRequestTemplateQuery) ForShare(opts ...sql.LockOption) *ChannelMonitorRequestTemplateQuery { + if _q.driver.Dialect() == dialect.Postgres { + _q.Unique(false) + } + _q.modifiers = append(_q.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return _q +} + +// ChannelMonitorRequestTemplateGroupBy is the group-by builder for ChannelMonitorRequestTemplate entities. +type ChannelMonitorRequestTemplateGroupBy struct { + selector + build *ChannelMonitorRequestTemplateQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *ChannelMonitorRequestTemplateGroupBy) Aggregate(fns ...AggregateFunc) *ChannelMonitorRequestTemplateGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *ChannelMonitorRequestTemplateGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*ChannelMonitorRequestTemplateQuery, *ChannelMonitorRequestTemplateGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *ChannelMonitorRequestTemplateGroupBy) sqlScan(ctx context.Context, root *ChannelMonitorRequestTemplateQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// ChannelMonitorRequestTemplateSelect is the builder for selecting fields of ChannelMonitorRequestTemplate entities. +type ChannelMonitorRequestTemplateSelect struct { + *ChannelMonitorRequestTemplateQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *ChannelMonitorRequestTemplateSelect) Aggregate(fns ...AggregateFunc) *ChannelMonitorRequestTemplateSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *ChannelMonitorRequestTemplateSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*ChannelMonitorRequestTemplateQuery, *ChannelMonitorRequestTemplateSelect](ctx, _s.ChannelMonitorRequestTemplateQuery, _s, _s.inters, v) +} + +func (_s *ChannelMonitorRequestTemplateSelect) sqlScan(ctx context.Context, root *ChannelMonitorRequestTemplateQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/backend/ent/channelmonitorrequesttemplate_update.go b/backend/ent/channelmonitorrequesttemplate_update.go new file mode 100644 index 00000000..8f55ba04 --- /dev/null +++ b/backend/ent/channelmonitorrequesttemplate_update.go @@ -0,0 +1,639 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/Wei-Shaw/sub2api/ent/channelmonitor" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" + "github.com/Wei-Shaw/sub2api/ent/predicate" +) + +// ChannelMonitorRequestTemplateUpdate is the builder for updating ChannelMonitorRequestTemplate entities. +type ChannelMonitorRequestTemplateUpdate struct { + config + hooks []Hook + mutation *ChannelMonitorRequestTemplateMutation +} + +// Where appends a list predicates to the ChannelMonitorRequestTemplateUpdate builder. +func (_u *ChannelMonitorRequestTemplateUpdate) Where(ps ...predicate.ChannelMonitorRequestTemplate) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *ChannelMonitorRequestTemplateUpdate) SetUpdatedAt(v time.Time) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetName sets the "name" field. +func (_u *ChannelMonitorRequestTemplateUpdate) SetName(v string) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdate) SetNillableName(v *string) *ChannelMonitorRequestTemplateUpdate { + if v != nil { + _u.SetName(*v) + } + return _u +} + +// SetProvider sets the "provider" field. +func (_u *ChannelMonitorRequestTemplateUpdate) SetProvider(v channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.SetProvider(v) + return _u +} + +// SetNillableProvider sets the "provider" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdate) SetNillableProvider(v *channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateUpdate { + if v != nil { + _u.SetProvider(*v) + } + return _u +} + +// SetDescription sets the "description" field. +func (_u *ChannelMonitorRequestTemplateUpdate) SetDescription(v string) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.SetDescription(v) + return _u +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdate) SetNillableDescription(v *string) *ChannelMonitorRequestTemplateUpdate { + if v != nil { + _u.SetDescription(*v) + } + return _u +} + +// ClearDescription clears the value of the "description" field. +func (_u *ChannelMonitorRequestTemplateUpdate) ClearDescription() *ChannelMonitorRequestTemplateUpdate { + _u.mutation.ClearDescription() + return _u +} + +// SetExtraHeaders sets the "extra_headers" field. +func (_u *ChannelMonitorRequestTemplateUpdate) SetExtraHeaders(v map[string]string) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.SetExtraHeaders(v) + return _u +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (_u *ChannelMonitorRequestTemplateUpdate) SetBodyOverrideMode(v string) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.SetBodyOverrideMode(v) + return _u +} + +// SetNillableBodyOverrideMode sets the "body_override_mode" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdate) SetNillableBodyOverrideMode(v *string) *ChannelMonitorRequestTemplateUpdate { + if v != nil { + _u.SetBodyOverrideMode(*v) + } + return _u +} + +// SetBodyOverride sets the "body_override" field. +func (_u *ChannelMonitorRequestTemplateUpdate) SetBodyOverride(v map[string]interface{}) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.SetBodyOverride(v) + return _u +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (_u *ChannelMonitorRequestTemplateUpdate) ClearBodyOverride() *ChannelMonitorRequestTemplateUpdate { + _u.mutation.ClearBodyOverride() + return _u +} + +// AddMonitorIDs adds the "monitors" edge to the ChannelMonitor entity by IDs. +func (_u *ChannelMonitorRequestTemplateUpdate) AddMonitorIDs(ids ...int64) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.AddMonitorIDs(ids...) + return _u +} + +// AddMonitors adds the "monitors" edges to the ChannelMonitor entity. +func (_u *ChannelMonitorRequestTemplateUpdate) AddMonitors(v ...*ChannelMonitor) *ChannelMonitorRequestTemplateUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddMonitorIDs(ids...) +} + +// Mutation returns the ChannelMonitorRequestTemplateMutation object of the builder. +func (_u *ChannelMonitorRequestTemplateUpdate) Mutation() *ChannelMonitorRequestTemplateMutation { + return _u.mutation +} + +// ClearMonitors clears all "monitors" edges to the ChannelMonitor entity. +func (_u *ChannelMonitorRequestTemplateUpdate) ClearMonitors() *ChannelMonitorRequestTemplateUpdate { + _u.mutation.ClearMonitors() + return _u +} + +// RemoveMonitorIDs removes the "monitors" edge to ChannelMonitor entities by IDs. +func (_u *ChannelMonitorRequestTemplateUpdate) RemoveMonitorIDs(ids ...int64) *ChannelMonitorRequestTemplateUpdate { + _u.mutation.RemoveMonitorIDs(ids...) + return _u +} + +// RemoveMonitors removes "monitors" edges to ChannelMonitor entities. +func (_u *ChannelMonitorRequestTemplateUpdate) RemoveMonitors(v ...*ChannelMonitor) *ChannelMonitorRequestTemplateUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveMonitorIDs(ids...) +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *ChannelMonitorRequestTemplateUpdate) Save(ctx context.Context) (int, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *ChannelMonitorRequestTemplateUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *ChannelMonitorRequestTemplateUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *ChannelMonitorRequestTemplateUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *ChannelMonitorRequestTemplateUpdate) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := channelmonitorrequesttemplate.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *ChannelMonitorRequestTemplateUpdate) check() error { + if v, ok := _u.mutation.Name(); ok { + if err := channelmonitorrequesttemplate.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.name": %w`, err)} + } + } + if v, ok := _u.mutation.Provider(); ok { + if err := channelmonitorrequesttemplate.ProviderValidator(v); err != nil { + return &ValidationError{Name: "provider", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.provider": %w`, err)} + } + } + if v, ok := _u.mutation.Description(); ok { + if err := channelmonitorrequesttemplate.DescriptionValidator(v); err != nil { + return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.description": %w`, err)} + } + } + if v, ok := _u.mutation.BodyOverrideMode(); ok { + if err := channelmonitorrequesttemplate.BodyOverrideModeValidator(v); err != nil { + return &ValidationError{Name: "body_override_mode", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.body_override_mode": %w`, err)} + } + } + return nil +} + +func (_u *ChannelMonitorRequestTemplateUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(channelmonitorrequesttemplate.Table, channelmonitorrequesttemplate.Columns, sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldUpdatedAt, field.TypeTime, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldName, field.TypeString, value) + } + if value, ok := _u.mutation.Provider(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldProvider, field.TypeEnum, value) + } + if value, ok := _u.mutation.Description(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldDescription, field.TypeString, value) + } + if _u.mutation.DescriptionCleared() { + _spec.ClearField(channelmonitorrequesttemplate.FieldDescription, field.TypeString) + } + if value, ok := _u.mutation.ExtraHeaders(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldExtraHeaders, field.TypeJSON, value) + } + if value, ok := _u.mutation.BodyOverrideMode(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldBodyOverrideMode, field.TypeString, value) + } + if value, ok := _u.mutation.BodyOverride(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldBodyOverride, field.TypeJSON, value) + } + if _u.mutation.BodyOverrideCleared() { + _spec.ClearField(channelmonitorrequesttemplate.FieldBodyOverride, field.TypeJSON) + } + if _u.mutation.MonitorsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: true, + Table: channelmonitorrequesttemplate.MonitorsTable, + Columns: []string{channelmonitorrequesttemplate.MonitorsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitor.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedMonitorsIDs(); len(nodes) > 0 && !_u.mutation.MonitorsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: true, + Table: channelmonitorrequesttemplate.MonitorsTable, + Columns: []string{channelmonitorrequesttemplate.MonitorsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitor.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.MonitorsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: true, + Table: channelmonitorrequesttemplate.MonitorsTable, + Columns: []string{channelmonitorrequesttemplate.MonitorsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitor.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{channelmonitorrequesttemplate.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// ChannelMonitorRequestTemplateUpdateOne is the builder for updating a single ChannelMonitorRequestTemplate entity. +type ChannelMonitorRequestTemplateUpdateOne struct { + config + fields []string + hooks []Hook + mutation *ChannelMonitorRequestTemplateMutation +} + +// SetUpdatedAt sets the "updated_at" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetUpdatedAt(v time.Time) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.SetUpdatedAt(v) + return _u +} + +// SetName sets the "name" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetName(v string) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetNillableName(v *string) *ChannelMonitorRequestTemplateUpdateOne { + if v != nil { + _u.SetName(*v) + } + return _u +} + +// SetProvider sets the "provider" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetProvider(v channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.SetProvider(v) + return _u +} + +// SetNillableProvider sets the "provider" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetNillableProvider(v *channelmonitorrequesttemplate.Provider) *ChannelMonitorRequestTemplateUpdateOne { + if v != nil { + _u.SetProvider(*v) + } + return _u +} + +// SetDescription sets the "description" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetDescription(v string) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.SetDescription(v) + return _u +} + +// SetNillableDescription sets the "description" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetNillableDescription(v *string) *ChannelMonitorRequestTemplateUpdateOne { + if v != nil { + _u.SetDescription(*v) + } + return _u +} + +// ClearDescription clears the value of the "description" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) ClearDescription() *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.ClearDescription() + return _u +} + +// SetExtraHeaders sets the "extra_headers" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetExtraHeaders(v map[string]string) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.SetExtraHeaders(v) + return _u +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetBodyOverrideMode(v string) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.SetBodyOverrideMode(v) + return _u +} + +// SetNillableBodyOverrideMode sets the "body_override_mode" field if the given value is not nil. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetNillableBodyOverrideMode(v *string) *ChannelMonitorRequestTemplateUpdateOne { + if v != nil { + _u.SetBodyOverrideMode(*v) + } + return _u +} + +// SetBodyOverride sets the "body_override" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SetBodyOverride(v map[string]interface{}) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.SetBodyOverride(v) + return _u +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (_u *ChannelMonitorRequestTemplateUpdateOne) ClearBodyOverride() *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.ClearBodyOverride() + return _u +} + +// AddMonitorIDs adds the "monitors" edge to the ChannelMonitor entity by IDs. +func (_u *ChannelMonitorRequestTemplateUpdateOne) AddMonitorIDs(ids ...int64) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.AddMonitorIDs(ids...) + return _u +} + +// AddMonitors adds the "monitors" edges to the ChannelMonitor entity. +func (_u *ChannelMonitorRequestTemplateUpdateOne) AddMonitors(v ...*ChannelMonitor) *ChannelMonitorRequestTemplateUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddMonitorIDs(ids...) +} + +// Mutation returns the ChannelMonitorRequestTemplateMutation object of the builder. +func (_u *ChannelMonitorRequestTemplateUpdateOne) Mutation() *ChannelMonitorRequestTemplateMutation { + return _u.mutation +} + +// ClearMonitors clears all "monitors" edges to the ChannelMonitor entity. +func (_u *ChannelMonitorRequestTemplateUpdateOne) ClearMonitors() *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.ClearMonitors() + return _u +} + +// RemoveMonitorIDs removes the "monitors" edge to ChannelMonitor entities by IDs. +func (_u *ChannelMonitorRequestTemplateUpdateOne) RemoveMonitorIDs(ids ...int64) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.RemoveMonitorIDs(ids...) + return _u +} + +// RemoveMonitors removes "monitors" edges to ChannelMonitor entities. +func (_u *ChannelMonitorRequestTemplateUpdateOne) RemoveMonitors(v ...*ChannelMonitor) *ChannelMonitorRequestTemplateUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveMonitorIDs(ids...) +} + +// Where appends a list predicates to the ChannelMonitorRequestTemplateUpdate builder. +func (_u *ChannelMonitorRequestTemplateUpdateOne) Where(ps ...predicate.ChannelMonitorRequestTemplate) *ChannelMonitorRequestTemplateUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *ChannelMonitorRequestTemplateUpdateOne) Select(field string, fields ...string) *ChannelMonitorRequestTemplateUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated ChannelMonitorRequestTemplate entity. +func (_u *ChannelMonitorRequestTemplateUpdateOne) Save(ctx context.Context) (*ChannelMonitorRequestTemplate, error) { + _u.defaults() + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *ChannelMonitorRequestTemplateUpdateOne) SaveX(ctx context.Context) *ChannelMonitorRequestTemplate { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *ChannelMonitorRequestTemplateUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *ChannelMonitorRequestTemplateUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (_u *ChannelMonitorRequestTemplateUpdateOne) defaults() { + if _, ok := _u.mutation.UpdatedAt(); !ok { + v := channelmonitorrequesttemplate.UpdateDefaultUpdatedAt() + _u.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *ChannelMonitorRequestTemplateUpdateOne) check() error { + if v, ok := _u.mutation.Name(); ok { + if err := channelmonitorrequesttemplate.NameValidator(v); err != nil { + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.name": %w`, err)} + } + } + if v, ok := _u.mutation.Provider(); ok { + if err := channelmonitorrequesttemplate.ProviderValidator(v); err != nil { + return &ValidationError{Name: "provider", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.provider": %w`, err)} + } + } + if v, ok := _u.mutation.Description(); ok { + if err := channelmonitorrequesttemplate.DescriptionValidator(v); err != nil { + return &ValidationError{Name: "description", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.description": %w`, err)} + } + } + if v, ok := _u.mutation.BodyOverrideMode(); ok { + if err := channelmonitorrequesttemplate.BodyOverrideModeValidator(v); err != nil { + return &ValidationError{Name: "body_override_mode", err: fmt.Errorf(`ent: validator failed for field "ChannelMonitorRequestTemplate.body_override_mode": %w`, err)} + } + } + return nil +} + +func (_u *ChannelMonitorRequestTemplateUpdateOne) sqlSave(ctx context.Context) (_node *ChannelMonitorRequestTemplate, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(channelmonitorrequesttemplate.Table, channelmonitorrequesttemplate.Columns, sqlgraph.NewFieldSpec(channelmonitorrequesttemplate.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "ChannelMonitorRequestTemplate.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, channelmonitorrequesttemplate.FieldID) + for _, f := range fields { + if !channelmonitorrequesttemplate.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != channelmonitorrequesttemplate.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.UpdatedAt(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldUpdatedAt, field.TypeTime, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldName, field.TypeString, value) + } + if value, ok := _u.mutation.Provider(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldProvider, field.TypeEnum, value) + } + if value, ok := _u.mutation.Description(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldDescription, field.TypeString, value) + } + if _u.mutation.DescriptionCleared() { + _spec.ClearField(channelmonitorrequesttemplate.FieldDescription, field.TypeString) + } + if value, ok := _u.mutation.ExtraHeaders(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldExtraHeaders, field.TypeJSON, value) + } + if value, ok := _u.mutation.BodyOverrideMode(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldBodyOverrideMode, field.TypeString, value) + } + if value, ok := _u.mutation.BodyOverride(); ok { + _spec.SetField(channelmonitorrequesttemplate.FieldBodyOverride, field.TypeJSON, value) + } + if _u.mutation.BodyOverrideCleared() { + _spec.ClearField(channelmonitorrequesttemplate.FieldBodyOverride, field.TypeJSON) + } + if _u.mutation.MonitorsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: true, + Table: channelmonitorrequesttemplate.MonitorsTable, + Columns: []string{channelmonitorrequesttemplate.MonitorsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitor.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedMonitorsIDs(); len(nodes) > 0 && !_u.mutation.MonitorsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: true, + Table: channelmonitorrequesttemplate.MonitorsTable, + Columns: []string{channelmonitorrequesttemplate.MonitorsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitor.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.MonitorsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: true, + Table: channelmonitorrequesttemplate.MonitorsTable, + Columns: []string{channelmonitorrequesttemplate.MonitorsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(channelmonitor.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &ChannelMonitorRequestTemplate{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{channelmonitorrequesttemplate.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/backend/ent/client.go b/backend/ent/client.go index ebc7fc5e..df20ddfa 100644 --- a/backend/ent/client.go +++ b/backend/ent/client.go @@ -25,6 +25,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" @@ -77,6 +78,8 @@ type Client struct { ChannelMonitorDailyRollup *ChannelMonitorDailyRollupClient // ChannelMonitorHistory is the client for interacting with the ChannelMonitorHistory builders. ChannelMonitorHistory *ChannelMonitorHistoryClient + // ChannelMonitorRequestTemplate is the client for interacting with the ChannelMonitorRequestTemplate builders. + ChannelMonitorRequestTemplate *ChannelMonitorRequestTemplateClient // ErrorPassthroughRule is the client for interacting with the ErrorPassthroughRule builders. ErrorPassthroughRule *ErrorPassthroughRuleClient // Group is the client for interacting with the Group builders. @@ -144,6 +147,7 @@ func (c *Client) init() { c.ChannelMonitor = NewChannelMonitorClient(c.config) c.ChannelMonitorDailyRollup = NewChannelMonitorDailyRollupClient(c.config) c.ChannelMonitorHistory = NewChannelMonitorHistoryClient(c.config) + c.ChannelMonitorRequestTemplate = NewChannelMonitorRequestTemplateClient(c.config) c.ErrorPassthroughRule = NewErrorPassthroughRuleClient(c.config) c.Group = NewGroupClient(c.config) c.IdempotencyRecord = NewIdempotencyRecordClient(c.config) @@ -257,41 +261,42 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { cfg := c.config cfg.driver = tx return &Tx{ - ctx: ctx, - config: cfg, - APIKey: NewAPIKeyClient(cfg), - Account: NewAccountClient(cfg), - AccountGroup: NewAccountGroupClient(cfg), - Announcement: NewAnnouncementClient(cfg), - AnnouncementRead: NewAnnouncementReadClient(cfg), - AuthIdentity: NewAuthIdentityClient(cfg), - AuthIdentityChannel: NewAuthIdentityChannelClient(cfg), - ChannelMonitor: NewChannelMonitorClient(cfg), - ChannelMonitorDailyRollup: NewChannelMonitorDailyRollupClient(cfg), - ChannelMonitorHistory: NewChannelMonitorHistoryClient(cfg), - ErrorPassthroughRule: NewErrorPassthroughRuleClient(cfg), - Group: NewGroupClient(cfg), - IdempotencyRecord: NewIdempotencyRecordClient(cfg), - IdentityAdoptionDecision: NewIdentityAdoptionDecisionClient(cfg), - PaymentAuditLog: NewPaymentAuditLogClient(cfg), - PaymentOrder: NewPaymentOrderClient(cfg), - PaymentProviderInstance: NewPaymentProviderInstanceClient(cfg), - PendingAuthSession: NewPendingAuthSessionClient(cfg), - PromoCode: NewPromoCodeClient(cfg), - PromoCodeUsage: NewPromoCodeUsageClient(cfg), - Proxy: NewProxyClient(cfg), - RedeemCode: NewRedeemCodeClient(cfg), - SecuritySecret: NewSecuritySecretClient(cfg), - Setting: NewSettingClient(cfg), - SubscriptionPlan: NewSubscriptionPlanClient(cfg), - TLSFingerprintProfile: NewTLSFingerprintProfileClient(cfg), - UsageCleanupTask: NewUsageCleanupTaskClient(cfg), - UsageLog: NewUsageLogClient(cfg), - User: NewUserClient(cfg), - UserAllowedGroup: NewUserAllowedGroupClient(cfg), - UserAttributeDefinition: NewUserAttributeDefinitionClient(cfg), - UserAttributeValue: NewUserAttributeValueClient(cfg), - UserSubscription: NewUserSubscriptionClient(cfg), + ctx: ctx, + config: cfg, + APIKey: NewAPIKeyClient(cfg), + Account: NewAccountClient(cfg), + AccountGroup: NewAccountGroupClient(cfg), + Announcement: NewAnnouncementClient(cfg), + AnnouncementRead: NewAnnouncementReadClient(cfg), + AuthIdentity: NewAuthIdentityClient(cfg), + AuthIdentityChannel: NewAuthIdentityChannelClient(cfg), + ChannelMonitor: NewChannelMonitorClient(cfg), + ChannelMonitorDailyRollup: NewChannelMonitorDailyRollupClient(cfg), + ChannelMonitorHistory: NewChannelMonitorHistoryClient(cfg), + ChannelMonitorRequestTemplate: NewChannelMonitorRequestTemplateClient(cfg), + ErrorPassthroughRule: NewErrorPassthroughRuleClient(cfg), + Group: NewGroupClient(cfg), + IdempotencyRecord: NewIdempotencyRecordClient(cfg), + IdentityAdoptionDecision: NewIdentityAdoptionDecisionClient(cfg), + PaymentAuditLog: NewPaymentAuditLogClient(cfg), + PaymentOrder: NewPaymentOrderClient(cfg), + PaymentProviderInstance: NewPaymentProviderInstanceClient(cfg), + PendingAuthSession: NewPendingAuthSessionClient(cfg), + PromoCode: NewPromoCodeClient(cfg), + PromoCodeUsage: NewPromoCodeUsageClient(cfg), + Proxy: NewProxyClient(cfg), + RedeemCode: NewRedeemCodeClient(cfg), + SecuritySecret: NewSecuritySecretClient(cfg), + Setting: NewSettingClient(cfg), + SubscriptionPlan: NewSubscriptionPlanClient(cfg), + TLSFingerprintProfile: NewTLSFingerprintProfileClient(cfg), + UsageCleanupTask: NewUsageCleanupTaskClient(cfg), + UsageLog: NewUsageLogClient(cfg), + User: NewUserClient(cfg), + UserAllowedGroup: NewUserAllowedGroupClient(cfg), + UserAttributeDefinition: NewUserAttributeDefinitionClient(cfg), + UserAttributeValue: NewUserAttributeValueClient(cfg), + UserSubscription: NewUserSubscriptionClient(cfg), }, nil } @@ -309,41 +314,42 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) cfg := c.config cfg.driver = &txDriver{tx: tx, drv: c.driver} return &Tx{ - ctx: ctx, - config: cfg, - APIKey: NewAPIKeyClient(cfg), - Account: NewAccountClient(cfg), - AccountGroup: NewAccountGroupClient(cfg), - Announcement: NewAnnouncementClient(cfg), - AnnouncementRead: NewAnnouncementReadClient(cfg), - AuthIdentity: NewAuthIdentityClient(cfg), - AuthIdentityChannel: NewAuthIdentityChannelClient(cfg), - ChannelMonitor: NewChannelMonitorClient(cfg), - ChannelMonitorDailyRollup: NewChannelMonitorDailyRollupClient(cfg), - ChannelMonitorHistory: NewChannelMonitorHistoryClient(cfg), - ErrorPassthroughRule: NewErrorPassthroughRuleClient(cfg), - Group: NewGroupClient(cfg), - IdempotencyRecord: NewIdempotencyRecordClient(cfg), - IdentityAdoptionDecision: NewIdentityAdoptionDecisionClient(cfg), - PaymentAuditLog: NewPaymentAuditLogClient(cfg), - PaymentOrder: NewPaymentOrderClient(cfg), - PaymentProviderInstance: NewPaymentProviderInstanceClient(cfg), - PendingAuthSession: NewPendingAuthSessionClient(cfg), - PromoCode: NewPromoCodeClient(cfg), - PromoCodeUsage: NewPromoCodeUsageClient(cfg), - Proxy: NewProxyClient(cfg), - RedeemCode: NewRedeemCodeClient(cfg), - SecuritySecret: NewSecuritySecretClient(cfg), - Setting: NewSettingClient(cfg), - SubscriptionPlan: NewSubscriptionPlanClient(cfg), - TLSFingerprintProfile: NewTLSFingerprintProfileClient(cfg), - UsageCleanupTask: NewUsageCleanupTaskClient(cfg), - UsageLog: NewUsageLogClient(cfg), - User: NewUserClient(cfg), - UserAllowedGroup: NewUserAllowedGroupClient(cfg), - UserAttributeDefinition: NewUserAttributeDefinitionClient(cfg), - UserAttributeValue: NewUserAttributeValueClient(cfg), - UserSubscription: NewUserSubscriptionClient(cfg), + ctx: ctx, + config: cfg, + APIKey: NewAPIKeyClient(cfg), + Account: NewAccountClient(cfg), + AccountGroup: NewAccountGroupClient(cfg), + Announcement: NewAnnouncementClient(cfg), + AnnouncementRead: NewAnnouncementReadClient(cfg), + AuthIdentity: NewAuthIdentityClient(cfg), + AuthIdentityChannel: NewAuthIdentityChannelClient(cfg), + ChannelMonitor: NewChannelMonitorClient(cfg), + ChannelMonitorDailyRollup: NewChannelMonitorDailyRollupClient(cfg), + ChannelMonitorHistory: NewChannelMonitorHistoryClient(cfg), + ChannelMonitorRequestTemplate: NewChannelMonitorRequestTemplateClient(cfg), + ErrorPassthroughRule: NewErrorPassthroughRuleClient(cfg), + Group: NewGroupClient(cfg), + IdempotencyRecord: NewIdempotencyRecordClient(cfg), + IdentityAdoptionDecision: NewIdentityAdoptionDecisionClient(cfg), + PaymentAuditLog: NewPaymentAuditLogClient(cfg), + PaymentOrder: NewPaymentOrderClient(cfg), + PaymentProviderInstance: NewPaymentProviderInstanceClient(cfg), + PendingAuthSession: NewPendingAuthSessionClient(cfg), + PromoCode: NewPromoCodeClient(cfg), + PromoCodeUsage: NewPromoCodeUsageClient(cfg), + Proxy: NewProxyClient(cfg), + RedeemCode: NewRedeemCodeClient(cfg), + SecuritySecret: NewSecuritySecretClient(cfg), + Setting: NewSettingClient(cfg), + SubscriptionPlan: NewSubscriptionPlanClient(cfg), + TLSFingerprintProfile: NewTLSFingerprintProfileClient(cfg), + UsageCleanupTask: NewUsageCleanupTaskClient(cfg), + UsageLog: NewUsageLogClient(cfg), + User: NewUserClient(cfg), + UserAllowedGroup: NewUserAllowedGroupClient(cfg), + UserAttributeDefinition: NewUserAttributeDefinitionClient(cfg), + UserAttributeValue: NewUserAttributeValueClient(cfg), + UserSubscription: NewUserSubscriptionClient(cfg), }, nil } @@ -375,8 +381,9 @@ func (c *Client) Use(hooks ...Hook) { for _, n := range []interface{ Use(...Hook) }{ c.APIKey, c.Account, c.AccountGroup, c.Announcement, c.AnnouncementRead, c.AuthIdentity, c.AuthIdentityChannel, c.ChannelMonitor, - c.ChannelMonitorDailyRollup, c.ChannelMonitorHistory, c.ErrorPassthroughRule, - c.Group, c.IdempotencyRecord, c.IdentityAdoptionDecision, c.PaymentAuditLog, + c.ChannelMonitorDailyRollup, c.ChannelMonitorHistory, + c.ChannelMonitorRequestTemplate, c.ErrorPassthroughRule, c.Group, + c.IdempotencyRecord, c.IdentityAdoptionDecision, c.PaymentAuditLog, c.PaymentOrder, c.PaymentProviderInstance, c.PendingAuthSession, c.PromoCode, c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, @@ -393,8 +400,9 @@ func (c *Client) Intercept(interceptors ...Interceptor) { for _, n := range []interface{ Intercept(...Interceptor) }{ c.APIKey, c.Account, c.AccountGroup, c.Announcement, c.AnnouncementRead, c.AuthIdentity, c.AuthIdentityChannel, c.ChannelMonitor, - c.ChannelMonitorDailyRollup, c.ChannelMonitorHistory, c.ErrorPassthroughRule, - c.Group, c.IdempotencyRecord, c.IdentityAdoptionDecision, c.PaymentAuditLog, + c.ChannelMonitorDailyRollup, c.ChannelMonitorHistory, + c.ChannelMonitorRequestTemplate, c.ErrorPassthroughRule, c.Group, + c.IdempotencyRecord, c.IdentityAdoptionDecision, c.PaymentAuditLog, c.PaymentOrder, c.PaymentProviderInstance, c.PendingAuthSession, c.PromoCode, c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, @@ -428,6 +436,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { return c.ChannelMonitorDailyRollup.mutate(ctx, m) case *ChannelMonitorHistoryMutation: return c.ChannelMonitorHistory.mutate(ctx, m) + case *ChannelMonitorRequestTemplateMutation: + return c.ChannelMonitorRequestTemplate.mutate(ctx, m) case *ErrorPassthroughRuleMutation: return c.ErrorPassthroughRule.mutate(ctx, m) case *GroupMutation: @@ -1761,6 +1771,22 @@ func (c *ChannelMonitorClient) QueryDailyRollups(_m *ChannelMonitor) *ChannelMon return query } +// QueryRequestTemplate queries the request_template edge of a ChannelMonitor. +func (c *ChannelMonitorClient) QueryRequestTemplate(_m *ChannelMonitor) *ChannelMonitorRequestTemplateQuery { + query := (&ChannelMonitorRequestTemplateClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(channelmonitor.Table, channelmonitor.FieldID, id), + sqlgraph.To(channelmonitorrequesttemplate.Table, channelmonitorrequesttemplate.FieldID), + sqlgraph.Edge(sqlgraph.M2O, false, channelmonitor.RequestTemplateTable, channelmonitor.RequestTemplateColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + // Hooks returns the client hooks. func (c *ChannelMonitorClient) Hooks() []Hook { return c.hooks.ChannelMonitor @@ -2084,6 +2110,155 @@ func (c *ChannelMonitorHistoryClient) mutate(ctx context.Context, m *ChannelMoni } } +// ChannelMonitorRequestTemplateClient is a client for the ChannelMonitorRequestTemplate schema. +type ChannelMonitorRequestTemplateClient struct { + config +} + +// NewChannelMonitorRequestTemplateClient returns a client for the ChannelMonitorRequestTemplate from the given config. +func NewChannelMonitorRequestTemplateClient(c config) *ChannelMonitorRequestTemplateClient { + return &ChannelMonitorRequestTemplateClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `channelmonitorrequesttemplate.Hooks(f(g(h())))`. +func (c *ChannelMonitorRequestTemplateClient) Use(hooks ...Hook) { + c.hooks.ChannelMonitorRequestTemplate = append(c.hooks.ChannelMonitorRequestTemplate, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `channelmonitorrequesttemplate.Intercept(f(g(h())))`. +func (c *ChannelMonitorRequestTemplateClient) Intercept(interceptors ...Interceptor) { + c.inters.ChannelMonitorRequestTemplate = append(c.inters.ChannelMonitorRequestTemplate, interceptors...) +} + +// Create returns a builder for creating a ChannelMonitorRequestTemplate entity. +func (c *ChannelMonitorRequestTemplateClient) Create() *ChannelMonitorRequestTemplateCreate { + mutation := newChannelMonitorRequestTemplateMutation(c.config, OpCreate) + return &ChannelMonitorRequestTemplateCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of ChannelMonitorRequestTemplate entities. +func (c *ChannelMonitorRequestTemplateClient) CreateBulk(builders ...*ChannelMonitorRequestTemplateCreate) *ChannelMonitorRequestTemplateCreateBulk { + return &ChannelMonitorRequestTemplateCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *ChannelMonitorRequestTemplateClient) MapCreateBulk(slice any, setFunc func(*ChannelMonitorRequestTemplateCreate, int)) *ChannelMonitorRequestTemplateCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &ChannelMonitorRequestTemplateCreateBulk{err: fmt.Errorf("calling to ChannelMonitorRequestTemplateClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*ChannelMonitorRequestTemplateCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &ChannelMonitorRequestTemplateCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for ChannelMonitorRequestTemplate. +func (c *ChannelMonitorRequestTemplateClient) Update() *ChannelMonitorRequestTemplateUpdate { + mutation := newChannelMonitorRequestTemplateMutation(c.config, OpUpdate) + return &ChannelMonitorRequestTemplateUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *ChannelMonitorRequestTemplateClient) UpdateOne(_m *ChannelMonitorRequestTemplate) *ChannelMonitorRequestTemplateUpdateOne { + mutation := newChannelMonitorRequestTemplateMutation(c.config, OpUpdateOne, withChannelMonitorRequestTemplate(_m)) + return &ChannelMonitorRequestTemplateUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *ChannelMonitorRequestTemplateClient) UpdateOneID(id int64) *ChannelMonitorRequestTemplateUpdateOne { + mutation := newChannelMonitorRequestTemplateMutation(c.config, OpUpdateOne, withChannelMonitorRequestTemplateID(id)) + return &ChannelMonitorRequestTemplateUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for ChannelMonitorRequestTemplate. +func (c *ChannelMonitorRequestTemplateClient) Delete() *ChannelMonitorRequestTemplateDelete { + mutation := newChannelMonitorRequestTemplateMutation(c.config, OpDelete) + return &ChannelMonitorRequestTemplateDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *ChannelMonitorRequestTemplateClient) DeleteOne(_m *ChannelMonitorRequestTemplate) *ChannelMonitorRequestTemplateDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *ChannelMonitorRequestTemplateClient) DeleteOneID(id int64) *ChannelMonitorRequestTemplateDeleteOne { + builder := c.Delete().Where(channelmonitorrequesttemplate.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &ChannelMonitorRequestTemplateDeleteOne{builder} +} + +// Query returns a query builder for ChannelMonitorRequestTemplate. +func (c *ChannelMonitorRequestTemplateClient) Query() *ChannelMonitorRequestTemplateQuery { + return &ChannelMonitorRequestTemplateQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeChannelMonitorRequestTemplate}, + inters: c.Interceptors(), + } +} + +// Get returns a ChannelMonitorRequestTemplate entity by its id. +func (c *ChannelMonitorRequestTemplateClient) Get(ctx context.Context, id int64) (*ChannelMonitorRequestTemplate, error) { + return c.Query().Where(channelmonitorrequesttemplate.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *ChannelMonitorRequestTemplateClient) GetX(ctx context.Context, id int64) *ChannelMonitorRequestTemplate { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryMonitors queries the monitors edge of a ChannelMonitorRequestTemplate. +func (c *ChannelMonitorRequestTemplateClient) QueryMonitors(_m *ChannelMonitorRequestTemplate) *ChannelMonitorQuery { + query := (&ChannelMonitorClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(channelmonitorrequesttemplate.Table, channelmonitorrequesttemplate.FieldID, id), + sqlgraph.To(channelmonitor.Table, channelmonitor.FieldID), + sqlgraph.Edge(sqlgraph.O2M, true, channelmonitorrequesttemplate.MonitorsTable, channelmonitorrequesttemplate.MonitorsColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *ChannelMonitorRequestTemplateClient) Hooks() []Hook { + return c.hooks.ChannelMonitorRequestTemplate +} + +// Interceptors returns the client interceptors. +func (c *ChannelMonitorRequestTemplateClient) Interceptors() []Interceptor { + return c.inters.ChannelMonitorRequestTemplate +} + +func (c *ChannelMonitorRequestTemplateClient) mutate(ctx context.Context, m *ChannelMonitorRequestTemplateMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&ChannelMonitorRequestTemplateCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&ChannelMonitorRequestTemplateUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&ChannelMonitorRequestTemplateUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&ChannelMonitorRequestTemplateDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown ChannelMonitorRequestTemplate mutation op: %q", m.Op()) + } +} + // ErrorPassthroughRuleClient is a client for the ErrorPassthroughRule schema. type ErrorPassthroughRuleClient struct { config @@ -5845,22 +6020,22 @@ type ( hooks struct { APIKey, Account, AccountGroup, Announcement, AnnouncementRead, AuthIdentity, AuthIdentityChannel, ChannelMonitor, ChannelMonitorDailyRollup, - ChannelMonitorHistory, ErrorPassthroughRule, Group, IdempotencyRecord, - IdentityAdoptionDecision, PaymentAuditLog, PaymentOrder, - PaymentProviderInstance, PendingAuthSession, PromoCode, PromoCodeUsage, Proxy, - RedeemCode, SecuritySecret, Setting, SubscriptionPlan, TLSFingerprintProfile, - UsageCleanupTask, UsageLog, User, UserAllowedGroup, UserAttributeDefinition, - UserAttributeValue, UserSubscription []ent.Hook + ChannelMonitorHistory, ChannelMonitorRequestTemplate, ErrorPassthroughRule, + Group, IdempotencyRecord, IdentityAdoptionDecision, PaymentAuditLog, + PaymentOrder, PaymentProviderInstance, PendingAuthSession, PromoCode, + PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan, + TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup, + UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Hook } inters struct { APIKey, Account, AccountGroup, Announcement, AnnouncementRead, AuthIdentity, AuthIdentityChannel, ChannelMonitor, ChannelMonitorDailyRollup, - ChannelMonitorHistory, ErrorPassthroughRule, Group, IdempotencyRecord, - IdentityAdoptionDecision, PaymentAuditLog, PaymentOrder, - PaymentProviderInstance, PendingAuthSession, PromoCode, PromoCodeUsage, Proxy, - RedeemCode, SecuritySecret, Setting, SubscriptionPlan, TLSFingerprintProfile, - UsageCleanupTask, UsageLog, User, UserAllowedGroup, UserAttributeDefinition, - UserAttributeValue, UserSubscription []ent.Interceptor + ChannelMonitorHistory, ChannelMonitorRequestTemplate, ErrorPassthroughRule, + Group, IdempotencyRecord, IdentityAdoptionDecision, PaymentAuditLog, + PaymentOrder, PaymentProviderInstance, PendingAuthSession, PromoCode, + PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan, + TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup, + UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Interceptor } ) diff --git a/backend/ent/ent.go b/backend/ent/ent.go index 71d17624..c9fcc314 100644 --- a/backend/ent/ent.go +++ b/backend/ent/ent.go @@ -22,6 +22,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" @@ -105,39 +106,40 @@ var ( func checkColumn(t, c string) error { initCheck.Do(func() { columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ - apikey.Table: apikey.ValidColumn, - account.Table: account.ValidColumn, - accountgroup.Table: accountgroup.ValidColumn, - announcement.Table: announcement.ValidColumn, - announcementread.Table: announcementread.ValidColumn, - authidentity.Table: authidentity.ValidColumn, - authidentitychannel.Table: authidentitychannel.ValidColumn, - channelmonitor.Table: channelmonitor.ValidColumn, - channelmonitordailyrollup.Table: channelmonitordailyrollup.ValidColumn, - channelmonitorhistory.Table: channelmonitorhistory.ValidColumn, - errorpassthroughrule.Table: errorpassthroughrule.ValidColumn, - group.Table: group.ValidColumn, - idempotencyrecord.Table: idempotencyrecord.ValidColumn, - identityadoptiondecision.Table: identityadoptiondecision.ValidColumn, - paymentauditlog.Table: paymentauditlog.ValidColumn, - paymentorder.Table: paymentorder.ValidColumn, - paymentproviderinstance.Table: paymentproviderinstance.ValidColumn, - pendingauthsession.Table: pendingauthsession.ValidColumn, - promocode.Table: promocode.ValidColumn, - promocodeusage.Table: promocodeusage.ValidColumn, - proxy.Table: proxy.ValidColumn, - redeemcode.Table: redeemcode.ValidColumn, - securitysecret.Table: securitysecret.ValidColumn, - setting.Table: setting.ValidColumn, - subscriptionplan.Table: subscriptionplan.ValidColumn, - tlsfingerprintprofile.Table: tlsfingerprintprofile.ValidColumn, - usagecleanuptask.Table: usagecleanuptask.ValidColumn, - usagelog.Table: usagelog.ValidColumn, - user.Table: user.ValidColumn, - userallowedgroup.Table: userallowedgroup.ValidColumn, - userattributedefinition.Table: userattributedefinition.ValidColumn, - userattributevalue.Table: userattributevalue.ValidColumn, - usersubscription.Table: usersubscription.ValidColumn, + apikey.Table: apikey.ValidColumn, + account.Table: account.ValidColumn, + accountgroup.Table: accountgroup.ValidColumn, + announcement.Table: announcement.ValidColumn, + announcementread.Table: announcementread.ValidColumn, + authidentity.Table: authidentity.ValidColumn, + authidentitychannel.Table: authidentitychannel.ValidColumn, + channelmonitor.Table: channelmonitor.ValidColumn, + channelmonitordailyrollup.Table: channelmonitordailyrollup.ValidColumn, + channelmonitorhistory.Table: channelmonitorhistory.ValidColumn, + channelmonitorrequesttemplate.Table: channelmonitorrequesttemplate.ValidColumn, + errorpassthroughrule.Table: errorpassthroughrule.ValidColumn, + group.Table: group.ValidColumn, + idempotencyrecord.Table: idempotencyrecord.ValidColumn, + identityadoptiondecision.Table: identityadoptiondecision.ValidColumn, + paymentauditlog.Table: paymentauditlog.ValidColumn, + paymentorder.Table: paymentorder.ValidColumn, + paymentproviderinstance.Table: paymentproviderinstance.ValidColumn, + pendingauthsession.Table: pendingauthsession.ValidColumn, + promocode.Table: promocode.ValidColumn, + promocodeusage.Table: promocodeusage.ValidColumn, + proxy.Table: proxy.ValidColumn, + redeemcode.Table: redeemcode.ValidColumn, + securitysecret.Table: securitysecret.ValidColumn, + setting.Table: setting.ValidColumn, + subscriptionplan.Table: subscriptionplan.ValidColumn, + tlsfingerprintprofile.Table: tlsfingerprintprofile.ValidColumn, + usagecleanuptask.Table: usagecleanuptask.ValidColumn, + usagelog.Table: usagelog.ValidColumn, + user.Table: user.ValidColumn, + userallowedgroup.Table: userallowedgroup.ValidColumn, + userattributedefinition.Table: userattributedefinition.ValidColumn, + userattributevalue.Table: userattributevalue.ValidColumn, + usersubscription.Table: usersubscription.ValidColumn, }) }) return columnCheck(t, c) diff --git a/backend/ent/hook/hook.go b/backend/ent/hook/hook.go index ff86c90d..414eba24 100644 --- a/backend/ent/hook/hook.go +++ b/backend/ent/hook/hook.go @@ -129,6 +129,18 @@ func (f ChannelMonitorHistoryFunc) Mutate(ctx context.Context, m ent.Mutation) ( return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ChannelMonitorHistoryMutation", m) } +// The ChannelMonitorRequestTemplateFunc type is an adapter to allow the use of ordinary +// function as ChannelMonitorRequestTemplate mutator. +type ChannelMonitorRequestTemplateFunc func(context.Context, *ent.ChannelMonitorRequestTemplateMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f ChannelMonitorRequestTemplateFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.ChannelMonitorRequestTemplateMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ChannelMonitorRequestTemplateMutation", m) +} + // The ErrorPassthroughRuleFunc type is an adapter to allow the use of ordinary // function as ErrorPassthroughRule mutator. type ErrorPassthroughRuleFunc func(context.Context, *ent.ErrorPassthroughRuleMutation) (ent.Value, error) diff --git a/backend/ent/intercept/intercept.go b/backend/ent/intercept/intercept.go index 0c83fc38..95b68e09 100644 --- a/backend/ent/intercept/intercept.go +++ b/backend/ent/intercept/intercept.go @@ -18,6 +18,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" @@ -370,6 +371,33 @@ func (f TraverseChannelMonitorHistory) Traverse(ctx context.Context, q ent.Query return fmt.Errorf("unexpected query type %T. expect *ent.ChannelMonitorHistoryQuery", q) } +// The ChannelMonitorRequestTemplateFunc type is an adapter to allow the use of ordinary function as a Querier. +type ChannelMonitorRequestTemplateFunc func(context.Context, *ent.ChannelMonitorRequestTemplateQuery) (ent.Value, error) + +// Query calls f(ctx, q). +func (f ChannelMonitorRequestTemplateFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { + if q, ok := q.(*ent.ChannelMonitorRequestTemplateQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *ent.ChannelMonitorRequestTemplateQuery", q) +} + +// The TraverseChannelMonitorRequestTemplate type is an adapter to allow the use of ordinary function as Traverser. +type TraverseChannelMonitorRequestTemplate func(context.Context, *ent.ChannelMonitorRequestTemplateQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraverseChannelMonitorRequestTemplate) Intercept(next ent.Querier) ent.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraverseChannelMonitorRequestTemplate) Traverse(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.ChannelMonitorRequestTemplateQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *ent.ChannelMonitorRequestTemplateQuery", q) +} + // The ErrorPassthroughRuleFunc type is an adapter to allow the use of ordinary function as a Querier. type ErrorPassthroughRuleFunc func(context.Context, *ent.ErrorPassthroughRuleQuery) (ent.Value, error) @@ -1014,6 +1042,8 @@ func NewQuery(q ent.Query) (Query, error) { return &query[*ent.ChannelMonitorDailyRollupQuery, predicate.ChannelMonitorDailyRollup, channelmonitordailyrollup.OrderOption]{typ: ent.TypeChannelMonitorDailyRollup, tq: q}, nil case *ent.ChannelMonitorHistoryQuery: return &query[*ent.ChannelMonitorHistoryQuery, predicate.ChannelMonitorHistory, channelmonitorhistory.OrderOption]{typ: ent.TypeChannelMonitorHistory, tq: q}, nil + case *ent.ChannelMonitorRequestTemplateQuery: + return &query[*ent.ChannelMonitorRequestTemplateQuery, predicate.ChannelMonitorRequestTemplate, channelmonitorrequesttemplate.OrderOption]{typ: ent.TypeChannelMonitorRequestTemplate, tq: q}, nil case *ent.ErrorPassthroughRuleQuery: return &query[*ent.ErrorPassthroughRuleQuery, predicate.ErrorPassthroughRule, errorpassthroughrule.OrderOption]{typ: ent.TypeErrorPassthroughRule, tq: q}, nil case *ent.GroupQuery: diff --git a/backend/ent/migrate/schema.go b/backend/ent/migrate/schema.go index dba43ddf..38366e95 100644 --- a/backend/ent/migrate/schema.go +++ b/backend/ent/migrate/schema.go @@ -437,12 +437,24 @@ var ( {Name: "interval_seconds", Type: field.TypeInt}, {Name: "last_checked_at", Type: field.TypeTime, Nullable: true}, {Name: "created_by", Type: field.TypeInt64}, + {Name: "extra_headers", Type: field.TypeJSON}, + {Name: "body_override_mode", Type: field.TypeString, Size: 10, Default: "off"}, + {Name: "body_override", Type: field.TypeJSON, Nullable: true}, + {Name: "template_id", Type: field.TypeInt64, Nullable: true}, } // ChannelMonitorsTable holds the schema information for the "channel_monitors" table. ChannelMonitorsTable = &schema.Table{ Name: "channel_monitors", Columns: ChannelMonitorsColumns, PrimaryKey: []*schema.Column{ChannelMonitorsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "channel_monitors_channel_monitor_request_templates_request_template", + Columns: []*schema.Column{ChannelMonitorsColumns[17]}, + RefColumns: []*schema.Column{ChannelMonitorRequestTemplatesColumns[0]}, + OnDelete: schema.SetNull, + }, + }, Indexes: []*schema.Index{ { Name: "channelmonitor_enabled_last_checked_at", @@ -459,6 +471,11 @@ var ( Unique: false, Columns: []*schema.Column{ChannelMonitorsColumns[9]}, }, + { + Name: "channelmonitor_template_id", + Unique: false, + Columns: []*schema.Column{ChannelMonitorsColumns[17]}, + }, }, } // ChannelMonitorDailyRollupsColumns holds the columns for the "channel_monitor_daily_rollups" table. @@ -542,6 +559,31 @@ var ( }, }, } + // ChannelMonitorRequestTemplatesColumns holds the columns for the "channel_monitor_request_templates" table. + ChannelMonitorRequestTemplatesColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "name", Type: field.TypeString, Size: 100}, + {Name: "provider", Type: field.TypeEnum, Enums: []string{"openai", "anthropic", "gemini"}}, + {Name: "description", Type: field.TypeString, Nullable: true, Size: 500, Default: ""}, + {Name: "extra_headers", Type: field.TypeJSON}, + {Name: "body_override_mode", Type: field.TypeString, Size: 10, Default: "off"}, + {Name: "body_override", Type: field.TypeJSON, Nullable: true}, + } + // ChannelMonitorRequestTemplatesTable holds the schema information for the "channel_monitor_request_templates" table. + ChannelMonitorRequestTemplatesTable = &schema.Table{ + Name: "channel_monitor_request_templates", + Columns: ChannelMonitorRequestTemplatesColumns, + PrimaryKey: []*schema.Column{ChannelMonitorRequestTemplatesColumns[0]}, + Indexes: []*schema.Index{ + { + Name: "channelmonitorrequesttemplate_provider_name", + Unique: true, + Columns: []*schema.Column{ChannelMonitorRequestTemplatesColumns[4], ChannelMonitorRequestTemplatesColumns[3]}, + }, + }, + } // ErrorPassthroughRulesColumns holds the columns for the "error_passthrough_rules" table. ErrorPassthroughRulesColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -1644,6 +1686,7 @@ var ( ChannelMonitorsTable, ChannelMonitorDailyRollupsTable, ChannelMonitorHistoriesTable, + ChannelMonitorRequestTemplatesTable, ErrorPassthroughRulesTable, GroupsTable, IdempotencyRecordsTable, @@ -1701,6 +1744,7 @@ func init() { AuthIdentityChannelsTable.Annotation = &entsql.Annotation{ Table: "auth_identity_channels", } + ChannelMonitorsTable.ForeignKeys[0].RefTable = ChannelMonitorRequestTemplatesTable ChannelMonitorsTable.Annotation = &entsql.Annotation{ Table: "channel_monitors", } @@ -1712,6 +1756,9 @@ func init() { ChannelMonitorHistoriesTable.Annotation = &entsql.Annotation{ Table: "channel_monitor_histories", } + ChannelMonitorRequestTemplatesTable.Annotation = &entsql.Annotation{ + Table: "channel_monitor_request_templates", + } ErrorPassthroughRulesTable.Annotation = &entsql.Annotation{ Table: "error_passthrough_rules", } diff --git a/backend/ent/mutation.go b/backend/ent/mutation.go index 43e52371..568b3eb5 100644 --- a/backend/ent/mutation.go +++ b/backend/ent/mutation.go @@ -22,6 +22,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" @@ -58,39 +59,40 @@ const ( OpUpdateOne = ent.OpUpdateOne // Node types. - TypeAPIKey = "APIKey" - TypeAccount = "Account" - TypeAccountGroup = "AccountGroup" - TypeAnnouncement = "Announcement" - TypeAnnouncementRead = "AnnouncementRead" - TypeAuthIdentity = "AuthIdentity" - TypeAuthIdentityChannel = "AuthIdentityChannel" - TypeChannelMonitor = "ChannelMonitor" - TypeChannelMonitorDailyRollup = "ChannelMonitorDailyRollup" - TypeChannelMonitorHistory = "ChannelMonitorHistory" - TypeErrorPassthroughRule = "ErrorPassthroughRule" - TypeGroup = "Group" - TypeIdempotencyRecord = "IdempotencyRecord" - TypeIdentityAdoptionDecision = "IdentityAdoptionDecision" - TypePaymentAuditLog = "PaymentAuditLog" - TypePaymentOrder = "PaymentOrder" - TypePaymentProviderInstance = "PaymentProviderInstance" - TypePendingAuthSession = "PendingAuthSession" - TypePromoCode = "PromoCode" - TypePromoCodeUsage = "PromoCodeUsage" - TypeProxy = "Proxy" - TypeRedeemCode = "RedeemCode" - TypeSecuritySecret = "SecuritySecret" - TypeSetting = "Setting" - TypeSubscriptionPlan = "SubscriptionPlan" - TypeTLSFingerprintProfile = "TLSFingerprintProfile" - TypeUsageCleanupTask = "UsageCleanupTask" - TypeUsageLog = "UsageLog" - TypeUser = "User" - TypeUserAllowedGroup = "UserAllowedGroup" - TypeUserAttributeDefinition = "UserAttributeDefinition" - TypeUserAttributeValue = "UserAttributeValue" - TypeUserSubscription = "UserSubscription" + TypeAPIKey = "APIKey" + TypeAccount = "Account" + TypeAccountGroup = "AccountGroup" + TypeAnnouncement = "Announcement" + TypeAnnouncementRead = "AnnouncementRead" + TypeAuthIdentity = "AuthIdentity" + TypeAuthIdentityChannel = "AuthIdentityChannel" + TypeChannelMonitor = "ChannelMonitor" + TypeChannelMonitorDailyRollup = "ChannelMonitorDailyRollup" + TypeChannelMonitorHistory = "ChannelMonitorHistory" + TypeChannelMonitorRequestTemplate = "ChannelMonitorRequestTemplate" + TypeErrorPassthroughRule = "ErrorPassthroughRule" + TypeGroup = "Group" + TypeIdempotencyRecord = "IdempotencyRecord" + TypeIdentityAdoptionDecision = "IdentityAdoptionDecision" + TypePaymentAuditLog = "PaymentAuditLog" + TypePaymentOrder = "PaymentOrder" + TypePaymentProviderInstance = "PaymentProviderInstance" + TypePendingAuthSession = "PendingAuthSession" + TypePromoCode = "PromoCode" + TypePromoCodeUsage = "PromoCodeUsage" + TypeProxy = "Proxy" + TypeRedeemCode = "RedeemCode" + TypeSecuritySecret = "SecuritySecret" + TypeSetting = "Setting" + TypeSubscriptionPlan = "SubscriptionPlan" + TypeTLSFingerprintProfile = "TLSFingerprintProfile" + TypeUsageCleanupTask = "UsageCleanupTask" + TypeUsageLog = "UsageLog" + TypeUser = "User" + TypeUserAllowedGroup = "UserAllowedGroup" + TypeUserAttributeDefinition = "UserAttributeDefinition" + TypeUserAttributeValue = "UserAttributeValue" + TypeUserSubscription = "UserSubscription" ) // APIKeyMutation represents an operation that mutates the APIKey nodes in the graph. @@ -8743,35 +8745,40 @@ func (m *AuthIdentityChannelMutation) ResetEdge(name string) error { // ChannelMonitorMutation represents an operation that mutates the ChannelMonitor nodes in the graph. type ChannelMonitorMutation struct { config - op Op - typ string - id *int64 - created_at *time.Time - updated_at *time.Time - name *string - provider *channelmonitor.Provider - endpoint *string - api_key_encrypted *string - primary_model *string - extra_models *[]string - appendextra_models []string - group_name *string - enabled *bool - interval_seconds *int - addinterval_seconds *int - last_checked_at *time.Time - created_by *int64 - addcreated_by *int64 - clearedFields map[string]struct{} - history map[int64]struct{} - removedhistory map[int64]struct{} - clearedhistory bool - daily_rollups map[int64]struct{} - removeddaily_rollups map[int64]struct{} - cleareddaily_rollups bool - done bool - oldValue func(context.Context) (*ChannelMonitor, error) - predicates []predicate.ChannelMonitor + op Op + typ string + id *int64 + created_at *time.Time + updated_at *time.Time + name *string + provider *channelmonitor.Provider + endpoint *string + api_key_encrypted *string + primary_model *string + extra_models *[]string + appendextra_models []string + group_name *string + enabled *bool + interval_seconds *int + addinterval_seconds *int + last_checked_at *time.Time + created_by *int64 + addcreated_by *int64 + extra_headers *map[string]string + body_override_mode *string + body_override *map[string]interface{} + clearedFields map[string]struct{} + history map[int64]struct{} + removedhistory map[int64]struct{} + clearedhistory bool + daily_rollups map[int64]struct{} + removeddaily_rollups map[int64]struct{} + cleareddaily_rollups bool + request_template *int64 + clearedrequest_template bool + done bool + oldValue func(context.Context) (*ChannelMonitor, error) + predicates []predicate.ChannelMonitor } var _ ent.Mutation = (*ChannelMonitorMutation)(nil) @@ -9421,6 +9428,176 @@ func (m *ChannelMonitorMutation) ResetCreatedBy() { m.addcreated_by = nil } +// SetTemplateID sets the "template_id" field. +func (m *ChannelMonitorMutation) SetTemplateID(i int64) { + m.request_template = &i +} + +// TemplateID returns the value of the "template_id" field in the mutation. +func (m *ChannelMonitorMutation) TemplateID() (r int64, exists bool) { + v := m.request_template + if v == nil { + return + } + return *v, true +} + +// OldTemplateID returns the old "template_id" field's value of the ChannelMonitor entity. +// If the ChannelMonitor 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 *ChannelMonitorMutation) OldTemplateID(ctx context.Context) (v *int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTemplateID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTemplateID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTemplateID: %w", err) + } + return oldValue.TemplateID, nil +} + +// ClearTemplateID clears the value of the "template_id" field. +func (m *ChannelMonitorMutation) ClearTemplateID() { + m.request_template = nil + m.clearedFields[channelmonitor.FieldTemplateID] = struct{}{} +} + +// TemplateIDCleared returns if the "template_id" field was cleared in this mutation. +func (m *ChannelMonitorMutation) TemplateIDCleared() bool { + _, ok := m.clearedFields[channelmonitor.FieldTemplateID] + return ok +} + +// ResetTemplateID resets all changes to the "template_id" field. +func (m *ChannelMonitorMutation) ResetTemplateID() { + m.request_template = nil + delete(m.clearedFields, channelmonitor.FieldTemplateID) +} + +// SetExtraHeaders sets the "extra_headers" field. +func (m *ChannelMonitorMutation) SetExtraHeaders(value map[string]string) { + m.extra_headers = &value +} + +// ExtraHeaders returns the value of the "extra_headers" field in the mutation. +func (m *ChannelMonitorMutation) ExtraHeaders() (r map[string]string, exists bool) { + v := m.extra_headers + if v == nil { + return + } + return *v, true +} + +// OldExtraHeaders returns the old "extra_headers" field's value of the ChannelMonitor entity. +// If the ChannelMonitor 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 *ChannelMonitorMutation) OldExtraHeaders(ctx context.Context) (v map[string]string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldExtraHeaders is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldExtraHeaders requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldExtraHeaders: %w", err) + } + return oldValue.ExtraHeaders, nil +} + +// ResetExtraHeaders resets all changes to the "extra_headers" field. +func (m *ChannelMonitorMutation) ResetExtraHeaders() { + m.extra_headers = nil +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (m *ChannelMonitorMutation) SetBodyOverrideMode(s string) { + m.body_override_mode = &s +} + +// BodyOverrideMode returns the value of the "body_override_mode" field in the mutation. +func (m *ChannelMonitorMutation) BodyOverrideMode() (r string, exists bool) { + v := m.body_override_mode + if v == nil { + return + } + return *v, true +} + +// OldBodyOverrideMode returns the old "body_override_mode" field's value of the ChannelMonitor entity. +// If the ChannelMonitor 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 *ChannelMonitorMutation) OldBodyOverrideMode(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBodyOverrideMode is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBodyOverrideMode requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBodyOverrideMode: %w", err) + } + return oldValue.BodyOverrideMode, nil +} + +// ResetBodyOverrideMode resets all changes to the "body_override_mode" field. +func (m *ChannelMonitorMutation) ResetBodyOverrideMode() { + m.body_override_mode = nil +} + +// SetBodyOverride sets the "body_override" field. +func (m *ChannelMonitorMutation) SetBodyOverride(value map[string]interface{}) { + m.body_override = &value +} + +// BodyOverride returns the value of the "body_override" field in the mutation. +func (m *ChannelMonitorMutation) BodyOverride() (r map[string]interface{}, exists bool) { + v := m.body_override + if v == nil { + return + } + return *v, true +} + +// OldBodyOverride returns the old "body_override" field's value of the ChannelMonitor entity. +// If the ChannelMonitor 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 *ChannelMonitorMutation) OldBodyOverride(ctx context.Context) (v map[string]interface{}, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBodyOverride is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBodyOverride requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBodyOverride: %w", err) + } + return oldValue.BodyOverride, nil +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (m *ChannelMonitorMutation) ClearBodyOverride() { + m.body_override = nil + m.clearedFields[channelmonitor.FieldBodyOverride] = struct{}{} +} + +// BodyOverrideCleared returns if the "body_override" field was cleared in this mutation. +func (m *ChannelMonitorMutation) BodyOverrideCleared() bool { + _, ok := m.clearedFields[channelmonitor.FieldBodyOverride] + return ok +} + +// ResetBodyOverride resets all changes to the "body_override" field. +func (m *ChannelMonitorMutation) ResetBodyOverride() { + m.body_override = nil + delete(m.clearedFields, channelmonitor.FieldBodyOverride) +} + // AddHistoryIDs adds the "history" edge to the ChannelMonitorHistory entity by ids. func (m *ChannelMonitorMutation) AddHistoryIDs(ids ...int64) { if m.history == nil { @@ -9529,6 +9706,46 @@ func (m *ChannelMonitorMutation) ResetDailyRollups() { m.removeddaily_rollups = nil } +// SetRequestTemplateID sets the "request_template" edge to the ChannelMonitorRequestTemplate entity by id. +func (m *ChannelMonitorMutation) SetRequestTemplateID(id int64) { + m.request_template = &id +} + +// ClearRequestTemplate clears the "request_template" edge to the ChannelMonitorRequestTemplate entity. +func (m *ChannelMonitorMutation) ClearRequestTemplate() { + m.clearedrequest_template = true + m.clearedFields[channelmonitor.FieldTemplateID] = struct{}{} +} + +// RequestTemplateCleared reports if the "request_template" edge to the ChannelMonitorRequestTemplate entity was cleared. +func (m *ChannelMonitorMutation) RequestTemplateCleared() bool { + return m.TemplateIDCleared() || m.clearedrequest_template +} + +// RequestTemplateID returns the "request_template" edge ID in the mutation. +func (m *ChannelMonitorMutation) RequestTemplateID() (id int64, exists bool) { + if m.request_template != nil { + return *m.request_template, true + } + return +} + +// RequestTemplateIDs returns the "request_template" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// RequestTemplateID instead. It exists only for internal usage by the builders. +func (m *ChannelMonitorMutation) RequestTemplateIDs() (ids []int64) { + if id := m.request_template; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetRequestTemplate resets all changes to the "request_template" edge. +func (m *ChannelMonitorMutation) ResetRequestTemplate() { + m.request_template = nil + m.clearedrequest_template = false +} + // Where appends a list predicates to the ChannelMonitorMutation builder. func (m *ChannelMonitorMutation) Where(ps ...predicate.ChannelMonitor) { m.predicates = append(m.predicates, ps...) @@ -9563,7 +9780,7 @@ func (m *ChannelMonitorMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *ChannelMonitorMutation) Fields() []string { - fields := make([]string, 0, 13) + fields := make([]string, 0, 17) if m.created_at != nil { fields = append(fields, channelmonitor.FieldCreatedAt) } @@ -9603,6 +9820,18 @@ func (m *ChannelMonitorMutation) Fields() []string { if m.created_by != nil { fields = append(fields, channelmonitor.FieldCreatedBy) } + if m.request_template != nil { + fields = append(fields, channelmonitor.FieldTemplateID) + } + if m.extra_headers != nil { + fields = append(fields, channelmonitor.FieldExtraHeaders) + } + if m.body_override_mode != nil { + fields = append(fields, channelmonitor.FieldBodyOverrideMode) + } + if m.body_override != nil { + fields = append(fields, channelmonitor.FieldBodyOverride) + } return fields } @@ -9637,6 +9866,14 @@ func (m *ChannelMonitorMutation) Field(name string) (ent.Value, bool) { return m.LastCheckedAt() case channelmonitor.FieldCreatedBy: return m.CreatedBy() + case channelmonitor.FieldTemplateID: + return m.TemplateID() + case channelmonitor.FieldExtraHeaders: + return m.ExtraHeaders() + case channelmonitor.FieldBodyOverrideMode: + return m.BodyOverrideMode() + case channelmonitor.FieldBodyOverride: + return m.BodyOverride() } return nil, false } @@ -9672,6 +9909,14 @@ func (m *ChannelMonitorMutation) OldField(ctx context.Context, name string) (ent return m.OldLastCheckedAt(ctx) case channelmonitor.FieldCreatedBy: return m.OldCreatedBy(ctx) + case channelmonitor.FieldTemplateID: + return m.OldTemplateID(ctx) + case channelmonitor.FieldExtraHeaders: + return m.OldExtraHeaders(ctx) + case channelmonitor.FieldBodyOverrideMode: + return m.OldBodyOverrideMode(ctx) + case channelmonitor.FieldBodyOverride: + return m.OldBodyOverride(ctx) } return nil, fmt.Errorf("unknown ChannelMonitor field %s", name) } @@ -9772,6 +10017,34 @@ func (m *ChannelMonitorMutation) SetField(name string, value ent.Value) error { } m.SetCreatedBy(v) return nil + case channelmonitor.FieldTemplateID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTemplateID(v) + return nil + case channelmonitor.FieldExtraHeaders: + v, ok := value.(map[string]string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExtraHeaders(v) + return nil + case channelmonitor.FieldBodyOverrideMode: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBodyOverrideMode(v) + return nil + case channelmonitor.FieldBodyOverride: + v, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBodyOverride(v) + return nil } return fmt.Errorf("unknown ChannelMonitor field %s", name) } @@ -9835,6 +10108,12 @@ func (m *ChannelMonitorMutation) ClearedFields() []string { if m.FieldCleared(channelmonitor.FieldLastCheckedAt) { fields = append(fields, channelmonitor.FieldLastCheckedAt) } + if m.FieldCleared(channelmonitor.FieldTemplateID) { + fields = append(fields, channelmonitor.FieldTemplateID) + } + if m.FieldCleared(channelmonitor.FieldBodyOverride) { + fields = append(fields, channelmonitor.FieldBodyOverride) + } return fields } @@ -9855,6 +10134,12 @@ func (m *ChannelMonitorMutation) ClearField(name string) error { case channelmonitor.FieldLastCheckedAt: m.ClearLastCheckedAt() return nil + case channelmonitor.FieldTemplateID: + m.ClearTemplateID() + return nil + case channelmonitor.FieldBodyOverride: + m.ClearBodyOverride() + return nil } return fmt.Errorf("unknown ChannelMonitor nullable field %s", name) } @@ -9902,19 +10187,34 @@ func (m *ChannelMonitorMutation) ResetField(name string) error { case channelmonitor.FieldCreatedBy: m.ResetCreatedBy() return nil + case channelmonitor.FieldTemplateID: + m.ResetTemplateID() + return nil + case channelmonitor.FieldExtraHeaders: + m.ResetExtraHeaders() + return nil + case channelmonitor.FieldBodyOverrideMode: + m.ResetBodyOverrideMode() + return nil + case channelmonitor.FieldBodyOverride: + m.ResetBodyOverride() + return nil } return fmt.Errorf("unknown ChannelMonitor field %s", name) } // AddedEdges returns all edge names that were set/added in this mutation. func (m *ChannelMonitorMutation) AddedEdges() []string { - edges := make([]string, 0, 2) + edges := make([]string, 0, 3) if m.history != nil { edges = append(edges, channelmonitor.EdgeHistory) } if m.daily_rollups != nil { edges = append(edges, channelmonitor.EdgeDailyRollups) } + if m.request_template != nil { + edges = append(edges, channelmonitor.EdgeRequestTemplate) + } return edges } @@ -9934,13 +10234,17 @@ func (m *ChannelMonitorMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case channelmonitor.EdgeRequestTemplate: + if id := m.request_template; id != nil { + return []ent.Value{*id} + } } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *ChannelMonitorMutation) RemovedEdges() []string { - edges := make([]string, 0, 2) + edges := make([]string, 0, 3) if m.removedhistory != nil { edges = append(edges, channelmonitor.EdgeHistory) } @@ -9972,13 +10276,16 @@ func (m *ChannelMonitorMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *ChannelMonitorMutation) ClearedEdges() []string { - edges := make([]string, 0, 2) + edges := make([]string, 0, 3) if m.clearedhistory { edges = append(edges, channelmonitor.EdgeHistory) } if m.cleareddaily_rollups { edges = append(edges, channelmonitor.EdgeDailyRollups) } + if m.clearedrequest_template { + edges = append(edges, channelmonitor.EdgeRequestTemplate) + } return edges } @@ -9990,6 +10297,8 @@ func (m *ChannelMonitorMutation) EdgeCleared(name string) bool { return m.clearedhistory case channelmonitor.EdgeDailyRollups: return m.cleareddaily_rollups + case channelmonitor.EdgeRequestTemplate: + return m.clearedrequest_template } return false } @@ -9998,6 +10307,9 @@ func (m *ChannelMonitorMutation) EdgeCleared(name string) bool { // if that edge is not defined in the schema. func (m *ChannelMonitorMutation) ClearEdge(name string) error { switch name { + case channelmonitor.EdgeRequestTemplate: + m.ClearRequestTemplate() + return nil } return fmt.Errorf("unknown ChannelMonitor unique edge %s", name) } @@ -10012,6 +10324,9 @@ func (m *ChannelMonitorMutation) ResetEdge(name string) error { case channelmonitor.EdgeDailyRollups: m.ResetDailyRollups() return nil + case channelmonitor.EdgeRequestTemplate: + m.ResetRequestTemplate() + return nil } return fmt.Errorf("unknown ChannelMonitor edge %s", name) } @@ -12266,6 +12581,844 @@ func (m *ChannelMonitorHistoryMutation) ResetEdge(name string) error { return fmt.Errorf("unknown ChannelMonitorHistory edge %s", name) } +// ChannelMonitorRequestTemplateMutation represents an operation that mutates the ChannelMonitorRequestTemplate nodes in the graph. +type ChannelMonitorRequestTemplateMutation struct { + config + op Op + typ string + id *int64 + created_at *time.Time + updated_at *time.Time + name *string + provider *channelmonitorrequesttemplate.Provider + description *string + extra_headers *map[string]string + body_override_mode *string + body_override *map[string]interface{} + clearedFields map[string]struct{} + monitors map[int64]struct{} + removedmonitors map[int64]struct{} + clearedmonitors bool + done bool + oldValue func(context.Context) (*ChannelMonitorRequestTemplate, error) + predicates []predicate.ChannelMonitorRequestTemplate +} + +var _ ent.Mutation = (*ChannelMonitorRequestTemplateMutation)(nil) + +// channelmonitorrequesttemplateOption allows management of the mutation configuration using functional options. +type channelmonitorrequesttemplateOption func(*ChannelMonitorRequestTemplateMutation) + +// newChannelMonitorRequestTemplateMutation creates new mutation for the ChannelMonitorRequestTemplate entity. +func newChannelMonitorRequestTemplateMutation(c config, op Op, opts ...channelmonitorrequesttemplateOption) *ChannelMonitorRequestTemplateMutation { + m := &ChannelMonitorRequestTemplateMutation{ + config: c, + op: op, + typ: TypeChannelMonitorRequestTemplate, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withChannelMonitorRequestTemplateID sets the ID field of the mutation. +func withChannelMonitorRequestTemplateID(id int64) channelmonitorrequesttemplateOption { + return func(m *ChannelMonitorRequestTemplateMutation) { + var ( + err error + once sync.Once + value *ChannelMonitorRequestTemplate + ) + m.oldValue = func(ctx context.Context) (*ChannelMonitorRequestTemplate, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().ChannelMonitorRequestTemplate.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withChannelMonitorRequestTemplate sets the old ChannelMonitorRequestTemplate of the mutation. +func withChannelMonitorRequestTemplate(node *ChannelMonitorRequestTemplate) channelmonitorrequesttemplateOption { + return func(m *ChannelMonitorRequestTemplateMutation) { + m.oldValue = func(context.Context) (*ChannelMonitorRequestTemplate, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m ChannelMonitorRequestTemplateMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m ChannelMonitorRequestTemplateMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *ChannelMonitorRequestTemplateMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *ChannelMonitorRequestTemplateMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().ChannelMonitorRequestTemplate.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetCreatedAt sets the "created_at" field. +func (m *ChannelMonitorRequestTemplateMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_at" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *ChannelMonitorRequestTemplateMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetUpdatedAt() { + m.updated_at = nil +} + +// SetName sets the "name" field. +func (m *ChannelMonitorRequestTemplateMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetName() { + m.name = nil +} + +// SetProvider sets the "provider" field. +func (m *ChannelMonitorRequestTemplateMutation) SetProvider(c channelmonitorrequesttemplate.Provider) { + m.provider = &c +} + +// Provider returns the value of the "provider" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) Provider() (r channelmonitorrequesttemplate.Provider, exists bool) { + v := m.provider + if v == nil { + return + } + return *v, true +} + +// OldProvider returns the old "provider" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldProvider(ctx context.Context) (v channelmonitorrequesttemplate.Provider, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldProvider is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldProvider requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldProvider: %w", err) + } + return oldValue.Provider, nil +} + +// ResetProvider resets all changes to the "provider" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetProvider() { + m.provider = nil +} + +// SetDescription sets the "description" field. +func (m *ChannelMonitorRequestTemplateMutation) SetDescription(s string) { + m.description = &s +} + +// Description returns the value of the "description" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) Description() (r string, exists bool) { + v := m.description + if v == nil { + return + } + return *v, true +} + +// OldDescription returns the old "description" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldDescription(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDescription is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDescription requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDescription: %w", err) + } + return oldValue.Description, nil +} + +// ClearDescription clears the value of the "description" field. +func (m *ChannelMonitorRequestTemplateMutation) ClearDescription() { + m.description = nil + m.clearedFields[channelmonitorrequesttemplate.FieldDescription] = struct{}{} +} + +// DescriptionCleared returns if the "description" field was cleared in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) DescriptionCleared() bool { + _, ok := m.clearedFields[channelmonitorrequesttemplate.FieldDescription] + return ok +} + +// ResetDescription resets all changes to the "description" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetDescription() { + m.description = nil + delete(m.clearedFields, channelmonitorrequesttemplate.FieldDescription) +} + +// SetExtraHeaders sets the "extra_headers" field. +func (m *ChannelMonitorRequestTemplateMutation) SetExtraHeaders(value map[string]string) { + m.extra_headers = &value +} + +// ExtraHeaders returns the value of the "extra_headers" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) ExtraHeaders() (r map[string]string, exists bool) { + v := m.extra_headers + if v == nil { + return + } + return *v, true +} + +// OldExtraHeaders returns the old "extra_headers" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldExtraHeaders(ctx context.Context) (v map[string]string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldExtraHeaders is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldExtraHeaders requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldExtraHeaders: %w", err) + } + return oldValue.ExtraHeaders, nil +} + +// ResetExtraHeaders resets all changes to the "extra_headers" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetExtraHeaders() { + m.extra_headers = nil +} + +// SetBodyOverrideMode sets the "body_override_mode" field. +func (m *ChannelMonitorRequestTemplateMutation) SetBodyOverrideMode(s string) { + m.body_override_mode = &s +} + +// BodyOverrideMode returns the value of the "body_override_mode" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) BodyOverrideMode() (r string, exists bool) { + v := m.body_override_mode + if v == nil { + return + } + return *v, true +} + +// OldBodyOverrideMode returns the old "body_override_mode" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldBodyOverrideMode(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBodyOverrideMode is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBodyOverrideMode requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBodyOverrideMode: %w", err) + } + return oldValue.BodyOverrideMode, nil +} + +// ResetBodyOverrideMode resets all changes to the "body_override_mode" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetBodyOverrideMode() { + m.body_override_mode = nil +} + +// SetBodyOverride sets the "body_override" field. +func (m *ChannelMonitorRequestTemplateMutation) SetBodyOverride(value map[string]interface{}) { + m.body_override = &value +} + +// BodyOverride returns the value of the "body_override" field in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) BodyOverride() (r map[string]interface{}, exists bool) { + v := m.body_override + if v == nil { + return + } + return *v, true +} + +// OldBodyOverride returns the old "body_override" field's value of the ChannelMonitorRequestTemplate entity. +// If the ChannelMonitorRequestTemplate 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 *ChannelMonitorRequestTemplateMutation) OldBodyOverride(ctx context.Context) (v map[string]interface{}, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldBodyOverride is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldBodyOverride requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldBodyOverride: %w", err) + } + return oldValue.BodyOverride, nil +} + +// ClearBodyOverride clears the value of the "body_override" field. +func (m *ChannelMonitorRequestTemplateMutation) ClearBodyOverride() { + m.body_override = nil + m.clearedFields[channelmonitorrequesttemplate.FieldBodyOverride] = struct{}{} +} + +// BodyOverrideCleared returns if the "body_override" field was cleared in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) BodyOverrideCleared() bool { + _, ok := m.clearedFields[channelmonitorrequesttemplate.FieldBodyOverride] + return ok +} + +// ResetBodyOverride resets all changes to the "body_override" field. +func (m *ChannelMonitorRequestTemplateMutation) ResetBodyOverride() { + m.body_override = nil + delete(m.clearedFields, channelmonitorrequesttemplate.FieldBodyOverride) +} + +// AddMonitorIDs adds the "monitors" edge to the ChannelMonitor entity by ids. +func (m *ChannelMonitorRequestTemplateMutation) AddMonitorIDs(ids ...int64) { + if m.monitors == nil { + m.monitors = make(map[int64]struct{}) + } + for i := range ids { + m.monitors[ids[i]] = struct{}{} + } +} + +// ClearMonitors clears the "monitors" edge to the ChannelMonitor entity. +func (m *ChannelMonitorRequestTemplateMutation) ClearMonitors() { + m.clearedmonitors = true +} + +// MonitorsCleared reports if the "monitors" edge to the ChannelMonitor entity was cleared. +func (m *ChannelMonitorRequestTemplateMutation) MonitorsCleared() bool { + return m.clearedmonitors +} + +// RemoveMonitorIDs removes the "monitors" edge to the ChannelMonitor entity by IDs. +func (m *ChannelMonitorRequestTemplateMutation) RemoveMonitorIDs(ids ...int64) { + if m.removedmonitors == nil { + m.removedmonitors = make(map[int64]struct{}) + } + for i := range ids { + delete(m.monitors, ids[i]) + m.removedmonitors[ids[i]] = struct{}{} + } +} + +// RemovedMonitors returns the removed IDs of the "monitors" edge to the ChannelMonitor entity. +func (m *ChannelMonitorRequestTemplateMutation) RemovedMonitorsIDs() (ids []int64) { + for id := range m.removedmonitors { + ids = append(ids, id) + } + return +} + +// MonitorsIDs returns the "monitors" edge IDs in the mutation. +func (m *ChannelMonitorRequestTemplateMutation) MonitorsIDs() (ids []int64) { + for id := range m.monitors { + ids = append(ids, id) + } + return +} + +// ResetMonitors resets all changes to the "monitors" edge. +func (m *ChannelMonitorRequestTemplateMutation) ResetMonitors() { + m.monitors = nil + m.clearedmonitors = false + m.removedmonitors = nil +} + +// Where appends a list predicates to the ChannelMonitorRequestTemplateMutation builder. +func (m *ChannelMonitorRequestTemplateMutation) Where(ps ...predicate.ChannelMonitorRequestTemplate) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the ChannelMonitorRequestTemplateMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *ChannelMonitorRequestTemplateMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.ChannelMonitorRequestTemplate, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *ChannelMonitorRequestTemplateMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *ChannelMonitorRequestTemplateMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (ChannelMonitorRequestTemplate). +func (m *ChannelMonitorRequestTemplateMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *ChannelMonitorRequestTemplateMutation) Fields() []string { + fields := make([]string, 0, 8) + if m.created_at != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldCreatedAt) + } + if m.updated_at != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldUpdatedAt) + } + if m.name != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldName) + } + if m.provider != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldProvider) + } + if m.description != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldDescription) + } + if m.extra_headers != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldExtraHeaders) + } + if m.body_override_mode != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldBodyOverrideMode) + } + if m.body_override != nil { + fields = append(fields, channelmonitorrequesttemplate.FieldBodyOverride) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *ChannelMonitorRequestTemplateMutation) Field(name string) (ent.Value, bool) { + switch name { + case channelmonitorrequesttemplate.FieldCreatedAt: + return m.CreatedAt() + case channelmonitorrequesttemplate.FieldUpdatedAt: + return m.UpdatedAt() + case channelmonitorrequesttemplate.FieldName: + return m.Name() + case channelmonitorrequesttemplate.FieldProvider: + return m.Provider() + case channelmonitorrequesttemplate.FieldDescription: + return m.Description() + case channelmonitorrequesttemplate.FieldExtraHeaders: + return m.ExtraHeaders() + case channelmonitorrequesttemplate.FieldBodyOverrideMode: + return m.BodyOverrideMode() + case channelmonitorrequesttemplate.FieldBodyOverride: + return m.BodyOverride() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *ChannelMonitorRequestTemplateMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case channelmonitorrequesttemplate.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case channelmonitorrequesttemplate.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + case channelmonitorrequesttemplate.FieldName: + return m.OldName(ctx) + case channelmonitorrequesttemplate.FieldProvider: + return m.OldProvider(ctx) + case channelmonitorrequesttemplate.FieldDescription: + return m.OldDescription(ctx) + case channelmonitorrequesttemplate.FieldExtraHeaders: + return m.OldExtraHeaders(ctx) + case channelmonitorrequesttemplate.FieldBodyOverrideMode: + return m.OldBodyOverrideMode(ctx) + case channelmonitorrequesttemplate.FieldBodyOverride: + return m.OldBodyOverride(ctx) + } + return nil, fmt.Errorf("unknown ChannelMonitorRequestTemplate field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *ChannelMonitorRequestTemplateMutation) SetField(name string, value ent.Value) error { + switch name { + case channelmonitorrequesttemplate.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case channelmonitorrequesttemplate.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + case channelmonitorrequesttemplate.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case channelmonitorrequesttemplate.FieldProvider: + v, ok := value.(channelmonitorrequesttemplate.Provider) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetProvider(v) + return nil + case channelmonitorrequesttemplate.FieldDescription: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDescription(v) + return nil + case channelmonitorrequesttemplate.FieldExtraHeaders: + v, ok := value.(map[string]string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetExtraHeaders(v) + return nil + case channelmonitorrequesttemplate.FieldBodyOverrideMode: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBodyOverrideMode(v) + return nil + case channelmonitorrequesttemplate.FieldBodyOverride: + v, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetBodyOverride(v) + return nil + } + return fmt.Errorf("unknown ChannelMonitorRequestTemplate field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *ChannelMonitorRequestTemplateMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *ChannelMonitorRequestTemplateMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *ChannelMonitorRequestTemplateMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown ChannelMonitorRequestTemplate numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *ChannelMonitorRequestTemplateMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(channelmonitorrequesttemplate.FieldDescription) { + fields = append(fields, channelmonitorrequesttemplate.FieldDescription) + } + if m.FieldCleared(channelmonitorrequesttemplate.FieldBodyOverride) { + fields = append(fields, channelmonitorrequesttemplate.FieldBodyOverride) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *ChannelMonitorRequestTemplateMutation) ClearField(name string) error { + switch name { + case channelmonitorrequesttemplate.FieldDescription: + m.ClearDescription() + return nil + case channelmonitorrequesttemplate.FieldBodyOverride: + m.ClearBodyOverride() + return nil + } + return fmt.Errorf("unknown ChannelMonitorRequestTemplate nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *ChannelMonitorRequestTemplateMutation) ResetField(name string) error { + switch name { + case channelmonitorrequesttemplate.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case channelmonitorrequesttemplate.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + case channelmonitorrequesttemplate.FieldName: + m.ResetName() + return nil + case channelmonitorrequesttemplate.FieldProvider: + m.ResetProvider() + return nil + case channelmonitorrequesttemplate.FieldDescription: + m.ResetDescription() + return nil + case channelmonitorrequesttemplate.FieldExtraHeaders: + m.ResetExtraHeaders() + return nil + case channelmonitorrequesttemplate.FieldBodyOverrideMode: + m.ResetBodyOverrideMode() + return nil + case channelmonitorrequesttemplate.FieldBodyOverride: + m.ResetBodyOverride() + return nil + } + return fmt.Errorf("unknown ChannelMonitorRequestTemplate field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.monitors != nil { + edges = append(edges, channelmonitorrequesttemplate.EdgeMonitors) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) AddedIDs(name string) []ent.Value { + switch name { + case channelmonitorrequesttemplate.EdgeMonitors: + ids := make([]ent.Value, 0, len(m.monitors)) + for id := range m.monitors { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedmonitors != nil { + edges = append(edges, channelmonitorrequesttemplate.EdgeMonitors) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) RemovedIDs(name string) []ent.Value { + switch name { + case channelmonitorrequesttemplate.EdgeMonitors: + ids := make([]ent.Value, 0, len(m.removedmonitors)) + for id := range m.removedmonitors { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedmonitors { + edges = append(edges, channelmonitorrequesttemplate.EdgeMonitors) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *ChannelMonitorRequestTemplateMutation) EdgeCleared(name string) bool { + switch name { + case channelmonitorrequesttemplate.EdgeMonitors: + return m.clearedmonitors + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *ChannelMonitorRequestTemplateMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown ChannelMonitorRequestTemplate unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *ChannelMonitorRequestTemplateMutation) ResetEdge(name string) error { + switch name { + case channelmonitorrequesttemplate.EdgeMonitors: + m.ResetMonitors() + return nil + } + return fmt.Errorf("unknown ChannelMonitorRequestTemplate edge %s", name) +} + // ErrorPassthroughRuleMutation represents an operation that mutates the ErrorPassthroughRule nodes in the graph. type ErrorPassthroughRuleMutation struct { config diff --git a/backend/ent/predicate/predicate.go b/backend/ent/predicate/predicate.go index adb9a085..dc86471e 100644 --- a/backend/ent/predicate/predicate.go +++ b/backend/ent/predicate/predicate.go @@ -36,6 +36,9 @@ type ChannelMonitorDailyRollup func(*sql.Selector) // ChannelMonitorHistory is the predicate function for channelmonitorhistory builders. type ChannelMonitorHistory func(*sql.Selector) +// ChannelMonitorRequestTemplate is the predicate function for channelmonitorrequesttemplate builders. +type ChannelMonitorRequestTemplate func(*sql.Selector) + // ErrorPassthroughRule is the predicate function for errorpassthroughrule builders. type ErrorPassthroughRule func(*sql.Selector) diff --git a/backend/ent/runtime/runtime.go b/backend/ent/runtime/runtime.go index 63552bb5..aaa939c5 100644 --- a/backend/ent/runtime/runtime.go +++ b/backend/ent/runtime/runtime.go @@ -15,6 +15,7 @@ import ( "github.com/Wei-Shaw/sub2api/ent/channelmonitor" "github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup" "github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" "github.com/Wei-Shaw/sub2api/ent/errorpassthroughrule" "github.com/Wei-Shaw/sub2api/ent/group" "github.com/Wei-Shaw/sub2api/ent/idempotencyrecord" @@ -521,6 +522,16 @@ func init() { channelmonitorDescIntervalSeconds := channelmonitorFields[8].Descriptor() // channelmonitor.IntervalSecondsValidator is a validator for the "interval_seconds" field. It is called by the builders before save. channelmonitor.IntervalSecondsValidator = channelmonitorDescIntervalSeconds.Validators[0].(func(int) error) + // channelmonitorDescExtraHeaders is the schema descriptor for extra_headers field. + channelmonitorDescExtraHeaders := channelmonitorFields[12].Descriptor() + // channelmonitor.DefaultExtraHeaders holds the default value on creation for the extra_headers field. + channelmonitor.DefaultExtraHeaders = channelmonitorDescExtraHeaders.Default.(map[string]string) + // channelmonitorDescBodyOverrideMode is the schema descriptor for body_override_mode field. + channelmonitorDescBodyOverrideMode := channelmonitorFields[13].Descriptor() + // channelmonitor.DefaultBodyOverrideMode holds the default value on creation for the body_override_mode field. + channelmonitor.DefaultBodyOverrideMode = channelmonitorDescBodyOverrideMode.Default.(string) + // channelmonitor.BodyOverrideModeValidator is a validator for the "body_override_mode" field. It is called by the builders before save. + channelmonitor.BodyOverrideModeValidator = channelmonitorDescBodyOverrideMode.Validators[0].(func(string) error) channelmonitordailyrollupFields := schema.ChannelMonitorDailyRollup{}.Fields() _ = channelmonitordailyrollupFields // channelmonitordailyrollupDescModel is the schema descriptor for model field. @@ -617,6 +628,55 @@ func init() { channelmonitorhistoryDescCheckedAt := channelmonitorhistoryFields[6].Descriptor() // channelmonitorhistory.DefaultCheckedAt holds the default value on creation for the checked_at field. channelmonitorhistory.DefaultCheckedAt = channelmonitorhistoryDescCheckedAt.Default.(func() time.Time) + channelmonitorrequesttemplateMixin := schema.ChannelMonitorRequestTemplate{}.Mixin() + channelmonitorrequesttemplateMixinFields0 := channelmonitorrequesttemplateMixin[0].Fields() + _ = channelmonitorrequesttemplateMixinFields0 + channelmonitorrequesttemplateFields := schema.ChannelMonitorRequestTemplate{}.Fields() + _ = channelmonitorrequesttemplateFields + // channelmonitorrequesttemplateDescCreatedAt is the schema descriptor for created_at field. + channelmonitorrequesttemplateDescCreatedAt := channelmonitorrequesttemplateMixinFields0[0].Descriptor() + // channelmonitorrequesttemplate.DefaultCreatedAt holds the default value on creation for the created_at field. + channelmonitorrequesttemplate.DefaultCreatedAt = channelmonitorrequesttemplateDescCreatedAt.Default.(func() time.Time) + // channelmonitorrequesttemplateDescUpdatedAt is the schema descriptor for updated_at field. + channelmonitorrequesttemplateDescUpdatedAt := channelmonitorrequesttemplateMixinFields0[1].Descriptor() + // channelmonitorrequesttemplate.DefaultUpdatedAt holds the default value on creation for the updated_at field. + channelmonitorrequesttemplate.DefaultUpdatedAt = channelmonitorrequesttemplateDescUpdatedAt.Default.(func() time.Time) + // channelmonitorrequesttemplate.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. + channelmonitorrequesttemplate.UpdateDefaultUpdatedAt = channelmonitorrequesttemplateDescUpdatedAt.UpdateDefault.(func() time.Time) + // channelmonitorrequesttemplateDescName is the schema descriptor for name field. + channelmonitorrequesttemplateDescName := channelmonitorrequesttemplateFields[0].Descriptor() + // channelmonitorrequesttemplate.NameValidator is a validator for the "name" field. It is called by the builders before save. + channelmonitorrequesttemplate.NameValidator = func() func(string) error { + validators := channelmonitorrequesttemplateDescName.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(name string) error { + for _, fn := range fns { + if err := fn(name); err != nil { + return err + } + } + return nil + } + }() + // channelmonitorrequesttemplateDescDescription is the schema descriptor for description field. + channelmonitorrequesttemplateDescDescription := channelmonitorrequesttemplateFields[2].Descriptor() + // channelmonitorrequesttemplate.DefaultDescription holds the default value on creation for the description field. + channelmonitorrequesttemplate.DefaultDescription = channelmonitorrequesttemplateDescDescription.Default.(string) + // channelmonitorrequesttemplate.DescriptionValidator is a validator for the "description" field. It is called by the builders before save. + channelmonitorrequesttemplate.DescriptionValidator = channelmonitorrequesttemplateDescDescription.Validators[0].(func(string) error) + // channelmonitorrequesttemplateDescExtraHeaders is the schema descriptor for extra_headers field. + channelmonitorrequesttemplateDescExtraHeaders := channelmonitorrequesttemplateFields[3].Descriptor() + // channelmonitorrequesttemplate.DefaultExtraHeaders holds the default value on creation for the extra_headers field. + channelmonitorrequesttemplate.DefaultExtraHeaders = channelmonitorrequesttemplateDescExtraHeaders.Default.(map[string]string) + // channelmonitorrequesttemplateDescBodyOverrideMode is the schema descriptor for body_override_mode field. + channelmonitorrequesttemplateDescBodyOverrideMode := channelmonitorrequesttemplateFields[4].Descriptor() + // channelmonitorrequesttemplate.DefaultBodyOverrideMode holds the default value on creation for the body_override_mode field. + channelmonitorrequesttemplate.DefaultBodyOverrideMode = channelmonitorrequesttemplateDescBodyOverrideMode.Default.(string) + // channelmonitorrequesttemplate.BodyOverrideModeValidator is a validator for the "body_override_mode" field. It is called by the builders before save. + channelmonitorrequesttemplate.BodyOverrideModeValidator = channelmonitorrequesttemplateDescBodyOverrideMode.Validators[0].(func(string) error) errorpassthroughruleMixin := schema.ErrorPassthroughRule{}.Mixin() errorpassthroughruleMixinFields0 := errorpassthroughruleMixin[0].Fields() _ = errorpassthroughruleMixinFields0 diff --git a/backend/ent/schema/channel_monitor.go b/backend/ent/schema/channel_monitor.go index f6a6578d..355ade4b 100644 --- a/backend/ent/schema/channel_monitor.go +++ b/backend/ent/schema/channel_monitor.go @@ -62,6 +62,26 @@ func (ChannelMonitor) Fields() []ent.Field { Optional(). Nillable(), field.Int64("created_by"), + + // ---- 自定义请求快照字段(来自模板 / 手动编辑) ---- + + // template_id: 关联的请求模板 ID(仅用于 UI 分组 + 一键应用)。 + // 实际运行时 checker 只读下面 3 个快照字段,**不再回查模板表**。 + // 模板被删除时此字段会被 SET NULL(见 Edges 的 OnDelete 注解)。 + field.Int64("template_id"). + Optional(). + Nillable(), + // extra_headers: 自定义 HTTP 头快照(来自模板 or 用户手填)。 + // 运行时 merge 进 adapter 默认 headers。 + field.JSON("extra_headers", map[string]string{}). + Default(map[string]string{}), + // body_override_mode: 同 ChannelMonitorRequestTemplate.body_override_mode + field.String("body_override_mode"). + Default("off"). + MaxLen(10), + // body_override: 同 ChannelMonitorRequestTemplate.body_override + field.JSON("body_override", map[string]any{}). + Optional(), } } @@ -71,6 +91,12 @@ func (ChannelMonitor) Edges() []ent.Edge { Annotations(entsql.OnDelete(entsql.Cascade)), edge.To("daily_rollups", ChannelMonitorDailyRollup.Type). Annotations(entsql.OnDelete(entsql.Cascade)), + // 关联请求模板:模板被删除时 template_id 自动置空, + // 监控本身保留(继续用快照字段跑)。 + edge.To("request_template", ChannelMonitorRequestTemplate.Type). + Field("template_id"). + Unique(). + Annotations(entsql.OnDelete(entsql.SetNull)), } } @@ -79,5 +105,6 @@ func (ChannelMonitor) Indexes() []ent.Index { index.Fields("enabled", "last_checked_at"), index.Fields("provider"), index.Fields("group_name"), + index.Fields("template_id"), } } diff --git a/backend/ent/schema/channel_monitor_request_template.go b/backend/ent/schema/channel_monitor_request_template.go new file mode 100644 index 00000000..59df2f29 --- /dev/null +++ b/backend/ent/schema/channel_monitor_request_template.go @@ -0,0 +1,80 @@ +package schema + +import ( + "github.com/Wei-Shaw/sub2api/ent/schema/mixins" + + "entgo.io/ent" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" +) + +// ChannelMonitorRequestTemplate 请求模板:一组可复用的 headers + 可选 body 覆盖配置。 +// +// 语义为快照:模板被"应用"到监控时,extra_headers / body_override_mode / body_override +// 会被**拷贝**到 channel_monitors 同名字段;后续模板变动不会自动影响已应用的监控—— +// 必须用户主动在模板编辑 Dialog 里点「应用到关联监控」才会覆盖快照。 +// 这样模板改错不会瞬间打挂所有已经跑起来的监控。 +type ChannelMonitorRequestTemplate struct { + ent.Schema +} + +func (ChannelMonitorRequestTemplate) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "channel_monitor_request_templates"}, + } +} + +func (ChannelMonitorRequestTemplate) Mixin() []ent.Mixin { + return []ent.Mixin{ + mixins.TimeMixin{}, + } +} + +func (ChannelMonitorRequestTemplate) Fields() []ent.Field { + return []ent.Field{ + field.String("name"). + NotEmpty(). + MaxLen(100), + field.Enum("provider"). + Values("openai", "anthropic", "gemini"), + field.String("description"). + Optional(). + Default(""). + MaxLen(500), + // extra_headers: 用户自定义 HTTP 头(如 User-Agent 伪装)。 + // 运行时 merge 进 adapter 默认 headers,用户值优先; + // hop-by-hop 黑名单(Host/Content-Length/...)由 checker 过滤。 + field.JSON("extra_headers", map[string]string{}). + Default(map[string]string{}), + // body_override_mode: 'off' | 'merge' | 'replace' + // off - 用 adapter 默认 body(忽略 body_override) + // merge - adapter 默认 body 与 body_override 浅合并(body_override 优先, + // model/messages/contents 等关键字段在 checker 里走黑名单跳过) + // replace - 直接用 body_override 作为完整 body;此时跳过 challenge 校验, + // 改为 HTTP 2xx + 响应文本非空即视为可用 + field.String("body_override_mode"). + Default("off"). + MaxLen(10), + // body_override: JSON 对象,根据 body_override_mode 使用。 + // 用 map[string]any 以便前端传任意结构(含嵌套)。 + field.JSON("body_override", map[string]any{}). + Optional(), + } +} + +func (ChannelMonitorRequestTemplate) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("monitors", ChannelMonitor.Type). + Ref("request_template"), + } +} + +func (ChannelMonitorRequestTemplate) Indexes() []ent.Index { + return []ent.Index{ + // 同一 provider 内 name 唯一:允许 Anthropic + OpenAI 重名 "伪装官方客户端"。 + index.Fields("provider", "name").Unique(), + } +} diff --git a/backend/ent/tx.go b/backend/ent/tx.go index 0e65a940..611028e9 100644 --- a/backend/ent/tx.go +++ b/backend/ent/tx.go @@ -34,6 +34,8 @@ type Tx struct { ChannelMonitorDailyRollup *ChannelMonitorDailyRollupClient // ChannelMonitorHistory is the client for interacting with the ChannelMonitorHistory builders. ChannelMonitorHistory *ChannelMonitorHistoryClient + // ChannelMonitorRequestTemplate is the client for interacting with the ChannelMonitorRequestTemplate builders. + ChannelMonitorRequestTemplate *ChannelMonitorRequestTemplateClient // ErrorPassthroughRule is the client for interacting with the ErrorPassthroughRule builders. ErrorPassthroughRule *ErrorPassthroughRuleClient // Group is the client for interacting with the Group builders. @@ -221,6 +223,7 @@ func (tx *Tx) init() { tx.ChannelMonitor = NewChannelMonitorClient(tx.config) tx.ChannelMonitorDailyRollup = NewChannelMonitorDailyRollupClient(tx.config) tx.ChannelMonitorHistory = NewChannelMonitorHistoryClient(tx.config) + tx.ChannelMonitorRequestTemplate = NewChannelMonitorRequestTemplateClient(tx.config) tx.ErrorPassthroughRule = NewErrorPassthroughRuleClient(tx.config) tx.Group = NewGroupClient(tx.config) tx.IdempotencyRecord = NewIdempotencyRecordClient(tx.config) diff --git a/backend/internal/handler/admin/channel_monitor_handler.go b/backend/internal/handler/admin/channel_monitor_handler.go index ce86c3dc..e92c81fe 100644 --- a/backend/internal/handler/admin/channel_monitor_handler.go +++ b/backend/internal/handler/admin/channel_monitor_handler.go @@ -36,27 +36,36 @@ func NewChannelMonitorHandler(monitorService *service.ChannelMonitorService) *Ch // --- Request / Response --- type channelMonitorCreateRequest struct { - Name string `json:"name" binding:"required,max=100"` - Provider string `json:"provider" binding:"required,oneof=openai anthropic gemini"` - Endpoint string `json:"endpoint" binding:"required,max=500"` - APIKey string `json:"api_key" binding:"required,max=2000"` - PrimaryModel string `json:"primary_model" binding:"required,max=200"` - ExtraModels []string `json:"extra_models"` - GroupName string `json:"group_name" binding:"max=100"` - Enabled *bool `json:"enabled"` - IntervalSeconds int `json:"interval_seconds" binding:"required,min=15,max=3600"` + Name string `json:"name" binding:"required,max=100"` + Provider string `json:"provider" binding:"required,oneof=openai anthropic gemini"` + Endpoint string `json:"endpoint" binding:"required,max=500"` + APIKey string `json:"api_key" binding:"required,max=2000"` + PrimaryModel string `json:"primary_model" binding:"required,max=200"` + ExtraModels []string `json:"extra_models"` + GroupName string `json:"group_name" binding:"max=100"` + Enabled *bool `json:"enabled"` + IntervalSeconds int `json:"interval_seconds" binding:"required,min=15,max=3600"` + TemplateID *int64 `json:"template_id"` + ExtraHeaders map[string]string `json:"extra_headers"` + BodyOverrideMode string `json:"body_override_mode" binding:"omitempty,oneof=off merge replace"` + BodyOverride map[string]any `json:"body_override"` } type channelMonitorUpdateRequest struct { - Name *string `json:"name" binding:"omitempty,max=100"` - Provider *string `json:"provider" binding:"omitempty,oneof=openai anthropic gemini"` - Endpoint *string `json:"endpoint" binding:"omitempty,max=500"` - APIKey *string `json:"api_key" binding:"omitempty,max=2000"` - PrimaryModel *string `json:"primary_model" binding:"omitempty,max=200"` - ExtraModels *[]string `json:"extra_models"` - GroupName *string `json:"group_name" binding:"omitempty,max=100"` - Enabled *bool `json:"enabled"` - IntervalSeconds *int `json:"interval_seconds" binding:"omitempty,min=15,max=3600"` + Name *string `json:"name" binding:"omitempty,max=100"` + Provider *string `json:"provider" binding:"omitempty,oneof=openai anthropic gemini"` + Endpoint *string `json:"endpoint" binding:"omitempty,max=500"` + APIKey *string `json:"api_key" binding:"omitempty,max=2000"` + PrimaryModel *string `json:"primary_model" binding:"omitempty,max=200"` + ExtraModels *[]string `json:"extra_models"` + GroupName *string `json:"group_name" binding:"omitempty,max=100"` + Enabled *bool `json:"enabled"` + IntervalSeconds *int `json:"interval_seconds" binding:"omitempty,min=15,max=3600"` + TemplateID *int64 `json:"template_id"` + ClearTemplate bool `json:"clear_template"` // true 时把 template_id 置空,忽略 TemplateID + ExtraHeaders *map[string]string `json:"extra_headers"` + BodyOverrideMode *string `json:"body_override_mode" binding:"omitempty,oneof=off merge replace"` + BodyOverride *map[string]any `json:"body_override"` } type channelMonitorResponse struct { @@ -79,6 +88,11 @@ type channelMonitorResponse struct { PrimaryLatencyMs *int `json:"primary_latency_ms"` Availability7d float64 `json:"availability_7d"` ExtraModelsStatus []dto.ChannelMonitorExtraModelStatus `json:"extra_models_status"` + // 请求自定义快照:前端编辑 / 展示「高级设置」用 + TemplateID *int64 `json:"template_id"` + ExtraHeaders map[string]string `json:"extra_headers"` + BodyOverrideMode string `json:"body_override_mode"` + BodyOverride map[string]any `json:"body_override"` } type channelMonitorCheckResultResponse struct { @@ -116,6 +130,10 @@ func channelMonitorToResponse(m *service.ChannelMonitor) *channelMonitorResponse if extras == nil { extras = []string{} } + headers := m.ExtraHeaders + if headers == nil { + headers = map[string]string{} + } resp := &channelMonitorResponse{ ID: m.ID, Name: m.Name, @@ -131,6 +149,10 @@ func channelMonitorToResponse(m *service.ChannelMonitor) *channelMonitorResponse CreatedBy: m.CreatedBy, CreatedAt: m.CreatedAt.UTC().Format(time.RFC3339), UpdatedAt: m.UpdatedAt.UTC().Format(time.RFC3339), + TemplateID: m.TemplateID, + ExtraHeaders: headers, + BodyOverrideMode: m.BodyOverrideMode, + BodyOverride: m.BodyOverride, // PrimaryStatus / PrimaryLatencyMs / Availability7d 由 List handler 在批量聚合后填充。 } if m.LastCheckedAt != nil { @@ -279,16 +301,20 @@ func (h *ChannelMonitorHandler) Create(c *gin.Context) { } m, err := h.monitorService.Create(c.Request.Context(), service.ChannelMonitorCreateParams{ - Name: req.Name, - Provider: req.Provider, - Endpoint: req.Endpoint, - APIKey: req.APIKey, - PrimaryModel: req.PrimaryModel, - ExtraModels: req.ExtraModels, - GroupName: req.GroupName, - Enabled: enabled, - IntervalSeconds: req.IntervalSeconds, - CreatedBy: subject.UserID, + Name: req.Name, + Provider: req.Provider, + Endpoint: req.Endpoint, + APIKey: req.APIKey, + PrimaryModel: req.PrimaryModel, + ExtraModels: req.ExtraModels, + GroupName: req.GroupName, + Enabled: enabled, + IntervalSeconds: req.IntervalSeconds, + CreatedBy: subject.UserID, + TemplateID: req.TemplateID, + ExtraHeaders: req.ExtraHeaders, + BodyOverrideMode: req.BodyOverrideMode, + BodyOverride: req.BodyOverride, }) if err != nil { response.ErrorFrom(c, err) @@ -310,15 +336,20 @@ func (h *ChannelMonitorHandler) Update(c *gin.Context) { } m, err := h.monitorService.Update(c.Request.Context(), id, service.ChannelMonitorUpdateParams{ - Name: req.Name, - Provider: req.Provider, - Endpoint: req.Endpoint, - APIKey: req.APIKey, - PrimaryModel: req.PrimaryModel, - ExtraModels: req.ExtraModels, - GroupName: req.GroupName, - Enabled: req.Enabled, - IntervalSeconds: req.IntervalSeconds, + Name: req.Name, + Provider: req.Provider, + Endpoint: req.Endpoint, + APIKey: req.APIKey, + PrimaryModel: req.PrimaryModel, + ExtraModels: req.ExtraModels, + GroupName: req.GroupName, + Enabled: req.Enabled, + IntervalSeconds: req.IntervalSeconds, + TemplateID: req.TemplateID, + ClearTemplate: req.ClearTemplate, + ExtraHeaders: req.ExtraHeaders, + BodyOverrideMode: req.BodyOverrideMode, + BodyOverride: req.BodyOverride, }) if err != nil { response.ErrorFrom(c, err) diff --git a/backend/internal/handler/admin/channel_monitor_template_handler.go b/backend/internal/handler/admin/channel_monitor_template_handler.go new file mode 100644 index 00000000..8c1191ea --- /dev/null +++ b/backend/internal/handler/admin/channel_monitor_template_handler.go @@ -0,0 +1,195 @@ +package admin + +import ( + "strconv" + "strings" + "time" + + infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" + "github.com/Wei-Shaw/sub2api/internal/pkg/response" + "github.com/Wei-Shaw/sub2api/internal/service" + + "github.com/gin-gonic/gin" +) + +// ChannelMonitorRequestTemplateHandler 请求模板管理后台 handler。 +type ChannelMonitorRequestTemplateHandler struct { + templateService *service.ChannelMonitorRequestTemplateService +} + +// NewChannelMonitorRequestTemplateHandler 创建 handler。 +func NewChannelMonitorRequestTemplateHandler(templateService *service.ChannelMonitorRequestTemplateService) *ChannelMonitorRequestTemplateHandler { + return &ChannelMonitorRequestTemplateHandler{templateService: templateService} +} + +// --- DTO --- + +type channelMonitorTemplateCreateRequest struct { + Name string `json:"name" binding:"required,max=100"` + Provider string `json:"provider" binding:"required,oneof=openai anthropic gemini"` + Description string `json:"description" binding:"max=500"` + ExtraHeaders map[string]string `json:"extra_headers"` + BodyOverrideMode string `json:"body_override_mode" binding:"omitempty,oneof=off merge replace"` + BodyOverride map[string]any `json:"body_override"` +} + +type channelMonitorTemplateUpdateRequest struct { + Name *string `json:"name" binding:"omitempty,max=100"` + Description *string `json:"description" binding:"omitempty,max=500"` + ExtraHeaders *map[string]string `json:"extra_headers"` + BodyOverrideMode *string `json:"body_override_mode" binding:"omitempty,oneof=off merge replace"` + BodyOverride *map[string]any `json:"body_override"` +} + +type channelMonitorTemplateResponse struct { + ID int64 `json:"id"` + Name string `json:"name"` + Provider string `json:"provider"` + Description string `json:"description"` + ExtraHeaders map[string]string `json:"extra_headers"` + BodyOverrideMode string `json:"body_override_mode"` + BodyOverride map[string]any `json:"body_override"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + AssociatedMonitors int64 `json:"associated_monitors"` +} + +func (h *ChannelMonitorRequestTemplateHandler) toResponse(c *gin.Context, t *service.ChannelMonitorRequestTemplate) *channelMonitorTemplateResponse { + if t == nil { + return nil + } + headers := t.ExtraHeaders + if headers == nil { + headers = map[string]string{} + } + count, _ := h.templateService.CountAssociatedMonitors(c.Request.Context(), t.ID) + return &channelMonitorTemplateResponse{ + ID: t.ID, + Name: t.Name, + Provider: t.Provider, + Description: t.Description, + ExtraHeaders: headers, + BodyOverrideMode: t.BodyOverrideMode, + BodyOverride: t.BodyOverride, + CreatedAt: t.CreatedAt.UTC().Format(time.RFC3339), + UpdatedAt: t.UpdatedAt.UTC().Format(time.RFC3339), + AssociatedMonitors: count, + } +} + +// parseTemplateID 提取并校验 :id。 +func parseTemplateID(c *gin.Context) (int64, bool) { + id, err := strconv.ParseInt(c.Param("id"), 10, 64) + if err != nil || id <= 0 { + response.ErrorFrom(c, infraerrors.BadRequest("INVALID_TEMPLATE_ID", "invalid template id")) + return 0, false + } + return id, true +} + +// --- Handlers --- + +// List GET /api/v1/admin/channel-monitor-templates?provider=anthropic +func (h *ChannelMonitorRequestTemplateHandler) List(c *gin.Context) { + items, err := h.templateService.List(c.Request.Context(), service.ChannelMonitorRequestTemplateListParams{ + Provider: strings.TrimSpace(c.Query("provider")), + }) + if err != nil { + response.ErrorFrom(c, err) + return + } + out := make([]*channelMonitorTemplateResponse, 0, len(items)) + for _, t := range items { + out = append(out, h.toResponse(c, t)) + } + response.Success(c, gin.H{"items": out}) +} + +// Get GET /api/v1/admin/channel-monitor-templates/:id +func (h *ChannelMonitorRequestTemplateHandler) Get(c *gin.Context) { + id, ok := parseTemplateID(c) + if !ok { + return + } + t, err := h.templateService.Get(c.Request.Context(), id) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, h.toResponse(c, t)) +} + +// Create POST /api/v1/admin/channel-monitor-templates +func (h *ChannelMonitorRequestTemplateHandler) Create(c *gin.Context) { + var req channelMonitorTemplateCreateRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.ErrorFrom(c, infraerrors.BadRequest("VALIDATION_ERROR", err.Error())) + return + } + t, err := h.templateService.Create(c.Request.Context(), service.ChannelMonitorRequestTemplateCreateParams{ + Name: req.Name, + Provider: req.Provider, + Description: req.Description, + ExtraHeaders: req.ExtraHeaders, + BodyOverrideMode: req.BodyOverrideMode, + BodyOverride: req.BodyOverride, + }) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Created(c, h.toResponse(c, t)) +} + +// Update PUT /api/v1/admin/channel-monitor-templates/:id +func (h *ChannelMonitorRequestTemplateHandler) Update(c *gin.Context) { + id, ok := parseTemplateID(c) + if !ok { + return + } + var req channelMonitorTemplateUpdateRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.ErrorFrom(c, infraerrors.BadRequest("VALIDATION_ERROR", err.Error())) + return + } + t, err := h.templateService.Update(c.Request.Context(), id, service.ChannelMonitorRequestTemplateUpdateParams{ + Name: req.Name, + Description: req.Description, + ExtraHeaders: req.ExtraHeaders, + BodyOverrideMode: req.BodyOverrideMode, + BodyOverride: req.BodyOverride, + }) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, h.toResponse(c, t)) +} + +// Delete DELETE /api/v1/admin/channel-monitor-templates/:id +func (h *ChannelMonitorRequestTemplateHandler) Delete(c *gin.Context) { + id, ok := parseTemplateID(c) + if !ok { + return + } + if err := h.templateService.Delete(c.Request.Context(), id); err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, nil) +} + +// Apply POST /api/v1/admin/channel-monitor-templates/:id/apply +// 一键把模板当前配置覆盖到所有关联监控上。 +func (h *ChannelMonitorRequestTemplateHandler) Apply(c *gin.Context) { + id, ok := parseTemplateID(c) + if !ok { + return + } + affected, err := h.templateService.ApplyToMonitors(c.Request.Context(), id) + if err != nil { + response.ErrorFrom(c, err) + return + } + response.Success(c, gin.H{"affected": affected}) +} diff --git a/backend/internal/handler/handler.go b/backend/internal/handler/handler.go index 58480c93..bedb81ae 100644 --- a/backend/internal/handler/handler.go +++ b/backend/internal/handler/handler.go @@ -6,33 +6,34 @@ import ( // AdminHandlers contains all admin-related HTTP handlers type AdminHandlers struct { - Dashboard *admin.DashboardHandler - User *admin.UserHandler - Group *admin.GroupHandler - Account *admin.AccountHandler - Announcement *admin.AnnouncementHandler - DataManagement *admin.DataManagementHandler - Backup *admin.BackupHandler - OAuth *admin.OAuthHandler - OpenAIOAuth *admin.OpenAIOAuthHandler - GeminiOAuth *admin.GeminiOAuthHandler - AntigravityOAuth *admin.AntigravityOAuthHandler - Proxy *admin.ProxyHandler - Redeem *admin.RedeemHandler - Promo *admin.PromoHandler - Setting *admin.SettingHandler - Ops *admin.OpsHandler - System *admin.SystemHandler - Subscription *admin.SubscriptionHandler - Usage *admin.UsageHandler - UserAttribute *admin.UserAttributeHandler - ErrorPassthrough *admin.ErrorPassthroughHandler - TLSFingerprintProfile *admin.TLSFingerprintProfileHandler - APIKey *admin.AdminAPIKeyHandler - ScheduledTest *admin.ScheduledTestHandler - Channel *admin.ChannelHandler - ChannelMonitor *admin.ChannelMonitorHandler - Payment *admin.PaymentHandler + Dashboard *admin.DashboardHandler + User *admin.UserHandler + Group *admin.GroupHandler + Account *admin.AccountHandler + Announcement *admin.AnnouncementHandler + DataManagement *admin.DataManagementHandler + Backup *admin.BackupHandler + OAuth *admin.OAuthHandler + OpenAIOAuth *admin.OpenAIOAuthHandler + GeminiOAuth *admin.GeminiOAuthHandler + AntigravityOAuth *admin.AntigravityOAuthHandler + Proxy *admin.ProxyHandler + Redeem *admin.RedeemHandler + Promo *admin.PromoHandler + Setting *admin.SettingHandler + Ops *admin.OpsHandler + System *admin.SystemHandler + Subscription *admin.SubscriptionHandler + Usage *admin.UsageHandler + UserAttribute *admin.UserAttributeHandler + ErrorPassthrough *admin.ErrorPassthroughHandler + TLSFingerprintProfile *admin.TLSFingerprintProfileHandler + APIKey *admin.AdminAPIKeyHandler + ScheduledTest *admin.ScheduledTestHandler + Channel *admin.ChannelHandler + ChannelMonitor *admin.ChannelMonitorHandler + ChannelMonitorTemplate *admin.ChannelMonitorRequestTemplateHandler + Payment *admin.PaymentHandler } // Handlers contains all HTTP handlers diff --git a/backend/internal/handler/wire.go b/backend/internal/handler/wire.go index 7c1a5d1b..6584eb70 100644 --- a/backend/internal/handler/wire.go +++ b/backend/internal/handler/wire.go @@ -35,36 +35,38 @@ func ProvideAdminHandlers( scheduledTestHandler *admin.ScheduledTestHandler, channelHandler *admin.ChannelHandler, channelMonitorHandler *admin.ChannelMonitorHandler, + channelMonitorTemplateHandler *admin.ChannelMonitorRequestTemplateHandler, paymentHandler *admin.PaymentHandler, ) *AdminHandlers { return &AdminHandlers{ - Dashboard: dashboardHandler, - User: userHandler, - Group: groupHandler, - Account: accountHandler, - Announcement: announcementHandler, - DataManagement: dataManagementHandler, - Backup: backupHandler, - OAuth: oauthHandler, - OpenAIOAuth: openaiOAuthHandler, - GeminiOAuth: geminiOAuthHandler, - AntigravityOAuth: antigravityOAuthHandler, - Proxy: proxyHandler, - Redeem: redeemHandler, - Promo: promoHandler, - Setting: settingHandler, - Ops: opsHandler, - System: systemHandler, - Subscription: subscriptionHandler, - Usage: usageHandler, - UserAttribute: userAttributeHandler, - ErrorPassthrough: errorPassthroughHandler, - TLSFingerprintProfile: tlsFingerprintProfileHandler, - APIKey: apiKeyHandler, - ScheduledTest: scheduledTestHandler, - Channel: channelHandler, - ChannelMonitor: channelMonitorHandler, - Payment: paymentHandler, + Dashboard: dashboardHandler, + User: userHandler, + Group: groupHandler, + Account: accountHandler, + Announcement: announcementHandler, + DataManagement: dataManagementHandler, + Backup: backupHandler, + OAuth: oauthHandler, + OpenAIOAuth: openaiOAuthHandler, + GeminiOAuth: geminiOAuthHandler, + AntigravityOAuth: antigravityOAuthHandler, + Proxy: proxyHandler, + Redeem: redeemHandler, + Promo: promoHandler, + Setting: settingHandler, + Ops: opsHandler, + System: systemHandler, + Subscription: subscriptionHandler, + Usage: usageHandler, + UserAttribute: userAttributeHandler, + ErrorPassthrough: errorPassthroughHandler, + TLSFingerprintProfile: tlsFingerprintProfileHandler, + APIKey: apiKeyHandler, + ScheduledTest: scheduledTestHandler, + Channel: channelHandler, + ChannelMonitor: channelMonitorHandler, + ChannelMonitorTemplate: channelMonitorTemplateHandler, + Payment: paymentHandler, } } @@ -162,6 +164,7 @@ var ProviderSet = wire.NewSet( admin.NewScheduledTestHandler, admin.NewChannelHandler, admin.NewChannelMonitorHandler, + admin.NewChannelMonitorRequestTemplateHandler, admin.NewPaymentHandler, // AdminHandlers and Handlers constructors diff --git a/backend/internal/repository/channel_monitor_repo.go b/backend/internal/repository/channel_monitor_repo.go index f4e2a0ec..67dccd6c 100644 --- a/backend/internal/repository/channel_monitor_repo.go +++ b/backend/internal/repository/channel_monitor_repo.go @@ -44,7 +44,15 @@ func (r *channelMonitorRepository) Create(ctx context.Context, m *service.Channe SetGroupName(m.GroupName). SetEnabled(m.Enabled). SetIntervalSeconds(m.IntervalSeconds). - SetCreatedBy(m.CreatedBy) + SetCreatedBy(m.CreatedBy). + SetExtraHeaders(emptyHeadersIfNilRepo(m.ExtraHeaders)). + SetBodyOverrideMode(defaultBodyModeRepo(m.BodyOverrideMode)) + if m.TemplateID != nil { + builder = builder.SetTemplateID(*m.TemplateID) + } + if m.BodyOverride != nil { + builder = builder.SetBodyOverride(m.BodyOverride) + } created, err := builder.Save(ctx) if err != nil { @@ -77,7 +85,19 @@ func (r *channelMonitorRepository) Update(ctx context.Context, m *service.Channe SetExtraModels(emptySliceIfNil(m.ExtraModels)). SetGroupName(m.GroupName). SetEnabled(m.Enabled). - SetIntervalSeconds(m.IntervalSeconds) + SetIntervalSeconds(m.IntervalSeconds). + SetExtraHeaders(emptyHeadersIfNilRepo(m.ExtraHeaders)). + SetBodyOverrideMode(defaultBodyModeRepo(m.BodyOverrideMode)) + if m.TemplateID != nil { + updater = updater.SetTemplateID(*m.TemplateID) + } else { + updater = updater.ClearTemplateID() + } + if m.BodyOverride != nil { + updater = updater.SetBodyOverride(m.BodyOverride) + } else { + updater = updater.ClearBodyOverride() + } updated, err := updater.Save(ctx) if err != nil { @@ -716,22 +736,51 @@ func entToServiceMonitor(row *dbent.ChannelMonitor) *service.ChannelMonitor { if extras == nil { extras = []string{} } - return &service.ChannelMonitor{ - ID: row.ID, - Name: row.Name, - Provider: string(row.Provider), - Endpoint: row.Endpoint, - APIKey: row.APIKeyEncrypted, // 仍为密文,service 层负责解密 - PrimaryModel: row.PrimaryModel, - ExtraModels: extras, - GroupName: row.GroupName, - Enabled: row.Enabled, - IntervalSeconds: row.IntervalSeconds, - LastCheckedAt: row.LastCheckedAt, - CreatedBy: row.CreatedBy, - CreatedAt: row.CreatedAt, - UpdatedAt: row.UpdatedAt, + headers := row.ExtraHeaders + if headers == nil { + headers = map[string]string{} } + out := &service.ChannelMonitor{ + ID: row.ID, + Name: row.Name, + Provider: string(row.Provider), + Endpoint: row.Endpoint, + APIKey: row.APIKeyEncrypted, // 仍为密文,service 层负责解密 + PrimaryModel: row.PrimaryModel, + ExtraModels: extras, + GroupName: row.GroupName, + Enabled: row.Enabled, + IntervalSeconds: row.IntervalSeconds, + LastCheckedAt: row.LastCheckedAt, + CreatedBy: row.CreatedBy, + CreatedAt: row.CreatedAt, + UpdatedAt: row.UpdatedAt, + ExtraHeaders: headers, + BodyOverrideMode: row.BodyOverrideMode, + BodyOverride: row.BodyOverride, + } + if row.TemplateID != nil { + id := *row.TemplateID + out.TemplateID = &id + } + return out +} + +// emptyHeadersIfNilRepo 与 service.emptyHeadersIfNil 功能一致, +// repo 独立一份避免 import 循环。 +func emptyHeadersIfNilRepo(h map[string]string) map[string]string { + if h == nil { + return map[string]string{} + } + return h +} + +// defaultBodyModeRepo 空串归一为 off(同上不循环)。 +func defaultBodyModeRepo(mode string) string { + if mode == "" { + return "off" + } + return mode } func emptySliceIfNil(in []string) []string { diff --git a/backend/internal/repository/channel_monitor_template_repo.go b/backend/internal/repository/channel_monitor_template_repo.go new file mode 100644 index 00000000..03f3692b --- /dev/null +++ b/backend/internal/repository/channel_monitor_template_repo.go @@ -0,0 +1,168 @@ +package repository + +import ( + "context" + "database/sql" + "fmt" + + dbent "github.com/Wei-Shaw/sub2api/ent" + "github.com/Wei-Shaw/sub2api/ent/channelmonitor" + "github.com/Wei-Shaw/sub2api/ent/channelmonitorrequesttemplate" + "github.com/Wei-Shaw/sub2api/internal/service" +) + +// channelMonitorRequestTemplateRepository 实现 service.ChannelMonitorRequestTemplateRepository。 +// 与 channelMonitorRepository 分开一个文件,职责清晰。 +type channelMonitorRequestTemplateRepository struct { + client *dbent.Client + db *sql.DB +} + +// NewChannelMonitorRequestTemplateRepository 创建模板仓储实例。 +func NewChannelMonitorRequestTemplateRepository(client *dbent.Client, db *sql.DB) service.ChannelMonitorRequestTemplateRepository { + return &channelMonitorRequestTemplateRepository{client: client, db: db} +} + +// ---------- CRUD ---------- + +func (r *channelMonitorRequestTemplateRepository) Create(ctx context.Context, t *service.ChannelMonitorRequestTemplate) error { + client := clientFromContext(ctx, r.client) + builder := client.ChannelMonitorRequestTemplate.Create(). + SetName(t.Name). + SetProvider(channelmonitorrequesttemplate.Provider(t.Provider)). + SetDescription(t.Description). + SetExtraHeaders(emptyHeadersIfNilRepo(t.ExtraHeaders)). + SetBodyOverrideMode(defaultBodyModeRepo(t.BodyOverrideMode)) + if t.BodyOverride != nil { + builder = builder.SetBodyOverride(t.BodyOverride) + } + + created, err := builder.Save(ctx) + if err != nil { + return translatePersistenceError(err, service.ErrChannelMonitorTemplateNotFound, nil) + } + t.ID = created.ID + t.CreatedAt = created.CreatedAt + t.UpdatedAt = created.UpdatedAt + return nil +} + +func (r *channelMonitorRequestTemplateRepository) GetByID(ctx context.Context, id int64) (*service.ChannelMonitorRequestTemplate, error) { + row, err := r.client.ChannelMonitorRequestTemplate.Query(). + Where(channelmonitorrequesttemplate.IDEQ(id)). + Only(ctx) + if err != nil { + return nil, translatePersistenceError(err, service.ErrChannelMonitorTemplateNotFound, nil) + } + return entToServiceTemplate(row), nil +} + +func (r *channelMonitorRequestTemplateRepository) Update(ctx context.Context, t *service.ChannelMonitorRequestTemplate) error { + client := clientFromContext(ctx, r.client) + updater := client.ChannelMonitorRequestTemplate.UpdateOneID(t.ID). + SetName(t.Name). + SetDescription(t.Description). + SetExtraHeaders(emptyHeadersIfNilRepo(t.ExtraHeaders)). + SetBodyOverrideMode(defaultBodyModeRepo(t.BodyOverrideMode)) + if t.BodyOverride != nil { + updater = updater.SetBodyOverride(t.BodyOverride) + } else { + updater = updater.ClearBodyOverride() + } + updated, err := updater.Save(ctx) + if err != nil { + return translatePersistenceError(err, service.ErrChannelMonitorTemplateNotFound, nil) + } + t.UpdatedAt = updated.UpdatedAt + return nil +} + +func (r *channelMonitorRequestTemplateRepository) Delete(ctx context.Context, id int64) error { + client := clientFromContext(ctx, r.client) + if err := client.ChannelMonitorRequestTemplate.DeleteOneID(id).Exec(ctx); err != nil { + return translatePersistenceError(err, service.ErrChannelMonitorTemplateNotFound, nil) + } + return nil +} + +func (r *channelMonitorRequestTemplateRepository) List(ctx context.Context, params service.ChannelMonitorRequestTemplateListParams) ([]*service.ChannelMonitorRequestTemplate, error) { + q := r.client.ChannelMonitorRequestTemplate.Query() + if params.Provider != "" { + q = q.Where(channelmonitorrequesttemplate.ProviderEQ(channelmonitorrequesttemplate.Provider(params.Provider))) + } + rows, err := q. + Order(dbent.Asc(channelmonitorrequesttemplate.FieldProvider), dbent.Asc(channelmonitorrequesttemplate.FieldName)). + All(ctx) + if err != nil { + return nil, fmt.Errorf("list monitor templates: %w", err) + } + out := make([]*service.ChannelMonitorRequestTemplate, 0, len(rows)) + for _, row := range rows { + out = append(out, entToServiceTemplate(row)) + } + return out, nil +} + +// ApplyToMonitors 把模板当前配置批量覆盖到 template_id = id 的监控上。 +// +// 用一条 UPDATE 完成:extra_headers / body_override_mode / body_override 都覆盖。 +// 走 ent 的 UpdateMany 保证走 ent hooks;走原生 SQL 也可以但 ent jsonb 序列化更省心。 +func (r *channelMonitorRequestTemplateRepository) ApplyToMonitors(ctx context.Context, id int64) (int64, error) { + client := clientFromContext(ctx, r.client) + tpl, err := client.ChannelMonitorRequestTemplate.Query(). + Where(channelmonitorrequesttemplate.IDEQ(id)). + Only(ctx) + if err != nil { + return 0, translatePersistenceError(err, service.ErrChannelMonitorTemplateNotFound, nil) + } + + updater := client.ChannelMonitor.Update(). + Where(channelmonitor.TemplateIDEQ(id)). + SetExtraHeaders(emptyHeadersIfNilRepo(tpl.ExtraHeaders)). + SetBodyOverrideMode(defaultBodyModeRepo(tpl.BodyOverrideMode)) + if tpl.BodyOverride != nil { + updater = updater.SetBodyOverride(tpl.BodyOverride) + } else { + updater = updater.ClearBodyOverride() + } + + affected, err := updater.Save(ctx) + if err != nil { + return 0, fmt.Errorf("apply template to monitors: %w", err) + } + return int64(affected), nil +} + +// CountAssociatedMonitors 统计关联监控数(UI 展示「N 个配置」用)。 +func (r *channelMonitorRequestTemplateRepository) CountAssociatedMonitors(ctx context.Context, id int64) (int64, error) { + count, err := r.client.ChannelMonitor.Query(). + Where(channelmonitor.TemplateIDEQ(id)). + Count(ctx) + if err != nil { + return 0, fmt.Errorf("count monitors for template %d: %w", id, err) + } + return int64(count), nil +} + +// ---------- helpers ---------- + +func entToServiceTemplate(row *dbent.ChannelMonitorRequestTemplate) *service.ChannelMonitorRequestTemplate { + if row == nil { + return nil + } + headers := row.ExtraHeaders + if headers == nil { + headers = map[string]string{} + } + return &service.ChannelMonitorRequestTemplate{ + ID: row.ID, + Name: row.Name, + Provider: string(row.Provider), + Description: row.Description, + ExtraHeaders: headers, + BodyOverrideMode: row.BodyOverrideMode, + BodyOverride: row.BodyOverride, + CreatedAt: row.CreatedAt, + UpdatedAt: row.UpdatedAt, + } +} diff --git a/backend/internal/repository/wire.go b/backend/internal/repository/wire.go index 7427cd04..b1d5e36a 100644 --- a/backend/internal/repository/wire.go +++ b/backend/internal/repository/wire.go @@ -90,6 +90,7 @@ var ProviderSet = wire.NewSet( NewTLSFingerprintProfileRepository, NewChannelRepository, NewChannelMonitorRepository, + NewChannelMonitorRequestTemplateRepository, // Cache implementations NewGatewayCache, diff --git a/backend/internal/server/routes/admin.go b/backend/internal/server/routes/admin.go index 0381dc57..13cecd59 100644 --- a/backend/internal/server/routes/admin.go +++ b/backend/internal/server/routes/admin.go @@ -579,4 +579,14 @@ func registerChannelMonitorRoutes(admin *gin.RouterGroup, h *handler.Handlers) { monitors.POST("/:id/run", h.Admin.ChannelMonitor.Run) monitors.GET("/:id/history", h.Admin.ChannelMonitor.History) } + + templates := admin.Group("/channel-monitor-templates") + { + templates.GET("", h.Admin.ChannelMonitorTemplate.List) + templates.POST("", h.Admin.ChannelMonitorTemplate.Create) + templates.GET("/:id", h.Admin.ChannelMonitorTemplate.Get) + templates.PUT("/:id", h.Admin.ChannelMonitorTemplate.Update) + templates.DELETE("/:id", h.Admin.ChannelMonitorTemplate.Delete) + templates.POST("/:id/apply", h.Admin.ChannelMonitorTemplate.Apply) + } } diff --git a/backend/internal/service/channel_monitor_checker.go b/backend/internal/service/channel_monitor_checker.go index e03c2e3a..33570629 100644 --- a/backend/internal/service/channel_monitor_checker.go +++ b/backend/internal/service/channel_monitor_checker.go @@ -37,9 +37,23 @@ func newSSRFSafeHTTPClient(timeout time.Duration) *http.Client { return &http.Client{Timeout: timeout, Transport: tr} } +// CheckOptions 承载一次检测的自定义入参。 +// 所有字段都是可选(零值即等价于"用默认行为")。 +type CheckOptions struct { + // ExtraHeaders 用户自定义 HTTP 头(merge 到 adapter 默认 headers,用户优先)。 + ExtraHeaders map[string]string + // BodyOverrideMode: off | merge | replace + BodyOverrideMode string + // BodyOverride 在 merge 模式下做浅合并(key 命中黑名单时静默丢弃), + // 在 replace 模式下直接当作完整 body。 + BodyOverride map[string]any +} + // runCheckForModel 对单个 (provider, model) 做一次完整检测。 // 不返回 error:所有失败都包装进 CheckResult.Status=error/failed。 -func runCheckForModel(ctx context.Context, provider, endpoint, apiKey, model string) *CheckResult { +// +// opts 承载模板 / 监控快照带来的自定义配置。nil 等同于 "off + 无 extra headers"。 +func runCheckForModel(ctx context.Context, provider, endpoint, apiKey, model string, opts *CheckOptions) *CheckResult { res := &CheckResult{ Model: model, Status: MonitorStatusError, @@ -47,9 +61,10 @@ func runCheckForModel(ctx context.Context, provider, endpoint, apiKey, model str } challenge := generateChallenge() + mode := bodyOverrideMode(opts) start := time.Now() - respText, rawBody, statusCode, err := callProvider(ctx, provider, endpoint, apiKey, model, challenge.Prompt) + respText, rawBody, statusCode, err := callProvider(ctx, provider, endpoint, apiKey, model, challenge.Prompt, opts) latency := time.Since(start) latencyMs := int(latency / time.Millisecond) res.LatencyMs = &latencyMs @@ -68,22 +83,47 @@ func runCheckForModel(ctx context.Context, provider, endpoint, apiKey, model str return res } + // Replace 模式:跳过 challenge 校验(用户 body 是静态的,challenge 没法嵌入)。 + // 改用「HTTP 2xx + 响应文本(adapter.textPath 抽取)非空」作为 operational 判定。 + // 响应文本为空则降级为 failed(视为上游回了 200 但没实际内容)。 + if mode == MonitorBodyOverrideModeReplace { + if strings.TrimSpace(respText) == "" { + res.Status = MonitorStatusFailed + res.Message = truncateMessage("replace-mode: upstream returned 2xx with empty text") + return res + } + return finalizeOperationalOrDegraded(res, latency, latencyMs) + } + if !validateChallenge(respText, challenge.Expected) { res.Status = MonitorStatusFailed res.Message = truncateMessage(sanitizeErrorMessage(fmt.Sprintf("challenge mismatch (expected %s, got %q)", challenge.Expected, respText))) return res } + return finalizeOperationalOrDegraded(res, latency, latencyMs) +} + +// finalizeOperationalOrDegraded 负责走到最后一步的 operational/degraded 判定。 +// 拆出来是为了让 runCheckForModel 不超过 30 行。 +func finalizeOperationalOrDegraded(res *CheckResult, latency time.Duration, latencyMs int) *CheckResult { if latency >= monitorDegradedThreshold { res.Status = MonitorStatusDegraded res.Message = truncateMessage(fmt.Sprintf("slow response: %dms", latencyMs)) return res } - res.Status = MonitorStatusOperational return res } +// bodyOverrideMode 归一取 opts.BodyOverrideMode,nil opts / 空串都视为 off。 +func bodyOverrideMode(opts *CheckOptions) string { + if opts == nil || opts.BodyOverrideMode == "" { + return MonitorBodyOverrideModeOff + } + return opts.BodyOverrideMode +} + // pingEndpointOrigin 对 endpoint 的 origin (scheme://host) 发起 HEAD 请求,返回耗时。 // 失败时返回 nil(不影响主状态判定)。 func pingEndpointOrigin(ctx context.Context, endpoint string) *int { @@ -183,29 +223,109 @@ func isSupportedProvider(p string) bool { } // callProvider 通过 providerAdapters 分发到具体实现。 +// opts 承载用户的自定义 headers / body 覆盖(可为 nil)。 // // 返回值: // - extractedText: 按 textPath 抽出的成功文本,仅在 status 2xx 时有意义;非 2xx 时通常为空串 // - rawBody: 完整响应体的字符串形式(已被 monitorResponseMaxBytes 截断),用于错误路径保留上游真实回包 // - status: HTTP 状态码 // - err: 网络 / 序列化错误 -func callProvider(ctx context.Context, provider, endpoint, apiKey, model, prompt string) (extractedText, rawBody string, status int, err error) { +func callProvider(ctx context.Context, provider, endpoint, apiKey, model, prompt string, opts *CheckOptions) (extractedText, rawBody string, status int, err error) { adapter, ok := providerAdapters[provider] if !ok { return "", "", 0, fmt.Errorf("unsupported provider %q", provider) } - body, err := adapter.buildBody(model, prompt) + body, err := buildRequestBody(adapter, provider, model, prompt, opts) if err != nil { - return "", "", 0, fmt.Errorf("marshal body: %w", err) + return "", "", 0, err } + headers := mergeHeaders(adapter.buildHeaders(apiKey), opts) full := joinURL(endpoint, adapter.buildPath(model)) - respBytes, status, err := postRawJSON(ctx, full, body, adapter.buildHeaders(apiKey)) + respBytes, status, err := postRawJSON(ctx, full, body, headers) if err != nil { return "", "", status, err } return gjson.GetBytes(respBytes, adapter.textPath).String(), string(respBytes), status, nil } +// mergeHeaders 把用户自定义 headers 合并到 adapter 默认 headers 上。 +// 用户值覆盖默认;命中黑名单(hop-by-hop / 由 http.Client 自管的)的 key 静默丢弃。 +func mergeHeaders(base map[string]string, opts *CheckOptions) map[string]string { + if opts == nil || len(opts.ExtraHeaders) == 0 { + return base + } + out := make(map[string]string, len(base)+len(opts.ExtraHeaders)) + for k, v := range base { + out[k] = v + } + for k, v := range opts.ExtraHeaders { + if IsForbiddenHeaderName(k) { + continue + } + out[k] = v + } + return out +} + +// buildRequestBody 根据 body_override_mode 构造请求 body。 +// +// - off: adapter 默认 body +// - merge: adapter 默认 body 与 BodyOverride 浅合并;BodyOverride 中命中 +// bodyMergeKeyDenyList[provider] 的 key 会被静默丢弃,避免破坏 challenge / model 路由 +// - replace: 直接 marshal BodyOverride 作为完整 body +// +// 任何 mode 返回的 []byte 都已经是合法 JSON,可直接送入 postRawJSON。 +func buildRequestBody(adapter providerAdapter, provider, model, prompt string, opts *CheckOptions) ([]byte, error) { + mode := bodyOverrideMode(opts) + + if mode == MonitorBodyOverrideModeReplace { + if opts == nil || len(opts.BodyOverride) == 0 { + return nil, fmt.Errorf("replace mode: body_override is empty") + } + body, err := json.Marshal(opts.BodyOverride) + if err != nil { + return nil, fmt.Errorf("marshal body_override (replace): %w", err) + } + return body, nil + } + + defaultBody, err := adapter.buildBody(model, prompt) + if err != nil { + return nil, fmt.Errorf("marshal default body: %w", err) + } + if mode != MonitorBodyOverrideModeMerge || opts == nil || len(opts.BodyOverride) == 0 { + return defaultBody, nil + } + + var defaultMap map[string]any + if err := json.Unmarshal(defaultBody, &defaultMap); err != nil { + return nil, fmt.Errorf("unmarshal default body for merge: %w", err) + } + deny := bodyMergeKeyDenyList[provider] + for k, v := range opts.BodyOverride { + if deny[k] { + continue + } + defaultMap[k] = v + } + merged, err := json.Marshal(defaultMap) + if err != nil { + return nil, fmt.Errorf("marshal merged body: %w", err) + } + return merged, nil +} + +// bodyMergeKeyDenyList 在 merge 模式下,禁止用户覆盖这些 provider-specific 的关键字段。 +// 思路抄 check-cx 的 EXCLUDED_METADATA_KEYS:保护 challenge / model 路由不被用户误伤。 +// 用户想动这些字段就用 replace 模式(已知会跳 challenge 校验)。 +// +//nolint:gochecknoglobals // 静态查表,初始化后不变。 +var bodyMergeKeyDenyList = map[string]map[string]bool{ + MonitorProviderOpenAI: {"model": true, "messages": true, "stream": true}, + MonitorProviderAnthropic: {"model": true, "messages": true}, + MonitorProviderGemini: {"contents": true}, +} + // postRawJSON 发送 POST + 已序列化好的 JSON 字节,限制响应体大小,返回响应字节、HTTP status、错误。 // adapter 自行 marshal 是为了精确控制字段顺序与类型,所以这里直接收 []byte 而不是 any。 func postRawJSON(ctx context.Context, fullURL string, payload []byte, headers map[string]string) ([]byte, int, error) { diff --git a/backend/internal/service/channel_monitor_checker_body_test.go b/backend/internal/service/channel_monitor_checker_body_test.go new file mode 100644 index 00000000..323cf8b7 --- /dev/null +++ b/backend/internal/service/channel_monitor_checker_body_test.go @@ -0,0 +1,173 @@ +//go:build unit + +package service + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" +) + +// swapMonitorHTTPClient 临时替换 monitorHTTPClient 为不带 SSRF 校验的普通 client, +// 让 httptest (127.0.0.1) 能连通。测试结束后恢复。 +func swapMonitorHTTPClient(t *testing.T) { + t.Helper() + orig := monitorHTTPClient + monitorHTTPClient = &http.Client{Timeout: 5 * time.Second} + t.Cleanup(func() { monitorHTTPClient = orig }) +} + +// captureHandler 把每次收到的请求 body 和 headers 存起来,测试断言用。 +type captureHandler struct { + lastBody map[string]any + lastHeaders http.Header + respondText string // 写到 Anthropic content[0].text 里(校验用) + status int +} + +func (h *captureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + h.lastHeaders = r.Header.Clone() + defer func() { _ = r.Body.Close() }() + var parsed map[string]any + _ = json.NewDecoder(r.Body).Decode(&parsed) + h.lastBody = parsed + + if h.status == 0 { + h.status = 200 + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(h.status) + // 构造 Anthropic 格式的响应:content[0].text = h.respondText + _ = json.NewEncoder(w).Encode(map[string]any{ + "content": []map[string]any{ + {"type": "text", "text": h.respondText}, + }, + }) +} + +func setupFakeAnthropic(t *testing.T, handler *captureHandler) string { + t.Helper() + swapMonitorHTTPClient(t) + srv := httptest.NewServer(handler) + t.Cleanup(srv.Close) + return srv.URL +} + +func TestRunCheckForModel_OffMode_PreservesDefaultBody(t *testing.T) { + h := &captureHandler{respondText: "the answer is 42"} + endpoint := setupFakeAnthropic(t, h) + + // 跑一次 off 模式(opts=nil),确认默认 body 行为未变 + _ = runCheckForModel(context.Background(), MonitorProviderAnthropic, endpoint, "sk-fake", "claude-x", nil) + + if h.lastBody["model"] != "claude-x" { + t.Errorf("default body should contain model=claude-x, got %v", h.lastBody["model"]) + } + if _, ok := h.lastBody["messages"]; !ok { + t.Error("default body should contain messages") + } + if h.lastHeaders.Get("x-api-key") != "sk-fake" { + t.Errorf("expected adapter's x-api-key header, got %q", h.lastHeaders.Get("x-api-key")) + } +} + +func TestRunCheckForModel_MergeMode_UserFieldsWinButDenyListProtects(t *testing.T) { + h := &captureHandler{respondText: "the answer is 42"} + endpoint := setupFakeAnthropic(t, h) + + opts := &CheckOptions{ + BodyOverrideMode: MonitorBodyOverrideModeMerge, + BodyOverride: map[string]any{ + "system": "You are Claude Code...", + "max_tokens": float64(999), // 应该覆盖默认 50 + "model": "hacked-model", // 应该被黑名单挡住,保留原 model + "messages": []any{}, // 同上,被挡 + }, + ExtraHeaders: map[string]string{ + "User-Agent": "claude-cli/1.0", + "Content-Length": "999", // 黑名单 + "x-custom": "ok", + }, + } + _ = runCheckForModel(context.Background(), MonitorProviderAnthropic, endpoint, "sk-fake", "claude-x", opts) + + if h.lastBody["system"] != "You are Claude Code..." { + t.Errorf("merge mode should inject system, got %v", h.lastBody["system"]) + } + // max_tokens 覆盖生效 + if mt, ok := h.lastBody["max_tokens"].(float64); !ok || mt != 999 { + t.Errorf("merge mode should override max_tokens to 999, got %v", h.lastBody["max_tokens"]) + } + // model 在黑名单 — 应该保留默认值 + if h.lastBody["model"] != "claude-x" { + t.Errorf("model should be protected by deny list, got %v", h.lastBody["model"]) + } + // messages 在黑名单 — 应该保留默认值(非空) + msgs, _ := h.lastBody["messages"].([]any) + if len(msgs) == 0 { + t.Error("messages should be protected by deny list (kept default, non-empty)") + } + // header 合并 + if h.lastHeaders.Get("User-Agent") != "claude-cli/1.0" { + t.Errorf("extra User-Agent should override, got %q", h.lastHeaders.Get("User-Agent")) + } + if h.lastHeaders.Get("x-custom") != "ok" { + t.Errorf("extra custom header should be present, got %q", h.lastHeaders.Get("x-custom")) + } + // Content-Length 黑名单:会被 net/http 自动重算,但不应由用户的 "999" 决定。 + // 我们无法直接断言丢弃(http.Client 总会填上),只断言请求成功即可。 +} + +func TestRunCheckForModel_ReplaceMode_FullBodyUsedAndChallengeSkipped(t *testing.T) { + // replace 模式下我们的 body 完全自定义,challenge 数学题不会出现在请求里, + // 上游也不会回正确答案 — 但只要 2xx + 响应文本非空,就算 operational + h := &captureHandler{respondText: "any non-empty text"} + endpoint := setupFakeAnthropic(t, h) + + userBody := map[string]any{ + "model": "user-forced-model", + "messages": []any{map[string]any{"role": "user", "content": "hi"}}, + "max_tokens": float64(10), + "system": "You are someone else", + } + opts := &CheckOptions{ + BodyOverrideMode: MonitorBodyOverrideModeReplace, + BodyOverride: userBody, + } + res := runCheckForModel(context.Background(), MonitorProviderAnthropic, endpoint, "sk-fake", "claude-x", opts) + + // 请求 body = 用户提供的原样 + if h.lastBody["model"] != "user-forced-model" { + t.Errorf("replace mode should use user's model, got %v", h.lastBody["model"]) + } + if h.lastBody["system"] != "You are someone else" { + t.Errorf("replace mode should use user's system, got %v", h.lastBody["system"]) + } + // challenge 虽然没命中,但由于 replace 模式跳过 challenge 校验 + 响应非空 → operational + if res.Status != MonitorStatusOperational { + t.Errorf("replace mode with 2xx + non-empty text should be operational, got status=%s message=%q", + res.Status, res.Message) + } +} + +func TestRunCheckForModel_ReplaceMode_EmptyResponseIsFailed(t *testing.T) { + h := &captureHandler{respondText: ""} // 上游 200 但 content[0].text 为空 + endpoint := setupFakeAnthropic(t, h) + + opts := &CheckOptions{ + BodyOverrideMode: MonitorBodyOverrideModeReplace, + BodyOverride: map[string]any{"model": "x", "messages": []any{}}, + } + res := runCheckForModel(context.Background(), MonitorProviderAnthropic, endpoint, "sk-fake", "claude-x", opts) + + if res.Status != MonitorStatusFailed { + t.Errorf("replace mode with empty text should be failed, got status=%s", res.Status) + } + if !strings.Contains(res.Message, "replace-mode") { + t.Errorf("failure message should hint replace-mode, got %q", res.Message) + } +} diff --git a/backend/internal/service/channel_monitor_service.go b/backend/internal/service/channel_monitor_service.go index 144c66a0..ec1107a3 100644 --- a/backend/internal/service/channel_monitor_service.go +++ b/backend/internal/service/channel_monitor_service.go @@ -104,21 +104,31 @@ func (s *ChannelMonitorService) Create(ctx context.Context, p ChannelMonitorCrea if err := validateCreateParams(p); err != nil { return nil, err } + if err := validateBodyModeParams(p.BodyOverrideMode, p.BodyOverride); err != nil { + return nil, err + } + if err := validateExtraHeaders(p.ExtraHeaders); err != nil { + return nil, err + } encrypted, err := s.encryptor.Encrypt(p.APIKey) if err != nil { return nil, fmt.Errorf("encrypt api key: %w", err) } m := &ChannelMonitor{ - Name: strings.TrimSpace(p.Name), - Provider: p.Provider, - Endpoint: normalizeEndpoint(p.Endpoint), - APIKey: encrypted, // 注意:传入 repository 时该字段为密文 - PrimaryModel: strings.TrimSpace(p.PrimaryModel), - ExtraModels: normalizeModels(p.ExtraModels), - GroupName: strings.TrimSpace(p.GroupName), - Enabled: p.Enabled, - IntervalSeconds: p.IntervalSeconds, - CreatedBy: p.CreatedBy, + Name: strings.TrimSpace(p.Name), + Provider: p.Provider, + Endpoint: normalizeEndpoint(p.Endpoint), + APIKey: encrypted, // 注意:传入 repository 时该字段为密文 + PrimaryModel: strings.TrimSpace(p.PrimaryModel), + ExtraModels: normalizeModels(p.ExtraModels), + GroupName: strings.TrimSpace(p.GroupName), + Enabled: p.Enabled, + IntervalSeconds: p.IntervalSeconds, + CreatedBy: p.CreatedBy, + TemplateID: p.TemplateID, + ExtraHeaders: emptyHeadersIfNil(p.ExtraHeaders), + BodyOverrideMode: defaultBodyMode(p.BodyOverrideMode), + BodyOverride: p.BodyOverride, } if err := s.repo.Create(ctx, m); err != nil { return nil, fmt.Errorf("create channel monitor: %w", err) @@ -272,12 +282,19 @@ func (s *ChannelMonitorService) runChecksConcurrent(ctx context.Context, m *Chan // ping 共享一次,所有模型记录同一个 ping 延迟。 pingMs := pingEndpointOrigin(ctx, m.Endpoint) + // 所有模型共用同一份 CheckOptions(来自监控的快照字段)。 + opts := &CheckOptions{ + ExtraHeaders: m.ExtraHeaders, + BodyOverrideMode: m.BodyOverrideMode, + BodyOverride: m.BodyOverride, + } + var eg errgroup.Group var mu sync.Mutex for i, model := range models { i, model := i, model eg.Go(func() error { - r := runCheckForModel(ctx, m.Provider, m.Endpoint, m.APIKey, model) + r := runCheckForModel(ctx, m.Provider, m.Endpoint, m.APIKey, model, opts) r.PingLatencyMs = pingMs mu.Lock() results[i] = r @@ -476,5 +493,38 @@ func applyMonitorUpdate(existing *ChannelMonitor, p ChannelMonitorUpdateParams) } existing.IntervalSeconds = *p.IntervalSeconds } + return applyMonitorAdvancedUpdate(existing, p) +} + +// applyMonitorAdvancedUpdate 处理自定义请求快照相关字段,从 applyMonitorUpdate 拆出避免过长。 +func applyMonitorAdvancedUpdate(existing *ChannelMonitor, p ChannelMonitorUpdateParams) error { + if p.ClearTemplate { + existing.TemplateID = nil + } else if p.TemplateID != nil { + id := *p.TemplateID + existing.TemplateID = &id + } + if p.ExtraHeaders != nil { + if err := validateExtraHeaders(*p.ExtraHeaders); err != nil { + return err + } + existing.ExtraHeaders = emptyHeadersIfNil(*p.ExtraHeaders) + } + // BodyOverrideMode / BodyOverride 联合校验,和模板一致。 + newMode := existing.BodyOverrideMode + newBody := existing.BodyOverride + if p.BodyOverrideMode != nil { + newMode = *p.BodyOverrideMode + } + if p.BodyOverride != nil { + newBody = *p.BodyOverride + } + if p.BodyOverrideMode != nil || p.BodyOverride != nil { + if err := validateBodyModeParams(newMode, newBody); err != nil { + return err + } + existing.BodyOverrideMode = defaultBodyMode(newMode) + existing.BodyOverride = newBody + } return nil } diff --git a/backend/internal/service/channel_monitor_template_service.go b/backend/internal/service/channel_monitor_template_service.go new file mode 100644 index 00000000..98fc930b --- /dev/null +++ b/backend/internal/service/channel_monitor_template_service.go @@ -0,0 +1,225 @@ +package service + +import ( + "context" + "fmt" + "regexp" + "strings" +) + +// ChannelMonitorRequestTemplateRepository 模板数据访问接口。 +type ChannelMonitorRequestTemplateRepository interface { + Create(ctx context.Context, t *ChannelMonitorRequestTemplate) error + GetByID(ctx context.Context, id int64) (*ChannelMonitorRequestTemplate, error) + Update(ctx context.Context, t *ChannelMonitorRequestTemplate) error + Delete(ctx context.Context, id int64) error + List(ctx context.Context, params ChannelMonitorRequestTemplateListParams) ([]*ChannelMonitorRequestTemplate, error) + // ApplyToMonitors 把模板当前的 extra_headers / body_override_mode / body_override + // 批量覆盖到所有 template_id = id 的监控上。返回被覆盖的监控数量。 + ApplyToMonitors(ctx context.Context, id int64) (int64, error) + // CountAssociatedMonitors 统计 template_id = id 的监控数(用于 UI 展示「应用到 N 个配置」)。 + CountAssociatedMonitors(ctx context.Context, id int64) (int64, error) +} + +// ChannelMonitorRequestTemplateService 模板管理 service。 +type ChannelMonitorRequestTemplateService struct { + repo ChannelMonitorRequestTemplateRepository +} + +// NewChannelMonitorRequestTemplateService 创建模板 service。 +func NewChannelMonitorRequestTemplateService(repo ChannelMonitorRequestTemplateRepository) *ChannelMonitorRequestTemplateService { + return &ChannelMonitorRequestTemplateService{repo: repo} +} + +// ---------- CRUD ---------- + +// List 按 provider 过滤(空串 = 全部),不分页(模板量级小)。 +func (s *ChannelMonitorRequestTemplateService) List(ctx context.Context, params ChannelMonitorRequestTemplateListParams) ([]*ChannelMonitorRequestTemplate, error) { + if params.Provider != "" { + if err := validateProvider(params.Provider); err != nil { + return nil, err + } + } + return s.repo.List(ctx, params) +} + +// Get 返回单个模板。 +func (s *ChannelMonitorRequestTemplateService) Get(ctx context.Context, id int64) (*ChannelMonitorRequestTemplate, error) { + return s.repo.GetByID(ctx, id) +} + +// Create 创建模板(会校验 headers 黑名单和 body 模式匹配)。 +func (s *ChannelMonitorRequestTemplateService) Create(ctx context.Context, p ChannelMonitorRequestTemplateCreateParams) (*ChannelMonitorRequestTemplate, error) { + if err := validateTemplateCreateParams(p); err != nil { + return nil, err + } + t := &ChannelMonitorRequestTemplate{ + Name: strings.TrimSpace(p.Name), + Provider: p.Provider, + Description: strings.TrimSpace(p.Description), + ExtraHeaders: emptyHeadersIfNil(p.ExtraHeaders), + BodyOverrideMode: defaultBodyMode(p.BodyOverrideMode), + BodyOverride: p.BodyOverride, + } + if err := s.repo.Create(ctx, t); err != nil { + return nil, fmt.Errorf("create template: %w", err) + } + return t, nil +} + +// Update 更新模板(provider 不可改)。 +func (s *ChannelMonitorRequestTemplateService) Update(ctx context.Context, id int64, p ChannelMonitorRequestTemplateUpdateParams) (*ChannelMonitorRequestTemplate, error) { + existing, err := s.repo.GetByID(ctx, id) + if err != nil { + return nil, err + } + if err := applyTemplateUpdate(existing, p); err != nil { + return nil, err + } + if err := s.repo.Update(ctx, existing); err != nil { + return nil, fmt.Errorf("update template: %w", err) + } + return existing, nil +} + +// Delete 删除模板。关联监控的 template_id 会被 SET NULL,监控保留快照继续跑。 +func (s *ChannelMonitorRequestTemplateService) Delete(ctx context.Context, id int64) error { + if err := s.repo.Delete(ctx, id); err != nil { + return fmt.Errorf("delete template: %w", err) + } + return nil +} + +// ApplyToMonitors 把模板当前配置一键应用到所有关联监控。 +// 返回被影响的监控数。 +func (s *ChannelMonitorRequestTemplateService) ApplyToMonitors(ctx context.Context, id int64) (int64, error) { + if _, err := s.repo.GetByID(ctx, id); err != nil { + return 0, err + } + affected, err := s.repo.ApplyToMonitors(ctx, id) + if err != nil { + return 0, fmt.Errorf("apply template to monitors: %w", err) + } + return affected, nil +} + +// CountAssociatedMonitors 返回关联监控数。 +func (s *ChannelMonitorRequestTemplateService) CountAssociatedMonitors(ctx context.Context, id int64) (int64, error) { + return s.repo.CountAssociatedMonitors(ctx, id) +} + +// ---------- 校验 & 工具 ---------- + +// validateTemplateCreateParams 聚合 create 入参校验,避免函数超过 30 行。 +func validateTemplateCreateParams(p ChannelMonitorRequestTemplateCreateParams) error { + if strings.TrimSpace(p.Name) == "" { + return ErrChannelMonitorTemplateMissingName + } + if err := validateProvider(p.Provider); err != nil { + return ErrChannelMonitorTemplateInvalidProvider + } + if err := validateBodyModeParams(p.BodyOverrideMode, p.BodyOverride); err != nil { + return err + } + if err := validateExtraHeaders(p.ExtraHeaders); err != nil { + return err + } + return nil +} + +// applyTemplateUpdate 把 update params 中非 nil 字段应用到 existing 上。 +func applyTemplateUpdate(existing *ChannelMonitorRequestTemplate, p ChannelMonitorRequestTemplateUpdateParams) error { + if p.Name != nil { + name := strings.TrimSpace(*p.Name) + if name == "" { + return ErrChannelMonitorTemplateMissingName + } + existing.Name = name + } + if p.Description != nil { + existing.Description = strings.TrimSpace(*p.Description) + } + if p.ExtraHeaders != nil { + if err := validateExtraHeaders(*p.ExtraHeaders); err != nil { + return err + } + existing.ExtraHeaders = emptyHeadersIfNil(*p.ExtraHeaders) + } + // BodyOverrideMode / BodyOverride 联合校验:任一变化都用「更新后的值」做校验。 + newMode := existing.BodyOverrideMode + newBody := existing.BodyOverride + if p.BodyOverrideMode != nil { + newMode = *p.BodyOverrideMode + } + if p.BodyOverride != nil { + newBody = *p.BodyOverride + } + if err := validateBodyModeParams(newMode, newBody); err != nil { + return err + } + existing.BodyOverrideMode = defaultBodyMode(newMode) + existing.BodyOverride = newBody + return nil +} + +// validateBodyModeParams 校验 body_override_mode 合法,且 merge/replace 模式下 body_override 非空。 +func validateBodyModeParams(mode string, body map[string]any) error { + switch mode { + case "", MonitorBodyOverrideModeOff: + return nil + case MonitorBodyOverrideModeMerge, MonitorBodyOverrideModeReplace: + if len(body) == 0 { + return ErrChannelMonitorTemplateBodyRequired + } + return nil + default: + return ErrChannelMonitorTemplateInvalidBodyMode + } +} + +// headerNameRegex 合法 header 名:RFC 7230 token(ASCII 可见字符减特殊符号)。 +var headerNameRegex = regexp.MustCompile(`^[A-Za-z0-9!#$%&'*+\-.^_` + "`" + `|~]+$`) + +// forbiddenHeaderNames hop-by-hop + HTTP 客户端自管的 header;禁止用户覆盖, +// 否则会让 Go http.Client 行为异常(双重 Content-Length、连接复用错乱等)。 +var forbiddenHeaderNames = map[string]bool{ + "host": true, + "content-length": true, + "content-encoding": true, + "transfer-encoding": true, + "connection": true, +} + +// IsForbiddenHeaderName 对外暴露,checker 运行时也会再过滤一次做兜底。 +func IsForbiddenHeaderName(name string) bool { + return forbiddenHeaderNames[strings.ToLower(strings.TrimSpace(name))] +} + +// validateExtraHeaders 校验 header 名字格式 + 黑名单。保存时就拒绝非法 header,早失败。 +func validateExtraHeaders(h map[string]string) error { + for k := range h { + if !headerNameRegex.MatchString(k) { + return ErrChannelMonitorTemplateHeaderInvalidName + } + if IsForbiddenHeaderName(k) { + return ErrChannelMonitorTemplateHeaderForbidden + } + } + return nil +} + +// emptyHeadersIfNil 把 nil map 归一成空 map(repo 层写库时 JSONB 需要非 nil)。 +func emptyHeadersIfNil(h map[string]string) map[string]string { + if h == nil { + return map[string]string{} + } + return h +} + +// defaultBodyMode 空串归一为 off。 +func defaultBodyMode(mode string) string { + if mode == "" { + return MonitorBodyOverrideModeOff + } + return mode +} diff --git a/backend/internal/service/channel_monitor_template_types.go b/backend/internal/service/channel_monitor_template_types.go new file mode 100644 index 00000000..a6e2bb59 --- /dev/null +++ b/backend/internal/service/channel_monitor_template_types.go @@ -0,0 +1,74 @@ +package service + +import ( + infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" + "time" +) + +// ChannelMonitorRequestTemplate 请求模板(service 层模型)。 +// 作用:把一组可复用的 headers + 可选 body 覆盖配置抽出来管理, +// 被监控「应用」时以快照方式拷贝到监控本身的同名字段。 +type ChannelMonitorRequestTemplate struct { + ID int64 + Name string + Provider string + Description string + ExtraHeaders map[string]string + BodyOverrideMode string + BodyOverride map[string]any + CreatedAt time.Time + UpdatedAt time.Time +} + +// ChannelMonitorRequestTemplateListParams 列表过滤。 +type ChannelMonitorRequestTemplateListParams struct { + Provider string // 空 = 全部;非空则按 provider 过滤 +} + +// ChannelMonitorRequestTemplateCreateParams 创建参数。 +type ChannelMonitorRequestTemplateCreateParams struct { + Name string + Provider string + Description string + ExtraHeaders map[string]string + BodyOverrideMode string + BodyOverride map[string]any +} + +// ChannelMonitorRequestTemplateUpdateParams 更新参数(指针字段 = 不修改)。 +// 注意 Provider 不可修改:改 provider 会让已关联监控的 body 黑名单语义错乱。 +type ChannelMonitorRequestTemplateUpdateParams struct { + Name *string + Description *string + ExtraHeaders *map[string]string + BodyOverrideMode *string + BodyOverride *map[string]any +} + +// 模板相关错误(命名与现有 ErrChannelMonitor* 风格保持一致)。 +var ( + ErrChannelMonitorTemplateNotFound = infraerrors.NotFound( + "CHANNEL_MONITOR_TEMPLATE_NOT_FOUND", "channel monitor request template not found", + ) + ErrChannelMonitorTemplateInvalidProvider = infraerrors.BadRequest( + "CHANNEL_MONITOR_TEMPLATE_INVALID_PROVIDER", "template provider must be one of openai/anthropic/gemini", + ) + ErrChannelMonitorTemplateMissingName = infraerrors.BadRequest( + "CHANNEL_MONITOR_TEMPLATE_MISSING_NAME", "template name is required", + ) + ErrChannelMonitorTemplateInvalidBodyMode = infraerrors.BadRequest( + "CHANNEL_MONITOR_TEMPLATE_INVALID_BODY_MODE", "body_override_mode must be one of off/merge/replace", + ) + ErrChannelMonitorTemplateBodyRequired = infraerrors.BadRequest( + "CHANNEL_MONITOR_TEMPLATE_BODY_REQUIRED", "body_override is required when body_override_mode is merge or replace", + ) + ErrChannelMonitorTemplateHeaderForbidden = infraerrors.BadRequest( + "CHANNEL_MONITOR_TEMPLATE_HEADER_FORBIDDEN", "header name is forbidden (hop-by-hop or computed by HTTP client)", + ) + ErrChannelMonitorTemplateHeaderInvalidName = infraerrors.BadRequest( + "CHANNEL_MONITOR_TEMPLATE_HEADER_INVALID_NAME", "header name contains invalid characters", + ) + ErrChannelMonitorTemplateProviderMismatch = infraerrors.BadRequest( + "CHANNEL_MONITOR_TEMPLATE_PROVIDER_MISMATCH", "monitor provider does not match template provider", + ) +) diff --git a/backend/internal/service/channel_monitor_types.go b/backend/internal/service/channel_monitor_types.go index 739c82fb..b797a89b 100644 --- a/backend/internal/service/channel_monitor_types.go +++ b/backend/internal/service/channel_monitor_types.go @@ -2,6 +2,19 @@ package service import "time" +// MonitorBodyOverrideMode 自定义请求体处理模式。 +// +// - off 使用 adapter 默认 body(忽略 BodyOverride) +// - merge adapter 默认 body 与 BodyOverride 浅合并(用户优先; +// model/messages/contents 等关键字段在 checker 黑名单内会被静默丢弃) +// - replace 完全用 BodyOverride 作为 body;跳过 challenge 校验, +// 改成 HTTP 2xx + 响应非空即视为可用(用户负责构造 body) +const ( + MonitorBodyOverrideModeOff = "off" + MonitorBodyOverrideModeMerge = "merge" + MonitorBodyOverrideModeReplace = "replace" +) + // ChannelMonitor 渠道监控配置(service 层模型,不直接暴露 ent 类型)。 type ChannelMonitor struct { ID int64 @@ -19,6 +32,12 @@ type ChannelMonitor struct { CreatedAt time.Time UpdatedAt time.Time + // 请求自定义快照(来自模板拷贝 or 用户手填,运行时直接读取) + TemplateID *int64 // 仅用于 UI 分组 + 一键应用,运行时不用 + ExtraHeaders map[string]string // 与 adapter 默认 headers 合并,用户优先 + BodyOverrideMode string // off / merge / replace + BodyOverride map[string]any // 仅 mode != off 时使用 + // APIKeyDecryptFailed 表示 APIKey 字段无法解密(密钥不一致或损坏)。 // 此时 APIKey 为空字符串,runner / RunCheck 必须跳过该监控并提示重填。 APIKeyDecryptFailed bool @@ -35,16 +54,20 @@ type ChannelMonitorListParams struct { // ChannelMonitorCreateParams 创建参数。 type ChannelMonitorCreateParams struct { - Name string - Provider string - Endpoint string - APIKey string - PrimaryModel string - ExtraModels []string - GroupName string - Enabled bool - IntervalSeconds int - CreatedBy int64 + Name string + Provider string + Endpoint string + APIKey string + PrimaryModel string + ExtraModels []string + GroupName string + Enabled bool + IntervalSeconds int + CreatedBy int64 + TemplateID *int64 + ExtraHeaders map[string]string + BodyOverrideMode string + BodyOverride map[string]any } // ChannelMonitorUpdateParams 更新参数(指针字段表示"未提供则不更新")。 @@ -58,6 +81,14 @@ type ChannelMonitorUpdateParams struct { GroupName *string Enabled *bool IntervalSeconds *int + // 自定义快照字段:指针为 nil 表示不更新,非 nil 覆盖 + // TemplateID *(*int64):用 ** 表达三态:nil=不更新;&nil=清空;&&id=设为 id。 + // 简化处理:用 ClearTemplate 显式标志 + TemplateID(普通指针) + TemplateID *int64 + ClearTemplate bool // true 时无视 TemplateID,把监控的 template_id 置空 + ExtraHeaders *map[string]string + BodyOverrideMode *string + BodyOverride *map[string]any } // CheckResult 单个模型一次检测的结果。 diff --git a/backend/internal/service/wire.go b/backend/internal/service/wire.go index 1482d650..3148f865 100644 --- a/backend/internal/service/wire.go +++ b/backend/internal/service/wire.go @@ -472,6 +472,7 @@ var ProviderSet = wire.NewSet( ProvideBalanceNotifyService, ProvideChannelMonitorService, ProvideChannelMonitorRunner, + NewChannelMonitorRequestTemplateService, ) // ProvidePaymentConfigService wraps NewPaymentConfigService to accept the named diff --git a/backend/migrations/128_add_channel_monitor_request_templates.sql b/backend/migrations/128_add_channel_monitor_request_templates.sql new file mode 100644 index 00000000..2db8fef6 --- /dev/null +++ b/backend/migrations/128_add_channel_monitor_request_templates.sql @@ -0,0 +1,70 @@ +-- Migration: 128_add_channel_monitor_request_templates +-- 加请求模板表 + 给 channel_monitors 加 4 个快照字段(template_id 关联引用 + extra_headers / +-- body_override_mode / body_override 三个真正运行时使用的快照)。 +-- +-- 设计要点: +-- 1) 模板与监控之间是「应用即拷贝」的快照语义,运行时 checker 不再回查模板表。 +-- 模板 UPDATE 不会自动影响监控;只有用户主动「应用到关联监控」才会刷新快照。 +-- 2) ON DELETE SET NULL:模板删除不级联清理监控;监控保留快照继续工作。 +-- 3) extra_headers / body_override 都是 JSONB;body_override_mode 用 varchar(不是 enum) +-- 便于将来加新模式无需 ALTER TYPE。 +-- 4) 同一 provider 内模板 name 唯一(允许 Anthropic + OpenAI 重名 "伪装官方客户端")。 + +CREATE TABLE IF NOT EXISTS channel_monitor_request_templates ( + id BIGSERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + provider VARCHAR(20) NOT NULL, + description VARCHAR(500) NOT NULL DEFAULT '', + extra_headers JSONB NOT NULL DEFAULT '{}'::jsonb, + body_override_mode VARCHAR(10) NOT NULL DEFAULT 'off', + body_override JSONB NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + CONSTRAINT channel_monitor_request_templates_provider_check + CHECK (provider IN ('openai', 'anthropic', 'gemini')), + CONSTRAINT channel_monitor_request_templates_body_mode_check + CHECK (body_override_mode IN ('off', 'merge', 'replace')) +); + +CREATE UNIQUE INDEX IF NOT EXISTS channel_monitor_request_templates_provider_name + ON channel_monitor_request_templates (provider, name); + +-- channel_monitors 加 4 列(ADD COLUMN IF NOT EXISTS 需要 PG 9.6+,生产使用 PG 16) +ALTER TABLE channel_monitors + ADD COLUMN IF NOT EXISTS template_id BIGINT NULL; +ALTER TABLE channel_monitors + ADD COLUMN IF NOT EXISTS extra_headers JSONB NOT NULL DEFAULT '{}'::jsonb; +ALTER TABLE channel_monitors + ADD COLUMN IF NOT EXISTS body_override_mode VARCHAR(10) NOT NULL DEFAULT 'off'; +ALTER TABLE channel_monitors + ADD COLUMN IF NOT EXISTS body_override JSONB NULL; + +-- 约束 + 外键(DO 块里 IF NOT EXISTS 判断,保证幂等) +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'channel_monitors_body_mode_check' + AND table_name = 'channel_monitors' + ) THEN + ALTER TABLE channel_monitors + ADD CONSTRAINT channel_monitors_body_mode_check + CHECK (body_override_mode IN ('off', 'merge', 'replace')); + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'channel_monitors_template_id_fkey' + AND table_name = 'channel_monitors' + ) THEN + ALTER TABLE channel_monitors + ADD CONSTRAINT channel_monitors_template_id_fkey + FOREIGN KEY (template_id) + REFERENCES channel_monitor_request_templates (id) + ON DELETE SET NULL; + END IF; +END $$; + +CREATE INDEX IF NOT EXISTS idx_channel_monitors_template_id + ON channel_monitors (template_id) + WHERE template_id IS NOT NULL; diff --git a/frontend/src/api/admin/channelMonitor.ts b/frontend/src/api/admin/channelMonitor.ts index d9cc6aed..949c4bc8 100644 --- a/frontend/src/api/admin/channelMonitor.ts +++ b/frontend/src/api/admin/channelMonitor.ts @@ -7,6 +7,7 @@ import { apiClient } from '../client' export type Provider = 'openai' | 'anthropic' | 'gemini' export type MonitorStatus = 'operational' | 'degraded' | 'failed' | 'error' +export type BodyOverrideMode = 'off' | 'merge' | 'replace' export interface ChannelMonitor { id: number @@ -37,6 +38,11 @@ export interface ChannelMonitor { availability_7d: number /** Latest status per extra model (used for hover tooltip) */ extra_models_status: ExtraModelStatus[] + /** 请求自定义快照字段(高级设置) */ + template_id: number | null + extra_headers: Record + body_override_mode: BodyOverrideMode + body_override: Record | null } export interface ExtraModelStatus { @@ -71,10 +77,16 @@ export interface CreateParams { group_name?: string enabled?: boolean interval_seconds: number + template_id?: number | null + extra_headers?: Record + body_override_mode?: BodyOverrideMode + body_override?: Record | null } -// Update request: api_key empty string means "do not modify" -export type UpdateParams = Partial +// Update request: api_key 空串 = 不修改;clear_template=true 时把 template_id 置空 +export type UpdateParams = Partial & { + clear_template?: boolean +} export interface CheckResult { model: string diff --git a/frontend/src/api/admin/channelMonitorTemplate.ts b/frontend/src/api/admin/channelMonitorTemplate.ts new file mode 100644 index 00000000..258adab8 --- /dev/null +++ b/frontend/src/api/admin/channelMonitorTemplate.ts @@ -0,0 +1,108 @@ +/** + * Admin Channel Monitor Request Template API. + * + * 模板 = 一组可复用的 headers + 可选 body 覆盖配置。 + * 应用到监控 = 拷贝快照;模板后续变动不自动同步,需手动点「应用到关联监控」刷新。 + */ + +import { apiClient } from '../client' +import type { BodyOverrideMode, Provider } from './channelMonitor' + +export interface ChannelMonitorTemplate { + id: number + name: string + provider: Provider + description: string + extra_headers: Record + body_override_mode: BodyOverrideMode + body_override: Record | null + created_at: string + updated_at: string + /** 关联的监控数量(快照来自此模板,仅 template_id 匹配即可) */ + associated_monitors: number +} + +export interface ListParams { + provider?: Provider +} + +export interface ListResponse { + items: ChannelMonitorTemplate[] +} + +export interface CreateParams { + name: string + provider: Provider + description?: string + extra_headers?: Record + body_override_mode?: BodyOverrideMode + body_override?: Record | null +} + +export interface UpdateParams { + name?: string + description?: string + extra_headers?: Record + body_override_mode?: BodyOverrideMode + body_override?: Record | null +} + +export interface ApplyResponse { + affected: number +} + +export async function list(params: ListParams = {}): Promise { + const { data } = await apiClient.get('/admin/channel-monitor-templates', { + params, + }) + return data +} + +export async function get(id: number): Promise { + const { data } = await apiClient.get( + `/admin/channel-monitor-templates/${id}`, + ) + return data +} + +export async function create(params: CreateParams): Promise { + const { data } = await apiClient.post( + '/admin/channel-monitor-templates', + params, + ) + return data +} + +export async function update(id: number, params: UpdateParams): Promise { + const { data } = await apiClient.put( + `/admin/channel-monitor-templates/${id}`, + params, + ) + return data +} + +export async function del(id: number): Promise { + await apiClient.delete(`/admin/channel-monitor-templates/${id}`) +} + +/** + * Apply the template to all associated monitors (overwrite snapshot fields). + * Returns count of affected monitors. + */ +export async function apply(id: number): Promise { + const { data } = await apiClient.post( + `/admin/channel-monitor-templates/${id}/apply`, + ) + return data +} + +export const channelMonitorTemplateAPI = { + list, + get, + create, + update, + del, + apply, +} + +export default channelMonitorTemplateAPI diff --git a/frontend/src/api/admin/index.ts b/frontend/src/api/admin/index.ts index 5e2a9959..9cda5814 100644 --- a/frontend/src/api/admin/index.ts +++ b/frontend/src/api/admin/index.ts @@ -27,6 +27,7 @@ import backupAPI from './backup' import tlsFingerprintProfileAPI from './tlsFingerprintProfile' import channelsAPI from './channels' import channelMonitorAPI from './channelMonitor' +import channelMonitorTemplateAPI from './channelMonitorTemplate' import adminPaymentAPI from './payment' /** @@ -57,6 +58,7 @@ export const adminAPI = { tlsFingerprintProfiles: tlsFingerprintProfileAPI, channels: channelsAPI, channelMonitor: channelMonitorAPI, + channelMonitorTemplate: channelMonitorTemplateAPI, payment: adminPaymentAPI } @@ -85,6 +87,7 @@ export { tlsFingerprintProfileAPI, channelsAPI, channelMonitorAPI, + channelMonitorTemplateAPI, adminPaymentAPI } diff --git a/frontend/src/components/admin/monitor/MonitorAdvancedRequestConfig.vue b/frontend/src/components/admin/monitor/MonitorAdvancedRequestConfig.vue new file mode 100644 index 00000000..24827316 --- /dev/null +++ b/frontend/src/components/admin/monitor/MonitorAdvancedRequestConfig.vue @@ -0,0 +1,205 @@ +