diff --git a/internal/chat/resolver.go b/internal/chat/resolver.go index a600c9f6..e47529e7 100644 --- a/internal/chat/resolver.go +++ b/internal/chat/resolver.go @@ -598,22 +598,27 @@ func (r *Resolver) loadUserSettings(ctx context.Context, userID string) (int, st if err != nil { return 0, "", err } - settings, err := r.queries.GetSettingsByUserID(ctx, pgUserID) + settingsRow, err := r.queries.GetSettingsByUserID(ctx, pgUserID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return defaultMaxContextMinutes, "Same as user input", nil } return 0, "", err } - maxLoad := int(settings.MaxContextLoadTime) + maxLoad, language := normalizeUserSettingRow(settingsRow) + return maxLoad, language, nil +} + +func normalizeUserSettingRow(row sqlc.UserSetting) (int, string) { + maxLoad := int(row.MaxContextLoadTime) if maxLoad <= 0 { maxLoad = defaultMaxContextMinutes } - language := strings.TrimSpace(settings.Language) + language := strings.TrimSpace(row.Language) if language == "" { language = "Same as user input" } - return maxLoad, language, nil + return maxLoad, language } func normalizeClientType(clientType string) (string, error) { diff --git a/internal/db/sqlc/history.sql.go b/internal/db/sqlc/history.sql.go index d775400b..00f6f50b 100644 --- a/internal/db/sqlc/history.sql.go +++ b/internal/db/sqlc/history.sql.go @@ -35,41 +35,24 @@ func (q *Queries) CreateHistory(ctx context.Context, arg CreateHistoryParams) (H return i, err } -const listHistoryByUserSince = `-- name: ListHistoryByUserSince :many -SELECT id, messages, timestamp, "user" -FROM history -WHERE "user" = $1 AND timestamp >= $2 -ORDER BY timestamp ASC +const deleteHistoryByID = `-- name: DeleteHistoryByID :exec +DELETE FROM history +WHERE id = $1 ` -type ListHistoryByUserSinceParams struct { - User pgtype.UUID `json:"user"` - Timestamp pgtype.Timestamptz `json:"timestamp"` +func (q *Queries) DeleteHistoryByID(ctx context.Context, id pgtype.UUID) error { + _, err := q.db.Exec(ctx, deleteHistoryByID, id) + return err } -func (q *Queries) ListHistoryByUserSince(ctx context.Context, arg ListHistoryByUserSinceParams) ([]History, error) { - rows, err := q.db.Query(ctx, listHistoryByUserSince, arg.User, arg.Timestamp) - if err != nil { - return nil, err - } - defer rows.Close() - var items []History - for rows.Next() { - var i History - if err := rows.Scan( - &i.ID, - &i.Messages, - &i.Timestamp, - &i.User, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil +const deleteHistoryByUser = `-- name: DeleteHistoryByUser :exec +DELETE FROM history +WHERE "user" = $1 +` + +func (q *Queries) DeleteHistoryByUser(ctx context.Context, user pgtype.UUID) error { + _, err := q.db.Exec(ctx, deleteHistoryByUser, user) + return err } const getHistoryByID = `-- name: GetHistoryByID :one @@ -128,22 +111,39 @@ func (q *Queries) ListHistoryByUser(ctx context.Context, arg ListHistoryByUserPa return items, nil } -const deleteHistoryByID = `-- name: DeleteHistoryByID :exec -DELETE FROM history -WHERE id = $1 +const listHistoryByUserSince = `-- name: ListHistoryByUserSince :many +SELECT id, messages, timestamp, "user" +FROM history +WHERE "user" = $1 AND timestamp >= $2 +ORDER BY timestamp ASC ` -func (q *Queries) DeleteHistoryByID(ctx context.Context, id pgtype.UUID) error { - _, err := q.db.Exec(ctx, deleteHistoryByID, id) - return err +type ListHistoryByUserSinceParams struct { + User pgtype.UUID `json:"user"` + Timestamp pgtype.Timestamptz `json:"timestamp"` } -const deleteHistoryByUser = `-- name: DeleteHistoryByUser :exec -DELETE FROM history -WHERE "user" = $1 -` - -func (q *Queries) DeleteHistoryByUser(ctx context.Context, user pgtype.UUID) error { - _, err := q.db.Exec(ctx, deleteHistoryByUser, user) - return err +func (q *Queries) ListHistoryByUserSince(ctx context.Context, arg ListHistoryByUserSinceParams) ([]History, error) { + rows, err := q.db.Query(ctx, listHistoryByUserSince, arg.User, arg.Timestamp) + if err != nil { + return nil, err + } + defer rows.Close() + var items []History + for rows.Next() { + var i History + if err := rows.Scan( + &i.ID, + &i.Messages, + &i.Timestamp, + &i.User, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil } diff --git a/internal/db/sqlc/models.go b/internal/db/sqlc/models.go index 56371bb0..21229e0f 100644 --- a/internal/db/sqlc/models.go +++ b/internal/db/sqlc/models.go @@ -40,12 +40,6 @@ type History struct { User pgtype.UUID `json:"user"` } -type Settings struct { - UserID pgtype.UUID `json:"user_id"` - MaxContextLoadTime int32 `json:"max_context_load_time"` - Language string `json:"language"` -} - type LifecycleEvent struct { ID string `json:"id"` ContainerID string `json:"container_id"` @@ -111,3 +105,9 @@ type User struct { UpdatedAt pgtype.Timestamptz `json:"updated_at"` LastLoginAt pgtype.Timestamptz `json:"last_login_at"` } + +type UserSetting struct { + UserID pgtype.UUID `json:"user_id"` + MaxContextLoadTime int32 `json:"max_context_load_time"` + Language string `json:"language"` +} diff --git a/internal/db/sqlc/settings.sql.go b/internal/db/sqlc/settings.sql.go index d697d55c..14fb440c 100644 --- a/internal/db/sqlc/settings.sql.go +++ b/internal/db/sqlc/settings.sql.go @@ -11,20 +11,26 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +const deleteSettingsByUserID = `-- name: DeleteSettingsByUserID :exec +DELETE FROM user_settings +WHERE user_id = $1 +` + +func (q *Queries) DeleteSettingsByUserID(ctx context.Context, userID pgtype.UUID) error { + _, err := q.db.Exec(ctx, deleteSettingsByUserID, userID) + return err +} + const getSettingsByUserID = `-- name: GetSettingsByUserID :one SELECT user_id, max_context_load_time, language FROM user_settings WHERE user_id = $1 ` -func (q *Queries) GetSettingsByUserID(ctx context.Context, userID pgtype.UUID) (Settings, error) { +func (q *Queries) GetSettingsByUserID(ctx context.Context, userID pgtype.UUID) (UserSetting, error) { row := q.db.QueryRow(ctx, getSettingsByUserID, userID) - var i Settings - err := row.Scan( - &i.UserID, - &i.MaxContextLoadTime, - &i.Language, - ) + var i UserSetting + err := row.Scan(&i.UserID, &i.MaxContextLoadTime, &i.Language) return i, err } @@ -43,24 +49,9 @@ type UpsertSettingsParams struct { Language string `json:"language"` } -func (q *Queries) UpsertSettings(ctx context.Context, arg UpsertSettingsParams) (Settings, error) { +func (q *Queries) UpsertSettings(ctx context.Context, arg UpsertSettingsParams) (UserSetting, error) { row := q.db.QueryRow(ctx, upsertSettings, arg.UserID, arg.MaxContextLoadTime, arg.Language) - var i Settings - err := row.Scan( - &i.UserID, - &i.MaxContextLoadTime, - &i.Language, - ) + var i UserSetting + err := row.Scan(&i.UserID, &i.MaxContextLoadTime, &i.Language) return i, err } - -const deleteSettingsByUserID = `-- name: DeleteSettingsByUserID :exec -DELETE FROM user_settings -WHERE user_id = $1 -` - -func (q *Queries) DeleteSettingsByUserID(ctx context.Context, userID pgtype.UUID) error { - _, err := q.db.Exec(ctx, deleteSettingsByUserID, userID) - return err -} - diff --git a/internal/db/sqlc/users.sql.go b/internal/db/sqlc/users.sql.go index 28067a69..0f311c78 100644 --- a/internal/db/sqlc/users.sql.go +++ b/internal/db/sqlc/users.sql.go @@ -11,6 +11,17 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +const countUsers = `-- name: CountUsers :one +SELECT COUNT(*)::bigint AS count FROM users +` + +func (q *Queries) CountUsers(ctx context.Context) (int64, error) { + row := q.db.QueryRow(ctx, countUsers) + var count int64 + err := row.Scan(&count) + return count, err +} + const createUser = `-- name: CreateUser :one INSERT INTO users (username, email, password_hash, role, display_name, avatar_url, is_active, data_root) VALUES ( @@ -90,17 +101,6 @@ func (q *Queries) GetUserByUsername(ctx context.Context, username string) (User, return i, err } -const countUsers = `-- name: CountUsers :one -SELECT COUNT(*)::bigint AS count FROM users -` - -func (q *Queries) CountUsers(ctx context.Context) (int64, error) { - row := q.db.QueryRow(ctx, countUsers) - var count int64 - err := row.Scan(&count) - return count, err -} - const upsertUserByUsername = `-- name: UpsertUserByUsername :one INSERT INTO users (username, email, password_hash, role, display_name, avatar_url, is_active, data_root) VALUES ( diff --git a/internal/settings/service.go b/internal/settings/service.go index 5b1fbb85..cb52f87e 100644 --- a/internal/settings/service.go +++ b/internal/settings/service.go @@ -36,17 +36,7 @@ func (s *Service) Get(ctx context.Context, userID string) (Settings, error) { } return Settings{}, err } - settings := Settings{ - MaxContextLoadTime: int(row.MaxContextLoadTime), - Language: strings.TrimSpace(row.Language), - } - if settings.MaxContextLoadTime <= 0 { - settings.MaxContextLoadTime = DefaultMaxContextLoadTime - } - if settings.Language == "" { - settings.Language = DefaultLanguage - } - return settings, nil + return normalizeUserSetting(row), nil } func (s *Service) Upsert(ctx context.Context, userID string, req UpsertRequest) (Settings, error) { @@ -67,14 +57,7 @@ func (s *Service) Upsert(ctx context.Context, userID string, req UpsertRequest) return Settings{}, err } if err == nil { - current.MaxContextLoadTime = int(existing.MaxContextLoadTime) - current.Language = strings.TrimSpace(existing.Language) - if current.MaxContextLoadTime <= 0 { - current.MaxContextLoadTime = DefaultMaxContextLoadTime - } - if current.Language == "" { - current.Language = DefaultLanguage - } + current = normalizeUserSetting(existing) } if req.MaxContextLoadTime != nil && *req.MaxContextLoadTime > 0 { @@ -106,6 +89,20 @@ func (s *Service) Delete(ctx context.Context, userID string) error { return s.queries.DeleteSettingsByUserID(ctx, pgID) } +func normalizeUserSetting(row sqlc.UserSetting) Settings { + settings := Settings{ + MaxContextLoadTime: int(row.MaxContextLoadTime), + Language: strings.TrimSpace(row.Language), + } + if settings.MaxContextLoadTime <= 0 { + settings.MaxContextLoadTime = DefaultMaxContextLoadTime + } + if settings.Language == "" { + settings.Language = DefaultLanguage + } + return settings +} + func parseUUID(id string) (pgtype.UUID, error) { parsed, err := uuid.Parse(id) if err != nil { @@ -116,4 +113,3 @@ func parseUUID(id string) (pgtype.UUID, error) { copy(pgID.Bytes[:], parsed[:]) return pgID, nil } -