feat: golem15.feedback plugin with the widget config route
- 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
This commit is contained in:
95
updates/01_feedback.go
Normal file
95
updates/01_feedback.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package updates
|
||||
|
||||
import (
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// The WinterCMS plugin's three migrations (create_feedback_submissions_table,
|
||||
// add_type_and_locale_labels, create_user_preferences_table) give the two
|
||||
// tables below; the type column is folded into the create. String columns
|
||||
// are TEXT, as in every Go port (PHP's 255-character user_agent column
|
||||
// would refuse the 500 characters its own validation allows on Postgres).
|
||||
var submissionsMigration = &gormigrate.Migration{
|
||||
ID: "202610030201_create_feedback_submissions",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
for _, stmt := range []string{
|
||||
`CREATE TABLE golem15_feedback_submissions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
message TEXT NOT NULL,
|
||||
type TEXT NOT NULL DEFAULT 'bug',
|
||||
email TEXT,
|
||||
page_url TEXT NOT NULL,
|
||||
user_agent TEXT,
|
||||
console_log TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
g15office_task_id TEXT,
|
||||
g15office_error TEXT,
|
||||
created_at TIMESTAMPTZ,
|
||||
updated_at TIMESTAMPTZ
|
||||
)`,
|
||||
`CREATE INDEX golem15_feedback_submissions_status_index ON golem15_feedback_submissions (status)`,
|
||||
} {
|
||||
if err := tx.Exec(stmt).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return tx.Exec(`DROP TABLE IF EXISTS golem15_feedback_submissions`).Error
|
||||
},
|
||||
}
|
||||
|
||||
var userPreferencesMigration = &gormigrate.Migration{
|
||||
ID: "202610030202_create_feedback_user_preferences",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.Exec(`CREATE TABLE golem15_feedback_user_preferences (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL,
|
||||
hidden BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ,
|
||||
updated_at TIMESTAMPTZ,
|
||||
CONSTRAINT golem15_feedback_user_preferences_user_id_unique UNIQUE (user_id)
|
||||
)`).Error
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return tx.Exec(`DROP TABLE IF EXISTS golem15_feedback_user_preferences`).Error
|
||||
},
|
||||
}
|
||||
|
||||
// settingsMigration creates the typed settings singleton (D-18): the
|
||||
// WinterCMS plugin kept these values in its system_settings row
|
||||
// golem15_feedback_settings, which feedback:import-settings copies once.
|
||||
var settingsMigration = &gormigrate.Migration{
|
||||
ID: "202610030203_create_feedback_settings",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.Exec(`CREATE TABLE golem15_feedback_settings (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
widget_key TEXT NOT NULL,
|
||||
allow_hide BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
position TEXT,
|
||||
allowed_origins TEXT,
|
||||
color_primary TEXT,
|
||||
color_accent TEXT,
|
||||
label_title_pl TEXT,
|
||||
label_title_en TEXT,
|
||||
label_placeholder_pl TEXT,
|
||||
label_placeholder_en TEXT,
|
||||
label_success_pl TEXT,
|
||||
label_success_en TEXT,
|
||||
g15office_task_status TEXT,
|
||||
g15office_task_priority TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)`).Error
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return tx.Exec(`DROP TABLE IF EXISTS golem15_feedback_settings`).Error
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(submissionsMigration, userPreferencesMigration, settingsMigration)
|
||||
}
|
||||
17
updates/registry.go
Normal file
17
updates/registry.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Package updates holds the golem15.feedback migrations.
|
||||
package updates
|
||||
|
||||
import "github.com/go-gormigrate/gormigrate/v2"
|
||||
|
||||
var all []*gormigrate.Migration
|
||||
|
||||
// Register appends gormigrate steps, so a migration file adds itself
|
||||
// without editing plugin.go.
|
||||
func Register(ms ...*gormigrate.Migration) {
|
||||
all = append(all, ms...)
|
||||
}
|
||||
|
||||
// All returns every migration registered by this package, in order.
|
||||
func All() []*gormigrate.Migration {
|
||||
return all
|
||||
}
|
||||
Reference in New Issue
Block a user