axonhub / internal /server /backup /backup_ops.go
llzai's picture
Upload 1793 files
9853396 verified
package backup
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/samber/lo"
"github.com/looplj/axonhub/internal/contexts"
"github.com/looplj/axonhub/internal/ent"
)
func (svc *BackupService) Backup(ctx context.Context, opts BackupOptions) ([]byte, error) {
user, ok := contexts.GetUser(ctx)
if !ok || user == nil {
return nil, fmt.Errorf("user not found in context")
}
if !user.IsOwner {
return nil, fmt.Errorf("only owners can perform backup operations")
}
return svc.doBackup(ctx, opts)
}
// BackupWithoutAuth performs backup without user authentication check.
// This is used by the auto-backup scheduler which runs in a privileged context.
func (svc *BackupService) BackupWithoutAuth(ctx context.Context, opts BackupOptions) ([]byte, error) {
return svc.doBackup(ctx, opts)
}
func (svc *BackupService) doBackup(ctx context.Context, opts BackupOptions) ([]byte, error) {
var (
channelDataList []*BackupChannel
channelModelPriceDataList []*BackupChannelModelPrice
)
if opts.IncludeChannels {
channels, err := svc.db.Channel.Query().All(ctx)
if err != nil {
return nil, err
}
channelDataList = lo.Map(channels, func(ch *ent.Channel, _ int) *BackupChannel {
return &BackupChannel{
Channel: *ch,
Credentials: ch.Credentials,
}
})
}
if opts.IncludeModelPrices {
prices, err := svc.db.ChannelModelPrice.Query().
WithChannel().
All(ctx)
if err != nil {
return nil, err
}
channelModelPriceDataList = lo.FilterMap(prices, func(p *ent.ChannelModelPrice, _ int) (*BackupChannelModelPrice, bool) {
if p.Edges.Channel == nil {
return nil, false
}
return &BackupChannelModelPrice{
ChannelName: p.Edges.Channel.Name,
ModelID: p.ModelID,
Price: p.Price,
ReferenceID: p.ReferenceID,
}, true
})
}
var modelDataList []*BackupModel
if opts.IncludeModels {
models, err := svc.db.Model.Query().All(ctx)
if err != nil {
return nil, err
}
modelDataList = lo.Map(models, func(m *ent.Model, _ int) *BackupModel {
return &BackupModel{
Model: *m,
}
})
}
var apiKeyDataList []*BackupAPIKey
if opts.IncludeAPIKeys {
apiKeys, err := svc.db.APIKey.Query().WithProject().All(ctx)
if err != nil {
return nil, err
}
apiKeyDataList = lo.Map(apiKeys, func(ak *ent.APIKey, _ int) *BackupAPIKey {
projectName := ""
if ak.Edges.Project != nil {
projectName = ak.Edges.Project.Name
}
return &BackupAPIKey{
APIKey: *ak,
ProjectName: projectName,
}
})
}
backupData := &BackupData{
Version: BackupVersion,
Timestamp: time.Now(),
Channels: channelDataList,
Models: modelDataList,
ChannelModelPrices: channelModelPriceDataList,
APIKeys: apiKeyDataList,
}
return json.MarshalIndent(backupData, "", " ")
}