store

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Overview

Package store provides the Dolt-backed canonical store for omniroadmap, following visionstudio's Dolt wiring: a MySQL-wire connection to a `dolt sql-server` (launched as a subprocess if not already running), Ent over the MySQL dialect, and Dolt commits wrapped around sync runs. Server lifecycle, DSN handling, and commit plumbing delegate to github.com/grokify/godolt, the shared Dolt integration module.

Index

Constants

View Source
const (
	EnvDSN     = "OMNIROADMAP_DSN"
	EnvPort    = "OMNIROADMAP_PORT"
	EnvDataDir = "OMNIROADMAP_DATA_DIR"
)

Environment variables overriding config-file values (CLI flags override both): OMNIROADMAP_DSN, OMNIROADMAP_PORT, OMNIROADMAP_DATA_DIR.

View Source
const (
	// DefaultPort is the default dolt sql-server port for omniroadmap
	// (distinct from visionstudio's 13306).
	DefaultPort = 13307

	// DefaultDatabase is the Dolt database name.
	DefaultDatabase = "omniroadmap"
)
View Source
const (
	// ReportDatasetStatusDraft marks a just-compiled dataset awaiting PM
	// review.
	ReportDatasetStatusDraft = "draft"

	// ReportDatasetStatusFinal marks a dataset that has been reviewed and
	// rank-materialized (RMI-OMNIROADMAP-006).
	ReportDatasetStatusFinal = "final"
)
View Source
const (
	ConfigFileName = "config.json"
)

Config file names inside the data directory (DefaultDataDir). ConfigFileName is canonical; the dotted variant is also accepted.

Variables

This section is empty.

Functions

func ConfigPath

func ConfigPath() string

ConfigPath returns the config file path: <data dir>/config.json, or the .config.json variant when only that exists.

func DSNForPort

func DSNForPort(port int, database string) string

DSNForPort builds the standard local DSN for a port and database name.

func DefaultDSN

func DefaultDSN() string

DefaultDSN returns the default MySQL-wire DSN for the local dolt sql-server.

func DefaultDataDir

func DefaultDataDir() string

DefaultDataDir returns the default Dolt data directory (~/.omniroadmap).

func EnsureServer

func EnsureServer(dataDir string, port int) error

EnsureServer checks that a dolt sql-server is reachable on the given port, launching one as a subprocess over dataDir if not. Requires the `dolt` binary on PATH when a launch is needed. The launched process is detached — it keeps serving after the caller exits, matching visionstudio's ensureDoltRunning behavior.

func InitDatabase

func InitDatabase(dsn string) error

InitDatabase connects to the server addressed by dsn without selecting its database, creates that database if needed, and returns nil. Use before New on a fresh server.

func PortFromDSN

func PortFromDSN(dsn string) (int, bool)

PortFromDSN extracts the TCP port from a go-sql-driver DSN like "root:@tcp(127.0.0.1:13307)/omniroadmap".

Types

type Config

type Config struct {
	// Port for the local dolt sql-server. Ignored when DSN is set — the
	// DSN's own port wins.
	Port int `json:"port,omitempty"`
	// Database is the Dolt database name (default "omniroadmap").
	Database string `json:"database,omitempty"`
	// DataDir is the Dolt data directory (default ~/.omniroadmap).
	DataDir string `json:"data_dir,omitempty"`
	// DSN is a full MySQL-wire DSN; when set it takes precedence over
	// Port/Database.
	DSN string `json:"dsn,omitempty"`
}

Config is the persisted store configuration (~/.omniroadmap/config.json). All fields are optional; unset fields fall back to built-in defaults. Values are resolved in order: CLI flag > environment variable > config file > default.

Running several Dolt-backed tools side by side (e.g. visionstudio on 13306) is the main use case: set Port (or a full DSN) to keep each tool's dolt sql-server on its own port.

func LoadConfig

func LoadConfig() (*Config, error)

LoadConfig reads the config file from ConfigPath. A missing file yields an empty Config (all defaults); a malformed file is an error.

func LoadConfigFrom

func LoadConfigFrom(path string) (*Config, error)

LoadConfigFrom reads a Config from an explicit path, with the same missing-file behavior as LoadConfig.

func (*Config) Resolve

func (c *Config) Resolve(flagDSN string, flagPort int, flagDataDir string) (Settings, error)

Resolve merges CLI-flag overrides (zero value = not set) with environment variables, the config file, and built-in defaults into final Settings. When the DSN is given explicitly (flag, env, or config), its embedded port is authoritative — EnsureServer must watch the port clients actually connect to.

func (*Config) Save

func (c *Config) Save() error

Save writes the config to <data dir>/config.json.

func (*Config) SaveTo

func (c *Config) SaveTo(path string) error

SaveTo writes the config to an explicit path, creating parent directories as needed.

type DoltStore

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

DoltStore is an Ent client over a Dolt database, reached via the MySQL wire protocol.

func New

func New(dsn string) (*DoltStore, error)

New opens a DoltStore from a MySQL-compatible DSN. The target database must already exist — see InitDatabase.

func (*DoltStore) Client

func (s *DoltStore) Client() *ent.Client

Client exposes the Ent client for queries beyond the Store interface.

func (*DoltStore) Close

func (s *DoltStore) Close() error

Close closes the underlying connections.

func (*DoltStore) Commit

func (s *DoltStore) Commit(ctx context.Context, message string) error

Commit stages and commits all Dolt changes with the given message. A clean working set is a no-op.

func (*DoltStore) DeleteEvidence

func (s *DoltStore) DeleteEvidence(ctx context.Context, id string) error

DeleteEvidence removes one evidence record by ID. Deleting a nonexistent record is a no-op.

func (*DoltStore) DeleteItemAugment

func (s *DoltStore) DeleteItemAugment(ctx context.Context, providerName, sourceRef string) error

DeleteItemAugment removes the augment for (provider, source_ref). Deleting a nonexistent augment is a no-op.

func (*DoltStore) DeleteOpportunityAssessment

func (s *DoltStore) DeleteOpportunityAssessment(ctx context.Context, id string) error

DeleteOpportunityAssessment removes one assessment cycle by ID. Deleting a nonexistent assessment is a no-op.

func (*DoltStore) DeleteProfileAssignment

func (s *DoltStore) DeleteProfileAssignment(ctx context.Context, specID string) error

DeleteProfileAssignment removes the profile assignment for one opportunity spec. Deleting a nonexistent assignment is a no-op.

func (*DoltStore) DeleteRankOverride

func (s *DoltStore) DeleteRankOverride(ctx context.Context, assessmentID string) error

DeleteRankOverride removes the override for one assessment, reverting it to its calculated rank on the next compile. Deleting a nonexistent override is a no-op.

func (*DoltStore) EnsureBuiltinDimensions

func (s *DoltStore) EnsureBuiltinDimensions(ctx context.Context) error

EnsureBuiltinDimensions registers Kano and Market Investment Horizon (github.com/grokify/prism-roadmap/assessment.KanoDimension, MarketInvestmentHorizonDimension) if not already present. Idempotent — safe to call on every startup. Deliberately not wired into Migrate: that method's job is schema migration, not seed data, and conflating the two would make a seed-data change look like a schema change in its diff.

func (*DoltStore) EvidenceCitations

func (s *DoltStore) EvidenceCitations(ctx context.Context, evidenceID string) ([]assessment.EvidenceRef, error)

EvidenceCitations returns every assessment/question reference citing the given evidence ID, across every assessment cycle — the reverse lookup prism-roadmap PRD FR5 asks for ("which assessments cite this source").

func (*DoltStore) GetDimension

func (s *DoltStore) GetDimension(ctx context.Context, dimensionID, version string) (*assessment.DimensionDefinition, error)

GetDimension returns a dimension definition, with its options in definition order, by ID+version — or omniroadmap.ErrNotFound.

func (*DoltStore) GetEvidence

func (s *DoltStore) GetEvidence(ctx context.Context, id string) (*assessment.Evidence, error)

GetEvidence returns one evidence record by ID, or omniroadmap.ErrNotFound.

func (*DoltStore) GetItem

func (s *DoltStore) GetItem(ctx context.Context, providerName, ref string) (*provider.Item, error)

GetItem reads one item by its source reference (e.g. "MYPROJ-123"), source ID, or canonical ID, with augments applied. Returns omniroadmap.ErrNotFound when no item matches.

func (*DoltStore) GetItemAugment

func (s *DoltStore) GetItemAugment(ctx context.Context, providerName, sourceRef string) (*augment.ItemAugment, error)

GetItemAugment returns the augment for (provider, source_ref), or omniroadmap.ErrNotFound when none exists.

func (*DoltStore) GetLatestReportDataset

func (s *DoltStore) GetLatestReportDataset(ctx context.Context) (*assessment.ReportDataset, error)

GetLatestReportDataset returns the most recently generated dataset (by GeneratedAt), or (nil, nil) if none has ever been compiled — a deliberate non-error "nothing yet" signal, since a first compile has nothing to diff deltas against and that's an entirely normal state, not a fault.

func (*DoltStore) GetOpportunityAssessment

func (s *DoltStore) GetOpportunityAssessment(ctx context.Context, id string) (*assessment.OpportunityAssessment, error)

GetOpportunityAssessment returns one assessment cycle by ID, or omniroadmap.ErrNotFound when none exists.

func (*DoltStore) GetOpportunitySpec

func (s *DoltStore) GetOpportunitySpec(ctx context.Context, id string) (*canvas.OpportunitySpec, error)

GetOpportunitySpec returns one spec by ID, or omniroadmap.ErrNotFound when none exists.

func (*DoltStore) GetProfileAssignment

func (s *DoltStore) GetProfileAssignment(ctx context.Context, specID string) (*assessment.ProfileAssignment, error)

GetProfileAssignment returns the current profile assignment for one opportunity spec, or omniroadmap.ErrNotFound if none exists.

func (*DoltStore) GetRankOverride

func (s *DoltStore) GetRankOverride(ctx context.Context, assessmentID string) (*assessment.RankOverride, error)

GetRankOverride returns the active override for one assessment, or omniroadmap.ErrNotFound if none exists.

func (*DoltStore) GetReportDataset

func (s *DoltStore) GetReportDataset(ctx context.Context, id string) (*assessment.ReportDataset, error)

GetReportDataset returns one compile run by ID, or omniroadmap.ErrNotFound.

func (*DoltStore) GetSyncMeta

func (s *DoltStore) GetSyncMeta(ctx context.Context) ([]SyncMetaEntry, error)

GetSyncMeta returns all sync metadata entries, ordered by provider then kind.

func (*DoltStore) ListCurrentOpportunityAssessments

func (s *DoltStore) ListCurrentOpportunityAssessments(ctx context.Context) ([]assessment.OpportunityAssessment, error)

ListCurrentOpportunityAssessments returns the current cycle for every opportunity that has one — the corpus a compile run (RMI-OMNIROADMAP-004) operates over.

func (*DoltStore) ListCustomDimensions

func (s *DoltStore) ListCustomDimensions(ctx context.Context) ([]assessment.DimensionDefinition, error)

ListCustomDimensions returns only non-built-in dimension definitions — the ones an organization registered itself.

func (*DoltStore) ListDimensions

func (s *DoltStore) ListDimensions(ctx context.Context) ([]assessment.DimensionDefinition, error)

ListDimensions returns every registered dimension definition (every version of every dimension ID), ordered by dimension ID then version.

func (*DoltStore) ListEvidence

func (s *DoltStore) ListEvidence(ctx context.Context) ([]assessment.Evidence, error)

ListEvidence returns every evidence record, ordered by ID.

func (*DoltStore) ListItemAugments

func (s *DoltStore) ListItemAugments(ctx context.Context, providerName string) ([]augment.ItemAugment, error)

ListItemAugments returns all augments, optionally filtered to one provider (empty providerName = all), ordered by provider then ref.

func (*DoltStore) ListItems

func (s *DoltStore) ListItems(ctx context.Context, f ItemFilter) ([]provider.Item, error)

ListItems reads canonical items back from the store. By default, locally-authored augments (MoSCoW, Kano, RICE, OKR refs, notes) are overlaid, winning over what sync stored.

func (*DoltStore) ListOpportunityAssessments

func (s *DoltStore) ListOpportunityAssessments(ctx context.Context, opportunitySpecID string) ([]assessment.OpportunityAssessment, error)

ListOpportunityAssessments returns every cycle recorded for one opportunity (by OpportunitySpecID), ordered oldest cycle first.

func (*DoltStore) ListProfileAssignments

func (s *DoltStore) ListProfileAssignments(ctx context.Context) ([]assessment.ProfileAssignment, error)

ListProfileAssignments returns every current profile assignment, ordered by opportunity spec ID — the input omniroadmap's compile gating needs to check whether an opportunity's Compass.ProfileID has been PM-confirmed.

func (*DoltStore) ListRankOverrides

func (s *DoltStore) ListRankOverrides(ctx context.Context) ([]assessment.RankOverride, error)

ListRankOverrides returns every active override, ordered by assessment ID — the input assessment.ApplyOverrides needs for a compile run.

func (*DoltStore) ListReportDatasets

func (s *DoltStore) ListReportDatasets(ctx context.Context) ([]assessment.ReportDataset, error)

ListReportDatasets returns every compile run, newest first.

func (*DoltStore) Migrate

func (s *DoltStore) Migrate(ctx context.Context) error

Migrate creates/updates the schema (plain append-style Schema.Create, matching visionstudio).

func (*DoltStore) RegisterDimension

func (s *DoltStore) RegisterDimension(ctx context.Context, def assessment.DimensionDefinition, builtIn bool) error

RegisterDimension upserts a dimension definition and its options. Registering (or updating) a custom portfolio dimension is exactly this call — an INSERT into two tables, never a schema migration (prism-roadmap PRD FR4).

func (*DoltStore) SaveEvidence

func (s *DoltStore) SaveEvidence(ctx context.Context, e assessment.Evidence) error

SaveEvidence upserts an evidence record. Projection columns (system, sensitivity, capturedBy, capturedAt, sourceURI, verified) are computed from e's canonical fields at save time — every column is set explicitly, including empty/zero values, so a re-save fully replaces the prior projection (same discipline as SaveOpportunityAssessment).

func (*DoltStore) SaveOpportunityAssessment

func (s *DoltStore) SaveOpportunityAssessment(ctx context.Context, a assessment.OpportunityAssessment) error

SaveOpportunityAssessment upserts a as its own row, and — when a.Cycle.SupersedesID is set — atomically flips the row it supersedes to Current=false in the same transaction. This enforces "at most one current row per opportunity" without requiring the caller to remember a second call: prism-roadmap's OpportunityAssessment.NextCycle leaves calling MarkSuperseded to "the caller" by design, and this store is that caller.

Indexed projection columns (moscow_class, rice_score, rice_computable, kano_category, mih_category) are computed from a's canonical fields at save time — every column is set explicitly, including empty/zero values, so a re-save of the same ID (e.g. re-running a judge pass mid-cycle) fully replaces the prior projection rather than leaving stale values behind (prism-roadmap TRD: "omniroadmap relational fields = indexed/ materialized projection"). opportunity_rank_calculated/final are left untouched here — ranking is inherently cross-opportunity and is populated separately by rank materialization across the full corpus (RMI-OMNIROADMAP-006).

func (*DoltStore) SaveOpportunitySpec

func (s *DoltStore) SaveOpportunitySpec(ctx context.Context, spec canvas.OpportunitySpec) error

SaveOpportunitySpec upserts spec by its Metadata.ID. Every column is set explicitly, including empty/zero values, so a re-save fully replaces the prior record rather than leaving stale values behind (same discipline as SaveOpportunityAssessment/SaveEvidence).

func (*DoltStore) SaveProfileAssignment

func (s *DoltStore) SaveProfileAssignment(ctx context.Context, a assessment.ProfileAssignment) error

SaveProfileAssignment upserts the current profile assignment for one opportunity spec. Call a.Validate() (required fields) before calling this — this store does not re-validate, matching this repo's existing division of labor between domain-type validation and store persistence. A re-save (e.g. compassbridge.ConfirmProfile's result) fully replaces the prior row.

func (*DoltStore) SaveRankOverride

func (s *DoltStore) SaveRankOverride(ctx context.Context, o assessment.RankOverride) error

SaveRankOverride upserts a governance override for one assessment. Call o.Validate() (required fields) before calling this — this store does not re-validate, matching this repo's existing division of labor between domain-type validation and store persistence.

func (*DoltStore) SaveReportDataset

func (s *DoltStore) SaveReportDataset(ctx context.Context, id string, dataset assessment.ReportDataset, status string) error

SaveReportDataset persists one compile run under id and status. Every compile produces a NEW id (never reused) — datasets are never mutated in place, mirroring OpportunityAssessment's own cycle-history discipline.

func (*DoltStore) SetItemAugment

func (s *DoltStore) SetItemAugment(ctx context.Context, aug augment.ItemAugment) error

SetItemAugment upserts locally-authored data for one item, replacing any existing augment for the same (provider, source_ref) wholesale. Sync never touches augments, so they survive provider re-syncs.

func (*DoltStore) SetOpportunityRank

func (s *DoltStore) SetOpportunityRank(ctx context.Context, assessmentID string, calculated, final int) error

SetOpportunityRank updates only the opportunity_rank_calculated/final projection columns for one assessment — never touches canonical or any other column. This is the promised follow-up to SaveOpportunityAssessment (RMI-OMNIROADMAP-001), which deliberately left these two columns unset: ranking is inherently cross-opportunity and cannot be derived from a single assessment in isolation. Rank materialization (RMI-OMNIROADMAP-006) calls this once a compiled ReportDataset has been reviewed and approved.

func (*DoltStore) SetReportDatasetStatus

func (s *DoltStore) SetReportDatasetStatus(ctx context.Context, id, status string) error

SetReportDatasetStatus updates one compile run's review status (e.g. draft -> final once PM review and rank materialization complete).

func (*DoltStore) SetSyncMeta

func (s *DoltStore) SetSyncMeta(ctx context.Context, providerName, kind string, lastSync time.Time, count int) error

SetSyncMeta records the last sync time and record count for a (provider, kind) pair.

func (*DoltStore) StaleEvidence

func (s *DoltStore) StaleEvidence(ctx context.Context, now time.Time) ([]assessment.Evidence, error)

StaleEvidence returns every evidence record whose capture time has exceeded its system's DefaultValidityWindow as of now (prism-roadmap PRD FR11).

func (*DoltStore) StaleEvidenceCitations

func (s *DoltStore) StaleEvidenceCitations(ctx context.Context, now time.Time) (map[string][]assessment.EvidenceRef, error)

StaleEvidenceCitations finds every stale evidence record and the assessment/question references that cite it, keyed by evidence ID — the input a staleness sweep needs to visibly degrade those assessments' Confidence display rather than silently trusting stale support (prism-roadmap PRD FR11).

func (*DoltStore) UpsertCustomFieldDefinitions

func (s *DoltStore) UpsertCustomFieldDefinitions(ctx context.Context, providerName string, defs []provider.CustomFieldDefinition) error

UpsertCustomFieldDefinitions inserts or updates custom field definitions for a provider.

func (*DoltStore) UpsertItems

func (s *DoltStore) UpsertItems(ctx context.Context, items []provider.Item) error

UpsertItems inserts or updates canonical items by ID.

func (*DoltStore) UpsertReleases

func (s *DoltStore) UpsertReleases(ctx context.Context, releases []provider.Release) error

UpsertReleases inserts or updates canonical releases by ID.

type ItemFilter

type ItemFilter struct {
	Provider string
	Kinds    []provider.ItemKind

	// WithoutAugments returns raw synced provider data, skipping the
	// augment overlay.
	WithoutAugments bool
}

ItemFilter narrows a ListItems call. Zero value = every item.

type Settings

type Settings struct {
	DSN     string
	Port    int
	DataDir string

	DSNSource     string
	PortSource    string
	DataDirSource string
}

Settings is a fully-resolved store configuration, with the source of each value ("flag", "env", "config", "dsn", or "default") for diagnostics.

type SyncMetaEntry

type SyncMetaEntry struct {
	Provider    string
	Kind        string
	LastSync    time.Time
	RecordCount int
}

SyncMetaEntry is one (provider, kind) sync record.

Jump to

Keyboard shortcuts

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