- 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
97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/lagoon/attach"
|
|
)
|
|
|
|
// Submission statuses (FeedbackSubmission::STATUS_*).
|
|
const (
|
|
StatusPending = "pending"
|
|
StatusSent = "sent"
|
|
StatusFailed = "failed"
|
|
)
|
|
|
|
// Submission types (FeedbackSubmission::TYPE_*).
|
|
const (
|
|
TypeBug = "bug"
|
|
TypeFeature = "feature"
|
|
TypeOther = "other"
|
|
)
|
|
|
|
// ScreenshotField is the attachOne relation of the screenshot.
|
|
const ScreenshotField = "screenshot"
|
|
|
|
// G15OfficeTypeMap is FeedbackSubmission::G15OFFICE_TYPE_MAP: the widget
|
|
// type to the g15office task type name ("other" is the generic Task).
|
|
var G15OfficeTypeMap = map[string]string{
|
|
TypeBug: "Bug",
|
|
TypeFeature: "Feature",
|
|
TypeOther: "Task",
|
|
}
|
|
|
|
// Submission is one feedback report (golem15_feedback_submissions), the Go
|
|
// form of FeedbackSubmission. Its screenshot is a public attachOne file.
|
|
type Submission struct {
|
|
ID uint `gorm:"column:id;primaryKey"`
|
|
Message string `gorm:"column:message"`
|
|
Type string `gorm:"column:type"`
|
|
Email *string `gorm:"column:email"`
|
|
PageURL string `gorm:"column:page_url"`
|
|
UserAgent *string `gorm:"column:user_agent"`
|
|
ConsoleLog *string `gorm:"column:console_log"`
|
|
Status string `gorm:"column:status"`
|
|
G15OfficeTaskID *string `gorm:"column:g15office_task_id"`
|
|
G15OfficeError *string `gorm:"column:g15office_error"`
|
|
CreatedAt time.Time `gorm:"column:created_at"`
|
|
UpdatedAt time.Time `gorm:"column:updated_at"`
|
|
}
|
|
|
|
var (
|
|
_ attach.Owner = Submission{}
|
|
_ attach.HasRelations = Submission{}
|
|
)
|
|
|
|
// TableName is golem15_feedback_submissions.
|
|
func (Submission) TableName() string { return "golem15_feedback_submissions" }
|
|
|
|
// MorphName is the PHP class stored in system_files.attachment_type.
|
|
func (Submission) MorphName() string { return `Golem15\Feedback\Models\FeedbackSubmission` }
|
|
|
|
// AttachRelations declares the public attachOne screenshot.
|
|
func (Submission) AttachRelations() []attach.Relation {
|
|
return []attach.Relation{{Name: ScreenshotField, Public: true}}
|
|
}
|
|
|
|
// Fillable is FeedbackSubmission::$fillable.
|
|
func (Submission) Fillable() []string {
|
|
return []string{
|
|
"message", "type", "email", "page_url", "user_agent", "console_log",
|
|
"status", "g15office_task_id", "g15office_error",
|
|
}
|
|
}
|
|
|
|
// Rules are FeedbackSubmission::$rules.
|
|
func (Submission) Rules() map[string]string {
|
|
return map[string]string{
|
|
"message": "required|string|max:5000",
|
|
"type": "required|in:bug,feature,other",
|
|
"email": "nullable|email|max:255",
|
|
"page_url": "required|string|max:2000",
|
|
}
|
|
}
|
|
|
|
// G15OfficeTaskType is FeedbackSubmission::g15officeTaskType: the task type
|
|
// of the submission's widget type, Task for an unknown one.
|
|
func (s Submission) G15OfficeTaskType() string {
|
|
if t, ok := G15OfficeTypeMap[s.Type]; ok {
|
|
return t
|
|
}
|
|
return G15OfficeTypeMap[TypeOther]
|
|
}
|
|
|
|
func init() {
|
|
Register(Submission{})
|
|
}
|