streakd

package module
v0.0.0-...-3d30ee6 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 2 Imported by: 0

README

streakd

An open-source streak engine: timezone-correct day boundaries, freezes, repair, at-risk reminder events — the retention feature you keep reimplementing, done once.

Status: pre-alpha. See docs/DESIGN.md and docs/PLAN.md.

Modes

  • Embedded — import the Go library, it owns a streaks schema in your existing Postgres. No new infrastructure.
  • Sidecar — run the same engine as a container with an HTTP API for any stack. (Planned, Phase 5.)

Why

Streak logic looks trivial and is not: per-user IANA timezones, DST, travel, idempotent recording under concurrency, freeze consumption, lazy expiry that never shows stale counts, and reminders that do not nag about already-dead streaks. streakd's state is a pure function of an append-only ledger — a dead scheduler can delay a notification but can never corrupt a streak.

License

MIT

Documentation

Overview

Package streakd is an embeddable streak engine: timezone-correct period math, freezes, repair, and at-risk reminder events on top of your existing Postgres.

Quickstart:

pool, _ := pgxpool.New(ctx, dsn)
eng, _ := streakd.New(pool,
    streakd.WithDefaultTimezone("UTC"),
    streakd.WithStreakType("practice", streakd.Config{
        Period:     streakd.PeriodDay,
        Milestones: []int{3, 7, 14, 30, 50, 100, 365},
        Freezes:    streakd.FreezePolicy{EarnEveryNPeriods: 7, Max: 2, AutoConsume: true},
    }),
    streakd.WithEventHandler(func(ev streakd.Event) { /* push, telegram, ... */ }),
)
_ = eng.Migrate(ctx)               // owns the `streaks` schema, own version table
go eng.RunScheduler(ctx, 5*time.Minute)

view, _ := eng.Record(ctx, streakd.RecordReq{Subject: "user:1", Key: "practice"})
view, _ = eng.Get(ctx, "user:1", "practice") // always derived, never stale

State is a pure function of an append-only ledger: reads are correct even if the scheduler never runs — a dead cron can delay a notification but can never corrupt a streak or show a stale count.

Index

Constants

View Source
const (
	PeriodDay   = core.PeriodDay
	PeriodWeek  = core.PeriodWeek
	PeriodMonth = core.PeriodMonth

	Alive  = core.Alive
	Frozen = core.Frozen
	Broken = core.Broken

	EventExtended       = core.EventExtended
	EventFreezeEarned   = core.EventFreezeEarned
	EventFreezeConsumed = core.EventFreezeConsumed
	EventBroken         = core.EventBroken
	EventMilestone      = core.EventMilestone
	EventCompleted      = core.EventCompleted
	EventRepaired       = core.EventRepaired
	EventAtRisk         = core.EventAtRisk
)

Variables

View Source
var (
	New                 = engine.New
	WithClock           = engine.WithClock
	WithDefaultTimezone = engine.WithDefaultTimezone
	WithStreakType      = engine.WithStreakType
	WithEventHandler    = engine.WithEventHandler
	WithLogger          = engine.WithLogger

	MigrateDB = engine.MigrateDB

	ParseDate = core.ParseDate
	MustDate  = core.MustDate
)

Constructor and options.

View Source
var (
	ErrNotFound          = engine.ErrNotFound
	ErrBadTimezone       = engine.ErrBadTimezone
	ErrOutsidePeriod     = engine.ErrOutsidePeriod
	ErrNothingToRepair   = engine.ErrNothingToRepair
	ErrUnknownStreakType = engine.ErrUnknownStreakType
)

Sentinel errors.

Functions

This section is empty.

Types

type CalendarDay

type CalendarDay = engine.CalendarDay

Engine and its option/request/response types.

type Config

type Config = core.Config

Streak behavior configuration.

type Date

type Date = core.Date

Streak behavior configuration.

type Engine

type Engine = engine.Engine

Engine and its option/request/response types.

type Event

type Event = engine.Event

Engine and its option/request/response types.

type EventType

type EventType = core.EventType

Streak behavior configuration.

type FreezePolicy

type FreezePolicy = core.FreezePolicy

Streak behavior configuration.

type FreezesView

type FreezesView = engine.FreezesView

Engine and its option/request/response types.

type Liveness

type Liveness = core.Liveness

Streak behavior configuration.

type MilestoneView

type MilestoneView = engine.MilestoneView

Engine and its option/request/response types.

type Option

type Option = engine.Option

Engine and its option/request/response types.

type Period

type Period = core.Period

Streak behavior configuration.

type RecordReq

type RecordReq = engine.RecordReq

Engine and its option/request/response types.

type StreakView

type StreakView = engine.StreakView

Engine and its option/request/response types.

type TargetView

type TargetView = engine.TargetView

Engine and its option/request/response types.

Directories

Path Synopsis
internal
core
Package core implements the pure streak semantics: period math, derivation, and state transitions.
Package core implements the pure streak semantics: period math, derivation, and state transitions.
engine
Package engine orchestrates core transitions over the store within transactions: recording, reads, timezone changes, repair, and the outbox.
Package engine orchestrates core transitions over the store within transactions: recording, reads, timezone changes, repair, and the outbox.
store
Package store owns the streaks.* Postgres schema: migrations and typed queries.
Package store owns the streaks.* Postgres schema: migrations and typed queries.
Package streaktest is a time-travel harness for testing streak behavior: drive a simulated clock through days, DST nights, and timezone changes and assert on derived state and emitted events.
Package streaktest is a time-travel harness for testing streak behavior: drive a simulated clock through days, DST nights, and timezone changes and assert on derived state and emitted events.

Jump to

Keyboard shortcuts

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