store

package
v0.36.0 Latest Latest
Warning

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

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

Documentation

Overview

Package store handles all SQLite persistence for spec. No other package opens the database or writes raw SQL.

Index

Constants

View Source
const (
	SurfaceCLI = "cli"
	SurfaceTUI = "tui"
	SurfaceMCP = "mcp"
)

Sync audit surfaces — which client triggered a sync action.

View Source
const (
	OutcomeOK       = "ok"
	OutcomeQueued   = "queued"
	OutcomeConflict = "conflict"
	OutcomeError    = "error"
)

Sync audit outcomes.

View Source
const (
	PMOpCreate = "create" // create-or-find the epic and persist its key
	PMOpLink   = "link"   // set the remote back-link on the epic
	PMOpStatus = "status" // transition the epic to the mapped board status
	PMOpStory  = "story"  // reconcile per-step stories under the epic
)

PM sync operation kinds queued for retry.

View Source
const (
	QueueStatusQueued          = "queued"           // awaiting flush
	QueueStatusNeedsResolution = "needs-resolution" // same-section conflict; needs a human
)

Queued-push states.

Variables

This section is empty.

Functions

func DefaultDBPath

func DefaultDBPath() string

DefaultDBPath returns the default database path.

Types

type ActivityEntry

type ActivityEntry struct {
	ID        int64
	SpecID    string
	EventType string
	Summary   string
	Metadata  string
	UserName  string
	CreatedAt time.Time
}

ActivityEntry represents a single event in the activity log.

type CacheEntry

type CacheEntry struct {
	Value     string
	Fresh     bool
	FetchedAt time.Time
}

CacheEntry holds a cached value along with its metadata.

type DB

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

DB wraps a SQLite database connection.

func Open

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

Open opens or creates the SQLite database at the given path.

func OpenMemory

func OpenMemory() (*DB, error)

OpenMemory opens an in-memory SQLite database for testing.

func (*DB) ActivityCountByType

func (db *DB) ActivityCountByType(since time.Time) (map[string]int, error)

ActivityCountByType returns event counts grouped by event_type since the given time.

func (*DB) ActivityForSpec

func (db *DB) ActivityForSpec(specID string, limit int) ([]ActivityEntry, error)

ActivityForSpec returns activity entries for a specific spec.

func (*DB) ActivityForType

func (db *DB) ActivityForType(eventType string, since time.Time) ([]ActivityEntry, error)

ActivityForType returns all entries of a specific event type since the given time.

func (*DB) ActivityLog

func (db *DB) ActivityLog(specID, eventType, summary, metadata, userName string) error

ActivityLog appends an event to the activity log.

func (*DB) ActivityPrune

func (db *DB) ActivityPrune(olderThan time.Duration) (int64, error)

ActivityPrune removes activity older than the given duration.

func (*DB) ActivitySince

func (db *DB) ActivitySince(since time.Time) ([]ActivityEntry, error)

ActivitySince returns activity entries since the given time.

func (*DB) CacheClear

func (db *DB) CacheClear() error

CacheClear removes all cache entries.

func (*DB) CacheDelete

func (db *DB) CacheDelete(key string) error

CacheDelete removes a cache entry.

func (*DB) CacheGet

func (db *DB) CacheGet(key string) (value string, fresh bool, err error)

CacheGet retrieves a cached value by key. Returns the value and whether the cache entry is still fresh (within TTL). Returns "", false if not found.

func (*DB) CacheGetEntry

func (db *DB) CacheGetEntry(key string) (CacheEntry, error)

CacheGetEntry retrieves a cache entry with full metadata including fetch time.

func (*DB) CacheSet

func (db *DB) CacheSet(key, value string, ttlSeconds int) error

CacheSet stores a value in the cache with the given TTL in seconds.

func (*DB) Close

func (db *DB) Close() error

Close closes the database connection.

func (*DB) Conn

func (db *DB) Conn() *sql.DB

Conn returns the underlying sql.DB for direct queries.

func (*DB) DeleteSpecSearch added in v0.34.0

func (db *DB) DeleteSpecSearch(ctx context.Context, specID string) error

DeleteSpecSearch removes every indexed row and state entry for a spec. Used when a spec is deleted entirely.

func (*DB) DeleteSpecSearchByPath added in v0.34.0

func (db *DB) DeleteSpecSearchByPath(ctx context.Context, path string) error

DeleteSpecSearchByPath removes indexed rows whose state records the given path. Used when a file is renamed/moved (the new file re-indexes under the same spec id) or removed from disk.

func (*DB) FocusedSpecClear

func (db *DB) FocusedSpecClear() error

FocusedSpecClear clears the globally focused spec ID.

func (*DB) FocusedSpecGet

func (db *DB) FocusedSpecGet() (string, error)

FocusedSpecGet returns the globally focused spec ID, if one is set.

func (*DB) FocusedSpecSet

func (db *DB) FocusedSpecSet(specID string) error

FocusedSpecSet stores the globally focused spec ID.

func (*DB) LastFetchGet added in v0.11.1

func (db *DB) LastFetchGet(repoKey string) (time.Time, error)

LastFetchGet returns the timestamp of the last successful fetch for a specs repo (keyed by "owner/repo"), or the zero time if none is recorded.

func (*DB) LastFetchSet added in v0.11.1

func (db *DB) LastFetchSet(repoKey string, at time.Time) error

LastFetchSet records the timestamp of a successful fetch for a specs repo.

func (*DB) MarkThreadSeen added in v0.35.0

func (db *DB) MarkThreadSeen(specID, threadID, viewer string, at time.Time) error

MarkThreadSeen records that a viewer has viewed a thread up to the given activity timestamp. The watermark is monotonic so out-of-order async writes cannot make an already-read thread unread again.

func (*DB) MarkThreadUnseen added in v0.35.0

func (db *DB) MarkThreadUnseen(specID, threadID, viewer string) error

MarkThreadUnseen removes a viewer's thread read-state row.

func (*DB) PMQueueCount added in v0.22.1

func (db *DB) PMQueueCount() (int, error)

PMQueueCount returns the number of queued PM operations.

func (*DB) PMQueueEnqueue added in v0.22.1

func (db *DB) PMQueueEnqueue(item PMQueueItem) (int64, error)

PMQueueEnqueue records a failed PM operation for later retry. It collapses duplicates: a queued op with the same (spec_id, op, payload) is updated rather than duplicated, so repeated failures don't pile up.

func (*DB) PMQueueMark added in v0.22.1

func (db *DB) PMQueueMark(id int64, status, detail string) error

PMQueueMark updates a queued PM operation's status and detail.

func (*DB) PMQueuePending added in v0.22.1

func (db *DB) PMQueuePending(specID string) ([]PMQueueItem, error)

PMQueuePending returns queued PM operations, oldest first. When specID is non-empty the result is scoped to that spec.

func (*DB) PMQueueResolve added in v0.22.1

func (db *DB) PMQueueResolve(id int64) error

PMQueueResolve removes a queued PM operation once it has succeeded.

func (*DB) QuerySpecSearch added in v0.34.0

func (db *DB) QuerySpecSearch(ctx context.Context, match string, scope SearchScope, limit int) ([]SearchRow, error)

QuerySpecSearch runs an FTS5 MATCH query against the index and returns bm25-ranked, section-anchored rows. match must be a valid FTS5 query expression (the caller tokenises/escapes user input). Lower bm25 score is better (the function returns negative scores).

func (*DB) QueuePushCount added in v0.11.1

func (db *DB) QueuePushCount(repoKey string) (int, error)

QueuePushCount returns the number of queued (flushable) entries for a repo.

func (*DB) QueuePushEnqueue added in v0.11.1

func (db *DB) QueuePushEnqueue(q QueuedPush) (int64, error)

QueuePushEnqueue records a queued (offline / contention-exhausted) push.

func (*DB) QueuePushMark added in v0.11.1

func (db *DB) QueuePushMark(id int64, status, detail string) error

QueuePushMark updates a queued entry's status (e.g. needs-resolution).

func (*DB) QueuePushPending added in v0.11.1

func (db *DB) QueuePushPending(repoKey string) ([]QueuedPush, error)

QueuePushPending returns queued entries for a repo that should be flushed, oldest first. Entries marked needs-resolution are excluded — they require a human and must not be retried automatically.

func (*DB) QueuePushResolve added in v0.11.1

func (db *DB) QueuePushResolve(id int64) error

QueuePushResolve removes a queued entry once it has been flushed.

func (*DB) ReaderPositionGet added in v0.35.0

func (db *DB) ReaderPositionGet(specID string) (string, int, error)

ReaderPositionGet returns the last section and viewport offset used for a spec. Missing state is not an error.

func (*DB) ReaderPositionSet added in v0.35.0

func (db *DB) ReaderPositionSet(specID, section string, offset int) error

ReaderPositionSet stores a reader section and offset as one local setting.

func (*DB) SearchIndexEmpty added in v0.34.0

func (db *DB) SearchIndexEmpty(ctx context.Context) (bool, error)

SearchIndexEmpty reports whether the index has never been populated. The search package uses this to decide whether to fall back to a live scan.

func (*DB) SearchStateDiff added in v0.34.0

func (db *DB) SearchStateDiff(ctx context.Context, disk map[string]int64) (changed, removed []string, err error)

SearchStateDiff compares the on-disk path→mtime map against the indexed state and returns the paths that need (re)indexing and the paths that have been removed from disk (and so should be dropped from the index).

func (*DB) SearchStateHash added in v0.34.0

func (db *DB) SearchStateHash(ctx context.Context, path string) (string, error)

SearchStateHash returns the stored content hash for a path, or "" if the path is not indexed. Lets the indexer cheaply skip mtime-only touches.

func (*DB) SessionDelete

func (db *DB) SessionDelete(specID string) error

SessionDelete removes a session.

func (*DB) SessionGet

func (db *DB) SessionGet(specID string) (string, error)

SessionGet retrieves the session state JSON for a spec.

func (*DB) SessionList

func (db *DB) SessionList() ([]string, error)

SessionList returns all active sessions.

func (*DB) SessionMostRecent

func (db *DB) SessionMostRecent() (string, error)

SessionMostRecent returns the spec ID of the most recently updated session.

func (*DB) SessionSet

func (db *DB) SessionSet(specID, state string) error

SessionSet stores session state for a spec.

func (*DB) SyncAuditLog added in v0.11.1

func (db *DB) SyncAuditLog(entry SyncAuditEntry) error

SyncAuditLog appends one sync audit entry and prunes the table to maxAuditRows.

func (*DB) SyncAuditRecent added in v0.11.1

func (db *DB) SyncAuditRecent(limit int) ([]SyncAuditEntry, error)

SyncAuditRecent returns the most recent sync audit entries, newest first.

func (*DB) SyncStateForSpec

func (db *DB) SyncStateForSpec(specID string) (map[string]map[string]SyncStateEntry, error)

SyncStateForSpec returns all sync state entries for a spec keyed by section and direction.

func (*DB) SyncStateGet

func (db *DB) SyncStateGet(specID, section, direction string) (*SyncStateEntry, error)

SyncStateGet returns the last synced hash for a spec section and direction.

func (*DB) SyncStateSet

func (db *DB) SyncStateSet(specID, section, direction, hash string) error

SyncStateSet upserts the last synced hash for a spec section and direction.

func (*DB) ThreadSeen added in v0.35.0

func (db *DB) ThreadSeen(specID, viewer string) (map[string]time.Time, error)

ThreadSeen returns the recorded last-seen timestamp per thread ID for a spec and viewer. A thread with no row has never been seen.

func (*DB) TruncateSearchIndex added in v0.34.0

func (db *DB) TruncateSearchIndex(ctx context.Context) error

TruncateSearchIndex drops all indexed rows and state. Used by `spec search --reindex` to force a clean full rebuild.

func (*DB) UpsertSpecSections added in v0.34.0

func (db *DB) UpsertSpecSections(ctx context.Context, doc SearchDoc, mtime int64, hash string) error

UpsertSpecSections replaces all indexed rows for a spec with the given sections, then records the indexing state. It runs in a single transaction so a partial index never persists. The hash is the caller-computed content fingerprint stored for incremental reindex; mtime is the file's mod time.

type PMQueueItem added in v0.22.1

type PMQueueItem struct {
	ID        int64
	SpecID    string
	EpicKey   string
	Op        string
	Payload   string // op-specific: target status, spec URL, etc.
	Status    string // queued | needs-resolution
	Attempts  int
	Detail    string
	CreatedAt time.Time
	UpdatedAt time.Time
}

PMQueueItem is a PM-tool operation that failed and must be retried so the board never silently drifts from spec state (docs/JIRA_HARDENING_PLAN.md §P5).

type QueuedPush added in v0.11.1

type QueuedPush struct {
	ID        int64
	RepoKey   string // owner/repo — scopes the queue to a clone
	Branch    string
	CommitSHA string // local commit to flush
	Surface   string
	Trigger   string
	SpecID    string
	Status    string // queued | needs-resolution
	Detail    string
	CreatedAt time.Time
	UpdatedAt time.Time
}

QueuedPush records a committed-but-unpushed operation that must be flushed to the remote on a later online operation. Each entry is reconciled independently so one conflict never strands the rest (SPEC-013 §7.1).

type SearchDoc added in v0.34.0

type SearchDoc struct {
	SpecID    string
	Path      string
	Title     string
	Status    string
	Author    string
	Assignees []string
	Cycle     string
	EpicKey   string
	Archived  bool
	Sections  []SearchSection
}

SearchDoc is a fully parsed spec ready for indexing: one row per section. The metadata fields (Author, Assignees, Cycle, EpicKey) are duplicated on every section row so any section hit carries them and MATCH can find specs by them.

type SearchRow added in v0.34.0

type SearchRow struct {
	SpecID         string
	Title          string
	Status         string
	Author         string
	Archived       bool
	SectionSlug    string
	SectionHeading string
	Snippet        string
	Score          float64 // bm25(): negative, lower is better
}

SearchRow is one ranked result row from a search query.

type SearchScope added in v0.34.0

type SearchScope int

SearchScope bounds a spec-search query to active, archived, or all specs.

const (
	ScopeAll SearchScope = iota
	ScopeActive
	ScopeArchived
)

type SearchSection added in v0.34.0

type SearchSection struct {
	Slug    string
	Heading string
	Body    string
}

SearchSection is one indexable section of a spec. The store accepts these rather than internal/markdown.Section so the dependency arrow points store ← search (the store never imports markdown).

type SyncAuditEntry added in v0.11.1

type SyncAuditEntry struct {
	ID        int64
	Op        string // fetch | commit | push | recover | queue-flush
	Actor     string // git user.name
	Surface   string // cli | tui | mcp
	Trigger   string // command/action name
	SpecID    string // optional
	Outcome   string // ok | queued | conflict | error
	Detail    string // free-form context
	CreatedAt time.Time
}

SyncAuditEntry is one recorded sync operation (fetch / commit / push / deferral / auto-recovery) with actor, surface, trigger, and outcome.

type SyncStateEntry

type SyncStateEntry struct {
	SpecID    string
	Section   string
	Direction string
	Hash      string
	SyncedAt  time.Time
}

SyncStateEntry records the last hash synced for one spec section and direction.

Jump to

Keyboard shortcuts

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