85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
// Package postgres provides PostgreSQL implementations of port interfaces.
|
|
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
"git.threesix.ai/jordan/slack5-1770541397/pkg/logging"
|
|
"git.threesix.ai/jordan/slack5-1770541397/services/preferences-api/internal/domain"
|
|
"git.threesix.ai/jordan/slack5-1770541397/services/preferences-api/internal/port"
|
|
)
|
|
|
|
// preferencesRow represents a row in the user_preferences table.
|
|
type preferencesRow struct {
|
|
UserID string `db:"user_id"`
|
|
Preferences []byte `db:"preferences"`
|
|
UpdatedAt time.Time `db:"updated_at"`
|
|
}
|
|
|
|
// PreferencesRepository implements port.PreferencesRepository using PostgreSQL.
|
|
type PreferencesRepository struct {
|
|
db *sqlx.DB
|
|
logger *logging.Logger
|
|
}
|
|
|
|
var _ port.PreferencesRepository = (*PreferencesRepository)(nil)
|
|
|
|
// NewPreferencesRepository creates a new PostgreSQL preferences repository.
|
|
func NewPreferencesRepository(db *sqlx.DB, logger *logging.Logger) *PreferencesRepository {
|
|
return &PreferencesRepository{
|
|
db: db,
|
|
logger: logger.WithComponent("PreferencesRepository"),
|
|
}
|
|
}
|
|
|
|
// Get retrieves preferences for a user by ID.
|
|
// Returns domain.ErrPreferencesNotFound if no row exists.
|
|
func (r *PreferencesRepository) Get(ctx context.Context, userID domain.UserID) (*domain.UserPreferences, error) {
|
|
var row preferencesRow
|
|
err := r.db.GetContext(ctx, &row,
|
|
`SELECT user_id, preferences, updated_at FROM user_preferences WHERE user_id = $1`,
|
|
string(userID),
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, domain.ErrPreferencesNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
var prefs domain.Preferences
|
|
if err := json.Unmarshal(row.Preferences, &prefs); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &domain.UserPreferences{
|
|
UserID: domain.UserID(row.UserID),
|
|
Preferences: prefs,
|
|
UpdatedAt: row.UpdatedAt,
|
|
}, nil
|
|
}
|
|
|
|
// Upsert creates or replaces preferences for a user.
|
|
func (r *PreferencesRepository) Upsert(ctx context.Context, prefs *domain.UserPreferences) error {
|
|
prefsJSON, err := json.Marshal(prefs.Preferences)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = r.db.ExecContext(ctx, `
|
|
INSERT INTO user_preferences (user_id, preferences, updated_at)
|
|
VALUES ($1, $2, $3)
|
|
ON CONFLICT (user_id) DO UPDATE SET
|
|
preferences = $2,
|
|
updated_at = $3
|
|
`, string(prefs.UserID), prefsJSON, prefs.UpdatedAt)
|
|
|
|
return err
|
|
}
|