Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
31fe0178
Commit
31fe0178
authored
Feb 03, 2026
by
yangjianbo
Browse files
Merge branch 'main' of
https://github.com/mt21625457/aicodex2api
parents
d9e345f2
ba5a0d47
Changes
235
Hide whitespace changes
Inline
Side-by-side
backend/ent/schema/user_subscription.go
View file @
31fe0178
...
@@ -4,7 +4,7 @@ import (
...
@@ -4,7 +4,7 @@ import (
"time"
"time"
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"github.com/Wei-Shaw/sub2api/ent/schema/mixins"
"github.com/Wei-Shaw/sub2api/internal/
service
"
"github.com/Wei-Shaw/sub2api/internal/
domain
"
"entgo.io/ent"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect"
...
@@ -44,7 +44,7 @@ func (UserSubscription) Fields() []ent.Field {
...
@@ -44,7 +44,7 @@ func (UserSubscription) Fields() []ent.Field {
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"timestamptz"
}),
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"timestamptz"
}),
field
.
String
(
"status"
)
.
field
.
String
(
"status"
)
.
MaxLen
(
20
)
.
MaxLen
(
20
)
.
Default
(
service
.
SubscriptionStatusActive
),
Default
(
domain
.
SubscriptionStatusActive
),
field
.
Time
(
"daily_window_start"
)
.
field
.
Time
(
"daily_window_start"
)
.
Optional
()
.
Optional
()
.
...
...
backend/ent/tx.go
View file @
31fe0178
...
@@ -20,6 +20,10 @@ type Tx struct {
...
@@ -20,6 +20,10 @@ type Tx struct {
Account
*
AccountClient
Account
*
AccountClient
// AccountGroup is the client for interacting with the AccountGroup builders.
// AccountGroup is the client for interacting with the AccountGroup builders.
AccountGroup
*
AccountGroupClient
AccountGroup
*
AccountGroupClient
// Announcement is the client for interacting with the Announcement builders.
Announcement
*
AnnouncementClient
// AnnouncementRead is the client for interacting with the AnnouncementRead builders.
AnnouncementRead
*
AnnouncementReadClient
// Group is the client for interacting with the Group builders.
// Group is the client for interacting with the Group builders.
Group
*
GroupClient
Group
*
GroupClient
// PromoCode is the client for interacting with the PromoCode builders.
// PromoCode is the client for interacting with the PromoCode builders.
...
@@ -180,6 +184,8 @@ func (tx *Tx) init() {
...
@@ -180,6 +184,8 @@ func (tx *Tx) init() {
tx
.
APIKey
=
NewAPIKeyClient
(
tx
.
config
)
tx
.
APIKey
=
NewAPIKeyClient
(
tx
.
config
)
tx
.
Account
=
NewAccountClient
(
tx
.
config
)
tx
.
Account
=
NewAccountClient
(
tx
.
config
)
tx
.
AccountGroup
=
NewAccountGroupClient
(
tx
.
config
)
tx
.
AccountGroup
=
NewAccountGroupClient
(
tx
.
config
)
tx
.
Announcement
=
NewAnnouncementClient
(
tx
.
config
)
tx
.
AnnouncementRead
=
NewAnnouncementReadClient
(
tx
.
config
)
tx
.
Group
=
NewGroupClient
(
tx
.
config
)
tx
.
Group
=
NewGroupClient
(
tx
.
config
)
tx
.
PromoCode
=
NewPromoCodeClient
(
tx
.
config
)
tx
.
PromoCode
=
NewPromoCodeClient
(
tx
.
config
)
tx
.
PromoCodeUsage
=
NewPromoCodeUsageClient
(
tx
.
config
)
tx
.
PromoCodeUsage
=
NewPromoCodeUsageClient
(
tx
.
config
)
...
...
backend/ent/user.go
View file @
31fe0178
...
@@ -39,6 +39,12 @@ type User struct {
...
@@ -39,6 +39,12 @@ type User struct {
Username
string
`json:"username,omitempty"`
Username
string
`json:"username,omitempty"`
// Notes holds the value of the "notes" field.
// Notes holds the value of the "notes" field.
Notes
string
`json:"notes,omitempty"`
Notes
string
`json:"notes,omitempty"`
// TotpSecretEncrypted holds the value of the "totp_secret_encrypted" field.
TotpSecretEncrypted
*
string
`json:"totp_secret_encrypted,omitempty"`
// TotpEnabled holds the value of the "totp_enabled" field.
TotpEnabled
bool
`json:"totp_enabled,omitempty"`
// TotpEnabledAt holds the value of the "totp_enabled_at" field.
TotpEnabledAt
*
time
.
Time
`json:"totp_enabled_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the UserQuery when eager-loading is set.
// The values are being populated by the UserQuery when eager-loading is set.
Edges
UserEdges
`json:"edges"`
Edges
UserEdges
`json:"edges"`
...
@@ -55,6 +61,8 @@ type UserEdges struct {
...
@@ -55,6 +61,8 @@ type UserEdges struct {
Subscriptions
[]
*
UserSubscription
`json:"subscriptions,omitempty"`
Subscriptions
[]
*
UserSubscription
`json:"subscriptions,omitempty"`
// AssignedSubscriptions holds the value of the assigned_subscriptions edge.
// AssignedSubscriptions holds the value of the assigned_subscriptions edge.
AssignedSubscriptions
[]
*
UserSubscription
`json:"assigned_subscriptions,omitempty"`
AssignedSubscriptions
[]
*
UserSubscription
`json:"assigned_subscriptions,omitempty"`
// AnnouncementReads holds the value of the announcement_reads edge.
AnnouncementReads
[]
*
AnnouncementRead
`json:"announcement_reads,omitempty"`
// AllowedGroups holds the value of the allowed_groups edge.
// AllowedGroups holds the value of the allowed_groups edge.
AllowedGroups
[]
*
Group
`json:"allowed_groups,omitempty"`
AllowedGroups
[]
*
Group
`json:"allowed_groups,omitempty"`
// UsageLogs holds the value of the usage_logs edge.
// UsageLogs holds the value of the usage_logs edge.
...
@@ -67,7 +75,7 @@ type UserEdges struct {
...
@@ -67,7 +75,7 @@ type UserEdges struct {
UserAllowedGroups
[]
*
UserAllowedGroup
`json:"user_allowed_groups,omitempty"`
UserAllowedGroups
[]
*
UserAllowedGroup
`json:"user_allowed_groups,omitempty"`
// loadedTypes holds the information for reporting if a
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
// type was loaded (or requested) in eager-loading or not.
loadedTypes
[
9
]
bool
loadedTypes
[
10
]
bool
}
}
// APIKeysOrErr returns the APIKeys value or an error if the edge
// APIKeysOrErr returns the APIKeys value or an error if the edge
...
@@ -106,10 +114,19 @@ func (e UserEdges) AssignedSubscriptionsOrErr() ([]*UserSubscription, error) {
...
@@ -106,10 +114,19 @@ func (e UserEdges) AssignedSubscriptionsOrErr() ([]*UserSubscription, error) {
return
nil
,
&
NotLoadedError
{
edge
:
"assigned_subscriptions"
}
return
nil
,
&
NotLoadedError
{
edge
:
"assigned_subscriptions"
}
}
}
// AnnouncementReadsOrErr returns the AnnouncementReads value or an error if the edge
// was not loaded in eager-loading.
func
(
e
UserEdges
)
AnnouncementReadsOrErr
()
([]
*
AnnouncementRead
,
error
)
{
if
e
.
loadedTypes
[
4
]
{
return
e
.
AnnouncementReads
,
nil
}
return
nil
,
&
NotLoadedError
{
edge
:
"announcement_reads"
}
}
// AllowedGroupsOrErr returns the AllowedGroups value or an error if the edge
// AllowedGroupsOrErr returns the AllowedGroups value or an error if the edge
// was not loaded in eager-loading.
// was not loaded in eager-loading.
func
(
e
UserEdges
)
AllowedGroupsOrErr
()
([]
*
Group
,
error
)
{
func
(
e
UserEdges
)
AllowedGroupsOrErr
()
([]
*
Group
,
error
)
{
if
e
.
loadedTypes
[
4
]
{
if
e
.
loadedTypes
[
5
]
{
return
e
.
AllowedGroups
,
nil
return
e
.
AllowedGroups
,
nil
}
}
return
nil
,
&
NotLoadedError
{
edge
:
"allowed_groups"
}
return
nil
,
&
NotLoadedError
{
edge
:
"allowed_groups"
}
...
@@ -118,7 +135,7 @@ func (e UserEdges) AllowedGroupsOrErr() ([]*Group, error) {
...
@@ -118,7 +135,7 @@ func (e UserEdges) AllowedGroupsOrErr() ([]*Group, error) {
// UsageLogsOrErr returns the UsageLogs value or an error if the edge
// UsageLogsOrErr returns the UsageLogs value or an error if the edge
// was not loaded in eager-loading.
// was not loaded in eager-loading.
func
(
e
UserEdges
)
UsageLogsOrErr
()
([]
*
UsageLog
,
error
)
{
func
(
e
UserEdges
)
UsageLogsOrErr
()
([]
*
UsageLog
,
error
)
{
if
e
.
loadedTypes
[
5
]
{
if
e
.
loadedTypes
[
6
]
{
return
e
.
UsageLogs
,
nil
return
e
.
UsageLogs
,
nil
}
}
return
nil
,
&
NotLoadedError
{
edge
:
"usage_logs"
}
return
nil
,
&
NotLoadedError
{
edge
:
"usage_logs"
}
...
@@ -127,7 +144,7 @@ func (e UserEdges) UsageLogsOrErr() ([]*UsageLog, error) {
...
@@ -127,7 +144,7 @@ func (e UserEdges) UsageLogsOrErr() ([]*UsageLog, error) {
// AttributeValuesOrErr returns the AttributeValues value or an error if the edge
// AttributeValuesOrErr returns the AttributeValues value or an error if the edge
// was not loaded in eager-loading.
// was not loaded in eager-loading.
func
(
e
UserEdges
)
AttributeValuesOrErr
()
([]
*
UserAttributeValue
,
error
)
{
func
(
e
UserEdges
)
AttributeValuesOrErr
()
([]
*
UserAttributeValue
,
error
)
{
if
e
.
loadedTypes
[
6
]
{
if
e
.
loadedTypes
[
7
]
{
return
e
.
AttributeValues
,
nil
return
e
.
AttributeValues
,
nil
}
}
return
nil
,
&
NotLoadedError
{
edge
:
"attribute_values"
}
return
nil
,
&
NotLoadedError
{
edge
:
"attribute_values"
}
...
@@ -136,7 +153,7 @@ func (e UserEdges) AttributeValuesOrErr() ([]*UserAttributeValue, error) {
...
@@ -136,7 +153,7 @@ func (e UserEdges) AttributeValuesOrErr() ([]*UserAttributeValue, error) {
// PromoCodeUsagesOrErr returns the PromoCodeUsages value or an error if the edge
// PromoCodeUsagesOrErr returns the PromoCodeUsages value or an error if the edge
// was not loaded in eager-loading.
// was not loaded in eager-loading.
func
(
e
UserEdges
)
PromoCodeUsagesOrErr
()
([]
*
PromoCodeUsage
,
error
)
{
func
(
e
UserEdges
)
PromoCodeUsagesOrErr
()
([]
*
PromoCodeUsage
,
error
)
{
if
e
.
loadedTypes
[
7
]
{
if
e
.
loadedTypes
[
8
]
{
return
e
.
PromoCodeUsages
,
nil
return
e
.
PromoCodeUsages
,
nil
}
}
return
nil
,
&
NotLoadedError
{
edge
:
"promo_code_usages"
}
return
nil
,
&
NotLoadedError
{
edge
:
"promo_code_usages"
}
...
@@ -145,7 +162,7 @@ func (e UserEdges) PromoCodeUsagesOrErr() ([]*PromoCodeUsage, error) {
...
@@ -145,7 +162,7 @@ func (e UserEdges) PromoCodeUsagesOrErr() ([]*PromoCodeUsage, error) {
// UserAllowedGroupsOrErr returns the UserAllowedGroups value or an error if the edge
// UserAllowedGroupsOrErr returns the UserAllowedGroups value or an error if the edge
// was not loaded in eager-loading.
// was not loaded in eager-loading.
func
(
e
UserEdges
)
UserAllowedGroupsOrErr
()
([]
*
UserAllowedGroup
,
error
)
{
func
(
e
UserEdges
)
UserAllowedGroupsOrErr
()
([]
*
UserAllowedGroup
,
error
)
{
if
e
.
loadedTypes
[
8
]
{
if
e
.
loadedTypes
[
9
]
{
return
e
.
UserAllowedGroups
,
nil
return
e
.
UserAllowedGroups
,
nil
}
}
return
nil
,
&
NotLoadedError
{
edge
:
"user_allowed_groups"
}
return
nil
,
&
NotLoadedError
{
edge
:
"user_allowed_groups"
}
...
@@ -156,13 +173,15 @@ func (*User) scanValues(columns []string) ([]any, error) {
...
@@ -156,13 +173,15 @@ func (*User) scanValues(columns []string) ([]any, error) {
values
:=
make
([]
any
,
len
(
columns
))
values
:=
make
([]
any
,
len
(
columns
))
for
i
:=
range
columns
{
for
i
:=
range
columns
{
switch
columns
[
i
]
{
switch
columns
[
i
]
{
case
user
.
FieldTotpEnabled
:
values
[
i
]
=
new
(
sql
.
NullBool
)
case
user
.
FieldBalance
:
case
user
.
FieldBalance
:
values
[
i
]
=
new
(
sql
.
NullFloat64
)
values
[
i
]
=
new
(
sql
.
NullFloat64
)
case
user
.
FieldID
,
user
.
FieldConcurrency
:
case
user
.
FieldID
,
user
.
FieldConcurrency
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
values
[
i
]
=
new
(
sql
.
NullInt64
)
case
user
.
FieldEmail
,
user
.
FieldPasswordHash
,
user
.
FieldRole
,
user
.
FieldStatus
,
user
.
FieldUsername
,
user
.
FieldNotes
:
case
user
.
FieldEmail
,
user
.
FieldPasswordHash
,
user
.
FieldRole
,
user
.
FieldStatus
,
user
.
FieldUsername
,
user
.
FieldNotes
,
user
.
FieldTotpSecretEncrypted
:
values
[
i
]
=
new
(
sql
.
NullString
)
values
[
i
]
=
new
(
sql
.
NullString
)
case
user
.
FieldCreatedAt
,
user
.
FieldUpdatedAt
,
user
.
FieldDeletedAt
:
case
user
.
FieldCreatedAt
,
user
.
FieldUpdatedAt
,
user
.
FieldDeletedAt
,
user
.
FieldTotpEnabledAt
:
values
[
i
]
=
new
(
sql
.
NullTime
)
values
[
i
]
=
new
(
sql
.
NullTime
)
default
:
default
:
values
[
i
]
=
new
(
sql
.
UnknownType
)
values
[
i
]
=
new
(
sql
.
UnknownType
)
...
@@ -252,6 +271,26 @@ func (_m *User) assignValues(columns []string, values []any) error {
...
@@ -252,6 +271,26 @@ func (_m *User) assignValues(columns []string, values []any) error {
}
else
if
value
.
Valid
{
}
else
if
value
.
Valid
{
_m
.
Notes
=
value
.
String
_m
.
Notes
=
value
.
String
}
}
case
user
.
FieldTotpSecretEncrypted
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullString
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field totp_secret_encrypted"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
TotpSecretEncrypted
=
new
(
string
)
*
_m
.
TotpSecretEncrypted
=
value
.
String
}
case
user
.
FieldTotpEnabled
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullBool
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field totp_enabled"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
TotpEnabled
=
value
.
Bool
}
case
user
.
FieldTotpEnabledAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field totp_enabled_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
TotpEnabledAt
=
new
(
time
.
Time
)
*
_m
.
TotpEnabledAt
=
value
.
Time
}
default
:
default
:
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
}
}
...
@@ -285,6 +324,11 @@ func (_m *User) QueryAssignedSubscriptions() *UserSubscriptionQuery {
...
@@ -285,6 +324,11 @@ func (_m *User) QueryAssignedSubscriptions() *UserSubscriptionQuery {
return
NewUserClient
(
_m
.
config
)
.
QueryAssignedSubscriptions
(
_m
)
return
NewUserClient
(
_m
.
config
)
.
QueryAssignedSubscriptions
(
_m
)
}
}
// QueryAnnouncementReads queries the "announcement_reads" edge of the User entity.
func
(
_m
*
User
)
QueryAnnouncementReads
()
*
AnnouncementReadQuery
{
return
NewUserClient
(
_m
.
config
)
.
QueryAnnouncementReads
(
_m
)
}
// QueryAllowedGroups queries the "allowed_groups" edge of the User entity.
// QueryAllowedGroups queries the "allowed_groups" edge of the User entity.
func
(
_m
*
User
)
QueryAllowedGroups
()
*
GroupQuery
{
func
(
_m
*
User
)
QueryAllowedGroups
()
*
GroupQuery
{
return
NewUserClient
(
_m
.
config
)
.
QueryAllowedGroups
(
_m
)
return
NewUserClient
(
_m
.
config
)
.
QueryAllowedGroups
(
_m
)
...
@@ -367,6 +411,19 @@ func (_m *User) String() string {
...
@@ -367,6 +411,19 @@ func (_m *User) String() string {
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"notes="
)
builder
.
WriteString
(
"notes="
)
builder
.
WriteString
(
_m
.
Notes
)
builder
.
WriteString
(
_m
.
Notes
)
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
TotpSecretEncrypted
;
v
!=
nil
{
builder
.
WriteString
(
"totp_secret_encrypted="
)
builder
.
WriteString
(
*
v
)
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"totp_enabled="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
TotpEnabled
))
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
TotpEnabledAt
;
v
!=
nil
{
builder
.
WriteString
(
"totp_enabled_at="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteByte
(
')'
)
builder
.
WriteByte
(
')'
)
return
builder
.
String
()
return
builder
.
String
()
}
}
...
...
backend/ent/user/user.go
View file @
31fe0178
...
@@ -37,6 +37,12 @@ const (
...
@@ -37,6 +37,12 @@ const (
FieldUsername
=
"username"
FieldUsername
=
"username"
// FieldNotes holds the string denoting the notes field in the database.
// FieldNotes holds the string denoting the notes field in the database.
FieldNotes
=
"notes"
FieldNotes
=
"notes"
// FieldTotpSecretEncrypted holds the string denoting the totp_secret_encrypted field in the database.
FieldTotpSecretEncrypted
=
"totp_secret_encrypted"
// FieldTotpEnabled holds the string denoting the totp_enabled field in the database.
FieldTotpEnabled
=
"totp_enabled"
// FieldTotpEnabledAt holds the string denoting the totp_enabled_at field in the database.
FieldTotpEnabledAt
=
"totp_enabled_at"
// EdgeAPIKeys holds the string denoting the api_keys edge name in mutations.
// EdgeAPIKeys holds the string denoting the api_keys edge name in mutations.
EdgeAPIKeys
=
"api_keys"
EdgeAPIKeys
=
"api_keys"
// EdgeRedeemCodes holds the string denoting the redeem_codes edge name in mutations.
// EdgeRedeemCodes holds the string denoting the redeem_codes edge name in mutations.
...
@@ -45,6 +51,8 @@ const (
...
@@ -45,6 +51,8 @@ const (
EdgeSubscriptions
=
"subscriptions"
EdgeSubscriptions
=
"subscriptions"
// EdgeAssignedSubscriptions holds the string denoting the assigned_subscriptions edge name in mutations.
// EdgeAssignedSubscriptions holds the string denoting the assigned_subscriptions edge name in mutations.
EdgeAssignedSubscriptions
=
"assigned_subscriptions"
EdgeAssignedSubscriptions
=
"assigned_subscriptions"
// EdgeAnnouncementReads holds the string denoting the announcement_reads edge name in mutations.
EdgeAnnouncementReads
=
"announcement_reads"
// EdgeAllowedGroups holds the string denoting the allowed_groups edge name in mutations.
// EdgeAllowedGroups holds the string denoting the allowed_groups edge name in mutations.
EdgeAllowedGroups
=
"allowed_groups"
EdgeAllowedGroups
=
"allowed_groups"
// EdgeUsageLogs holds the string denoting the usage_logs edge name in mutations.
// EdgeUsageLogs holds the string denoting the usage_logs edge name in mutations.
...
@@ -85,6 +93,13 @@ const (
...
@@ -85,6 +93,13 @@ const (
AssignedSubscriptionsInverseTable
=
"user_subscriptions"
AssignedSubscriptionsInverseTable
=
"user_subscriptions"
// AssignedSubscriptionsColumn is the table column denoting the assigned_subscriptions relation/edge.
// AssignedSubscriptionsColumn is the table column denoting the assigned_subscriptions relation/edge.
AssignedSubscriptionsColumn
=
"assigned_by"
AssignedSubscriptionsColumn
=
"assigned_by"
// AnnouncementReadsTable is the table that holds the announcement_reads relation/edge.
AnnouncementReadsTable
=
"announcement_reads"
// AnnouncementReadsInverseTable is the table name for the AnnouncementRead entity.
// It exists in this package in order to avoid circular dependency with the "announcementread" package.
AnnouncementReadsInverseTable
=
"announcement_reads"
// AnnouncementReadsColumn is the table column denoting the announcement_reads relation/edge.
AnnouncementReadsColumn
=
"user_id"
// AllowedGroupsTable is the table that holds the allowed_groups relation/edge. The primary key declared below.
// AllowedGroupsTable is the table that holds the allowed_groups relation/edge. The primary key declared below.
AllowedGroupsTable
=
"user_allowed_groups"
AllowedGroupsTable
=
"user_allowed_groups"
// AllowedGroupsInverseTable is the table name for the Group entity.
// AllowedGroupsInverseTable is the table name for the Group entity.
...
@@ -134,6 +149,9 @@ var Columns = []string{
...
@@ -134,6 +149,9 @@ var Columns = []string{
FieldStatus
,
FieldStatus
,
FieldUsername
,
FieldUsername
,
FieldNotes
,
FieldNotes
,
FieldTotpSecretEncrypted
,
FieldTotpEnabled
,
FieldTotpEnabledAt
,
}
}
var
(
var
(
...
@@ -188,6 +206,8 @@ var (
...
@@ -188,6 +206,8 @@ var (
UsernameValidator
func
(
string
)
error
UsernameValidator
func
(
string
)
error
// DefaultNotes holds the default value on creation for the "notes" field.
// DefaultNotes holds the default value on creation for the "notes" field.
DefaultNotes
string
DefaultNotes
string
// DefaultTotpEnabled holds the default value on creation for the "totp_enabled" field.
DefaultTotpEnabled
bool
)
)
// OrderOption defines the ordering options for the User queries.
// OrderOption defines the ordering options for the User queries.
...
@@ -253,6 +273,21 @@ func ByNotes(opts ...sql.OrderTermOption) OrderOption {
...
@@ -253,6 +273,21 @@ func ByNotes(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldNotes
,
opts
...
)
.
ToFunc
()
return
sql
.
OrderByField
(
FieldNotes
,
opts
...
)
.
ToFunc
()
}
}
// ByTotpSecretEncrypted orders the results by the totp_secret_encrypted field.
func
ByTotpSecretEncrypted
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldTotpSecretEncrypted
,
opts
...
)
.
ToFunc
()
}
// ByTotpEnabled orders the results by the totp_enabled field.
func
ByTotpEnabled
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldTotpEnabled
,
opts
...
)
.
ToFunc
()
}
// ByTotpEnabledAt orders the results by the totp_enabled_at field.
func
ByTotpEnabledAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldTotpEnabledAt
,
opts
...
)
.
ToFunc
()
}
// ByAPIKeysCount orders the results by api_keys count.
// ByAPIKeysCount orders the results by api_keys count.
func
ByAPIKeysCount
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
func
ByAPIKeysCount
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
return
func
(
s
*
sql
.
Selector
)
{
...
@@ -309,6 +344,20 @@ func ByAssignedSubscriptions(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOp
...
@@ -309,6 +344,20 @@ func ByAssignedSubscriptions(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOp
}
}
}
}
// ByAnnouncementReadsCount orders the results by announcement_reads count.
func
ByAnnouncementReadsCount
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
sqlgraph
.
OrderByNeighborsCount
(
s
,
newAnnouncementReadsStep
(),
opts
...
)
}
}
// ByAnnouncementReads orders the results by announcement_reads terms.
func
ByAnnouncementReads
(
term
sql
.
OrderTerm
,
terms
...
sql
.
OrderTerm
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
sqlgraph
.
OrderByNeighborTerms
(
s
,
newAnnouncementReadsStep
(),
append
([]
sql
.
OrderTerm
{
term
},
terms
...
)
...
)
}
}
// ByAllowedGroupsCount orders the results by allowed_groups count.
// ByAllowedGroupsCount orders the results by allowed_groups count.
func
ByAllowedGroupsCount
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
func
ByAllowedGroupsCount
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
return
func
(
s
*
sql
.
Selector
)
{
...
@@ -406,6 +455,13 @@ func newAssignedSubscriptionsStep() *sqlgraph.Step {
...
@@ -406,6 +455,13 @@ func newAssignedSubscriptionsStep() *sqlgraph.Step {
sqlgraph
.
Edge
(
sqlgraph
.
O2M
,
false
,
AssignedSubscriptionsTable
,
AssignedSubscriptionsColumn
),
sqlgraph
.
Edge
(
sqlgraph
.
O2M
,
false
,
AssignedSubscriptionsTable
,
AssignedSubscriptionsColumn
),
)
)
}
}
func
newAnnouncementReadsStep
()
*
sqlgraph
.
Step
{
return
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
To
(
AnnouncementReadsInverseTable
,
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
O2M
,
false
,
AnnouncementReadsTable
,
AnnouncementReadsColumn
),
)
}
func
newAllowedGroupsStep
()
*
sqlgraph
.
Step
{
func
newAllowedGroupsStep
()
*
sqlgraph
.
Step
{
return
sqlgraph
.
NewStep
(
return
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
From
(
Table
,
FieldID
),
...
...
backend/ent/user/where.go
View file @
31fe0178
...
@@ -110,6 +110,21 @@ func Notes(v string) predicate.User {
...
@@ -110,6 +110,21 @@ func Notes(v string) predicate.User {
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldNotes
,
v
))
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldNotes
,
v
))
}
}
// TotpSecretEncrypted applies equality check predicate on the "totp_secret_encrypted" field. It's identical to TotpSecretEncryptedEQ.
func
TotpSecretEncrypted
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpEnabled applies equality check predicate on the "totp_enabled" field. It's identical to TotpEnabledEQ.
func
TotpEnabled
(
v
bool
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldTotpEnabled
,
v
))
}
// TotpEnabledAt applies equality check predicate on the "totp_enabled_at" field. It's identical to TotpEnabledAtEQ.
func
TotpEnabledAt
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldTotpEnabledAt
,
v
))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func
CreatedAtEQ
(
v
time
.
Time
)
predicate
.
User
{
func
CreatedAtEQ
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldCreatedAt
,
v
))
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldCreatedAt
,
v
))
...
@@ -710,6 +725,141 @@ func NotesContainsFold(v string) predicate.User {
...
@@ -710,6 +725,141 @@ func NotesContainsFold(v string) predicate.User {
return
predicate
.
User
(
sql
.
FieldContainsFold
(
FieldNotes
,
v
))
return
predicate
.
User
(
sql
.
FieldContainsFold
(
FieldNotes
,
v
))
}
}
// TotpSecretEncryptedEQ applies the EQ predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedEQ
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedNEQ applies the NEQ predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedNEQ
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldNEQ
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedIn applies the In predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedIn
(
vs
...
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldIn
(
FieldTotpSecretEncrypted
,
vs
...
))
}
// TotpSecretEncryptedNotIn applies the NotIn predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedNotIn
(
vs
...
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldNotIn
(
FieldTotpSecretEncrypted
,
vs
...
))
}
// TotpSecretEncryptedGT applies the GT predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedGT
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldGT
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedGTE applies the GTE predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedGTE
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldGTE
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedLT applies the LT predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedLT
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldLT
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedLTE applies the LTE predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedLTE
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldLTE
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedContains applies the Contains predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedContains
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldContains
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedHasPrefix applies the HasPrefix predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedHasPrefix
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldHasPrefix
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedHasSuffix applies the HasSuffix predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedHasSuffix
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldHasSuffix
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedIsNil applies the IsNil predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedIsNil
()
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldIsNull
(
FieldTotpSecretEncrypted
))
}
// TotpSecretEncryptedNotNil applies the NotNil predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedNotNil
()
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldNotNull
(
FieldTotpSecretEncrypted
))
}
// TotpSecretEncryptedEqualFold applies the EqualFold predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedEqualFold
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEqualFold
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpSecretEncryptedContainsFold applies the ContainsFold predicate on the "totp_secret_encrypted" field.
func
TotpSecretEncryptedContainsFold
(
v
string
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldContainsFold
(
FieldTotpSecretEncrypted
,
v
))
}
// TotpEnabledEQ applies the EQ predicate on the "totp_enabled" field.
func
TotpEnabledEQ
(
v
bool
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldTotpEnabled
,
v
))
}
// TotpEnabledNEQ applies the NEQ predicate on the "totp_enabled" field.
func
TotpEnabledNEQ
(
v
bool
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldNEQ
(
FieldTotpEnabled
,
v
))
}
// TotpEnabledAtEQ applies the EQ predicate on the "totp_enabled_at" field.
func
TotpEnabledAtEQ
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldEQ
(
FieldTotpEnabledAt
,
v
))
}
// TotpEnabledAtNEQ applies the NEQ predicate on the "totp_enabled_at" field.
func
TotpEnabledAtNEQ
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldNEQ
(
FieldTotpEnabledAt
,
v
))
}
// TotpEnabledAtIn applies the In predicate on the "totp_enabled_at" field.
func
TotpEnabledAtIn
(
vs
...
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldIn
(
FieldTotpEnabledAt
,
vs
...
))
}
// TotpEnabledAtNotIn applies the NotIn predicate on the "totp_enabled_at" field.
func
TotpEnabledAtNotIn
(
vs
...
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldNotIn
(
FieldTotpEnabledAt
,
vs
...
))
}
// TotpEnabledAtGT applies the GT predicate on the "totp_enabled_at" field.
func
TotpEnabledAtGT
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldGT
(
FieldTotpEnabledAt
,
v
))
}
// TotpEnabledAtGTE applies the GTE predicate on the "totp_enabled_at" field.
func
TotpEnabledAtGTE
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldGTE
(
FieldTotpEnabledAt
,
v
))
}
// TotpEnabledAtLT applies the LT predicate on the "totp_enabled_at" field.
func
TotpEnabledAtLT
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldLT
(
FieldTotpEnabledAt
,
v
))
}
// TotpEnabledAtLTE applies the LTE predicate on the "totp_enabled_at" field.
func
TotpEnabledAtLTE
(
v
time
.
Time
)
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldLTE
(
FieldTotpEnabledAt
,
v
))
}
// TotpEnabledAtIsNil applies the IsNil predicate on the "totp_enabled_at" field.
func
TotpEnabledAtIsNil
()
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldIsNull
(
FieldTotpEnabledAt
))
}
// TotpEnabledAtNotNil applies the NotNil predicate on the "totp_enabled_at" field.
func
TotpEnabledAtNotNil
()
predicate
.
User
{
return
predicate
.
User
(
sql
.
FieldNotNull
(
FieldTotpEnabledAt
))
}
// HasAPIKeys applies the HasEdge predicate on the "api_keys" edge.
// HasAPIKeys applies the HasEdge predicate on the "api_keys" edge.
func
HasAPIKeys
()
predicate
.
User
{
func
HasAPIKeys
()
predicate
.
User
{
return
predicate
.
User
(
func
(
s
*
sql
.
Selector
)
{
return
predicate
.
User
(
func
(
s
*
sql
.
Selector
)
{
...
@@ -802,6 +952,29 @@ func HasAssignedSubscriptionsWith(preds ...predicate.UserSubscription) predicate
...
@@ -802,6 +952,29 @@ func HasAssignedSubscriptionsWith(preds ...predicate.UserSubscription) predicate
})
})
}
}
// HasAnnouncementReads applies the HasEdge predicate on the "announcement_reads" edge.
func
HasAnnouncementReads
()
predicate
.
User
{
return
predicate
.
User
(
func
(
s
*
sql
.
Selector
)
{
step
:=
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
O2M
,
false
,
AnnouncementReadsTable
,
AnnouncementReadsColumn
),
)
sqlgraph
.
HasNeighbors
(
s
,
step
)
})
}
// HasAnnouncementReadsWith applies the HasEdge predicate on the "announcement_reads" edge with a given conditions (other predicates).
func
HasAnnouncementReadsWith
(
preds
...
predicate
.
AnnouncementRead
)
predicate
.
User
{
return
predicate
.
User
(
func
(
s
*
sql
.
Selector
)
{
step
:=
newAnnouncementReadsStep
()
sqlgraph
.
HasNeighborsWith
(
s
,
step
,
func
(
s
*
sql
.
Selector
)
{
for
_
,
p
:=
range
preds
{
p
(
s
)
}
})
})
}
// HasAllowedGroups applies the HasEdge predicate on the "allowed_groups" edge.
// HasAllowedGroups applies the HasEdge predicate on the "allowed_groups" edge.
func
HasAllowedGroups
()
predicate
.
User
{
func
HasAllowedGroups
()
predicate
.
User
{
return
predicate
.
User
(
func
(
s
*
sql
.
Selector
)
{
return
predicate
.
User
(
func
(
s
*
sql
.
Selector
)
{
...
...
backend/ent/user_create.go
View file @
31fe0178
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/announcementread"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/promocodeusage"
"github.com/Wei-Shaw/sub2api/ent/promocodeusage"
...
@@ -167,6 +168,48 @@ func (_c *UserCreate) SetNillableNotes(v *string) *UserCreate {
...
@@ -167,6 +168,48 @@ func (_c *UserCreate) SetNillableNotes(v *string) *UserCreate {
return
_c
return
_c
}
}
// SetTotpSecretEncrypted sets the "totp_secret_encrypted" field.
func
(
_c
*
UserCreate
)
SetTotpSecretEncrypted
(
v
string
)
*
UserCreate
{
_c
.
mutation
.
SetTotpSecretEncrypted
(
v
)
return
_c
}
// SetNillableTotpSecretEncrypted sets the "totp_secret_encrypted" field if the given value is not nil.
func
(
_c
*
UserCreate
)
SetNillableTotpSecretEncrypted
(
v
*
string
)
*
UserCreate
{
if
v
!=
nil
{
_c
.
SetTotpSecretEncrypted
(
*
v
)
}
return
_c
}
// SetTotpEnabled sets the "totp_enabled" field.
func
(
_c
*
UserCreate
)
SetTotpEnabled
(
v
bool
)
*
UserCreate
{
_c
.
mutation
.
SetTotpEnabled
(
v
)
return
_c
}
// SetNillableTotpEnabled sets the "totp_enabled" field if the given value is not nil.
func
(
_c
*
UserCreate
)
SetNillableTotpEnabled
(
v
*
bool
)
*
UserCreate
{
if
v
!=
nil
{
_c
.
SetTotpEnabled
(
*
v
)
}
return
_c
}
// SetTotpEnabledAt sets the "totp_enabled_at" field.
func
(
_c
*
UserCreate
)
SetTotpEnabledAt
(
v
time
.
Time
)
*
UserCreate
{
_c
.
mutation
.
SetTotpEnabledAt
(
v
)
return
_c
}
// SetNillableTotpEnabledAt sets the "totp_enabled_at" field if the given value is not nil.
func
(
_c
*
UserCreate
)
SetNillableTotpEnabledAt
(
v
*
time
.
Time
)
*
UserCreate
{
if
v
!=
nil
{
_c
.
SetTotpEnabledAt
(
*
v
)
}
return
_c
}
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
func
(
_c
*
UserCreate
)
AddAPIKeyIDs
(
ids
...
int64
)
*
UserCreate
{
func
(
_c
*
UserCreate
)
AddAPIKeyIDs
(
ids
...
int64
)
*
UserCreate
{
_c
.
mutation
.
AddAPIKeyIDs
(
ids
...
)
_c
.
mutation
.
AddAPIKeyIDs
(
ids
...
)
...
@@ -227,6 +270,21 @@ func (_c *UserCreate) AddAssignedSubscriptions(v ...*UserSubscription) *UserCrea
...
@@ -227,6 +270,21 @@ func (_c *UserCreate) AddAssignedSubscriptions(v ...*UserSubscription) *UserCrea
return
_c
.
AddAssignedSubscriptionIDs
(
ids
...
)
return
_c
.
AddAssignedSubscriptionIDs
(
ids
...
)
}
}
// AddAnnouncementReadIDs adds the "announcement_reads" edge to the AnnouncementRead entity by IDs.
func
(
_c
*
UserCreate
)
AddAnnouncementReadIDs
(
ids
...
int64
)
*
UserCreate
{
_c
.
mutation
.
AddAnnouncementReadIDs
(
ids
...
)
return
_c
}
// AddAnnouncementReads adds the "announcement_reads" edges to the AnnouncementRead entity.
func
(
_c
*
UserCreate
)
AddAnnouncementReads
(
v
...*
AnnouncementRead
)
*
UserCreate
{
ids
:=
make
([]
int64
,
len
(
v
))
for
i
:=
range
v
{
ids
[
i
]
=
v
[
i
]
.
ID
}
return
_c
.
AddAnnouncementReadIDs
(
ids
...
)
}
// AddAllowedGroupIDs adds the "allowed_groups" edge to the Group entity by IDs.
// AddAllowedGroupIDs adds the "allowed_groups" edge to the Group entity by IDs.
func
(
_c
*
UserCreate
)
AddAllowedGroupIDs
(
ids
...
int64
)
*
UserCreate
{
func
(
_c
*
UserCreate
)
AddAllowedGroupIDs
(
ids
...
int64
)
*
UserCreate
{
_c
.
mutation
.
AddAllowedGroupIDs
(
ids
...
)
_c
.
mutation
.
AddAllowedGroupIDs
(
ids
...
)
...
@@ -362,6 +420,10 @@ func (_c *UserCreate) defaults() error {
...
@@ -362,6 +420,10 @@ func (_c *UserCreate) defaults() error {
v
:=
user
.
DefaultNotes
v
:=
user
.
DefaultNotes
_c
.
mutation
.
SetNotes
(
v
)
_c
.
mutation
.
SetNotes
(
v
)
}
}
if
_
,
ok
:=
_c
.
mutation
.
TotpEnabled
();
!
ok
{
v
:=
user
.
DefaultTotpEnabled
_c
.
mutation
.
SetTotpEnabled
(
v
)
}
return
nil
return
nil
}
}
...
@@ -422,6 +484,9 @@ func (_c *UserCreate) check() error {
...
@@ -422,6 +484,9 @@ func (_c *UserCreate) check() error {
if
_
,
ok
:=
_c
.
mutation
.
Notes
();
!
ok
{
if
_
,
ok
:=
_c
.
mutation
.
Notes
();
!
ok
{
return
&
ValidationError
{
Name
:
"notes"
,
err
:
errors
.
New
(
`ent: missing required field "User.notes"`
)}
return
&
ValidationError
{
Name
:
"notes"
,
err
:
errors
.
New
(
`ent: missing required field "User.notes"`
)}
}
}
if
_
,
ok
:=
_c
.
mutation
.
TotpEnabled
();
!
ok
{
return
&
ValidationError
{
Name
:
"totp_enabled"
,
err
:
errors
.
New
(
`ent: missing required field "User.totp_enabled"`
)}
}
return
nil
return
nil
}
}
...
@@ -493,6 +558,18 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
...
@@ -493,6 +558,18 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
_spec
.
SetField
(
user
.
FieldNotes
,
field
.
TypeString
,
value
)
_spec
.
SetField
(
user
.
FieldNotes
,
field
.
TypeString
,
value
)
_node
.
Notes
=
value
_node
.
Notes
=
value
}
}
if
value
,
ok
:=
_c
.
mutation
.
TotpSecretEncrypted
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpSecretEncrypted
,
field
.
TypeString
,
value
)
_node
.
TotpSecretEncrypted
=
&
value
}
if
value
,
ok
:=
_c
.
mutation
.
TotpEnabled
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpEnabled
,
field
.
TypeBool
,
value
)
_node
.
TotpEnabled
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
TotpEnabledAt
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpEnabledAt
,
field
.
TypeTime
,
value
)
_node
.
TotpEnabledAt
=
&
value
}
if
nodes
:=
_c
.
mutation
.
APIKeysIDs
();
len
(
nodes
)
>
0
{
if
nodes
:=
_c
.
mutation
.
APIKeysIDs
();
len
(
nodes
)
>
0
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Rel
:
sqlgraph
.
O2M
,
...
@@ -557,6 +634,22 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
...
@@ -557,6 +634,22 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
}
}
_spec
.
Edges
=
append
(
_spec
.
Edges
,
edge
)
_spec
.
Edges
=
append
(
_spec
.
Edges
,
edge
)
}
}
if
nodes
:=
_c
.
mutation
.
AnnouncementReadsIDs
();
len
(
nodes
)
>
0
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Inverse
:
false
,
Table
:
user
.
AnnouncementReadsTable
,
Columns
:
[]
string
{
user
.
AnnouncementReadsColumn
},
Bidi
:
false
,
Target
:
&
sqlgraph
.
EdgeTarget
{
IDSpec
:
sqlgraph
.
NewFieldSpec
(
announcementread
.
FieldID
,
field
.
TypeInt64
),
},
}
for
_
,
k
:=
range
nodes
{
edge
.
Target
.
Nodes
=
append
(
edge
.
Target
.
Nodes
,
k
)
}
_spec
.
Edges
=
append
(
_spec
.
Edges
,
edge
)
}
if
nodes
:=
_c
.
mutation
.
AllowedGroupsIDs
();
len
(
nodes
)
>
0
{
if
nodes
:=
_c
.
mutation
.
AllowedGroupsIDs
();
len
(
nodes
)
>
0
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
M2M
,
Rel
:
sqlgraph
.
M2M
,
...
@@ -815,6 +908,54 @@ func (u *UserUpsert) UpdateNotes() *UserUpsert {
...
@@ -815,6 +908,54 @@ func (u *UserUpsert) UpdateNotes() *UserUpsert {
return
u
return
u
}
}
// SetTotpSecretEncrypted sets the "totp_secret_encrypted" field.
func
(
u
*
UserUpsert
)
SetTotpSecretEncrypted
(
v
string
)
*
UserUpsert
{
u
.
Set
(
user
.
FieldTotpSecretEncrypted
,
v
)
return
u
}
// UpdateTotpSecretEncrypted sets the "totp_secret_encrypted" field to the value that was provided on create.
func
(
u
*
UserUpsert
)
UpdateTotpSecretEncrypted
()
*
UserUpsert
{
u
.
SetExcluded
(
user
.
FieldTotpSecretEncrypted
)
return
u
}
// ClearTotpSecretEncrypted clears the value of the "totp_secret_encrypted" field.
func
(
u
*
UserUpsert
)
ClearTotpSecretEncrypted
()
*
UserUpsert
{
u
.
SetNull
(
user
.
FieldTotpSecretEncrypted
)
return
u
}
// SetTotpEnabled sets the "totp_enabled" field.
func
(
u
*
UserUpsert
)
SetTotpEnabled
(
v
bool
)
*
UserUpsert
{
u
.
Set
(
user
.
FieldTotpEnabled
,
v
)
return
u
}
// UpdateTotpEnabled sets the "totp_enabled" field to the value that was provided on create.
func
(
u
*
UserUpsert
)
UpdateTotpEnabled
()
*
UserUpsert
{
u
.
SetExcluded
(
user
.
FieldTotpEnabled
)
return
u
}
// SetTotpEnabledAt sets the "totp_enabled_at" field.
func
(
u
*
UserUpsert
)
SetTotpEnabledAt
(
v
time
.
Time
)
*
UserUpsert
{
u
.
Set
(
user
.
FieldTotpEnabledAt
,
v
)
return
u
}
// UpdateTotpEnabledAt sets the "totp_enabled_at" field to the value that was provided on create.
func
(
u
*
UserUpsert
)
UpdateTotpEnabledAt
()
*
UserUpsert
{
u
.
SetExcluded
(
user
.
FieldTotpEnabledAt
)
return
u
}
// ClearTotpEnabledAt clears the value of the "totp_enabled_at" field.
func
(
u
*
UserUpsert
)
ClearTotpEnabledAt
()
*
UserUpsert
{
u
.
SetNull
(
user
.
FieldTotpEnabledAt
)
return
u
}
// UpdateNewValues updates the mutable fields using the new values that were set on create.
// UpdateNewValues updates the mutable fields using the new values that were set on create.
// Using this option is equivalent to using:
// Using this option is equivalent to using:
//
//
...
@@ -1021,6 +1162,62 @@ func (u *UserUpsertOne) UpdateNotes() *UserUpsertOne {
...
@@ -1021,6 +1162,62 @@ func (u *UserUpsertOne) UpdateNotes() *UserUpsertOne {
})
})
}
}
// SetTotpSecretEncrypted sets the "totp_secret_encrypted" field.
func
(
u
*
UserUpsertOne
)
SetTotpSecretEncrypted
(
v
string
)
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
SetTotpSecretEncrypted
(
v
)
})
}
// UpdateTotpSecretEncrypted sets the "totp_secret_encrypted" field to the value that was provided on create.
func
(
u
*
UserUpsertOne
)
UpdateTotpSecretEncrypted
()
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
UpdateTotpSecretEncrypted
()
})
}
// ClearTotpSecretEncrypted clears the value of the "totp_secret_encrypted" field.
func
(
u
*
UserUpsertOne
)
ClearTotpSecretEncrypted
()
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
ClearTotpSecretEncrypted
()
})
}
// SetTotpEnabled sets the "totp_enabled" field.
func
(
u
*
UserUpsertOne
)
SetTotpEnabled
(
v
bool
)
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
SetTotpEnabled
(
v
)
})
}
// UpdateTotpEnabled sets the "totp_enabled" field to the value that was provided on create.
func
(
u
*
UserUpsertOne
)
UpdateTotpEnabled
()
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
UpdateTotpEnabled
()
})
}
// SetTotpEnabledAt sets the "totp_enabled_at" field.
func
(
u
*
UserUpsertOne
)
SetTotpEnabledAt
(
v
time
.
Time
)
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
SetTotpEnabledAt
(
v
)
})
}
// UpdateTotpEnabledAt sets the "totp_enabled_at" field to the value that was provided on create.
func
(
u
*
UserUpsertOne
)
UpdateTotpEnabledAt
()
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
UpdateTotpEnabledAt
()
})
}
// ClearTotpEnabledAt clears the value of the "totp_enabled_at" field.
func
(
u
*
UserUpsertOne
)
ClearTotpEnabledAt
()
*
UserUpsertOne
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
ClearTotpEnabledAt
()
})
}
// Exec executes the query.
// Exec executes the query.
func
(
u
*
UserUpsertOne
)
Exec
(
ctx
context
.
Context
)
error
{
func
(
u
*
UserUpsertOne
)
Exec
(
ctx
context
.
Context
)
error
{
if
len
(
u
.
create
.
conflict
)
==
0
{
if
len
(
u
.
create
.
conflict
)
==
0
{
...
@@ -1393,6 +1590,62 @@ func (u *UserUpsertBulk) UpdateNotes() *UserUpsertBulk {
...
@@ -1393,6 +1590,62 @@ func (u *UserUpsertBulk) UpdateNotes() *UserUpsertBulk {
})
})
}
}
// SetTotpSecretEncrypted sets the "totp_secret_encrypted" field.
func
(
u
*
UserUpsertBulk
)
SetTotpSecretEncrypted
(
v
string
)
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
SetTotpSecretEncrypted
(
v
)
})
}
// UpdateTotpSecretEncrypted sets the "totp_secret_encrypted" field to the value that was provided on create.
func
(
u
*
UserUpsertBulk
)
UpdateTotpSecretEncrypted
()
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
UpdateTotpSecretEncrypted
()
})
}
// ClearTotpSecretEncrypted clears the value of the "totp_secret_encrypted" field.
func
(
u
*
UserUpsertBulk
)
ClearTotpSecretEncrypted
()
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
ClearTotpSecretEncrypted
()
})
}
// SetTotpEnabled sets the "totp_enabled" field.
func
(
u
*
UserUpsertBulk
)
SetTotpEnabled
(
v
bool
)
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
SetTotpEnabled
(
v
)
})
}
// UpdateTotpEnabled sets the "totp_enabled" field to the value that was provided on create.
func
(
u
*
UserUpsertBulk
)
UpdateTotpEnabled
()
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
UpdateTotpEnabled
()
})
}
// SetTotpEnabledAt sets the "totp_enabled_at" field.
func
(
u
*
UserUpsertBulk
)
SetTotpEnabledAt
(
v
time
.
Time
)
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
SetTotpEnabledAt
(
v
)
})
}
// UpdateTotpEnabledAt sets the "totp_enabled_at" field to the value that was provided on create.
func
(
u
*
UserUpsertBulk
)
UpdateTotpEnabledAt
()
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
UpdateTotpEnabledAt
()
})
}
// ClearTotpEnabledAt clears the value of the "totp_enabled_at" field.
func
(
u
*
UserUpsertBulk
)
ClearTotpEnabledAt
()
*
UserUpsertBulk
{
return
u
.
Update
(
func
(
s
*
UserUpsert
)
{
s
.
ClearTotpEnabledAt
()
})
}
// Exec executes the query.
// Exec executes the query.
func
(
u
*
UserUpsertBulk
)
Exec
(
ctx
context
.
Context
)
error
{
func
(
u
*
UserUpsertBulk
)
Exec
(
ctx
context
.
Context
)
error
{
if
u
.
create
.
err
!=
nil
{
if
u
.
create
.
err
!=
nil
{
...
...
backend/ent/user_query.go
View file @
31fe0178
...
@@ -13,6 +13,7 @@ import (
...
@@ -13,6 +13,7 @@ import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/announcementread"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/predicate"
...
@@ -36,6 +37,7 @@ type UserQuery struct {
...
@@ -36,6 +37,7 @@ type UserQuery struct {
withRedeemCodes
*
RedeemCodeQuery
withRedeemCodes
*
RedeemCodeQuery
withSubscriptions
*
UserSubscriptionQuery
withSubscriptions
*
UserSubscriptionQuery
withAssignedSubscriptions
*
UserSubscriptionQuery
withAssignedSubscriptions
*
UserSubscriptionQuery
withAnnouncementReads
*
AnnouncementReadQuery
withAllowedGroups
*
GroupQuery
withAllowedGroups
*
GroupQuery
withUsageLogs
*
UsageLogQuery
withUsageLogs
*
UsageLogQuery
withAttributeValues
*
UserAttributeValueQuery
withAttributeValues
*
UserAttributeValueQuery
...
@@ -166,6 +168,28 @@ func (_q *UserQuery) QueryAssignedSubscriptions() *UserSubscriptionQuery {
...
@@ -166,6 +168,28 @@ func (_q *UserQuery) QueryAssignedSubscriptions() *UserSubscriptionQuery {
return
query
return
query
}
}
// QueryAnnouncementReads chains the current query on the "announcement_reads" edge.
func
(
_q
*
UserQuery
)
QueryAnnouncementReads
()
*
AnnouncementReadQuery
{
query
:=
(
&
AnnouncementReadClient
{
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
(
user
.
Table
,
user
.
FieldID
,
selector
),
sqlgraph
.
To
(
announcementread
.
Table
,
announcementread
.
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
O2M
,
false
,
user
.
AnnouncementReadsTable
,
user
.
AnnouncementReadsColumn
),
)
fromU
=
sqlgraph
.
SetNeighbors
(
_q
.
driver
.
Dialect
(),
step
)
return
fromU
,
nil
}
return
query
}
// QueryAllowedGroups chains the current query on the "allowed_groups" edge.
// QueryAllowedGroups chains the current query on the "allowed_groups" edge.
func
(
_q
*
UserQuery
)
QueryAllowedGroups
()
*
GroupQuery
{
func
(
_q
*
UserQuery
)
QueryAllowedGroups
()
*
GroupQuery
{
query
:=
(
&
GroupClient
{
config
:
_q
.
config
})
.
Query
()
query
:=
(
&
GroupClient
{
config
:
_q
.
config
})
.
Query
()
...
@@ -472,6 +496,7 @@ func (_q *UserQuery) Clone() *UserQuery {
...
@@ -472,6 +496,7 @@ func (_q *UserQuery) Clone() *UserQuery {
withRedeemCodes
:
_q
.
withRedeemCodes
.
Clone
(),
withRedeemCodes
:
_q
.
withRedeemCodes
.
Clone
(),
withSubscriptions
:
_q
.
withSubscriptions
.
Clone
(),
withSubscriptions
:
_q
.
withSubscriptions
.
Clone
(),
withAssignedSubscriptions
:
_q
.
withAssignedSubscriptions
.
Clone
(),
withAssignedSubscriptions
:
_q
.
withAssignedSubscriptions
.
Clone
(),
withAnnouncementReads
:
_q
.
withAnnouncementReads
.
Clone
(),
withAllowedGroups
:
_q
.
withAllowedGroups
.
Clone
(),
withAllowedGroups
:
_q
.
withAllowedGroups
.
Clone
(),
withUsageLogs
:
_q
.
withUsageLogs
.
Clone
(),
withUsageLogs
:
_q
.
withUsageLogs
.
Clone
(),
withAttributeValues
:
_q
.
withAttributeValues
.
Clone
(),
withAttributeValues
:
_q
.
withAttributeValues
.
Clone
(),
...
@@ -527,6 +552,17 @@ func (_q *UserQuery) WithAssignedSubscriptions(opts ...func(*UserSubscriptionQue
...
@@ -527,6 +552,17 @@ func (_q *UserQuery) WithAssignedSubscriptions(opts ...func(*UserSubscriptionQue
return
_q
return
_q
}
}
// WithAnnouncementReads tells the query-builder to eager-load the nodes that are connected to
// the "announcement_reads" edge. The optional arguments are used to configure the query builder of the edge.
func
(
_q
*
UserQuery
)
WithAnnouncementReads
(
opts
...
func
(
*
AnnouncementReadQuery
))
*
UserQuery
{
query
:=
(
&
AnnouncementReadClient
{
config
:
_q
.
config
})
.
Query
()
for
_
,
opt
:=
range
opts
{
opt
(
query
)
}
_q
.
withAnnouncementReads
=
query
return
_q
}
// WithAllowedGroups tells the query-builder to eager-load the nodes that are connected to
// WithAllowedGroups tells the query-builder to eager-load the nodes that are connected to
// the "allowed_groups" edge. The optional arguments are used to configure the query builder of the edge.
// the "allowed_groups" edge. The optional arguments are used to configure the query builder of the edge.
func
(
_q
*
UserQuery
)
WithAllowedGroups
(
opts
...
func
(
*
GroupQuery
))
*
UserQuery
{
func
(
_q
*
UserQuery
)
WithAllowedGroups
(
opts
...
func
(
*
GroupQuery
))
*
UserQuery
{
...
@@ -660,11 +696,12 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
...
@@ -660,11 +696,12 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
var
(
var
(
nodes
=
[]
*
User
{}
nodes
=
[]
*
User
{}
_spec
=
_q
.
querySpec
()
_spec
=
_q
.
querySpec
()
loadedTypes
=
[
9
]
bool
{
loadedTypes
=
[
10
]
bool
{
_q
.
withAPIKeys
!=
nil
,
_q
.
withAPIKeys
!=
nil
,
_q
.
withRedeemCodes
!=
nil
,
_q
.
withRedeemCodes
!=
nil
,
_q
.
withSubscriptions
!=
nil
,
_q
.
withSubscriptions
!=
nil
,
_q
.
withAssignedSubscriptions
!=
nil
,
_q
.
withAssignedSubscriptions
!=
nil
,
_q
.
withAnnouncementReads
!=
nil
,
_q
.
withAllowedGroups
!=
nil
,
_q
.
withAllowedGroups
!=
nil
,
_q
.
withUsageLogs
!=
nil
,
_q
.
withUsageLogs
!=
nil
,
_q
.
withAttributeValues
!=
nil
,
_q
.
withAttributeValues
!=
nil
,
...
@@ -723,6 +760,13 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
...
@@ -723,6 +760,13 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
return
nil
,
err
return
nil
,
err
}
}
}
}
if
query
:=
_q
.
withAnnouncementReads
;
query
!=
nil
{
if
err
:=
_q
.
loadAnnouncementReads
(
ctx
,
query
,
nodes
,
func
(
n
*
User
)
{
n
.
Edges
.
AnnouncementReads
=
[]
*
AnnouncementRead
{}
},
func
(
n
*
User
,
e
*
AnnouncementRead
)
{
n
.
Edges
.
AnnouncementReads
=
append
(
n
.
Edges
.
AnnouncementReads
,
e
)
});
err
!=
nil
{
return
nil
,
err
}
}
if
query
:=
_q
.
withAllowedGroups
;
query
!=
nil
{
if
query
:=
_q
.
withAllowedGroups
;
query
!=
nil
{
if
err
:=
_q
.
loadAllowedGroups
(
ctx
,
query
,
nodes
,
if
err
:=
_q
.
loadAllowedGroups
(
ctx
,
query
,
nodes
,
func
(
n
*
User
)
{
n
.
Edges
.
AllowedGroups
=
[]
*
Group
{}
},
func
(
n
*
User
)
{
n
.
Edges
.
AllowedGroups
=
[]
*
Group
{}
},
...
@@ -887,6 +931,36 @@ func (_q *UserQuery) loadAssignedSubscriptions(ctx context.Context, query *UserS
...
@@ -887,6 +931,36 @@ func (_q *UserQuery) loadAssignedSubscriptions(ctx context.Context, query *UserS
}
}
return
nil
return
nil
}
}
func
(
_q
*
UserQuery
)
loadAnnouncementReads
(
ctx
context
.
Context
,
query
*
AnnouncementReadQuery
,
nodes
[]
*
User
,
init
func
(
*
User
),
assign
func
(
*
User
,
*
AnnouncementRead
))
error
{
fks
:=
make
([]
driver
.
Value
,
0
,
len
(
nodes
))
nodeids
:=
make
(
map
[
int64
]
*
User
)
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
(
announcementread
.
FieldUserID
)
}
query
.
Where
(
predicate
.
AnnouncementRead
(
func
(
s
*
sql
.
Selector
)
{
s
.
Where
(
sql
.
InValues
(
s
.
C
(
user
.
AnnouncementReadsColumn
),
fks
...
))
}))
neighbors
,
err
:=
query
.
All
(
ctx
)
if
err
!=
nil
{
return
err
}
for
_
,
n
:=
range
neighbors
{
fk
:=
n
.
UserID
node
,
ok
:=
nodeids
[
fk
]
if
!
ok
{
return
fmt
.
Errorf
(
`unexpected referenced foreign-key "user_id" returned %v for node %v`
,
fk
,
n
.
ID
)
}
assign
(
node
,
n
)
}
return
nil
}
func
(
_q
*
UserQuery
)
loadAllowedGroups
(
ctx
context
.
Context
,
query
*
GroupQuery
,
nodes
[]
*
User
,
init
func
(
*
User
),
assign
func
(
*
User
,
*
Group
))
error
{
func
(
_q
*
UserQuery
)
loadAllowedGroups
(
ctx
context
.
Context
,
query
*
GroupQuery
,
nodes
[]
*
User
,
init
func
(
*
User
),
assign
func
(
*
User
,
*
Group
))
error
{
edgeIDs
:=
make
([]
driver
.
Value
,
len
(
nodes
))
edgeIDs
:=
make
([]
driver
.
Value
,
len
(
nodes
))
byID
:=
make
(
map
[
int64
]
*
User
)
byID
:=
make
(
map
[
int64
]
*
User
)
...
...
backend/ent/user_update.go
View file @
31fe0178
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/announcementread"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/predicate"
...
@@ -187,6 +188,60 @@ func (_u *UserUpdate) SetNillableNotes(v *string) *UserUpdate {
...
@@ -187,6 +188,60 @@ func (_u *UserUpdate) SetNillableNotes(v *string) *UserUpdate {
return
_u
return
_u
}
}
// SetTotpSecretEncrypted sets the "totp_secret_encrypted" field.
func
(
_u
*
UserUpdate
)
SetTotpSecretEncrypted
(
v
string
)
*
UserUpdate
{
_u
.
mutation
.
SetTotpSecretEncrypted
(
v
)
return
_u
}
// SetNillableTotpSecretEncrypted sets the "totp_secret_encrypted" field if the given value is not nil.
func
(
_u
*
UserUpdate
)
SetNillableTotpSecretEncrypted
(
v
*
string
)
*
UserUpdate
{
if
v
!=
nil
{
_u
.
SetTotpSecretEncrypted
(
*
v
)
}
return
_u
}
// ClearTotpSecretEncrypted clears the value of the "totp_secret_encrypted" field.
func
(
_u
*
UserUpdate
)
ClearTotpSecretEncrypted
()
*
UserUpdate
{
_u
.
mutation
.
ClearTotpSecretEncrypted
()
return
_u
}
// SetTotpEnabled sets the "totp_enabled" field.
func
(
_u
*
UserUpdate
)
SetTotpEnabled
(
v
bool
)
*
UserUpdate
{
_u
.
mutation
.
SetTotpEnabled
(
v
)
return
_u
}
// SetNillableTotpEnabled sets the "totp_enabled" field if the given value is not nil.
func
(
_u
*
UserUpdate
)
SetNillableTotpEnabled
(
v
*
bool
)
*
UserUpdate
{
if
v
!=
nil
{
_u
.
SetTotpEnabled
(
*
v
)
}
return
_u
}
// SetTotpEnabledAt sets the "totp_enabled_at" field.
func
(
_u
*
UserUpdate
)
SetTotpEnabledAt
(
v
time
.
Time
)
*
UserUpdate
{
_u
.
mutation
.
SetTotpEnabledAt
(
v
)
return
_u
}
// SetNillableTotpEnabledAt sets the "totp_enabled_at" field if the given value is not nil.
func
(
_u
*
UserUpdate
)
SetNillableTotpEnabledAt
(
v
*
time
.
Time
)
*
UserUpdate
{
if
v
!=
nil
{
_u
.
SetTotpEnabledAt
(
*
v
)
}
return
_u
}
// ClearTotpEnabledAt clears the value of the "totp_enabled_at" field.
func
(
_u
*
UserUpdate
)
ClearTotpEnabledAt
()
*
UserUpdate
{
_u
.
mutation
.
ClearTotpEnabledAt
()
return
_u
}
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
func
(
_u
*
UserUpdate
)
AddAPIKeyIDs
(
ids
...
int64
)
*
UserUpdate
{
func
(
_u
*
UserUpdate
)
AddAPIKeyIDs
(
ids
...
int64
)
*
UserUpdate
{
_u
.
mutation
.
AddAPIKeyIDs
(
ids
...
)
_u
.
mutation
.
AddAPIKeyIDs
(
ids
...
)
...
@@ -247,6 +302,21 @@ func (_u *UserUpdate) AddAssignedSubscriptions(v ...*UserSubscription) *UserUpda
...
@@ -247,6 +302,21 @@ func (_u *UserUpdate) AddAssignedSubscriptions(v ...*UserSubscription) *UserUpda
return
_u
.
AddAssignedSubscriptionIDs
(
ids
...
)
return
_u
.
AddAssignedSubscriptionIDs
(
ids
...
)
}
}
// AddAnnouncementReadIDs adds the "announcement_reads" edge to the AnnouncementRead entity by IDs.
func
(
_u
*
UserUpdate
)
AddAnnouncementReadIDs
(
ids
...
int64
)
*
UserUpdate
{
_u
.
mutation
.
AddAnnouncementReadIDs
(
ids
...
)
return
_u
}
// AddAnnouncementReads adds the "announcement_reads" edges to the AnnouncementRead entity.
func
(
_u
*
UserUpdate
)
AddAnnouncementReads
(
v
...*
AnnouncementRead
)
*
UserUpdate
{
ids
:=
make
([]
int64
,
len
(
v
))
for
i
:=
range
v
{
ids
[
i
]
=
v
[
i
]
.
ID
}
return
_u
.
AddAnnouncementReadIDs
(
ids
...
)
}
// AddAllowedGroupIDs adds the "allowed_groups" edge to the Group entity by IDs.
// AddAllowedGroupIDs adds the "allowed_groups" edge to the Group entity by IDs.
func
(
_u
*
UserUpdate
)
AddAllowedGroupIDs
(
ids
...
int64
)
*
UserUpdate
{
func
(
_u
*
UserUpdate
)
AddAllowedGroupIDs
(
ids
...
int64
)
*
UserUpdate
{
_u
.
mutation
.
AddAllowedGroupIDs
(
ids
...
)
_u
.
mutation
.
AddAllowedGroupIDs
(
ids
...
)
...
@@ -396,6 +466,27 @@ func (_u *UserUpdate) RemoveAssignedSubscriptions(v ...*UserSubscription) *UserU
...
@@ -396,6 +466,27 @@ func (_u *UserUpdate) RemoveAssignedSubscriptions(v ...*UserSubscription) *UserU
return
_u
.
RemoveAssignedSubscriptionIDs
(
ids
...
)
return
_u
.
RemoveAssignedSubscriptionIDs
(
ids
...
)
}
}
// ClearAnnouncementReads clears all "announcement_reads" edges to the AnnouncementRead entity.
func
(
_u
*
UserUpdate
)
ClearAnnouncementReads
()
*
UserUpdate
{
_u
.
mutation
.
ClearAnnouncementReads
()
return
_u
}
// RemoveAnnouncementReadIDs removes the "announcement_reads" edge to AnnouncementRead entities by IDs.
func
(
_u
*
UserUpdate
)
RemoveAnnouncementReadIDs
(
ids
...
int64
)
*
UserUpdate
{
_u
.
mutation
.
RemoveAnnouncementReadIDs
(
ids
...
)
return
_u
}
// RemoveAnnouncementReads removes "announcement_reads" edges to AnnouncementRead entities.
func
(
_u
*
UserUpdate
)
RemoveAnnouncementReads
(
v
...*
AnnouncementRead
)
*
UserUpdate
{
ids
:=
make
([]
int64
,
len
(
v
))
for
i
:=
range
v
{
ids
[
i
]
=
v
[
i
]
.
ID
}
return
_u
.
RemoveAnnouncementReadIDs
(
ids
...
)
}
// ClearAllowedGroups clears all "allowed_groups" edges to the Group entity.
// ClearAllowedGroups clears all "allowed_groups" edges to the Group entity.
func
(
_u
*
UserUpdate
)
ClearAllowedGroups
()
*
UserUpdate
{
func
(
_u
*
UserUpdate
)
ClearAllowedGroups
()
*
UserUpdate
{
_u
.
mutation
.
ClearAllowedGroups
()
_u
.
mutation
.
ClearAllowedGroups
()
...
@@ -603,6 +694,21 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
...
@@ -603,6 +694,21 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if
value
,
ok
:=
_u
.
mutation
.
Notes
();
ok
{
if
value
,
ok
:=
_u
.
mutation
.
Notes
();
ok
{
_spec
.
SetField
(
user
.
FieldNotes
,
field
.
TypeString
,
value
)
_spec
.
SetField
(
user
.
FieldNotes
,
field
.
TypeString
,
value
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
TotpSecretEncrypted
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpSecretEncrypted
,
field
.
TypeString
,
value
)
}
if
_u
.
mutation
.
TotpSecretEncryptedCleared
()
{
_spec
.
ClearField
(
user
.
FieldTotpSecretEncrypted
,
field
.
TypeString
)
}
if
value
,
ok
:=
_u
.
mutation
.
TotpEnabled
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpEnabled
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
TotpEnabledAt
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpEnabledAt
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
TotpEnabledAtCleared
()
{
_spec
.
ClearField
(
user
.
FieldTotpEnabledAt
,
field
.
TypeTime
)
}
if
_u
.
mutation
.
APIKeysCleared
()
{
if
_u
.
mutation
.
APIKeysCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Rel
:
sqlgraph
.
O2M
,
...
@@ -783,6 +889,51 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
...
@@ -783,6 +889,51 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
}
}
_spec
.
Edges
.
Add
=
append
(
_spec
.
Edges
.
Add
,
edge
)
_spec
.
Edges
.
Add
=
append
(
_spec
.
Edges
.
Add
,
edge
)
}
}
if
_u
.
mutation
.
AnnouncementReadsCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Inverse
:
false
,
Table
:
user
.
AnnouncementReadsTable
,
Columns
:
[]
string
{
user
.
AnnouncementReadsColumn
},
Bidi
:
false
,
Target
:
&
sqlgraph
.
EdgeTarget
{
IDSpec
:
sqlgraph
.
NewFieldSpec
(
announcementread
.
FieldID
,
field
.
TypeInt64
),
},
}
_spec
.
Edges
.
Clear
=
append
(
_spec
.
Edges
.
Clear
,
edge
)
}
if
nodes
:=
_u
.
mutation
.
RemovedAnnouncementReadsIDs
();
len
(
nodes
)
>
0
&&
!
_u
.
mutation
.
AnnouncementReadsCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Inverse
:
false
,
Table
:
user
.
AnnouncementReadsTable
,
Columns
:
[]
string
{
user
.
AnnouncementReadsColumn
},
Bidi
:
false
,
Target
:
&
sqlgraph
.
EdgeTarget
{
IDSpec
:
sqlgraph
.
NewFieldSpec
(
announcementread
.
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
.
AnnouncementReadsIDs
();
len
(
nodes
)
>
0
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Inverse
:
false
,
Table
:
user
.
AnnouncementReadsTable
,
Columns
:
[]
string
{
user
.
AnnouncementReadsColumn
},
Bidi
:
false
,
Target
:
&
sqlgraph
.
EdgeTarget
{
IDSpec
:
sqlgraph
.
NewFieldSpec
(
announcementread
.
FieldID
,
field
.
TypeInt64
),
},
}
for
_
,
k
:=
range
nodes
{
edge
.
Target
.
Nodes
=
append
(
edge
.
Target
.
Nodes
,
k
)
}
_spec
.
Edges
.
Add
=
append
(
_spec
.
Edges
.
Add
,
edge
)
}
if
_u
.
mutation
.
AllowedGroupsCleared
()
{
if
_u
.
mutation
.
AllowedGroupsCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
M2M
,
Rel
:
sqlgraph
.
M2M
,
...
@@ -1147,6 +1298,60 @@ func (_u *UserUpdateOne) SetNillableNotes(v *string) *UserUpdateOne {
...
@@ -1147,6 +1298,60 @@ func (_u *UserUpdateOne) SetNillableNotes(v *string) *UserUpdateOne {
return
_u
return
_u
}
}
// SetTotpSecretEncrypted sets the "totp_secret_encrypted" field.
func
(
_u
*
UserUpdateOne
)
SetTotpSecretEncrypted
(
v
string
)
*
UserUpdateOne
{
_u
.
mutation
.
SetTotpSecretEncrypted
(
v
)
return
_u
}
// SetNillableTotpSecretEncrypted sets the "totp_secret_encrypted" field if the given value is not nil.
func
(
_u
*
UserUpdateOne
)
SetNillableTotpSecretEncrypted
(
v
*
string
)
*
UserUpdateOne
{
if
v
!=
nil
{
_u
.
SetTotpSecretEncrypted
(
*
v
)
}
return
_u
}
// ClearTotpSecretEncrypted clears the value of the "totp_secret_encrypted" field.
func
(
_u
*
UserUpdateOne
)
ClearTotpSecretEncrypted
()
*
UserUpdateOne
{
_u
.
mutation
.
ClearTotpSecretEncrypted
()
return
_u
}
// SetTotpEnabled sets the "totp_enabled" field.
func
(
_u
*
UserUpdateOne
)
SetTotpEnabled
(
v
bool
)
*
UserUpdateOne
{
_u
.
mutation
.
SetTotpEnabled
(
v
)
return
_u
}
// SetNillableTotpEnabled sets the "totp_enabled" field if the given value is not nil.
func
(
_u
*
UserUpdateOne
)
SetNillableTotpEnabled
(
v
*
bool
)
*
UserUpdateOne
{
if
v
!=
nil
{
_u
.
SetTotpEnabled
(
*
v
)
}
return
_u
}
// SetTotpEnabledAt sets the "totp_enabled_at" field.
func
(
_u
*
UserUpdateOne
)
SetTotpEnabledAt
(
v
time
.
Time
)
*
UserUpdateOne
{
_u
.
mutation
.
SetTotpEnabledAt
(
v
)
return
_u
}
// SetNillableTotpEnabledAt sets the "totp_enabled_at" field if the given value is not nil.
func
(
_u
*
UserUpdateOne
)
SetNillableTotpEnabledAt
(
v
*
time
.
Time
)
*
UserUpdateOne
{
if
v
!=
nil
{
_u
.
SetTotpEnabledAt
(
*
v
)
}
return
_u
}
// ClearTotpEnabledAt clears the value of the "totp_enabled_at" field.
func
(
_u
*
UserUpdateOne
)
ClearTotpEnabledAt
()
*
UserUpdateOne
{
_u
.
mutation
.
ClearTotpEnabledAt
()
return
_u
}
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
func
(
_u
*
UserUpdateOne
)
AddAPIKeyIDs
(
ids
...
int64
)
*
UserUpdateOne
{
func
(
_u
*
UserUpdateOne
)
AddAPIKeyIDs
(
ids
...
int64
)
*
UserUpdateOne
{
_u
.
mutation
.
AddAPIKeyIDs
(
ids
...
)
_u
.
mutation
.
AddAPIKeyIDs
(
ids
...
)
...
@@ -1207,6 +1412,21 @@ func (_u *UserUpdateOne) AddAssignedSubscriptions(v ...*UserSubscription) *UserU
...
@@ -1207,6 +1412,21 @@ func (_u *UserUpdateOne) AddAssignedSubscriptions(v ...*UserSubscription) *UserU
return
_u
.
AddAssignedSubscriptionIDs
(
ids
...
)
return
_u
.
AddAssignedSubscriptionIDs
(
ids
...
)
}
}
// AddAnnouncementReadIDs adds the "announcement_reads" edge to the AnnouncementRead entity by IDs.
func
(
_u
*
UserUpdateOne
)
AddAnnouncementReadIDs
(
ids
...
int64
)
*
UserUpdateOne
{
_u
.
mutation
.
AddAnnouncementReadIDs
(
ids
...
)
return
_u
}
// AddAnnouncementReads adds the "announcement_reads" edges to the AnnouncementRead entity.
func
(
_u
*
UserUpdateOne
)
AddAnnouncementReads
(
v
...*
AnnouncementRead
)
*
UserUpdateOne
{
ids
:=
make
([]
int64
,
len
(
v
))
for
i
:=
range
v
{
ids
[
i
]
=
v
[
i
]
.
ID
}
return
_u
.
AddAnnouncementReadIDs
(
ids
...
)
}
// AddAllowedGroupIDs adds the "allowed_groups" edge to the Group entity by IDs.
// AddAllowedGroupIDs adds the "allowed_groups" edge to the Group entity by IDs.
func
(
_u
*
UserUpdateOne
)
AddAllowedGroupIDs
(
ids
...
int64
)
*
UserUpdateOne
{
func
(
_u
*
UserUpdateOne
)
AddAllowedGroupIDs
(
ids
...
int64
)
*
UserUpdateOne
{
_u
.
mutation
.
AddAllowedGroupIDs
(
ids
...
)
_u
.
mutation
.
AddAllowedGroupIDs
(
ids
...
)
...
@@ -1356,6 +1576,27 @@ func (_u *UserUpdateOne) RemoveAssignedSubscriptions(v ...*UserSubscription) *Us
...
@@ -1356,6 +1576,27 @@ func (_u *UserUpdateOne) RemoveAssignedSubscriptions(v ...*UserSubscription) *Us
return
_u
.
RemoveAssignedSubscriptionIDs
(
ids
...
)
return
_u
.
RemoveAssignedSubscriptionIDs
(
ids
...
)
}
}
// ClearAnnouncementReads clears all "announcement_reads" edges to the AnnouncementRead entity.
func
(
_u
*
UserUpdateOne
)
ClearAnnouncementReads
()
*
UserUpdateOne
{
_u
.
mutation
.
ClearAnnouncementReads
()
return
_u
}
// RemoveAnnouncementReadIDs removes the "announcement_reads" edge to AnnouncementRead entities by IDs.
func
(
_u
*
UserUpdateOne
)
RemoveAnnouncementReadIDs
(
ids
...
int64
)
*
UserUpdateOne
{
_u
.
mutation
.
RemoveAnnouncementReadIDs
(
ids
...
)
return
_u
}
// RemoveAnnouncementReads removes "announcement_reads" edges to AnnouncementRead entities.
func
(
_u
*
UserUpdateOne
)
RemoveAnnouncementReads
(
v
...*
AnnouncementRead
)
*
UserUpdateOne
{
ids
:=
make
([]
int64
,
len
(
v
))
for
i
:=
range
v
{
ids
[
i
]
=
v
[
i
]
.
ID
}
return
_u
.
RemoveAnnouncementReadIDs
(
ids
...
)
}
// ClearAllowedGroups clears all "allowed_groups" edges to the Group entity.
// ClearAllowedGroups clears all "allowed_groups" edges to the Group entity.
func
(
_u
*
UserUpdateOne
)
ClearAllowedGroups
()
*
UserUpdateOne
{
func
(
_u
*
UserUpdateOne
)
ClearAllowedGroups
()
*
UserUpdateOne
{
_u
.
mutation
.
ClearAllowedGroups
()
_u
.
mutation
.
ClearAllowedGroups
()
...
@@ -1593,6 +1834,21 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
...
@@ -1593,6 +1834,21 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
if
value
,
ok
:=
_u
.
mutation
.
Notes
();
ok
{
if
value
,
ok
:=
_u
.
mutation
.
Notes
();
ok
{
_spec
.
SetField
(
user
.
FieldNotes
,
field
.
TypeString
,
value
)
_spec
.
SetField
(
user
.
FieldNotes
,
field
.
TypeString
,
value
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
TotpSecretEncrypted
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpSecretEncrypted
,
field
.
TypeString
,
value
)
}
if
_u
.
mutation
.
TotpSecretEncryptedCleared
()
{
_spec
.
ClearField
(
user
.
FieldTotpSecretEncrypted
,
field
.
TypeString
)
}
if
value
,
ok
:=
_u
.
mutation
.
TotpEnabled
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpEnabled
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
TotpEnabledAt
();
ok
{
_spec
.
SetField
(
user
.
FieldTotpEnabledAt
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
TotpEnabledAtCleared
()
{
_spec
.
ClearField
(
user
.
FieldTotpEnabledAt
,
field
.
TypeTime
)
}
if
_u
.
mutation
.
APIKeysCleared
()
{
if
_u
.
mutation
.
APIKeysCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Rel
:
sqlgraph
.
O2M
,
...
@@ -1773,6 +2029,51 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
...
@@ -1773,6 +2029,51 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
}
}
_spec
.
Edges
.
Add
=
append
(
_spec
.
Edges
.
Add
,
edge
)
_spec
.
Edges
.
Add
=
append
(
_spec
.
Edges
.
Add
,
edge
)
}
}
if
_u
.
mutation
.
AnnouncementReadsCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Inverse
:
false
,
Table
:
user
.
AnnouncementReadsTable
,
Columns
:
[]
string
{
user
.
AnnouncementReadsColumn
},
Bidi
:
false
,
Target
:
&
sqlgraph
.
EdgeTarget
{
IDSpec
:
sqlgraph
.
NewFieldSpec
(
announcementread
.
FieldID
,
field
.
TypeInt64
),
},
}
_spec
.
Edges
.
Clear
=
append
(
_spec
.
Edges
.
Clear
,
edge
)
}
if
nodes
:=
_u
.
mutation
.
RemovedAnnouncementReadsIDs
();
len
(
nodes
)
>
0
&&
!
_u
.
mutation
.
AnnouncementReadsCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Inverse
:
false
,
Table
:
user
.
AnnouncementReadsTable
,
Columns
:
[]
string
{
user
.
AnnouncementReadsColumn
},
Bidi
:
false
,
Target
:
&
sqlgraph
.
EdgeTarget
{
IDSpec
:
sqlgraph
.
NewFieldSpec
(
announcementread
.
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
.
AnnouncementReadsIDs
();
len
(
nodes
)
>
0
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
O2M
,
Inverse
:
false
,
Table
:
user
.
AnnouncementReadsTable
,
Columns
:
[]
string
{
user
.
AnnouncementReadsColumn
},
Bidi
:
false
,
Target
:
&
sqlgraph
.
EdgeTarget
{
IDSpec
:
sqlgraph
.
NewFieldSpec
(
announcementread
.
FieldID
,
field
.
TypeInt64
),
},
}
for
_
,
k
:=
range
nodes
{
edge
.
Target
.
Nodes
=
append
(
edge
.
Target
.
Nodes
,
k
)
}
_spec
.
Edges
.
Add
=
append
(
_spec
.
Edges
.
Add
,
edge
)
}
if
_u
.
mutation
.
AllowedGroupsCleared
()
{
if
_u
.
mutation
.
AllowedGroupsCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
M2M
,
Rel
:
sqlgraph
.
M2M
,
...
...
backend/go.mod
View file @
31fe0178
module github.com/Wei-Shaw/sub2api
module github.com/Wei-Shaw/sub2api
go 1.25.
5
go 1.25.
6
require (
require (
entgo.io/ent v0.14.5
entgo.io/ent v0.14.5
...
@@ -37,6 +37,7 @@ require (
...
@@ -37,6 +37,7 @@ require (
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/bmatcuk/doublestar v1.3.4 // indirect
github.com/bmatcuk/doublestar v1.3.4 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
...
@@ -106,6 +107,7 @@ require (
...
@@ -106,6 +107,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/pquerna/otp v1.5.0 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/quic-go v0.57.1 // indirect
github.com/quic-go/quic-go v0.57.1 // indirect
github.com/refraction-networking/utls v1.8.1 // indirect
github.com/refraction-networking/utls v1.8.1 // indirect
...
...
backend/go.sum
View file @
31fe0178
...
@@ -20,6 +20,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
...
@@ -20,6 +20,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
...
@@ -217,6 +219,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
...
@@ -217,6 +219,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs=
github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
...
...
backend/internal/config/config.go
View file @
31fe0178
...
@@ -47,6 +47,7 @@ type Config struct {
...
@@ -47,6 +47,7 @@ type Config struct {
Redis
RedisConfig
`mapstructure:"redis"`
Redis
RedisConfig
`mapstructure:"redis"`
Ops
OpsConfig
`mapstructure:"ops"`
Ops
OpsConfig
`mapstructure:"ops"`
JWT
JWTConfig
`mapstructure:"jwt"`
JWT
JWTConfig
`mapstructure:"jwt"`
Totp
TotpConfig
`mapstructure:"totp"`
LinuxDo
LinuxDoConnectConfig
`mapstructure:"linuxdo_connect"`
LinuxDo
LinuxDoConnectConfig
`mapstructure:"linuxdo_connect"`
Default
DefaultConfig
`mapstructure:"default"`
Default
DefaultConfig
`mapstructure:"default"`
RateLimit
RateLimitConfig
`mapstructure:"rate_limit"`
RateLimit
RateLimitConfig
`mapstructure:"rate_limit"`
...
@@ -414,6 +415,8 @@ type RedisConfig struct {
...
@@ -414,6 +415,8 @@ type RedisConfig struct {
PoolSize
int
`mapstructure:"pool_size"`
PoolSize
int
`mapstructure:"pool_size"`
// MinIdleConns: 最小空闲连接数,保持热连接减少冷启动延迟
// MinIdleConns: 最小空闲连接数,保持热连接减少冷启动延迟
MinIdleConns
int
`mapstructure:"min_idle_conns"`
MinIdleConns
int
`mapstructure:"min_idle_conns"`
// EnableTLS: 是否启用 TLS/SSL 连接
EnableTLS
bool
`mapstructure:"enable_tls"`
}
}
func
(
r
*
RedisConfig
)
Address
()
string
{
func
(
r
*
RedisConfig
)
Address
()
string
{
...
@@ -466,6 +469,16 @@ type JWTConfig struct {
...
@@ -466,6 +469,16 @@ type JWTConfig struct {
ExpireHour
int
`mapstructure:"expire_hour"`
ExpireHour
int
`mapstructure:"expire_hour"`
}
}
// TotpConfig TOTP 双因素认证配置
type
TotpConfig
struct
{
// EncryptionKey 用于加密 TOTP 密钥的 AES-256 密钥(32 字节 hex 编码)
// 如果为空,将自动生成一个随机密钥(仅适用于开发环境)
EncryptionKey
string
`mapstructure:"encryption_key"`
// EncryptionKeyConfigured 标记加密密钥是否为手动配置(非自动生成)
// 只有手动配置了密钥才允许在管理后台启用 TOTP 功能
EncryptionKeyConfigured
bool
`mapstructure:"-"`
}
type
TurnstileConfig
struct
{
type
TurnstileConfig
struct
{
Required
bool
`mapstructure:"required"`
Required
bool
`mapstructure:"required"`
}
}
...
@@ -626,6 +639,20 @@ func Load() (*Config, error) {
...
@@ -626,6 +639,20 @@ func Load() (*Config, error) {
log
.
Println
(
"Warning: JWT secret auto-generated. Consider setting a fixed secret for production."
)
log
.
Println
(
"Warning: JWT secret auto-generated. Consider setting a fixed secret for production."
)
}
}
// Auto-generate TOTP encryption key if not set (32 bytes = 64 hex chars for AES-256)
cfg
.
Totp
.
EncryptionKey
=
strings
.
TrimSpace
(
cfg
.
Totp
.
EncryptionKey
)
if
cfg
.
Totp
.
EncryptionKey
==
""
{
key
,
err
:=
generateJWTSecret
(
32
)
// Reuse the same random generation function
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"generate totp encryption key error: %w"
,
err
)
}
cfg
.
Totp
.
EncryptionKey
=
key
cfg
.
Totp
.
EncryptionKeyConfigured
=
false
log
.
Println
(
"Warning: TOTP encryption key auto-generated. Consider setting a fixed key for production."
)
}
else
{
cfg
.
Totp
.
EncryptionKeyConfigured
=
true
}
if
err
:=
cfg
.
Validate
();
err
!=
nil
{
if
err
:=
cfg
.
Validate
();
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"validate config error: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"validate config error: %w"
,
err
)
}
}
...
@@ -737,6 +764,7 @@ func setDefaults() {
...
@@ -737,6 +764,7 @@ func setDefaults() {
viper
.
SetDefault
(
"redis.write_timeout_seconds"
,
3
)
viper
.
SetDefault
(
"redis.write_timeout_seconds"
,
3
)
viper
.
SetDefault
(
"redis.pool_size"
,
128
)
viper
.
SetDefault
(
"redis.pool_size"
,
128
)
viper
.
SetDefault
(
"redis.min_idle_conns"
,
10
)
viper
.
SetDefault
(
"redis.min_idle_conns"
,
10
)
viper
.
SetDefault
(
"redis.enable_tls"
,
false
)
// Ops (vNext)
// Ops (vNext)
viper
.
SetDefault
(
"ops.enabled"
,
true
)
viper
.
SetDefault
(
"ops.enabled"
,
true
)
...
@@ -756,6 +784,9 @@ func setDefaults() {
...
@@ -756,6 +784,9 @@ func setDefaults() {
viper
.
SetDefault
(
"jwt.secret"
,
""
)
viper
.
SetDefault
(
"jwt.secret"
,
""
)
viper
.
SetDefault
(
"jwt.expire_hour"
,
24
)
viper
.
SetDefault
(
"jwt.expire_hour"
,
24
)
// TOTP
viper
.
SetDefault
(
"totp.encryption_key"
,
""
)
// Default
// Default
// Admin credentials are created via the setup flow (web wizard / CLI / AUTO_SETUP).
// Admin credentials are created via the setup flow (web wizard / CLI / AUTO_SETUP).
// Do not ship fixed defaults here to avoid insecure "known credentials" in production.
// Do not ship fixed defaults here to avoid insecure "known credentials" in production.
...
...
backend/internal/domain/announcement.go
0 → 100644
View file @
31fe0178
package
domain
import
(
"strings"
"time"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/pkg/errors"
)
const
(
AnnouncementStatusDraft
=
"draft"
AnnouncementStatusActive
=
"active"
AnnouncementStatusArchived
=
"archived"
)
const
(
AnnouncementConditionTypeSubscription
=
"subscription"
AnnouncementConditionTypeBalance
=
"balance"
)
const
(
AnnouncementOperatorIn
=
"in"
AnnouncementOperatorGT
=
"gt"
AnnouncementOperatorGTE
=
"gte"
AnnouncementOperatorLT
=
"lt"
AnnouncementOperatorLTE
=
"lte"
AnnouncementOperatorEQ
=
"eq"
)
var
(
ErrAnnouncementNotFound
=
infraerrors
.
NotFound
(
"ANNOUNCEMENT_NOT_FOUND"
,
"announcement not found"
)
ErrAnnouncementInvalidTarget
=
infraerrors
.
BadRequest
(
"ANNOUNCEMENT_INVALID_TARGET"
,
"invalid announcement targeting rules"
)
)
type
AnnouncementTargeting
struct
{
// AnyOf 表示 OR:任意一个条件组满足即可展示。
AnyOf
[]
AnnouncementConditionGroup
`json:"any_of,omitempty"`
}
type
AnnouncementConditionGroup
struct
{
// AllOf 表示 AND:组内所有条件都满足才算命中该组。
AllOf
[]
AnnouncementCondition
`json:"all_of,omitempty"`
}
type
AnnouncementCondition
struct
{
// Type: subscription | balance
Type
string
`json:"type"`
// Operator:
// - subscription: in
// - balance: gt/gte/lt/lte/eq
Operator
string
`json:"operator"`
// subscription 条件:匹配的订阅套餐(group_id)
GroupIDs
[]
int64
`json:"group_ids,omitempty"`
// balance 条件:比较阈值
Value
float64
`json:"value,omitempty"`
}
func
(
t
AnnouncementTargeting
)
Matches
(
balance
float64
,
activeSubscriptionGroupIDs
map
[
int64
]
struct
{})
bool
{
// 空规则:展示给所有用户
if
len
(
t
.
AnyOf
)
==
0
{
return
true
}
for
_
,
group
:=
range
t
.
AnyOf
{
if
len
(
group
.
AllOf
)
==
0
{
// 空条件组不命中(避免 OR 中出现无条件 “全命中”)
continue
}
allMatched
:=
true
for
_
,
cond
:=
range
group
.
AllOf
{
if
!
cond
.
Matches
(
balance
,
activeSubscriptionGroupIDs
)
{
allMatched
=
false
break
}
}
if
allMatched
{
return
true
}
}
return
false
}
func
(
c
AnnouncementCondition
)
Matches
(
balance
float64
,
activeSubscriptionGroupIDs
map
[
int64
]
struct
{})
bool
{
switch
c
.
Type
{
case
AnnouncementConditionTypeSubscription
:
if
c
.
Operator
!=
AnnouncementOperatorIn
{
return
false
}
if
len
(
c
.
GroupIDs
)
==
0
{
return
false
}
if
len
(
activeSubscriptionGroupIDs
)
==
0
{
return
false
}
for
_
,
gid
:=
range
c
.
GroupIDs
{
if
_
,
ok
:=
activeSubscriptionGroupIDs
[
gid
];
ok
{
return
true
}
}
return
false
case
AnnouncementConditionTypeBalance
:
switch
c
.
Operator
{
case
AnnouncementOperatorGT
:
return
balance
>
c
.
Value
case
AnnouncementOperatorGTE
:
return
balance
>=
c
.
Value
case
AnnouncementOperatorLT
:
return
balance
<
c
.
Value
case
AnnouncementOperatorLTE
:
return
balance
<=
c
.
Value
case
AnnouncementOperatorEQ
:
return
balance
==
c
.
Value
default
:
return
false
}
default
:
return
false
}
}
func
(
t
AnnouncementTargeting
)
NormalizeAndValidate
()
(
AnnouncementTargeting
,
error
)
{
normalized
:=
AnnouncementTargeting
{
AnyOf
:
make
([]
AnnouncementConditionGroup
,
0
,
len
(
t
.
AnyOf
))}
// 允许空 targeting(展示给所有用户)
if
len
(
t
.
AnyOf
)
==
0
{
return
normalized
,
nil
}
if
len
(
t
.
AnyOf
)
>
50
{
return
AnnouncementTargeting
{},
ErrAnnouncementInvalidTarget
}
for
_
,
g
:=
range
t
.
AnyOf
{
if
len
(
g
.
AllOf
)
==
0
{
return
AnnouncementTargeting
{},
ErrAnnouncementInvalidTarget
}
if
len
(
g
.
AllOf
)
>
50
{
return
AnnouncementTargeting
{},
ErrAnnouncementInvalidTarget
}
group
:=
AnnouncementConditionGroup
{
AllOf
:
make
([]
AnnouncementCondition
,
0
,
len
(
g
.
AllOf
))}
for
_
,
c
:=
range
g
.
AllOf
{
cond
:=
AnnouncementCondition
{
Type
:
strings
.
TrimSpace
(
c
.
Type
),
Operator
:
strings
.
TrimSpace
(
c
.
Operator
),
Value
:
c
.
Value
,
}
for
_
,
gid
:=
range
c
.
GroupIDs
{
if
gid
<=
0
{
return
AnnouncementTargeting
{},
ErrAnnouncementInvalidTarget
}
cond
.
GroupIDs
=
append
(
cond
.
GroupIDs
,
gid
)
}
if
err
:=
cond
.
validate
();
err
!=
nil
{
return
AnnouncementTargeting
{},
err
}
group
.
AllOf
=
append
(
group
.
AllOf
,
cond
)
}
normalized
.
AnyOf
=
append
(
normalized
.
AnyOf
,
group
)
}
return
normalized
,
nil
}
func
(
c
AnnouncementCondition
)
validate
()
error
{
switch
c
.
Type
{
case
AnnouncementConditionTypeSubscription
:
if
c
.
Operator
!=
AnnouncementOperatorIn
{
return
ErrAnnouncementInvalidTarget
}
if
len
(
c
.
GroupIDs
)
==
0
{
return
ErrAnnouncementInvalidTarget
}
return
nil
case
AnnouncementConditionTypeBalance
:
switch
c
.
Operator
{
case
AnnouncementOperatorGT
,
AnnouncementOperatorGTE
,
AnnouncementOperatorLT
,
AnnouncementOperatorLTE
,
AnnouncementOperatorEQ
:
return
nil
default
:
return
ErrAnnouncementInvalidTarget
}
default
:
return
ErrAnnouncementInvalidTarget
}
}
type
Announcement
struct
{
ID
int64
Title
string
Content
string
Status
string
Targeting
AnnouncementTargeting
StartsAt
*
time
.
Time
EndsAt
*
time
.
Time
CreatedBy
*
int64
UpdatedBy
*
int64
CreatedAt
time
.
Time
UpdatedAt
time
.
Time
}
func
(
a
*
Announcement
)
IsActiveAt
(
now
time
.
Time
)
bool
{
if
a
==
nil
{
return
false
}
if
a
.
Status
!=
AnnouncementStatusActive
{
return
false
}
if
a
.
StartsAt
!=
nil
&&
now
.
Before
(
*
a
.
StartsAt
)
{
return
false
}
if
a
.
EndsAt
!=
nil
&&
!
now
.
Before
(
*
a
.
EndsAt
)
{
// ends_at 语义:到点即下线
return
false
}
return
true
}
backend/internal/domain/constants.go
0 → 100644
View file @
31fe0178
package
domain
// Status constants
const
(
StatusActive
=
"active"
StatusDisabled
=
"disabled"
StatusError
=
"error"
StatusUnused
=
"unused"
StatusUsed
=
"used"
StatusExpired
=
"expired"
)
// Role constants
const
(
RoleAdmin
=
"admin"
RoleUser
=
"user"
)
// Platform constants
const
(
PlatformAnthropic
=
"anthropic"
PlatformOpenAI
=
"openai"
PlatformGemini
=
"gemini"
PlatformAntigravity
=
"antigravity"
)
// Account type constants
const
(
AccountTypeOAuth
=
"oauth"
// OAuth类型账号(full scope: profile + inference)
AccountTypeSetupToken
=
"setup-token"
// Setup Token类型账号(inference only scope)
AccountTypeAPIKey
=
"apikey"
// API Key类型账号
)
// Redeem type constants
const
(
RedeemTypeBalance
=
"balance"
RedeemTypeConcurrency
=
"concurrency"
RedeemTypeSubscription
=
"subscription"
RedeemTypeInvitation
=
"invitation"
)
// PromoCode status constants
const
(
PromoCodeStatusActive
=
"active"
PromoCodeStatusDisabled
=
"disabled"
)
// Admin adjustment type constants
const
(
AdjustmentTypeAdminBalance
=
"admin_balance"
// 管理员调整余额
AdjustmentTypeAdminConcurrency
=
"admin_concurrency"
// 管理员调整并发数
)
// Group subscription type constants
const
(
SubscriptionTypeStandard
=
"standard"
// 标准计费模式(按余额扣费)
SubscriptionTypeSubscription
=
"subscription"
// 订阅模式(按限额控制)
)
// Subscription status constants
const
(
SubscriptionStatusActive
=
"active"
SubscriptionStatusExpired
=
"expired"
SubscriptionStatusSuspended
=
"suspended"
)
backend/internal/handler/admin/account_handler.go
View file @
31fe0178
...
@@ -547,9 +547,18 @@ func (h *AccountHandler) Refresh(c *gin.Context) {
...
@@ -547,9 +547,18 @@ func (h *AccountHandler) Refresh(c *gin.Context) {
}
}
}
}
// 如果 project_id 获取失败,先更新凭证,再标记账户为 error
// 特殊处理 project_id:如果新值为空但旧值非空,保留旧值
// 这确保了即使 LoadCodeAssist 失败,project_id 也不会丢失
if
newProjectID
,
_
:=
newCredentials
[
"project_id"
]
.
(
string
);
newProjectID
==
""
{
if
oldProjectID
:=
strings
.
TrimSpace
(
account
.
GetCredential
(
"project_id"
));
oldProjectID
!=
""
{
newCredentials
[
"project_id"
]
=
oldProjectID
}
}
// 如果 project_id 获取失败,更新凭证但不标记为 error
// LoadCodeAssist 失败可能是临时网络问题,给它机会在下次自动刷新时重试
if
tokenInfo
.
ProjectIDMissing
{
if
tokenInfo
.
ProjectIDMissing
{
// 先更新凭证
// 先更新凭证
(token 本身刷新成功了)
_
,
updateErr
:=
h
.
adminService
.
UpdateAccount
(
c
.
Request
.
Context
(),
accountID
,
&
service
.
UpdateAccountInput
{
_
,
updateErr
:=
h
.
adminService
.
UpdateAccount
(
c
.
Request
.
Context
(),
accountID
,
&
service
.
UpdateAccountInput
{
Credentials
:
newCredentials
,
Credentials
:
newCredentials
,
})
})
...
@@ -557,14 +566,10 @@ func (h *AccountHandler) Refresh(c *gin.Context) {
...
@@ -557,14 +566,10 @@ func (h *AccountHandler) Refresh(c *gin.Context) {
response
.
InternalError
(
c
,
"Failed to update credentials: "
+
updateErr
.
Error
())
response
.
InternalError
(
c
,
"Failed to update credentials: "
+
updateErr
.
Error
())
return
return
}
}
// 标记账户为 error
// 不标记为 error,只返回警告信息
if
setErr
:=
h
.
adminService
.
SetAccountError
(
c
.
Request
.
Context
(),
accountID
,
"missing_project_id: 账户缺少project id,可能无法使用Antigravity"
);
setErr
!=
nil
{
response
.
InternalError
(
c
,
"Failed to set account error: "
+
setErr
.
Error
())
return
}
response
.
Success
(
c
,
gin
.
H
{
response
.
Success
(
c
,
gin
.
H
{
"message"
:
"Token refreshed but project_id
is missing, account marked as error
"
,
"message"
:
"Token refreshed
successfully,
but project_id
could not be retrieved (will retry automatically)
"
,
"warning"
:
"missing_project_id"
,
"warning"
:
"missing_project_id
_temporary
"
,
})
})
return
return
}
}
...
...
backend/internal/handler/admin/admin_service_stub_test.go
View file @
31fe0178
...
@@ -290,5 +290,9 @@ func (s *stubAdminService) ExpireRedeemCode(ctx context.Context, id int64) (*ser
...
@@ -290,5 +290,9 @@ func (s *stubAdminService) ExpireRedeemCode(ctx context.Context, id int64) (*ser
return
&
code
,
nil
return
&
code
,
nil
}
}
func
(
s
*
stubAdminService
)
GetUserBalanceHistory
(
ctx
context
.
Context
,
userID
int64
,
page
,
pageSize
int
,
codeType
string
)
([]
service
.
RedeemCode
,
int64
,
float64
,
error
)
{
return
s
.
redeems
,
int64
(
len
(
s
.
redeems
)),
100.0
,
nil
}
// Ensure stub implements interface.
// Ensure stub implements interface.
var
_
service
.
AdminService
=
(
*
stubAdminService
)(
nil
)
var
_
service
.
AdminService
=
(
*
stubAdminService
)(
nil
)
backend/internal/handler/admin/announcement_handler.go
0 → 100644
View file @
31fe0178
package
admin
import
(
"strconv"
"strings"
"time"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
middleware2
"github.com/Wei-Shaw/sub2api/internal/server/middleware"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/gin-gonic/gin"
)
// AnnouncementHandler handles admin announcement management
type
AnnouncementHandler
struct
{
announcementService
*
service
.
AnnouncementService
}
// NewAnnouncementHandler creates a new admin announcement handler
func
NewAnnouncementHandler
(
announcementService
*
service
.
AnnouncementService
)
*
AnnouncementHandler
{
return
&
AnnouncementHandler
{
announcementService
:
announcementService
,
}
}
type
CreateAnnouncementRequest
struct
{
Title
string
`json:"title" binding:"required"`
Content
string
`json:"content" binding:"required"`
Status
string
`json:"status" binding:"omitempty,oneof=draft active archived"`
Targeting
service
.
AnnouncementTargeting
`json:"targeting"`
StartsAt
*
int64
`json:"starts_at"`
// Unix seconds, 0/empty = immediate
EndsAt
*
int64
`json:"ends_at"`
// Unix seconds, 0/empty = never
}
type
UpdateAnnouncementRequest
struct
{
Title
*
string
`json:"title"`
Content
*
string
`json:"content"`
Status
*
string
`json:"status" binding:"omitempty,oneof=draft active archived"`
Targeting
*
service
.
AnnouncementTargeting
`json:"targeting"`
StartsAt
*
int64
`json:"starts_at"`
// Unix seconds, 0 = clear
EndsAt
*
int64
`json:"ends_at"`
// Unix seconds, 0 = clear
}
// List handles listing announcements with filters
// GET /api/v1/admin/announcements
func
(
h
*
AnnouncementHandler
)
List
(
c
*
gin
.
Context
)
{
page
,
pageSize
:=
response
.
ParsePagination
(
c
)
status
:=
strings
.
TrimSpace
(
c
.
Query
(
"status"
))
search
:=
strings
.
TrimSpace
(
c
.
Query
(
"search"
))
if
len
(
search
)
>
200
{
search
=
search
[
:
200
]
}
params
:=
pagination
.
PaginationParams
{
Page
:
page
,
PageSize
:
pageSize
,
}
items
,
paginationResult
,
err
:=
h
.
announcementService
.
List
(
c
.
Request
.
Context
(),
params
,
service
.
AnnouncementListFilters
{
Status
:
status
,
Search
:
search
},
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
out
:=
make
([]
dto
.
Announcement
,
0
,
len
(
items
))
for
i
:=
range
items
{
out
=
append
(
out
,
*
dto
.
AnnouncementFromService
(
&
items
[
i
]))
}
response
.
Paginated
(
c
,
out
,
paginationResult
.
Total
,
page
,
pageSize
)
}
// GetByID handles getting an announcement by ID
// GET /api/v1/admin/announcements/:id
func
(
h
*
AnnouncementHandler
)
GetByID
(
c
*
gin
.
Context
)
{
announcementID
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
||
announcementID
<=
0
{
response
.
BadRequest
(
c
,
"Invalid announcement ID"
)
return
}
item
,
err
:=
h
.
announcementService
.
GetByID
(
c
.
Request
.
Context
(),
announcementID
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
dto
.
AnnouncementFromService
(
item
))
}
// Create handles creating a new announcement
// POST /api/v1/admin/announcements
func
(
h
*
AnnouncementHandler
)
Create
(
c
*
gin
.
Context
)
{
var
req
CreateAnnouncementRequest
if
err
:=
c
.
ShouldBindJSON
(
&
req
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid request: "
+
err
.
Error
())
return
}
subject
,
ok
:=
middleware2
.
GetAuthSubjectFromContext
(
c
)
if
!
ok
{
response
.
Unauthorized
(
c
,
"User not found in context"
)
return
}
input
:=
&
service
.
CreateAnnouncementInput
{
Title
:
req
.
Title
,
Content
:
req
.
Content
,
Status
:
req
.
Status
,
Targeting
:
req
.
Targeting
,
ActorID
:
&
subject
.
UserID
,
}
if
req
.
StartsAt
!=
nil
&&
*
req
.
StartsAt
>
0
{
t
:=
time
.
Unix
(
*
req
.
StartsAt
,
0
)
input
.
StartsAt
=
&
t
}
if
req
.
EndsAt
!=
nil
&&
*
req
.
EndsAt
>
0
{
t
:=
time
.
Unix
(
*
req
.
EndsAt
,
0
)
input
.
EndsAt
=
&
t
}
created
,
err
:=
h
.
announcementService
.
Create
(
c
.
Request
.
Context
(),
input
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
dto
.
AnnouncementFromService
(
created
))
}
// Update handles updating an announcement
// PUT /api/v1/admin/announcements/:id
func
(
h
*
AnnouncementHandler
)
Update
(
c
*
gin
.
Context
)
{
announcementID
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
||
announcementID
<=
0
{
response
.
BadRequest
(
c
,
"Invalid announcement ID"
)
return
}
var
req
UpdateAnnouncementRequest
if
err
:=
c
.
ShouldBindJSON
(
&
req
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid request: "
+
err
.
Error
())
return
}
subject
,
ok
:=
middleware2
.
GetAuthSubjectFromContext
(
c
)
if
!
ok
{
response
.
Unauthorized
(
c
,
"User not found in context"
)
return
}
input
:=
&
service
.
UpdateAnnouncementInput
{
Title
:
req
.
Title
,
Content
:
req
.
Content
,
Status
:
req
.
Status
,
Targeting
:
req
.
Targeting
,
ActorID
:
&
subject
.
UserID
,
}
if
req
.
StartsAt
!=
nil
{
if
*
req
.
StartsAt
==
0
{
var
cleared
*
time
.
Time
=
nil
input
.
StartsAt
=
&
cleared
}
else
{
t
:=
time
.
Unix
(
*
req
.
StartsAt
,
0
)
ptr
:=
&
t
input
.
StartsAt
=
&
ptr
}
}
if
req
.
EndsAt
!=
nil
{
if
*
req
.
EndsAt
==
0
{
var
cleared
*
time
.
Time
=
nil
input
.
EndsAt
=
&
cleared
}
else
{
t
:=
time
.
Unix
(
*
req
.
EndsAt
,
0
)
ptr
:=
&
t
input
.
EndsAt
=
&
ptr
}
}
updated
,
err
:=
h
.
announcementService
.
Update
(
c
.
Request
.
Context
(),
announcementID
,
input
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
dto
.
AnnouncementFromService
(
updated
))
}
// Delete handles deleting an announcement
// DELETE /api/v1/admin/announcements/:id
func
(
h
*
AnnouncementHandler
)
Delete
(
c
*
gin
.
Context
)
{
announcementID
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
||
announcementID
<=
0
{
response
.
BadRequest
(
c
,
"Invalid announcement ID"
)
return
}
if
err
:=
h
.
announcementService
.
Delete
(
c
.
Request
.
Context
(),
announcementID
);
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
gin
.
H
{
"message"
:
"Announcement deleted successfully"
})
}
// ListReadStatus handles listing users read status for an announcement
// GET /api/v1/admin/announcements/:id/read-status
func
(
h
*
AnnouncementHandler
)
ListReadStatus
(
c
*
gin
.
Context
)
{
announcementID
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
||
announcementID
<=
0
{
response
.
BadRequest
(
c
,
"Invalid announcement ID"
)
return
}
page
,
pageSize
:=
response
.
ParsePagination
(
c
)
params
:=
pagination
.
PaginationParams
{
Page
:
page
,
PageSize
:
pageSize
,
}
search
:=
strings
.
TrimSpace
(
c
.
Query
(
"search"
))
if
len
(
search
)
>
200
{
search
=
search
[
:
200
]
}
items
,
paginationResult
,
err
:=
h
.
announcementService
.
ListUserReadStatus
(
c
.
Request
.
Context
(),
announcementID
,
params
,
search
,
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Paginated
(
c
,
items
,
paginationResult
.
Total
,
page
,
pageSize
)
}
backend/internal/handler/admin/group_handler.go
View file @
31fe0178
...
@@ -43,6 +43,8 @@ type CreateGroupRequest struct {
...
@@ -43,6 +43,8 @@ type CreateGroupRequest struct {
// 模型路由配置(仅 anthropic 平台使用)
// 模型路由配置(仅 anthropic 平台使用)
ModelRouting
map
[
string
][]
int64
`json:"model_routing"`
ModelRouting
map
[
string
][]
int64
`json:"model_routing"`
ModelRoutingEnabled
bool
`json:"model_routing_enabled"`
ModelRoutingEnabled
bool
`json:"model_routing_enabled"`
// 从指定分组复制账号(创建后自动绑定)
CopyAccountsFromGroupIDs
[]
int64
`json:"copy_accounts_from_group_ids"`
}
}
// UpdateGroupRequest represents update group request
// UpdateGroupRequest represents update group request
...
@@ -66,6 +68,8 @@ type UpdateGroupRequest struct {
...
@@ -66,6 +68,8 @@ type UpdateGroupRequest struct {
// 模型路由配置(仅 anthropic 平台使用)
// 模型路由配置(仅 anthropic 平台使用)
ModelRouting
map
[
string
][]
int64
`json:"model_routing"`
ModelRouting
map
[
string
][]
int64
`json:"model_routing"`
ModelRoutingEnabled
*
bool
`json:"model_routing_enabled"`
ModelRoutingEnabled
*
bool
`json:"model_routing_enabled"`
// 从指定分组复制账号(同步操作:先清空当前分组的账号绑定,再绑定源分组的账号)
CopyAccountsFromGroupIDs
[]
int64
`json:"copy_accounts_from_group_ids"`
}
}
// List handles listing all groups with pagination
// List handles listing all groups with pagination
...
@@ -155,22 +159,23 @@ func (h *GroupHandler) Create(c *gin.Context) {
...
@@ -155,22 +159,23 @@ func (h *GroupHandler) Create(c *gin.Context) {
}
}
group
,
err
:=
h
.
adminService
.
CreateGroup
(
c
.
Request
.
Context
(),
&
service
.
CreateGroupInput
{
group
,
err
:=
h
.
adminService
.
CreateGroup
(
c
.
Request
.
Context
(),
&
service
.
CreateGroupInput
{
Name
:
req
.
Name
,
Name
:
req
.
Name
,
Description
:
req
.
Description
,
Description
:
req
.
Description
,
Platform
:
req
.
Platform
,
Platform
:
req
.
Platform
,
RateMultiplier
:
req
.
RateMultiplier
,
RateMultiplier
:
req
.
RateMultiplier
,
IsExclusive
:
req
.
IsExclusive
,
IsExclusive
:
req
.
IsExclusive
,
SubscriptionType
:
req
.
SubscriptionType
,
SubscriptionType
:
req
.
SubscriptionType
,
DailyLimitUSD
:
req
.
DailyLimitUSD
,
DailyLimitUSD
:
req
.
DailyLimitUSD
,
WeeklyLimitUSD
:
req
.
WeeklyLimitUSD
,
WeeklyLimitUSD
:
req
.
WeeklyLimitUSD
,
MonthlyLimitUSD
:
req
.
MonthlyLimitUSD
,
MonthlyLimitUSD
:
req
.
MonthlyLimitUSD
,
ImagePrice1K
:
req
.
ImagePrice1K
,
ImagePrice1K
:
req
.
ImagePrice1K
,
ImagePrice2K
:
req
.
ImagePrice2K
,
ImagePrice2K
:
req
.
ImagePrice2K
,
ImagePrice4K
:
req
.
ImagePrice4K
,
ImagePrice4K
:
req
.
ImagePrice4K
,
ClaudeCodeOnly
:
req
.
ClaudeCodeOnly
,
ClaudeCodeOnly
:
req
.
ClaudeCodeOnly
,
FallbackGroupID
:
req
.
FallbackGroupID
,
FallbackGroupID
:
req
.
FallbackGroupID
,
ModelRouting
:
req
.
ModelRouting
,
ModelRouting
:
req
.
ModelRouting
,
ModelRoutingEnabled
:
req
.
ModelRoutingEnabled
,
ModelRoutingEnabled
:
req
.
ModelRoutingEnabled
,
CopyAccountsFromGroupIDs
:
req
.
CopyAccountsFromGroupIDs
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
response
.
ErrorFrom
(
c
,
err
)
...
@@ -196,23 +201,24 @@ func (h *GroupHandler) Update(c *gin.Context) {
...
@@ -196,23 +201,24 @@ func (h *GroupHandler) Update(c *gin.Context) {
}
}
group
,
err
:=
h
.
adminService
.
UpdateGroup
(
c
.
Request
.
Context
(),
groupID
,
&
service
.
UpdateGroupInput
{
group
,
err
:=
h
.
adminService
.
UpdateGroup
(
c
.
Request
.
Context
(),
groupID
,
&
service
.
UpdateGroupInput
{
Name
:
req
.
Name
,
Name
:
req
.
Name
,
Description
:
req
.
Description
,
Description
:
req
.
Description
,
Platform
:
req
.
Platform
,
Platform
:
req
.
Platform
,
RateMultiplier
:
req
.
RateMultiplier
,
RateMultiplier
:
req
.
RateMultiplier
,
IsExclusive
:
req
.
IsExclusive
,
IsExclusive
:
req
.
IsExclusive
,
Status
:
req
.
Status
,
Status
:
req
.
Status
,
SubscriptionType
:
req
.
SubscriptionType
,
SubscriptionType
:
req
.
SubscriptionType
,
DailyLimitUSD
:
req
.
DailyLimitUSD
,
DailyLimitUSD
:
req
.
DailyLimitUSD
,
WeeklyLimitUSD
:
req
.
WeeklyLimitUSD
,
WeeklyLimitUSD
:
req
.
WeeklyLimitUSD
,
MonthlyLimitUSD
:
req
.
MonthlyLimitUSD
,
MonthlyLimitUSD
:
req
.
MonthlyLimitUSD
,
ImagePrice1K
:
req
.
ImagePrice1K
,
ImagePrice1K
:
req
.
ImagePrice1K
,
ImagePrice2K
:
req
.
ImagePrice2K
,
ImagePrice2K
:
req
.
ImagePrice2K
,
ImagePrice4K
:
req
.
ImagePrice4K
,
ImagePrice4K
:
req
.
ImagePrice4K
,
ClaudeCodeOnly
:
req
.
ClaudeCodeOnly
,
ClaudeCodeOnly
:
req
.
ClaudeCodeOnly
,
FallbackGroupID
:
req
.
FallbackGroupID
,
FallbackGroupID
:
req
.
FallbackGroupID
,
ModelRouting
:
req
.
ModelRouting
,
ModelRouting
:
req
.
ModelRouting
,
ModelRoutingEnabled
:
req
.
ModelRoutingEnabled
,
ModelRoutingEnabled
:
req
.
ModelRoutingEnabled
,
CopyAccountsFromGroupIDs
:
req
.
CopyAccountsFromGroupIDs
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
response
.
ErrorFrom
(
c
,
err
)
...
...
backend/internal/handler/admin/redeem_handler.go
View file @
31fe0178
...
@@ -29,7 +29,7 @@ func NewRedeemHandler(adminService service.AdminService) *RedeemHandler {
...
@@ -29,7 +29,7 @@ func NewRedeemHandler(adminService service.AdminService) *RedeemHandler {
// GenerateRedeemCodesRequest represents generate redeem codes request
// GenerateRedeemCodesRequest represents generate redeem codes request
type
GenerateRedeemCodesRequest
struct
{
type
GenerateRedeemCodesRequest
struct
{
Count
int
`json:"count" binding:"required,min=1,max=100"`
Count
int
`json:"count" binding:"required,min=1,max=100"`
Type
string
`json:"type" binding:"required,oneof=balance concurrency subscription"`
Type
string
`json:"type" binding:"required,oneof=balance concurrency subscription
invitation
"`
Value
float64
`json:"value" binding:"min=0"`
Value
float64
`json:"value" binding:"min=0"`
GroupID
*
int64
`json:"group_id"`
// 订阅类型必填
GroupID
*
int64
`json:"group_id"`
// 订阅类型必填
ValidityDays
int
`json:"validity_days" binding:"omitempty,max=36500"`
// 订阅类型使用,默认30天,最大100年
ValidityDays
int
`json:"validity_days" binding:"omitempty,max=36500"`
// 订阅类型使用,默认30天,最大100年
...
...
backend/internal/handler/admin/setting_handler.go
View file @
31fe0178
...
@@ -48,6 +48,10 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
...
@@ -48,6 +48,10 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
RegistrationEnabled
:
settings
.
RegistrationEnabled
,
RegistrationEnabled
:
settings
.
RegistrationEnabled
,
EmailVerifyEnabled
:
settings
.
EmailVerifyEnabled
,
EmailVerifyEnabled
:
settings
.
EmailVerifyEnabled
,
PromoCodeEnabled
:
settings
.
PromoCodeEnabled
,
PromoCodeEnabled
:
settings
.
PromoCodeEnabled
,
PasswordResetEnabled
:
settings
.
PasswordResetEnabled
,
InvitationCodeEnabled
:
settings
.
InvitationCodeEnabled
,
TotpEnabled
:
settings
.
TotpEnabled
,
TotpEncryptionKeyConfigured
:
h
.
settingService
.
IsTotpEncryptionKeyConfigured
(),
SMTPHost
:
settings
.
SMTPHost
,
SMTPHost
:
settings
.
SMTPHost
,
SMTPPort
:
settings
.
SMTPPort
,
SMTPPort
:
settings
.
SMTPPort
,
SMTPUsername
:
settings
.
SMTPUsername
,
SMTPUsername
:
settings
.
SMTPUsername
,
...
@@ -70,6 +74,8 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
...
@@ -70,6 +74,8 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
DocURL
:
settings
.
DocURL
,
DocURL
:
settings
.
DocURL
,
HomeContent
:
settings
.
HomeContent
,
HomeContent
:
settings
.
HomeContent
,
HideCcsImportButton
:
settings
.
HideCcsImportButton
,
HideCcsImportButton
:
settings
.
HideCcsImportButton
,
PurchaseSubscriptionEnabled
:
settings
.
PurchaseSubscriptionEnabled
,
PurchaseSubscriptionURL
:
settings
.
PurchaseSubscriptionURL
,
DefaultConcurrency
:
settings
.
DefaultConcurrency
,
DefaultConcurrency
:
settings
.
DefaultConcurrency
,
DefaultBalance
:
settings
.
DefaultBalance
,
DefaultBalance
:
settings
.
DefaultBalance
,
EnableModelFallback
:
settings
.
EnableModelFallback
,
EnableModelFallback
:
settings
.
EnableModelFallback
,
...
@@ -89,9 +95,12 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
...
@@ -89,9 +95,12 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
// UpdateSettingsRequest 更新设置请求
// UpdateSettingsRequest 更新设置请求
type
UpdateSettingsRequest
struct
{
type
UpdateSettingsRequest
struct
{
// 注册设置
// 注册设置
RegistrationEnabled
bool
`json:"registration_enabled"`
RegistrationEnabled
bool
`json:"registration_enabled"`
EmailVerifyEnabled
bool
`json:"email_verify_enabled"`
EmailVerifyEnabled
bool
`json:"email_verify_enabled"`
PromoCodeEnabled
bool
`json:"promo_code_enabled"`
PromoCodeEnabled
bool
`json:"promo_code_enabled"`
PasswordResetEnabled
bool
`json:"password_reset_enabled"`
InvitationCodeEnabled
bool
`json:"invitation_code_enabled"`
TotpEnabled
bool
`json:"totp_enabled"`
// TOTP 双因素认证
// 邮件服务设置
// 邮件服务设置
SMTPHost
string
`json:"smtp_host"`
SMTPHost
string
`json:"smtp_host"`
...
@@ -114,14 +123,16 @@ type UpdateSettingsRequest struct {
...
@@ -114,14 +123,16 @@ type UpdateSettingsRequest struct {
LinuxDoConnectRedirectURL
string
`json:"linuxdo_connect_redirect_url"`
LinuxDoConnectRedirectURL
string
`json:"linuxdo_connect_redirect_url"`
// OEM设置
// OEM设置
SiteName
string
`json:"site_name"`
SiteName
string
`json:"site_name"`
SiteLogo
string
`json:"site_logo"`
SiteLogo
string
`json:"site_logo"`
SiteSubtitle
string
`json:"site_subtitle"`
SiteSubtitle
string
`json:"site_subtitle"`
APIBaseURL
string
`json:"api_base_url"`
APIBaseURL
string
`json:"api_base_url"`
ContactInfo
string
`json:"contact_info"`
ContactInfo
string
`json:"contact_info"`
DocURL
string
`json:"doc_url"`
DocURL
string
`json:"doc_url"`
HomeContent
string
`json:"home_content"`
HomeContent
string
`json:"home_content"`
HideCcsImportButton
bool
`json:"hide_ccs_import_button"`
HideCcsImportButton
bool
`json:"hide_ccs_import_button"`
PurchaseSubscriptionEnabled
*
bool
`json:"purchase_subscription_enabled"`
PurchaseSubscriptionURL
*
string
`json:"purchase_subscription_url"`
// 默认配置
// 默认配置
DefaultConcurrency
int
`json:"default_concurrency"`
DefaultConcurrency
int
`json:"default_concurrency"`
...
@@ -198,6 +209,16 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
...
@@ -198,6 +209,16 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
}
}
}
}
// TOTP 双因素认证参数验证
// 只有手动配置了加密密钥才允许启用 TOTP 功能
if
req
.
TotpEnabled
&&
!
previousSettings
.
TotpEnabled
{
// 尝试启用 TOTP,检查加密密钥是否已手动配置
if
!
h
.
settingService
.
IsTotpEncryptionKeyConfigured
()
{
response
.
BadRequest
(
c
,
"Cannot enable TOTP: TOTP_ENCRYPTION_KEY environment variable must be configured first. Generate a key with 'openssl rand -hex 32' and set it in your environment."
)
return
}
}
// LinuxDo Connect 参数验证
// LinuxDo Connect 参数验证
if
req
.
LinuxDoConnectEnabled
{
if
req
.
LinuxDoConnectEnabled
{
req
.
LinuxDoConnectClientID
=
strings
.
TrimSpace
(
req
.
LinuxDoConnectClientID
)
req
.
LinuxDoConnectClientID
=
strings
.
TrimSpace
(
req
.
LinuxDoConnectClientID
)
...
@@ -227,6 +248,34 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
...
@@ -227,6 +248,34 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
}
}
}
}
// “购买订阅”页面配置验证
purchaseEnabled
:=
previousSettings
.
PurchaseSubscriptionEnabled
if
req
.
PurchaseSubscriptionEnabled
!=
nil
{
purchaseEnabled
=
*
req
.
PurchaseSubscriptionEnabled
}
purchaseURL
:=
previousSettings
.
PurchaseSubscriptionURL
if
req
.
PurchaseSubscriptionURL
!=
nil
{
purchaseURL
=
strings
.
TrimSpace
(
*
req
.
PurchaseSubscriptionURL
)
}
// - 启用时要求 URL 合法且非空
// - 禁用时允许为空;若提供了 URL 也做基本校验,避免误配置
if
purchaseEnabled
{
if
purchaseURL
==
""
{
response
.
BadRequest
(
c
,
"Purchase Subscription URL is required when enabled"
)
return
}
if
err
:=
config
.
ValidateAbsoluteHTTPURL
(
purchaseURL
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Purchase Subscription URL must be an absolute http(s) URL"
)
return
}
}
else
if
purchaseURL
!=
""
{
if
err
:=
config
.
ValidateAbsoluteHTTPURL
(
purchaseURL
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Purchase Subscription URL must be an absolute http(s) URL"
)
return
}
}
// Ops metrics collector interval validation (seconds).
// Ops metrics collector interval validation (seconds).
if
req
.
OpsMetricsIntervalSeconds
!=
nil
{
if
req
.
OpsMetricsIntervalSeconds
!=
nil
{
v
:=
*
req
.
OpsMetricsIntervalSeconds
v
:=
*
req
.
OpsMetricsIntervalSeconds
...
@@ -240,40 +289,45 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
...
@@ -240,40 +289,45 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
}
}
settings
:=
&
service
.
SystemSettings
{
settings
:=
&
service
.
SystemSettings
{
RegistrationEnabled
:
req
.
RegistrationEnabled
,
RegistrationEnabled
:
req
.
RegistrationEnabled
,
EmailVerifyEnabled
:
req
.
EmailVerifyEnabled
,
EmailVerifyEnabled
:
req
.
EmailVerifyEnabled
,
PromoCodeEnabled
:
req
.
PromoCodeEnabled
,
PromoCodeEnabled
:
req
.
PromoCodeEnabled
,
SMTPHost
:
req
.
SMTPHost
,
PasswordResetEnabled
:
req
.
PasswordResetEnabled
,
SMTPPort
:
req
.
SMTPPort
,
InvitationCodeEnabled
:
req
.
InvitationCodeEnabled
,
SMTPUsername
:
req
.
SMTPUsername
,
TotpEnabled
:
req
.
TotpEnabled
,
SMTPPassword
:
req
.
SMTPPassword
,
SMTPHost
:
req
.
SMTPHost
,
SMTPFrom
:
req
.
SMTPFrom
,
SMTPPort
:
req
.
SMTPPort
,
SMTPFromName
:
req
.
SMTPFromName
,
SMTPUsername
:
req
.
SMTPUsername
,
SMTPUseTLS
:
req
.
SMTPUseTLS
,
SMTPPassword
:
req
.
SMTPPassword
,
TurnstileEnabled
:
req
.
TurnstileEnabled
,
SMTPFrom
:
req
.
SMTPFrom
,
TurnstileSiteKey
:
req
.
TurnstileSiteKey
,
SMTPFromName
:
req
.
SMTPFromName
,
TurnstileSecretKey
:
req
.
TurnstileSecretKey
,
SMTPUseTLS
:
req
.
SMTPUseTLS
,
LinuxDoConnectEnabled
:
req
.
LinuxDoConnectEnabled
,
TurnstileEnabled
:
req
.
TurnstileEnabled
,
LinuxDoConnectClientID
:
req
.
LinuxDoConnectClientID
,
TurnstileSiteKey
:
req
.
TurnstileSiteKey
,
LinuxDoConnectClientSecret
:
req
.
LinuxDoConnectClientSecret
,
TurnstileSecretKey
:
req
.
TurnstileSecretKey
,
LinuxDoConnectRedirectURL
:
req
.
LinuxDoConnectRedirectURL
,
LinuxDoConnectEnabled
:
req
.
LinuxDoConnectEnabled
,
SiteName
:
req
.
SiteName
,
LinuxDoConnectClientID
:
req
.
LinuxDoConnectClientID
,
SiteLogo
:
req
.
SiteLogo
,
LinuxDoConnectClientSecret
:
req
.
LinuxDoConnectClientSecret
,
SiteSubtitle
:
req
.
SiteSubtitle
,
LinuxDoConnectRedirectURL
:
req
.
LinuxDoConnectRedirectURL
,
APIBaseURL
:
req
.
APIBaseURL
,
SiteName
:
req
.
SiteName
,
ContactInfo
:
req
.
ContactInfo
,
SiteLogo
:
req
.
SiteLogo
,
DocURL
:
req
.
DocURL
,
SiteSubtitle
:
req
.
SiteSubtitle
,
HomeContent
:
req
.
HomeContent
,
APIBaseURL
:
req
.
APIBaseURL
,
HideCcsImportButton
:
req
.
HideCcsImportButton
,
ContactInfo
:
req
.
ContactInfo
,
DefaultConcurrency
:
req
.
DefaultConcurrency
,
DocURL
:
req
.
DocURL
,
DefaultBalance
:
req
.
DefaultBalance
,
HomeContent
:
req
.
HomeContent
,
EnableModelFallback
:
req
.
EnableModelFallback
,
HideCcsImportButton
:
req
.
HideCcsImportButton
,
FallbackModelAnthropic
:
req
.
FallbackModelAnthropic
,
PurchaseSubscriptionEnabled
:
purchaseEnabled
,
FallbackModelOpenAI
:
req
.
FallbackModelOpenAI
,
PurchaseSubscriptionURL
:
purchaseURL
,
FallbackModelGemini
:
req
.
FallbackModelGemini
,
DefaultConcurrency
:
req
.
DefaultConcurrency
,
FallbackModelAntigravity
:
req
.
FallbackModelAntigravity
,
DefaultBalance
:
req
.
DefaultBalance
,
EnableIdentityPatch
:
req
.
EnableIdentityPatch
,
EnableModelFallback
:
req
.
EnableModelFallback
,
IdentityPatchPrompt
:
req
.
IdentityPatchPrompt
,
FallbackModelAnthropic
:
req
.
FallbackModelAnthropic
,
FallbackModelOpenAI
:
req
.
FallbackModelOpenAI
,
FallbackModelGemini
:
req
.
FallbackModelGemini
,
FallbackModelAntigravity
:
req
.
FallbackModelAntigravity
,
EnableIdentityPatch
:
req
.
EnableIdentityPatch
,
IdentityPatchPrompt
:
req
.
IdentityPatchPrompt
,
OpsMonitoringEnabled
:
func
()
bool
{
OpsMonitoringEnabled
:
func
()
bool
{
if
req
.
OpsMonitoringEnabled
!=
nil
{
if
req
.
OpsMonitoringEnabled
!=
nil
{
return
*
req
.
OpsMonitoringEnabled
return
*
req
.
OpsMonitoringEnabled
...
@@ -318,6 +372,10 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
...
@@ -318,6 +372,10 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
RegistrationEnabled
:
updatedSettings
.
RegistrationEnabled
,
RegistrationEnabled
:
updatedSettings
.
RegistrationEnabled
,
EmailVerifyEnabled
:
updatedSettings
.
EmailVerifyEnabled
,
EmailVerifyEnabled
:
updatedSettings
.
EmailVerifyEnabled
,
PromoCodeEnabled
:
updatedSettings
.
PromoCodeEnabled
,
PromoCodeEnabled
:
updatedSettings
.
PromoCodeEnabled
,
PasswordResetEnabled
:
updatedSettings
.
PasswordResetEnabled
,
InvitationCodeEnabled
:
updatedSettings
.
InvitationCodeEnabled
,
TotpEnabled
:
updatedSettings
.
TotpEnabled
,
TotpEncryptionKeyConfigured
:
h
.
settingService
.
IsTotpEncryptionKeyConfigured
(),
SMTPHost
:
updatedSettings
.
SMTPHost
,
SMTPHost
:
updatedSettings
.
SMTPHost
,
SMTPPort
:
updatedSettings
.
SMTPPort
,
SMTPPort
:
updatedSettings
.
SMTPPort
,
SMTPUsername
:
updatedSettings
.
SMTPUsername
,
SMTPUsername
:
updatedSettings
.
SMTPUsername
,
...
@@ -340,6 +398,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
...
@@ -340,6 +398,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
DocURL
:
updatedSettings
.
DocURL
,
DocURL
:
updatedSettings
.
DocURL
,
HomeContent
:
updatedSettings
.
HomeContent
,
HomeContent
:
updatedSettings
.
HomeContent
,
HideCcsImportButton
:
updatedSettings
.
HideCcsImportButton
,
HideCcsImportButton
:
updatedSettings
.
HideCcsImportButton
,
PurchaseSubscriptionEnabled
:
updatedSettings
.
PurchaseSubscriptionEnabled
,
PurchaseSubscriptionURL
:
updatedSettings
.
PurchaseSubscriptionURL
,
DefaultConcurrency
:
updatedSettings
.
DefaultConcurrency
,
DefaultConcurrency
:
updatedSettings
.
DefaultConcurrency
,
DefaultBalance
:
updatedSettings
.
DefaultBalance
,
DefaultBalance
:
updatedSettings
.
DefaultBalance
,
EnableModelFallback
:
updatedSettings
.
EnableModelFallback
,
EnableModelFallback
:
updatedSettings
.
EnableModelFallback
,
...
@@ -384,6 +444,12 @@ func diffSettings(before *service.SystemSettings, after *service.SystemSettings,
...
@@ -384,6 +444,12 @@ func diffSettings(before *service.SystemSettings, after *service.SystemSettings,
if
before
.
EmailVerifyEnabled
!=
after
.
EmailVerifyEnabled
{
if
before
.
EmailVerifyEnabled
!=
after
.
EmailVerifyEnabled
{
changed
=
append
(
changed
,
"email_verify_enabled"
)
changed
=
append
(
changed
,
"email_verify_enabled"
)
}
}
if
before
.
PasswordResetEnabled
!=
after
.
PasswordResetEnabled
{
changed
=
append
(
changed
,
"password_reset_enabled"
)
}
if
before
.
TotpEnabled
!=
after
.
TotpEnabled
{
changed
=
append
(
changed
,
"totp_enabled"
)
}
if
before
.
SMTPHost
!=
after
.
SMTPHost
{
if
before
.
SMTPHost
!=
after
.
SMTPHost
{
changed
=
append
(
changed
,
"smtp_host"
)
changed
=
append
(
changed
,
"smtp_host"
)
}
}
...
...
backend/internal/handler/admin/subscription_handler.go
View file @
31fe0178
...
@@ -77,7 +77,11 @@ func (h *SubscriptionHandler) List(c *gin.Context) {
...
@@ -77,7 +77,11 @@ func (h *SubscriptionHandler) List(c *gin.Context) {
}
}
status
:=
c
.
Query
(
"status"
)
status
:=
c
.
Query
(
"status"
)
subscriptions
,
pagination
,
err
:=
h
.
subscriptionService
.
List
(
c
.
Request
.
Context
(),
page
,
pageSize
,
userID
,
groupID
,
status
)
// Parse sorting parameters
sortBy
:=
c
.
DefaultQuery
(
"sort_by"
,
"created_at"
)
sortOrder
:=
c
.
DefaultQuery
(
"sort_order"
,
"desc"
)
subscriptions
,
pagination
,
err
:=
h
.
subscriptionService
.
List
(
c
.
Request
.
Context
(),
page
,
pageSize
,
userID
,
groupID
,
status
,
sortBy
,
sortOrder
)
if
err
!=
nil
{
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
response
.
ErrorFrom
(
c
,
err
)
return
return
...
...
Prev
1
2
3
4
5
6
7
…
12
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment