omniroadmap

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: MIT Imports: 5 Imported by: 0

README

OmniRoadmap Core

Go CI Go Lint Go SAST Docs Visualization License

Core interfaces and canonical types for omniroadmap — a common, tool-agnostic representation of roadmap/product-management data (features, epics, initiatives, releases, objectives) that adapters for specific SaaS tools (Aha!, ProductBoard, ...) convert into.

This package follows the same shape as the omni*-core pattern used elsewhere in this ecosystem (see github.com/plexusone/omnillm-core for the canonical example): a small interface, canonical types, a provider registry, sentinel/structured errors, and a provider/providertest conformance-test suite every adapter runs against itself.

Where adapters live

Unlike omni-openai/omni-anthropic (separate repos wrapping a pre-existing official third-party SDK), the roadmap-tool SDKs in this ecosystem are built from scratch (no official Go SDK exists for Aha!, ProductBoard, or JPD) — so their adapters live as an embedded omniroadmap/ subpackage inside the SDK repo itself, not as a separate repo:

Provider Location Source
aha github.com/grokify/aha-go/omniroadmap live Aha! API
aha-studio github.com/grokify/aha-studio/omniroadmap aha-studio's local SQLite cache
productboard github.com/grokify/productboard-go/omniroadmap ProductBoard REST API v2
jpd github.com/grokify/go-atlassian/omniroadmap Jira Product Discovery ideas-as-issues

This mirrors elevenlabs-go/omnivoice/ and opik-go/integrations/omnillm/. The batteries-included omniroadmap repo bundles all of them plus the higher-level layers (Dolt store, sync engine, MoSCoW/RICE fieldmap, prism-roadmap export).

Provider interface

type Provider interface {
    Name() string
    Close() error
    Capabilities() Capabilities

    ListItems(ctx context.Context, req *ListItemsRequest) (*ListItemsResponse, error)
    GetItem(ctx context.Context, req *GetItemRequest) (*Item, error)
    ListReleases(ctx context.Context, req *ListReleasesRequest) (*ListReleasesResponse, error)
    ListStatuses(ctx context.Context, req *ListStatusesRequest) (*ListStatusesResponse, error)
    ListCustomFieldDefinitions(ctx context.Context, req *ListCustomFieldDefinitionsRequest) (*ListCustomFieldDefinitionsResponse, error)
}

Read-only in v0.1 — no write verbs yet.

Canonical types

Item, Release, Status, CustomField, CustomFieldDefinition, Person, Link, RICE, and Capabilities live in the provider package. Fields common across source tools are typed; anything provider-specific with no canonical equivalent lives in a Metadata map[string]any passthrough, namespaced by provider (e.g. "aha.progress_source").

Item also carries optional prioritization fields — MoSCoW string (empty = unset) and RICE *RICE (raw numeric inputs). Adapters never populate these (no PM tool exposes them as first-class API fields); they're filled downstream by a per-tenant custom-field mapping layer, since some Aha tenants store MoSCoW/RICE as custom fields.

These types are intentionally not wrappers around github.com/grokify/prism-roadmap's types — prism-roadmap's rmi.RoadmapItem centers on prioritization scoring (MoSCoW, RICE) that source APIs don't expose, and has no source-provenance concept. A separate, optional converter into prism-roadmap types may be added later if something needs it.

Writing an adapter

  1. Implement provider.Provider in a omniroadmap subpackage of your SDK repo.
  2. Register it from an init():
    func init() {
        _ = omniroadmap.RegisterProvider("aha", func(config any) (provider.Provider, error) {
            client, ok := config.(*aha.Client)
            if !ok {
                return nil, fmt.Errorf("omniroadmap/aha: expected *aha.Client, got %T", config)
            }
            return &Provider{client: client}, nil
        })
    }
    
  3. Test it against the shared conformance suite:
    func TestConformance(t *testing.T) {
        providertest.RunAll(t, providertest.Config{
            Provider:        NewProvider(client),
            SkipIntegration: !hasLiveCredentials(),
        })
    }
    

Development

go build ./...
go vet ./...
golangci-lint run ./...
go test ./...

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnsupportedProvider  = errors.New("unsupported provider")
	ErrProviderExists       = errors.New("provider already registered")
	ErrInvalidConfiguration = errors.New("invalid configuration")
	ErrNotFound             = errors.New("not found")
	ErrUnsupportedOperation = errors.New("operation not supported by this provider")
)

Sentinel errors returned by adapters and the registry.

Functions

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports whether err (or an error it wraps) is ErrNotFound.

func IsUnsupportedOperation

func IsUnsupportedOperation(err error) bool

IsUnsupportedOperation reports whether err (or an error it wraps) is ErrUnsupportedOperation — the caller asked for something this provider's Capabilities() doesn't advertise.

func NewProvider

func NewProvider(name string, config any) (provider.Provider, error)

NewProvider constructs a provider.Provider for name using its registered Factory and config.

func RegisterProvider

func RegisterProvider(name string, factory Factory) error

RegisterProvider registers a Factory under name. Adapters call this from an init() func. Registering the same name twice is an error — unlike omnillm-core's priority-based override (needed there for thin-vs-thick duplicate implementations of the same provider), omniroadmap has exactly one adapter per provider, so a duplicate registration is a bug, not a legitimate override.

func RegisteredProviders

func RegisteredProviders() []string

RegisteredProviders returns the names of all currently registered providers, sorted for deterministic output.

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
	Type       string
	Code       string
	Provider   string
}

APIError represents an error response from a provider's underlying API.

func NewAPIError

func NewAPIError(provider string, statusCode int, errorType, message string) *APIError

NewAPIError creates a new APIError.

func (*APIError) Error

func (e *APIError) Error() string

type Factory

type Factory func(config any) (provider.Provider, error)

Factory constructs a provider.Provider from a config value. The config type is adapter-specific (e.g. an Aha *aha.Client, or a struct of credentials) — factories type-assert it themselves.

Directories

Path Synopsis
Package provider defines the core interface and canonical types that external roadmap/product-management data sources must implement or produce to plug into omniroadmap.
Package provider defines the core interface and canonical types that external roadmap/product-management data sources must implement or produce to plug into omniroadmap.
providertest
Package providertest provides a conformance test suite for provider.Provider implementations.
Package providertest provides a conformance test suite for provider.Provider implementations.

Jump to

Keyboard shortcuts

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