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
- func ConfigPath() string
- func DSNForPort(port int, database string) string
- func DefaultDSN() string
- func DefaultDataDir() string
- func EnsureServer(dataDir string, port int) error
- func InitDatabase(dsn string) error
- func PortFromDSN(dsn string) (int, bool)
- type Config
- type DoltStore
- func (s *DoltStore) Client() *ent.Client
- func (s *DoltStore) Close() error
- func (s *DoltStore) Commit(ctx context.Context, message string) error
- func (s *DoltStore) DeleteEvidence(ctx context.Context, id string) error
- func (s *DoltStore) DeleteItemAugment(ctx context.Context, providerName, sourceRef string) error
- func (s *DoltStore) DeleteOpportunityAssessment(ctx context.Context, id string) error
- func (s *DoltStore) DeleteProfileAssignment(ctx context.Context, specID string) error
- func (s *DoltStore) DeleteRankOverride(ctx context.Context, assessmentID string) error
- func (s *DoltStore) EnsureBuiltinDimensions(ctx context.Context) error
- func (s *DoltStore) EvidenceCitations(ctx context.Context, evidenceID string) ([]assessment.EvidenceRef, error)
- func (s *DoltStore) GetDimension(ctx context.Context, dimensionID, version string) (*assessment.DimensionDefinition, error)
- func (s *DoltStore) GetEvidence(ctx context.Context, id string) (*assessment.Evidence, error)
- func (s *DoltStore) GetItem(ctx context.Context, providerName, ref string) (*provider.Item, error)
- func (s *DoltStore) GetItemAugment(ctx context.Context, providerName, sourceRef string) (*augment.ItemAugment, error)
- func (s *DoltStore) GetLatestReportDataset(ctx context.Context) (*assessment.ReportDataset, error)
- func (s *DoltStore) GetOpportunityAssessment(ctx context.Context, id string) (*assessment.OpportunityAssessment, error)
- func (s *DoltStore) GetOpportunitySpec(ctx context.Context, id string) (*canvas.OpportunitySpec, error)
- func (s *DoltStore) GetProfileAssignment(ctx context.Context, specID string) (*assessment.ProfileAssignment, error)
- func (s *DoltStore) GetRankOverride(ctx context.Context, assessmentID string) (*assessment.RankOverride, error)
- func (s *DoltStore) GetReportDataset(ctx context.Context, id string) (*assessment.ReportDataset, error)
- func (s *DoltStore) GetSyncMeta(ctx context.Context) ([]SyncMetaEntry, error)
- func (s *DoltStore) ListCurrentOpportunityAssessments(ctx context.Context) ([]assessment.OpportunityAssessment, error)
- func (s *DoltStore) ListCustomDimensions(ctx context.Context) ([]assessment.DimensionDefinition, error)
- func (s *DoltStore) ListDimensions(ctx context.Context) ([]assessment.DimensionDefinition, error)
- func (s *DoltStore) ListEvidence(ctx context.Context) ([]assessment.Evidence, error)
- func (s *DoltStore) ListItemAugments(ctx context.Context, providerName string) ([]augment.ItemAugment, error)
- func (s *DoltStore) ListItems(ctx context.Context, f ItemFilter) ([]provider.Item, error)
- func (s *DoltStore) ListOpportunityAssessments(ctx context.Context, opportunitySpecID string) ([]assessment.OpportunityAssessment, error)
- func (s *DoltStore) ListProfileAssignments(ctx context.Context) ([]assessment.ProfileAssignment, error)
- func (s *DoltStore) ListRankOverrides(ctx context.Context) ([]assessment.RankOverride, error)
- func (s *DoltStore) ListReportDatasets(ctx context.Context) ([]assessment.ReportDataset, error)
- func (s *DoltStore) Migrate(ctx context.Context) error
- func (s *DoltStore) RegisterDimension(ctx context.Context, def assessment.DimensionDefinition, builtIn bool) error
- func (s *DoltStore) SaveEvidence(ctx context.Context, e assessment.Evidence) error
- func (s *DoltStore) SaveOpportunityAssessment(ctx context.Context, a assessment.OpportunityAssessment) error
- func (s *DoltStore) SaveOpportunitySpec(ctx context.Context, spec canvas.OpportunitySpec) error
- func (s *DoltStore) SaveProfileAssignment(ctx context.Context, a assessment.ProfileAssignment) error
- func (s *DoltStore) SaveRankOverride(ctx context.Context, o assessment.RankOverride) error
- func (s *DoltStore) SaveReportDataset(ctx context.Context, id string, dataset assessment.ReportDataset, ...) error
- func (s *DoltStore) SetItemAugment(ctx context.Context, aug augment.ItemAugment) error
- func (s *DoltStore) SetOpportunityRank(ctx context.Context, assessmentID string, calculated, final int) error
- func (s *DoltStore) SetReportDatasetStatus(ctx context.Context, id, status string) error
- func (s *DoltStore) SetSyncMeta(ctx context.Context, providerName, kind string, lastSync time.Time, count int) error
- func (s *DoltStore) StaleEvidence(ctx context.Context, now time.Time) ([]assessment.Evidence, error)
- func (s *DoltStore) StaleEvidenceCitations(ctx context.Context, now time.Time) (map[string][]assessment.EvidenceRef, error)
- func (s *DoltStore) UpsertCustomFieldDefinitions(ctx context.Context, providerName string, ...) error
- func (s *DoltStore) UpsertItems(ctx context.Context, items []provider.Item) error
- func (s *DoltStore) UpsertReleases(ctx context.Context, releases []provider.Release) error
- type ItemFilter
- type Settings
- type SyncMetaEntry
Constants ¶
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.
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" )
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" )
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
LoadConfig reads the config file from ConfigPath. A missing file yields an empty Config (all defaults); a malformed file is an error.
func LoadConfigFrom ¶
LoadConfigFrom reads a Config from an explicit path, with the same missing-file behavior as LoadConfig.
func (*Config) Resolve ¶
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.
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 ¶
New opens a DoltStore from a MySQL-compatible DSN. The target database must already exist — see InitDatabase.
func (*DoltStore) Commit ¶
Commit stages and commits all Dolt changes with the given message. A clean working set is a no-op.
func (*DoltStore) DeleteEvidence ¶
DeleteEvidence removes one evidence record by ID. Deleting a nonexistent record is a no-op.
func (*DoltStore) DeleteItemAugment ¶
DeleteItemAugment removes the augment for (provider, source_ref). Deleting a nonexistent augment is a no-op.
func (*DoltStore) DeleteOpportunityAssessment ¶
DeleteOpportunityAssessment removes one assessment cycle by ID. Deleting a nonexistent assessment is a no-op.
func (*DoltStore) DeleteProfileAssignment ¶
DeleteProfileAssignment removes the profile assignment for one opportunity spec. Deleting a nonexistent assignment is a no-op.
func (*DoltStore) DeleteRankOverride ¶
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 ¶
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 ¶
GetEvidence returns one evidence record by ID, or omniroadmap.ErrNotFound.
func (*DoltStore) GetItem ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
UpsertItems inserts or updates canonical items 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.