survey

package
v0.65.2 Latest Latest
Warning

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

Go to latest
Published: Aug 17, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package survey is in-product micro-surveys — one question (NPS, rating, choice, or text), targeted by URL + sampling, answered by a tiny SDK widget. Responses arrive as ordinary events ($survey_shown / $survey_response), so results are a query-time aggregation like every other report — no separate response store, honoring the single-binary model.

Index

Constants

View Source
const (
	ShownEvent    = "$survey_shown"
	ResponseEvent = "$survey_response"
	PropSurvey    = "survey_id"
	PropAnswer    = "answer"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Count

type Count struct {
	Label string `json:"label"`
	N     int    `json:"n"`
}

Count is a labeled tally (NPS buckets, choice options).

type Result

type Result struct {
	Survey    string   `json:"survey"`
	Type      string   `json:"type"`
	Shown     int      `json:"shown"`     // distinct users who saw it
	Responses int      `json:"responses"` // distinct users who answered
	RatePct   float64  `json:"rate_pct"`
	NPS       *int     `json:"nps,omitempty"`       // type=nps: %promoters - %detractors
	Average   *float64 `json:"average,omitempty"`   // type=rating
	Breakdown []Count  `json:"breakdown,omitempty"` // nps buckets / choice counts
	Recent    []string `json:"recent,omitempty"`    // type=text, most recent first
	Note      string   `json:"note,omitempty"`
}

Result is the aggregate read for one survey.

func Results

func Results(evs []event.Event, surveyID, surveyType string, days int) Result

Results aggregates $survey_shown / $survey_response events for one survey. Pure + deterministic (stable sort order) so /v1 and MCP agree byte-for-byte.

type Store

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

Store persists surveys to a JSON file (atomic tmp+rename), same discipline as the cohort/flag stores. Surveys are id-keyed (Save assigns a random id on create), so an empty path = in-memory.

func Open

func Open(path string) (*Store, error)

func (*Store) Delete

func (s *Store) Delete(id string) (found bool, err error)

Delete removes a survey by id. found is true only when a survey actually went away, so callers never claim a removal that did not occur. A miss is not an error.

func (*Store) Get

func (s *Store) Get(id string) (Survey, bool)

func (*Store) List

func (s *Store) List() []Survey

func (*Store) Save

func (s *Store) Save(sv Survey) (Survey, error)

Save creates (empty ID → new random id) or updates (existing ID) a survey, validating it first.

func (*Store) SeedFixed added in v0.9.12

func (s *Store) SeedFixed(sv Survey)

SeedFixed inserts a survey verbatim, keeping its given ID (unlike Save, which mints a random one on create). For demo seeding and imports where the ID must be known ahead of time so the $survey_shown / $survey_response events can reference it. No-op on empty ID or a duplicate.

func (*Store) SetActive

func (s *Store) SetActive(id string, on bool) (Survey, error)

type Survey

type Survey struct {
	ID        string    `json:"id"`
	Name      string    `json:"name"`
	Type      string    `json:"type"` // nps | rating | choice | text
	Question  string    `json:"question"`
	Choices   []string  `json:"choices,omitempty"`    // for type=choice
	URLMatch  string    `json:"url_match,omitempty"`  // path substring; empty = every page
	SamplePct int       `json:"sample_pct,omitempty"` // 0 or 100 = everyone
	Active    bool      `json:"active"`
	Created   time.Time `json:"created"`
	Updated   time.Time `json:"updated"`
}

Survey is one saved micro-survey. One question keeps the widget tiny and the results legible; multi-step surveys are a deliberate later add.

Jump to

Keyboard shortcuts

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