Files
sm-feedback-plugin/models/submission.go
Jakub Zych b4b4135ad3 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
2026-10-04 00:01:22 +02:00

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{})
}