- plugin golem15.feedback (requires golem15.user), its config, lang (en, pl), models and migrations
- typed settings singleton golem15_feedback_settings with the WinterCMS defaults and a widget key generated on first creation
- GET /_feedback/api/v1/{key}/config behind the constant-time key check and the fail-closed Origin allow-list, with the feedback-config and feedback-submit buckets
55 lines
1.7 KiB
Go
55 lines
1.7 KiB
Go
package models
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
// UserPreference is one user's widget preference
|
|
// (golem15_feedback_user_preferences, one row per user who ever changed
|
|
// it). The hidden column is the signal, not the row: a row may hold
|
|
// hidden=false after the user showed the widget again.
|
|
type UserPreference struct {
|
|
ID uint `gorm:"column:id;primaryKey"`
|
|
UserID uint `gorm:"column:user_id"`
|
|
Hidden bool `gorm:"column:hidden"`
|
|
CreatedAt time.Time `gorm:"column:created_at"`
|
|
UpdatedAt time.Time `gorm:"column:updated_at"`
|
|
}
|
|
|
|
// TableName is golem15_feedback_user_preferences.
|
|
func (UserPreference) TableName() string { return "golem15_feedback_user_preferences" }
|
|
|
|
// IsWidgetHidden is UserPreference::isWidgetHidden: the user's hidden flag,
|
|
// false without a row.
|
|
func IsWidgetHidden(ctx context.Context, db *gorm.DB, userID uint) (bool, error) {
|
|
var p UserPreference
|
|
err := db.WithContext(ctx).Select("hidden").Where("user_id = ?", userID).Take(&p).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return false, nil
|
|
}
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return p.Hidden, nil
|
|
}
|
|
|
|
// SetWidgetHidden is UserPreference::setWidgetHidden (updateOrCreate on
|
|
// user_id): one atomic upsert of the user's row.
|
|
func SetWidgetHidden(ctx context.Context, db *gorm.DB, userID uint, hidden bool) error {
|
|
now := time.Now()
|
|
row := UserPreference{UserID: userID, Hidden: hidden, CreatedAt: now, UpdatedAt: now}
|
|
return db.WithContext(ctx).Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "user_id"}},
|
|
DoUpdates: clause.AssignmentColumns([]string{"hidden", "updated_at"}),
|
|
}).Create(&row).Error
|
|
}
|
|
|
|
func init() {
|
|
Register(UserPreference{})
|
|
}
|