81 lines
2.1 KiB
Go
81 lines
2.1 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
"git.threesix.ai/jordan/slack5-1770606136/services/preferences-api/internal/domain"
|
|
"git.threesix.ai/jordan/slack5-1770606136/services/preferences-api/internal/port"
|
|
)
|
|
|
|
// PreferenceRepository implements port.PreferenceRepository using PostgreSQL.
|
|
type PreferenceRepository struct {
|
|
db *sqlx.DB
|
|
}
|
|
|
|
// Compile-time interface verification.
|
|
var _ port.PreferenceRepository = (*PreferenceRepository)(nil)
|
|
|
|
// NewPreferenceRepository creates a new PostgreSQL preference repository.
|
|
func NewPreferenceRepository(db *sqlx.DB) *PreferenceRepository {
|
|
return &PreferenceRepository{db: db}
|
|
}
|
|
|
|
// preferenceRow represents a database row from the preferences table.
|
|
type preferenceRow struct {
|
|
UserID string `db:"user_id"`
|
|
Preferences []byte `db:"preferences"`
|
|
CreatedAt time.Time `db:"created_at"`
|
|
UpdatedAt time.Time `db:"updated_at"`
|
|
}
|
|
|
|
// Get returns preferences for a user.
|
|
// Returns nil, nil when no row exists.
|
|
func (r *PreferenceRepository) Get(ctx context.Context, userID string) (*domain.UserPreferences, error) {
|
|
var row preferenceRow
|
|
err := r.db.GetContext(ctx, &row,
|
|
`SELECT user_id, preferences, created_at, updated_at FROM preferences WHERE user_id = $1`,
|
|
userID,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
prefs := make(map[string]any)
|
|
if err := json.Unmarshal(row.Preferences, &prefs); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &domain.UserPreferences{
|
|
UserID: row.UserID,
|
|
Preferences: prefs,
|
|
CreatedAt: row.CreatedAt,
|
|
UpdatedAt: row.UpdatedAt,
|
|
}, nil
|
|
}
|
|
|
|
// Upsert creates or updates preferences for a user.
|
|
func (r *PreferenceRepository) 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 preferences (user_id, preferences, updated_at)
|
|
VALUES ($1, $2, NOW())
|
|
ON CONFLICT (user_id) DO UPDATE
|
|
SET preferences = $2, updated_at = NOW()`,
|
|
prefs.UserID, prefsJSON,
|
|
)
|
|
return err
|
|
}
|