mirror of
https://github.com/rishikanthc/Scriberr.git
synced 2026-07-01 08:15:46 +00:00
backend: move user settings to relational table
This commit is contained in:
@@ -27,10 +27,12 @@ var (
|
||||
ErrSmallLLMRequired = errors.New("small LLM model is required")
|
||||
ErrAPIKeyNotFound = errors.New("api key not found")
|
||||
ErrUserDisabled = errors.New("user is disabled")
|
||||
ErrSettingsUnavailable = errors.New("user settings repository is unavailable")
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
users repository.UserRepository
|
||||
settings repository.UserSettingsRepository
|
||||
refreshTokens repository.RefreshTokenRepository
|
||||
apiKeys repository.APIKeyRepository
|
||||
profiles repository.ProfileRepository
|
||||
@@ -52,9 +54,10 @@ type SettingsUpdate struct {
|
||||
AutoRenameEnabled *bool
|
||||
}
|
||||
|
||||
func NewService(users repository.UserRepository, refreshTokens repository.RefreshTokenRepository, apiKeys repository.APIKeyRepository, profiles repository.ProfileRepository, llmConfigs repository.LLMConfigRepository, authService *auth.AuthService) *Service {
|
||||
func NewService(users repository.UserRepository, settings repository.UserSettingsRepository, refreshTokens repository.RefreshTokenRepository, apiKeys repository.APIKeyRepository, profiles repository.ProfileRepository, llmConfigs repository.LLMConfigRepository, authService *auth.AuthService) *Service {
|
||||
return &Service{
|
||||
users: users,
|
||||
settings: settings,
|
||||
refreshTokens: refreshTokens,
|
||||
apiKeys: apiKeys,
|
||||
profiles: profiles,
|
||||
@@ -185,6 +188,10 @@ func (s *Service) UpdateSettings(ctx context.Context, userID uint, update Settin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
settings, err := s.settingsForUser(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultProfileID := user.DefaultProfileID
|
||||
if update.DefaultProfileIDSet {
|
||||
defaultProfileID = update.DefaultProfileID
|
||||
@@ -211,10 +218,13 @@ func (s *Service) UpdateSettings(ctx context.Context, userID uint, update Settin
|
||||
user.DefaultProfileID = defaultProfileID
|
||||
user.AutoTranscriptionEnabled = autoTranscription
|
||||
user.AutoRenameEnabled = autoRename
|
||||
if err := s.users.Update(ctx, user); err != nil {
|
||||
settings.DefaultProfileID = defaultProfileID
|
||||
settings.AutoTranscriptionEnabled = autoTranscription
|
||||
settings.AutoRenameEnabled = autoRename
|
||||
if err := s.settings.Upsert(ctx, settings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return user, nil
|
||||
return s.users.FindByID(ctx, userID)
|
||||
}
|
||||
|
||||
func (s *Service) ListAPIKeys(ctx context.Context, userID uint) ([]models.APIKey, error) {
|
||||
@@ -310,6 +320,31 @@ func (s *Service) smallLLMReady(ctx context.Context, userID uint) bool {
|
||||
strings.TrimSpace(*config.SmallModel) != ""
|
||||
}
|
||||
|
||||
func (s *Service) settingsForUser(ctx context.Context, user *models.User) (*models.UserSettings, error) {
|
||||
if s.settings == nil {
|
||||
return nil, ErrSettingsUnavailable
|
||||
}
|
||||
settings, err := s.settings.FindByUser(ctx, user.ID)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
settings = &models.UserSettings{
|
||||
UserID: user.ID,
|
||||
DefaultProfileID: user.DefaultProfileID,
|
||||
AutoTranscriptionEnabled: user.AutoTranscriptionEnabled,
|
||||
AutoRenameEnabled: user.AutoRenameEnabled,
|
||||
SummaryDefaultModel: user.SummaryDefaultModel,
|
||||
}
|
||||
if user.SettingsJSON == "" {
|
||||
settings.AutoTranscriptionEnabled = true
|
||||
settings.AutoRenameEnabled = true
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
func llmBaseURL(config *models.LLMConfig) string {
|
||||
if config.BaseURL != nil && strings.TrimSpace(*config.BaseURL) != "" {
|
||||
return strings.TrimSpace(*config.BaseURL)
|
||||
|
||||
@@ -72,6 +72,7 @@ func newAuthTestServer(t *testing.T) *authTestServer {
|
||||
require.NoError(t, err)
|
||||
accountService := account.NewService(
|
||||
repository.NewUserRepository(database.DB),
|
||||
repository.NewUserSettingsRepository(database.DB),
|
||||
repository.NewRefreshTokenRepository(database.DB),
|
||||
repository.NewAPIKeyRepository(database.DB),
|
||||
profileRepo,
|
||||
|
||||
@@ -237,10 +237,13 @@ func TestSettingsPartialUpdateAndValidation(t *testing.T) {
|
||||
require.Equal(t, profileID, body["default_profile_id"])
|
||||
require.Equal(t, true, body["local_only"])
|
||||
|
||||
var settings models.UserSettings
|
||||
require.NoError(t, database.DB.First(&settings).Error)
|
||||
require.NotNil(t, settings.DefaultProfileID)
|
||||
require.Equal(t, strings.TrimPrefix(profileID, "profile_"), *settings.DefaultProfileID)
|
||||
var user models.User
|
||||
require.NoError(t, database.DB.First(&user).Error)
|
||||
require.NotNil(t, user.DefaultProfileID)
|
||||
require.Equal(t, strings.TrimPrefix(profileID, "profile_"), *user.DefaultProfileID)
|
||||
require.NotContains(t, user.SettingsJSON, strings.TrimPrefix(profileID, "profile_"))
|
||||
|
||||
resp, body = s.request(t, http.MethodPatch, "/api/v1/settings", map[string]any{
|
||||
"default_profile_id": "profile_missing",
|
||||
|
||||
@@ -74,6 +74,7 @@ func Build(cfg *config.Config) (*App, error) {
|
||||
profileRepo := repository.NewProfileRepository(database.DB)
|
||||
tagRepo := repository.NewTagRepository(database.DB)
|
||||
userRepo := repository.NewUserRepository(database.DB)
|
||||
userSettingsRepo := repository.NewUserSettingsRepository(database.DB)
|
||||
refreshTokenRepo := repository.NewRefreshTokenRepository(database.DB)
|
||||
apiKeyRepo := repository.NewAPIKeyRepository(database.DB)
|
||||
chatRepo := repository.NewChatRepository(database.DB)
|
||||
@@ -104,7 +105,7 @@ func Build(cfg *config.Config) (*App, error) {
|
||||
})
|
||||
summaryService := summarization.NewService(summaryRepo, llmConfigRepo, jobRepo, summarization.Config{})
|
||||
chatService := chatdomain.NewService(chatRepo, llmConfigRepo)
|
||||
accountService := account.NewService(userRepo, refreshTokenRepo, apiKeyRepo, profileRepo, llmConfigRepo, authService)
|
||||
accountService := account.NewService(userRepo, userSettingsRepo, refreshTokenRepo, apiKeyRepo, profileRepo, llmConfigRepo, authService)
|
||||
adminService := admin.NewService(userRepo, refreshTokenRepo, apiKeyRepo)
|
||||
profileService := profiledomain.NewService(profileRepo)
|
||||
llmProviderService := llmprovider.NewService(llmConfigRepo, llmprovider.HTTPConnectionTester{})
|
||||
|
||||
@@ -63,6 +63,7 @@ func TestFreshSchemaInitialization(t *testing.T) {
|
||||
expectedTables := []string{
|
||||
"schema_migrations",
|
||||
"users",
|
||||
"user_settings",
|
||||
"api_keys",
|
||||
"refresh_tokens",
|
||||
"transcription_profiles",
|
||||
@@ -121,11 +122,18 @@ func TestFreshSchemaInitialization(t *testing.T) {
|
||||
assert.True(t, db.Migrator().HasColumn(&models.User{}, "status"))
|
||||
assert.True(t, db.Migrator().HasColumn(&models.User{}, "last_login_at"))
|
||||
assert.True(t, db.Migrator().HasColumn(&models.User{}, "password_changed_at"))
|
||||
assert.True(t, db.Migrator().HasColumn(&models.UserSettings{}, "default_profile_id"))
|
||||
assert.True(t, db.Migrator().HasColumn(&models.UserSettings{}, "auto_transcription_enabled"))
|
||||
assert.True(t, db.Migrator().HasColumn(&models.UserSettings{}, "auto_rename_enabled"))
|
||||
|
||||
title := "Fresh transcription"
|
||||
user := models.User{Username: "fresh-user", Password: "pw"}
|
||||
require.NoError(t, db.Create(&user).Error)
|
||||
require.NoError(t, repository.NewUserRepository(db).Create(t.Context(), &user))
|
||||
assert.Equal(t, models.UserStatusActive, user.Status)
|
||||
var userSettings models.UserSettings
|
||||
require.NoError(t, db.First(&userSettings, "user_id = ?", user.ID).Error)
|
||||
assert.True(t, userSettings.AutoTranscriptionEnabled)
|
||||
assert.True(t, userSettings.AutoRenameEnabled)
|
||||
|
||||
job := models.TranscriptionJob{UserID: 1, Title: &title, Status: models.StatusUploaded, AudioPath: "/tmp/audio.wav"}
|
||||
require.NoError(t, db.Create(&job).Error)
|
||||
|
||||
@@ -11,10 +11,11 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const latestSchemaVersion = 9
|
||||
const latestSchemaVersion = 10
|
||||
|
||||
var schemaModels = []any{
|
||||
&models.User{},
|
||||
&models.UserSettings{},
|
||||
&models.APIKey{},
|
||||
&models.RefreshToken{},
|
||||
&models.TranscriptionProfile{},
|
||||
|
||||
@@ -12,14 +12,15 @@ import (
|
||||
type migrationStep func(*gorm.DB) error
|
||||
|
||||
var schemaSteps = map[int]migrationStep{
|
||||
2: migrateStepV1ToV2,
|
||||
3: migrateStepV2ToV3,
|
||||
4: migrateStepV3ToV4,
|
||||
5: migrateStepV4ToV5,
|
||||
6: migrateStepV5ToV6,
|
||||
7: migrateStepV6ToV7,
|
||||
8: migrateStepV7ToV8,
|
||||
9: migrateStepV8ToV9,
|
||||
2: migrateStepV1ToV2,
|
||||
3: migrateStepV2ToV3,
|
||||
4: migrateStepV3ToV4,
|
||||
5: migrateStepV4ToV5,
|
||||
6: migrateStepV5ToV6,
|
||||
7: migrateStepV6ToV7,
|
||||
8: migrateStepV7ToV8,
|
||||
9: migrateStepV8ToV9,
|
||||
10: migrateStepV9ToV10,
|
||||
}
|
||||
|
||||
func runSchemaSteps(tx *gorm.DB, currentVersion int) error {
|
||||
@@ -78,6 +79,13 @@ func migrateStepV8ToV9(tx *gorm.DB) error {
|
||||
return tx.Exec(`CREATE INDEX IF NOT EXISTS idx_recording_sessions_artifact_cleanup ON recording_sessions(status, temporary_artifacts_cleaned_at)`).Error
|
||||
}
|
||||
|
||||
func migrateStepV9ToV10(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&models.UserSettings{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return backfillUserSettings(tx)
|
||||
}
|
||||
|
||||
func backfillCompatibilityColumns(tx *gorm.DB) error {
|
||||
if err := backfillUsers(tx); err != nil {
|
||||
return err
|
||||
@@ -120,6 +128,38 @@ func backfillUsers(tx *gorm.DB) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := backfillUserSettings(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func backfillUserSettings(tx *gorm.DB) error {
|
||||
var users []models.User
|
||||
if err := tx.Find(&users).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
for _, user := range users {
|
||||
settings := models.UserSettings{
|
||||
UserID: user.ID,
|
||||
DefaultProfileID: user.DefaultProfileID,
|
||||
AutoTranscriptionEnabled: user.AutoTranscriptionEnabled,
|
||||
AutoRenameEnabled: user.AutoRenameEnabled,
|
||||
SummaryDefaultModel: user.SummaryDefaultModel,
|
||||
}
|
||||
if settings.UserID == 0 {
|
||||
continue
|
||||
}
|
||||
if !settings.AutoTranscriptionEnabled && user.SettingsJSON == "" {
|
||||
settings.AutoTranscriptionEnabled = true
|
||||
}
|
||||
if !settings.AutoRenameEnabled && user.SettingsJSON == "" {
|
||||
settings.AutoRenameEnabled = true
|
||||
}
|
||||
if err := tx.Where("user_id = ?", settings.UserID).Assign(settings).FirstOrCreate(&settings).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,25 @@ type userSettings struct {
|
||||
SummaryDefaultModel string `json:"summary_default_model,omitempty"`
|
||||
}
|
||||
|
||||
type UserSettings struct {
|
||||
UserID uint `json:"user_id" gorm:"primaryKey;not null"`
|
||||
DefaultProfileID *string `json:"default_profile_id,omitempty" gorm:"type:varchar(36);index"`
|
||||
AutoTranscriptionEnabled bool `json:"auto_transcription_enabled" gorm:"not null;default:true"`
|
||||
AutoRenameEnabled bool `json:"auto_rename_enabled" gorm:"not null;default:true"`
|
||||
SummaryDefaultModel string `json:"summary_default_model,omitempty" gorm:"type:varchar(100)"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
||||
|
||||
User User `json:"-" gorm:"foreignKey:UserID;references:ID;constraint:OnDelete:CASCADE"`
|
||||
}
|
||||
|
||||
func (UserSettings) TableName() string { return "user_settings" }
|
||||
|
||||
func (s *UserSettings) ApplyDefaults() {
|
||||
s.AutoTranscriptionEnabled = true
|
||||
s.AutoRenameEnabled = true
|
||||
}
|
||||
|
||||
// RefreshToken represents a persistent refresh token for rotating access.
|
||||
type RefreshToken struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
var ErrQueueClaimConflict = errors.New("queue claim is no longer owned by this worker")
|
||||
@@ -37,12 +38,52 @@ func NewUserRepository(db *gorm.DB) UserRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *userRepository) Create(ctx context.Context, user *models.User) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(user).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
settings := models.UserSettings{
|
||||
UserID: user.ID,
|
||||
DefaultProfileID: user.DefaultProfileID,
|
||||
AutoTranscriptionEnabled: true,
|
||||
AutoRenameEnabled: true,
|
||||
SummaryDefaultModel: user.SummaryDefaultModel,
|
||||
}
|
||||
if user.AutoTranscriptionEnabled {
|
||||
settings.AutoTranscriptionEnabled = user.AutoTranscriptionEnabled
|
||||
}
|
||||
if user.AutoRenameEnabled {
|
||||
settings.AutoRenameEnabled = user.AutoRenameEnabled
|
||||
}
|
||||
return tx.FirstOrCreate(&settings, "user_id = ?", user.ID).Error
|
||||
})
|
||||
}
|
||||
|
||||
func (r *userRepository) FindByID(ctx context.Context, id interface{}) (*models.User, error) {
|
||||
var user models.User
|
||||
if err := r.db.WithContext(ctx).First(&user, "id = ?", id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.hydrateSettings(ctx, &user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (r *userRepository) Update(ctx context.Context, user *models.User) error {
|
||||
return r.db.WithContext(ctx).Save(user).Error
|
||||
}
|
||||
|
||||
func (r *userRepository) FindByUsername(ctx context.Context, username string) (*models.User, error) {
|
||||
var user models.User
|
||||
err := r.db.WithContext(ctx).Where("username = ?", username).First(&user).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.hydrateSettings(ctx, &user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
@@ -67,6 +108,11 @@ func (r *userRepository) ListUsersForAdmin(ctx context.Context, offset, limit in
|
||||
if err := query.Order("created_at DESC, id DESC").Offset(offset).Limit(limit).Find(&users).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
for i := range users {
|
||||
if err := r.hydrateSettings(ctx, &users[i]); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
}
|
||||
return users, count, nil
|
||||
}
|
||||
|
||||
@@ -85,17 +131,80 @@ func (r *userRepository) CountActiveAdmins(ctx context.Context) (int64, error) {
|
||||
}
|
||||
|
||||
func (r *userRepository) CountWithAutoTranscription(ctx context.Context) (int64, error) {
|
||||
var users []models.User
|
||||
if err := r.db.WithContext(ctx).Find(&users).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var count int64
|
||||
for _, user := range users {
|
||||
if user.AutoTranscriptionEnabled {
|
||||
count++
|
||||
}
|
||||
err := r.db.WithContext(ctx).Model(&models.UserSettings{}).
|
||||
Where("auto_transcription_enabled = ?", true).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *userRepository) hydrateSettings(ctx context.Context, user *models.User) error {
|
||||
if user == nil || user.ID == 0 {
|
||||
return nil
|
||||
}
|
||||
return count, nil
|
||||
var settings models.UserSettings
|
||||
err := r.db.WithContext(ctx).First(&settings, "user_id = ?", user.ID).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.DefaultProfileID = settings.DefaultProfileID
|
||||
user.AutoTranscriptionEnabled = settings.AutoTranscriptionEnabled
|
||||
user.AutoRenameEnabled = settings.AutoRenameEnabled
|
||||
user.SummaryDefaultModel = settings.SummaryDefaultModel
|
||||
return nil
|
||||
}
|
||||
|
||||
type UserSettingsRepository interface {
|
||||
FindByUser(ctx context.Context, userID uint) (*models.UserSettings, error)
|
||||
Upsert(ctx context.Context, settings *models.UserSettings) error
|
||||
}
|
||||
|
||||
type userSettingsRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewUserSettingsRepository(db *gorm.DB) UserSettingsRepository {
|
||||
return &userSettingsRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *userSettingsRepository) FindByUser(ctx context.Context, userID uint) (*models.UserSettings, error) {
|
||||
var settings models.UserSettings
|
||||
if err := r.db.WithContext(ctx).First(&settings, "user_id = ?", userID).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &settings, nil
|
||||
}
|
||||
|
||||
func (r *userSettingsRepository) Upsert(ctx context.Context, settings *models.UserSettings) error {
|
||||
if settings == nil {
|
||||
return fmt.Errorf("user settings are required")
|
||||
}
|
||||
if settings.UserID == 0 {
|
||||
return fmt.Errorf("user settings user ID is required")
|
||||
}
|
||||
now := time.Now()
|
||||
values := map[string]any{
|
||||
"user_id": settings.UserID,
|
||||
"default_profile_id": settings.DefaultProfileID,
|
||||
"auto_transcription_enabled": settings.AutoTranscriptionEnabled,
|
||||
"auto_rename_enabled": settings.AutoRenameEnabled,
|
||||
"summary_default_model": settings.SummaryDefaultModel,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}
|
||||
return r.db.WithContext(ctx).Table((&models.UserSettings{}).TableName()).Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{
|
||||
"default_profile_id",
|
||||
"auto_transcription_enabled",
|
||||
"auto_rename_enabled",
|
||||
"summary_default_model",
|
||||
"updated_at",
|
||||
}),
|
||||
}).Create(values).Error
|
||||
}
|
||||
|
||||
type FileListOptions struct {
|
||||
@@ -1698,24 +1807,38 @@ func (r *profileRepository) SetDefaultForUser(ctx context.Context, id string, us
|
||||
}
|
||||
|
||||
func saveUserDefaultProfileTx(tx *gorm.DB, userID uint, profileID *string) error {
|
||||
var user models.User
|
||||
if err := tx.First(&user, userID).Error; err != nil {
|
||||
return err
|
||||
settings := models.UserSettings{
|
||||
UserID: userID,
|
||||
DefaultProfileID: profileID,
|
||||
AutoTranscriptionEnabled: true,
|
||||
AutoRenameEnabled: true,
|
||||
}
|
||||
user.DefaultProfileID = profileID
|
||||
return tx.Save(&user).Error
|
||||
return tx.Where("user_id = ?", userID).Assign(map[string]any{
|
||||
"default_profile_id": profileID,
|
||||
}).FirstOrCreate(&settings).Error
|
||||
}
|
||||
|
||||
func clearUserDefaultProfileIfMatchesTx(tx *gorm.DB, userID uint, profileID string) error {
|
||||
result := tx.Model(&models.UserSettings{}).
|
||||
Where("user_id = ? AND default_profile_id = ?", userID, profileID).
|
||||
Update("default_profile_id", nil)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected > 0 {
|
||||
return nil
|
||||
}
|
||||
var user models.User
|
||||
if err := tx.First(&user, userID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if user.DefaultProfileID == nil || *user.DefaultProfileID != profileID {
|
||||
return nil
|
||||
settings := models.UserSettings{
|
||||
UserID: userID,
|
||||
DefaultProfileID: nil,
|
||||
AutoTranscriptionEnabled: true,
|
||||
AutoRenameEnabled: true,
|
||||
}
|
||||
user.DefaultProfileID = nil
|
||||
return tx.Save(&user).Error
|
||||
return tx.Where("user_id = ?", userID).FirstOrCreate(&settings).Error
|
||||
}
|
||||
|
||||
// LLMConfigRepository handles LLM configuration operations
|
||||
@@ -1849,20 +1972,23 @@ func (r *summaryRepository) FindByIDForUser(ctx context.Context, id string, user
|
||||
}
|
||||
|
||||
func (r *summaryRepository) GetSettingsByUser(ctx context.Context, userID uint) (*models.SummarySetting, error) {
|
||||
var user models.User
|
||||
if err := r.db.WithContext(ctx).Where("id = ?", userID).First(&user).Error; err != nil {
|
||||
var settings models.UserSettings
|
||||
if err := r.db.WithContext(ctx).Where("user_id = ?", userID).First(&settings).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &models.SummarySetting{DefaultModel: user.SummaryDefaultModel}, nil
|
||||
return &models.SummarySetting{DefaultModel: settings.SummaryDefaultModel}, nil
|
||||
}
|
||||
|
||||
func (r *summaryRepository) SaveSettingsByUser(ctx context.Context, userID uint, settings *models.SummarySetting) error {
|
||||
var user models.User
|
||||
if err := r.db.WithContext(ctx).Where("id = ?", userID).First(&user).Error; err != nil {
|
||||
return err
|
||||
userSettings := models.UserSettings{
|
||||
UserID: userID,
|
||||
AutoTranscriptionEnabled: true,
|
||||
AutoRenameEnabled: true,
|
||||
SummaryDefaultModel: settings.DefaultModel,
|
||||
}
|
||||
user.SummaryDefaultModel = settings.DefaultModel
|
||||
return r.db.WithContext(ctx).Save(&user).Error
|
||||
return r.db.WithContext(ctx).Where("user_id = ?", userID).Assign(map[string]any{
|
||||
"summary_default_model": settings.DefaultModel,
|
||||
}).FirstOrCreate(&userSettings).Error
|
||||
}
|
||||
|
||||
func (r *summaryRepository) SaveSummary(ctx context.Context, summary *models.Summary) error {
|
||||
|
||||
Reference in New Issue
Block a user