form

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package form provides domain models and repository interfaces for form management.

Index

Constants

View Source
const (
	StatusActive   = "active"
	StatusInactive = "inactive"
	StatusArchived = "archived"
)

Form status constants.

View Source
const (
	SubmissionStatusNew      = "new"
	SubmissionStatusRead     = "read"
	SubmissionStatusArchived = "archived"
	SubmissionStatusSpam     = "spam"
)

Submission status constants.

View Source
const (
	FieldTypeText     = "text"
	FieldTypeEmail    = "email"
	FieldTypePhone    = "phone"
	FieldTypeTextarea = "textarea"
	FieldTypeSelect   = "select"
	FieldTypeRadio    = "radio"
	FieldTypeCheckbox = "checkbox"
	FieldTypeDate     = "date"
	FieldTypeNumber   = "number"
	FieldTypeURL      = "url"
)

Field type constants.

Variables

View Source
var (
	ErrFormNotFound       = errors.New("form not found")
	ErrSubmissionNotFound = errors.New("submission not found")
	ErrSlugAlreadyExists  = errors.New("form slug already exists")
	ErrInvalidStatus      = errors.New("invalid form status")
	ErrInvalidFieldType   = errors.New("invalid field type")
)

Common errors.

Functions

func GetFieldTypes

func GetFieldTypes() []string

GetFieldTypes returns all supported field types.

func ValidFieldType

func ValidFieldType(fieldType string) bool

ValidFieldType checks if a field type is valid.

func ValidStatus

func ValidStatus(status string) bool

ValidStatus checks if a form status is valid.

func ValidSubmissionStatus

func ValidSubmissionStatus(status string) bool

ValidSubmissionStatus checks if a submission status is valid.

func ValidateSubmission

func ValidateSubmission(fields []FormField, data map[string]any) (map[string]any, map[string]string)

ValidateSubmission checks a public submission against the form's fields. It is the one validator behind the JSON and the urlencoded submit endpoints.

Only answers to fields the form defines are returned: unknown keys are ignored (never stored). Empty optional answers are dropped. The errors are keyed by field name; the returned data is nil when there is any error.

Types

type CreateFormInput

type CreateFormInput struct {
	Name        string       `json:"name"`
	Slug        string       `json:"slug,omitempty"`
	Description *string      `json:"description,omitempty"`
	Fields      []FormField  `json:"fields"`
	Settings    FormSettings `json:"settings"`
}

CreateFormInput represents input for creating a new form.

type CreateSubmissionInput

type CreateSubmissionInput struct {
	Data     map[string]any     `json:"data"`
	Metadata SubmissionMetadata `json:"metadata"`
	// Status is the initial status; empty means SubmissionStatusNew. Set by
	// the server (spam pipeline), never read from a request body.
	Status string `json:"-"`
}

CreateSubmissionInput represents input for creating a form submission.

type FieldOption

type FieldOption struct {
	Label string `json:"label"`
	Value string `json:"value"`
}

FieldOption represents an option for select, radio, or checkbox fields.

type FieldValidation

type FieldValidation struct {
	MinLength *int    `json:"min_length,omitempty"`
	MaxLength *int    `json:"max_length,omitempty"`
	Min       *int    `json:"min,omitempty"`
	Max       *int    `json:"max,omitempty"`
	Pattern   *string `json:"pattern,omitempty"`
	Message   *string `json:"message,omitempty"`
}

FieldValidation represents validation rules for a field.

type Form

type Form struct {
	ID          uuid.UUID    `json:"id"`
	Name        string       `json:"name"`
	Slug        string       `json:"slug"`
	Description *string      `json:"description,omitempty"`
	Fields      []FormField  `json:"fields"`
	Settings    FormSettings `json:"settings"`
	Status      string       `json:"status"`
	CreatedAt   time.Time    `json:"created_at"`
	UpdatedAt   time.Time    `json:"updated_at"`
}

Form represents a form definition.

type FormField

type FormField struct {
	ID           string            `json:"id"`
	Type         string            `json:"type"`
	Label        string            `json:"label"`
	Name         string            `json:"name"`
	Placeholder  string            `json:"placeholder,omitempty"`
	Required     bool              `json:"required"`
	Options      []FieldOption     `json:"options,omitempty"`
	Validation   *FieldValidation  `json:"validation,omitempty"`
	DefaultValue string            `json:"default_value,omitempty"`
	HelpText     string            `json:"help_text,omitempty"`
	Width        string            `json:"width,omitempty"` // "full", "half", "third"
	Position     int               `json:"position"`
	Attributes   map[string]string `json:"attributes,omitempty"`
}

FormField represents a single field in a form.

type FormSettings

type FormSettings struct {
	SubmitButtonText   string  `json:"submit_button_text,omitempty"`
	SuccessMessage     string  `json:"success_message,omitempty"`
	SuccessRedirectURL string  `json:"success_redirect_url,omitempty"`
	EnableCaptcha      bool    `json:"enable_captcha"`
	NotifyEmail        *string `json:"notify_email,omitempty"`
	ConfirmationEmail  bool    `json:"confirmation_email"`
	// ConfirmationMessage is the body of the submitter's confirmation email;
	// SuccessMessage is used when it is empty.
	ConfirmationMessage string `json:"confirmation_message,omitempty"`
	StoreSubmissions    bool   `json:"store_submissions"`
}

FormSettings represents form-level settings.

type FormSubmission

type FormSubmission struct {
	ID        uuid.UUID          `json:"id"`
	FormID    uuid.UUID          `json:"form_id"`
	Data      map[string]any     `json:"data"`
	Metadata  SubmissionMetadata `json:"metadata"`
	Status    string             `json:"status"`
	CreatedAt time.Time          `json:"created_at"`

	// Populated on read
	FormName *string `json:"form_name,omitempty"`
}

FormSubmission represents a submitted form entry.

type ListSubmissionsParams

type ListSubmissionsParams struct {
	Status string `json:"status,omitempty"`
	Limit  int    `json:"limit,omitempty"`
	Offset int    `json:"offset,omitempty"`
	// After continues a listing after this submission (keyset paging, newest
	// first): rows are neither repeated nor skipped when new ones arrive. It
	// replaces Offset and skips the total count.
	After *SubmissionCursor `json:"-"`
}

ListSubmissionsParams represents parameters for listing submissions.

type PostgresRepository

type PostgresRepository struct {
	// contains filtered or unexported fields
}

PostgresRepository implements Repository using PostgreSQL.

func NewPostgresRepository

func NewPostgresRepository(db *database.DB) *PostgresRepository

NewPostgresRepository creates a new PostgreSQL form repository.

func (*PostgresRepository) CreateForm

func (r *PostgresRepository) CreateForm(ctx context.Context, input *CreateFormInput) (*Form, error)

CreateForm inserts a new form.

func (*PostgresRepository) CreateSubmission

func (r *PostgresRepository) CreateSubmission(ctx context.Context, formID uuid.UUID, input *CreateSubmissionInput) (*FormSubmission, error)

CreateSubmission inserts a new form submission.

func (*PostgresRepository) DeleteForm

func (r *PostgresRepository) DeleteForm(ctx context.Context, id uuid.UUID) error

DeleteForm removes a form and all its submissions.

func (*PostgresRepository) DeleteSubmission

func (r *PostgresRepository) DeleteSubmission(ctx context.Context, id uuid.UUID) error

DeleteSubmission removes a submission.

func (*PostgresRepository) GetFormByID

func (r *PostgresRepository) GetFormByID(ctx context.Context, id uuid.UUID) (*Form, error)

GetFormByID retrieves a form by ID.

func (*PostgresRepository) GetFormBySlug

func (r *PostgresRepository) GetFormBySlug(ctx context.Context, slug string) (*Form, error)

GetFormBySlug retrieves a form by slug.

func (*PostgresRepository) GetSubmissionByID

func (r *PostgresRepository) GetSubmissionByID(ctx context.Context, id uuid.UUID) (*FormSubmission, error)

GetSubmissionByID retrieves a submission by ID.

func (*PostgresRepository) GetSubmissionCount

func (r *PostgresRepository) GetSubmissionCount(ctx context.Context, formID uuid.UUID) (int, error)

GetSubmissionCount returns the count of submissions for a form.

func (*PostgresRepository) ListForms

func (r *PostgresRepository) ListForms(ctx context.Context, status string) ([]*Form, error)

ListForms retrieves all forms for the tenant.

func (*PostgresRepository) ListSubmissions

func (r *PostgresRepository) ListSubmissions(ctx context.Context, formID uuid.UUID, params *ListSubmissionsParams) ([]*FormSubmission, int, error)

ListSubmissions retrieves submissions for a form with pagination.

func (*PostgresRepository) UpdateForm

func (r *PostgresRepository) UpdateForm(ctx context.Context, id uuid.UUID, input *UpdateFormInput) (*Form, error)

UpdateForm modifies a form.

func (*PostgresRepository) UpdateSubmission

func (r *PostgresRepository) UpdateSubmission(ctx context.Context, id uuid.UUID, input *UpdateSubmissionInput) (*FormSubmission, error)

UpdateSubmission modifies a submission.

type Repository

type Repository interface {
	// Form operations
	CreateForm(ctx context.Context, input *CreateFormInput) (*Form, error)
	GetFormByID(ctx context.Context, id uuid.UUID) (*Form, error)
	GetFormBySlug(ctx context.Context, slug string) (*Form, error)
	ListForms(ctx context.Context, status string) ([]*Form, error)
	UpdateForm(ctx context.Context, id uuid.UUID, input *UpdateFormInput) (*Form, error)
	DeleteForm(ctx context.Context, id uuid.UUID) error

	// Submission operations
	CreateSubmission(ctx context.Context, formID uuid.UUID, input *CreateSubmissionInput) (*FormSubmission, error)
	GetSubmissionByID(ctx context.Context, id uuid.UUID) (*FormSubmission, error)
	ListSubmissions(ctx context.Context, formID uuid.UUID, params *ListSubmissionsParams) ([]*FormSubmission, int, error)
	UpdateSubmission(ctx context.Context, id uuid.UUID, input *UpdateSubmissionInput) (*FormSubmission, error)
	DeleteSubmission(ctx context.Context, id uuid.UUID) error
	GetSubmissionCount(ctx context.Context, formID uuid.UUID) (int, error)
}

Repository defines the interface for form data operations.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service provides business logic for form management.

func NewService

func NewService(repo Repository, logger *slog.Logger) *Service

NewService creates a new form service.

func (*Service) CreateForm

func (s *Service) CreateForm(ctx context.Context, input *CreateFormInput) (*Form, error)

CreateForm creates a new form.

func (*Service) CreateSubmission

func (s *Service) CreateSubmission(ctx context.Context, formID uuid.UUID, input *CreateSubmissionInput) (*FormSubmission, error)

CreateSubmission creates a new form submission.

func (*Service) DeleteForm

func (s *Service) DeleteForm(ctx context.Context, id uuid.UUID) error

DeleteForm removes a form.

func (*Service) DeleteSubmission

func (s *Service) DeleteSubmission(ctx context.Context, id uuid.UUID) error

DeleteSubmission removes a submission.

func (*Service) GetForm

func (s *Service) GetForm(ctx context.Context, id uuid.UUID) (*Form, error)

GetForm retrieves a form by ID.

func (*Service) GetFormBySlug

func (s *Service) GetFormBySlug(ctx context.Context, slug string) (*Form, error)

GetFormBySlug retrieves a form by slug.

func (*Service) GetSubmission

func (s *Service) GetSubmission(ctx context.Context, id uuid.UUID) (*FormSubmission, error)

GetSubmission retrieves a submission by ID.

func (*Service) GetSubmissionCount

func (s *Service) GetSubmissionCount(ctx context.Context, formID uuid.UUID) (int, error)

GetSubmissionCount returns the count of submissions for a form.

func (*Service) ListForms

func (s *Service) ListForms(ctx context.Context, status string) ([]*Form, error)

ListForms retrieves all forms for the tenant.

func (*Service) ListSubmissions

func (s *Service) ListSubmissions(ctx context.Context, formID uuid.UUID, params *ListSubmissionsParams) ([]*FormSubmission, int, error)

ListSubmissions retrieves submissions for a form.

func (*Service) UpdateForm

func (s *Service) UpdateForm(ctx context.Context, id uuid.UUID, input *UpdateFormInput) (*Form, error)

UpdateForm modifies a form.

func (*Service) UpdateSubmission

func (s *Service) UpdateSubmission(ctx context.Context, id uuid.UUID, input *UpdateSubmissionInput) (*FormSubmission, error)

UpdateSubmission modifies a submission.

type SubmissionCursor

type SubmissionCursor struct {
	CreatedAt time.Time
	ID        uuid.UUID
}

SubmissionCursor is the position of the last submission of a page.

type SubmissionMetadata

type SubmissionMetadata struct {
	IPAddress string `json:"ip_address,omitempty"`
	UserAgent string `json:"user_agent,omitempty"`
	Referrer  string `json:"referrer,omitempty"`
	PageURL   string `json:"page_url,omitempty"`
}

SubmissionMetadata contains metadata about the submission.

type UpdateFormInput

type UpdateFormInput struct {
	Name        *string       `json:"name,omitempty"`
	Description *string       `json:"description,omitempty"`
	Fields      []FormField   `json:"fields,omitempty"`
	Settings    *FormSettings `json:"settings,omitempty"`
	Status      *string       `json:"status,omitempty"`
}

UpdateFormInput represents input for updating a form.

type UpdateSubmissionInput

type UpdateSubmissionInput struct {
	Status *string `json:"status,omitempty"`
}

UpdateSubmissionInput represents input for updating a submission.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL