Skip to content

Package internal/storage

Import path: go.devnw.com/canary/internal/storage

package storage // import "go.devnw.com/canary/internal/storage"

API (raw go doc)


package storage // import "go.devnw.com/canary/internal/storage"

CANARY: REQ=CBIN-146; FEATURE="ContextManagement"; ASPECT=Engine; STATUS=IMPL;
UPDATED=2025-10-18

CANARY: REQ=CBIN-129; FEATURE="DatabaseMigrations"; ASPECT=Storage; STATUS=IMPL;
OWNER=canary; UPDATED=2025-10-16

CANARY: REQ=CBIN-140; FEATURE="GapRepository"; ASPECT=Storage; STATUS=IMPL;
UPDATED=2025-10-17

CANARY: REQ=CBIN-146; FEATURE="DatabaseModes"; ASPECT=Storage; STATUS=IMPL;
UPDATED=2025-10-18

CANARY: REQ=CBIN-146; FEATURE="ProjectRegistry"; ASPECT=Storage; STATUS=IMPL;
UPDATED=2025-10-18

CANARY: REQ=CBIN-123; FEATURE="TokenStorage"; ASPECT=Storage; STATUS=IMPL;
OWNER=canary; UPDATED=2025-10-16

CONSTANTS

const (
    DBDriver        = "sqlite"
    DBMigrationPath = "migrations"
    DBSourceName    = "iofs"
    DBURLProtocol   = "sqlite://"
    MigrateAll      = "all"
    LatestVersion   = 5 // Update this when adding new migrations
)

VARIABLES

var ErrDatabaseNotPopulated = errors.New("database not migrated")

FUNCTIONS

func AutoMigrate(dbPath string) error
    AutoMigrate automatically migrates the database if needed

func DatabasePopulated(db *sqlx.DB, targetVersion int) (bool, error)
    DatabasePopulated checks if the database is fully migrated and populated
    We only return an error here if we're getting database issues. Bool return
    should reflect the state of the database.

func InitDB(dbPath string) (*sqlx.DB, error)
    InitDB initializes the database connection

func MigrateDB(dbPath string, steps string) error
    MigrateDB applies the database migrations stored in migrations/*.sql It
    takes a single argument which is either "all" to migrate to the latest
    version or an integer to migrate by that many steps.

func NeedsMigration(dbPath string) (bool, int, error)
    NeedsMigration checks if the database exists and needs migration

func TeardownDB(dbPath string, steps string) error
    TeardownDB is the negative inverse of MigrateDB, rolling back migrations It
    takes a single argument which is either "all" to roll back all migrations or
    an integer to roll back by that many steps.


TYPES

type Checkpoint struct {
    ID           int
    Name         string
    Description  string
    CommitHash   string
    CreatedAt    string
    TotalTokens  int
    StubCount    int
    ImplCount    int
    TestedCount  int
    BenchedCount int
    SnapshotJSON string
}
    Checkpoint represents a state snapshot

type ContextManager struct {
    // Has unexported fields.
}
    ContextManager manages the current project context

func NewContextManager(manager *DatabaseManager) *ContextManager
    NewContextManager creates a new context manager

func (cm *ContextManager) DetectProject() (*Project, error)
    DetectProject attempts to detect the current project from the working
    directory

func (cm *ContextManager) GetCurrent() (*Project, error)
    GetCurrent returns the currently active project

func (cm *ContextManager) SwitchTo(projectID string) error
    SwitchTo switches the current project context to the specified project ID

type DB struct {
    // Has unexported fields.
}
    DB wraps the SQLite database connection

func Open(dbPath string) (*DB, error)
    Open opens or creates the CANARY database Note: Migrations are handled
    automatically by the CLI's PersistentPreRunE

func (db *DB) Close() error
    Close closes the database connection

func (db *DB) CreateCheckpoint(name, description, commitHash, snapshotJSON string) error
    CreateCheckpoint creates a state snapshot

func (db *DB) GetAllTokens() ([]*Token, error)
    GetAllTokens retrieves all tokens across all projects

func (db *DB) GetCheckpoints() ([]*Checkpoint, error)
    GetCheckpoints retrieves all checkpoints

func (db *DB) GetFilesByReqID(reqID string, excludeSpecs bool) (map[string][]*Token, error)
    CANARY: REQ=CBIN-CLI-001; FEATURE="QueryAbstraction"; ASPECT=Storage;
    STATUS=TESTED; TEST=TestCANARY_CBIN_CLI_001_Storage_GetFilesByReqID;
    UPDATED=2025-10-16 GetFilesByReqID groups tokens by file path for a
    requirement

func (db *DB) GetTokensByProject(projectID string) ([]*Token, error)
    CANARY: REQ=CBIN-146; FEATURE="TokenNamespacing"; ASPECT=Storage;
    STATUS=IMPL; UPDATED=2025-10-18 GetTokensByProject retrieves all tokens for
    a specific project

func (db *DB) GetTokensByReqID(reqID string) ([]*Token, error)
    GetTokensByReqID retrieves all tokens for a requirement

func (db *DB) GetTokensByReqIDAndProject(reqID, projectID string) ([]*Token, error)
    GetTokensByReqIDAndProject retrieves tokens for a requirement within a
    specific project

func (db *DB) ListTokens(filters map[string]string, idPattern string, orderBy string, limit int) ([]*Token, error)
    CANARY: REQ=CBIN-145; FEATURE="PriorityFiltering"; ASPECT=Storage;
    STATUS=IMPL; UPDATED=2025-10-17 ListTokens retrieves tokens with filters and
    ordering idPattern is a regex pattern for filtering requirement IDs (e.g.,
    "CBIN-[1-9][0-9]{2,}")

func (db *DB) SearchTokens(keywords string) ([]*Token, error)
    SearchTokens searches by keywords

func (db *DB) UpdatePriority(reqID, feature string, priority int) error
    UpdatePriority updates the priority of a token

func (db *DB) UpdateSpecStatus(reqID, specStatus string) error
    UpdateSpecStatus updates the spec status

func (db *DB) UpsertToken(token *Token) error
    UpsertToken inserts or updates a token

type DatabaseManager struct {
    // Has unexported fields.
}
    DatabaseManager manages both global and local database connections

func NewDatabaseManager() *DatabaseManager
    NewDatabaseManager creates a new database manager

func (dm *DatabaseManager) Close() error
    Close closes the database connection

func (dm *DatabaseManager) DB() *sql.DB
    DB returns the underlying database connection

func (dm *DatabaseManager) Discover() error
    Discover attempts to find an existing database, with local taking precedence
    over global

func (dm *DatabaseManager) Initialize(mode DatabaseMode) error
    Initialize initializes the database in the specified mode

func (dm *DatabaseManager) Location() string
    Location returns the database file path

func (dm *DatabaseManager) Mode() DatabaseMode
    Mode returns the current database mode

type DatabaseMode int
    DatabaseMode represents the initialization mode for the database

const (
    GlobalMode DatabaseMode = iota
    LocalMode
)
func (dm DatabaseMode) String() string
    String returns the string representation of DatabaseMode

type GapCategory struct {
    ID          int
    Name        string
    Description string
    CreatedAt   time.Time
}
    GapCategory represents a gap category

type GapConfig struct {
    ID                  int
    MaxGapInjection     int
    MinHelpfulThreshold int
    RankingStrategy     string
    CreatedAt           time.Time
    UpdatedAt           time.Time
}
    GapConfig represents gap analysis configuration

type GapEntry struct {
    ID               int
    GapID            string
    ReqID            string
    Feature          string
    Aspect           string
    Category         string
    Description      string
    CorrectiveAction string
    CreatedAt        time.Time
    CreatedBy        string
    HelpfulCount     int
    UnhelpfulCount   int
}
    GapEntry represents a gap analysis entry

type GapQueryFilter struct {
    ReqID    string
    Feature  string
    Aspect   string
    Category string
    Limit    int
}
    GapQueryFilter represents query filters for gap entries

type GapRepository struct {
    // Has unexported fields.
}
    GapRepository handles gap analysis database operations

func NewGapRepository(db *DB) *GapRepository
    NewGapRepository creates a new gap repository

func (r *GapRepository) CreateEntry(entry *GapEntry) error
    CreateEntry creates a new gap analysis entry

func (r *GapRepository) GenerateGapReport(reqID string) (string, error)
    GenerateGapReport generates a formatted gap analysis report

func (r *GapRepository) GetCategories() ([]*GapCategory, error)
    GetCategories retrieves all gap categories

func (r *GapRepository) GetConfig() (*GapConfig, error)
    GetConfig retrieves the gap analysis configuration

func (r *GapRepository) GetEntriesByReqID(reqID string) ([]*GapEntry, error)
    GetEntriesByReqID retrieves all gap entries for a requirement

func (r *GapRepository) GetEntryByGapID(gapID string) (*GapEntry, error)
    GetEntryByGapID retrieves a gap entry by its gap ID

func (r *GapRepository) GetTopGaps(reqID string, config *GapConfig) ([]*GapEntry, error)
    GetTopGaps retrieves top gaps for a requirement based on configuration

func (r *GapRepository) MarkHelpful(gapID string) error
    MarkHelpful increments the helpful count for a gap entry

func (r *GapRepository) MarkUnhelpful(gapID string) error
    MarkUnhelpful increments the unhelpful count for a gap entry

func (r *GapRepository) QueryEntries(filter GapQueryFilter) ([]*GapEntry, error)
    QueryEntries queries gap entries with filters

func (r *GapRepository) UpdateConfig(config *GapConfig) error
    UpdateConfig updates the gap analysis configuration

type Project struct {
    ID        string
    Name      string
    Path      string
    Active    bool
    CreatedAt string
    Metadata  string // JSON metadata
}
    Project represents a registered project in the canary system

type ProjectRegistry struct {
    // Has unexported fields.
}
    ProjectRegistry manages project registration and queries

func NewProjectRegistry(manager *DatabaseManager) *ProjectRegistry
    NewProjectRegistry creates a new project registry

func (pr *ProjectRegistry) GetByID(id string) (*Project, error)
    GetByID retrieves a project by its ID

func (pr *ProjectRegistry) GetByPath(path string) (*Project, error)
    GetByPath retrieves a project by its path

func (pr *ProjectRegistry) List() ([]*Project, error)
    List returns all registered projects

func (pr *ProjectRegistry) Register(project *Project) error
    Register adds a new project to the registry

func (pr *ProjectRegistry) Remove(id string) error
    Remove deletes a project from the registry

type Token struct {
    ID          int
    ReqID       string
    Feature     string
    Aspect      string
    Status      string
    FilePath    string
    LineNumber  int
    Test        string
    Bench       string
    Owner       string
    Priority    int
    Phase       string
    Keywords    string
    SpecStatus  string
    CreatedAt   string
    UpdatedAt   string
    StartedAt   string
    CompletedAt string
    CommitHash  string
    Branch      string
    DependsOn   string
    Blocks      string
    RelatedTo   string
    RawToken    string
    IndexedAt   string

    // CANARY: REQ=CBIN-136; FEATURE="DocDatabaseSchema"; ASPECT=Storage; STATUS=IMPL; UPDATED=2025-10-16
    // Documentation tracking fields
    DocPath      string // Comma-separated doc file paths (e.g., "user:docs/user.md,api:docs/api.md")
    DocHash      string // Comma-separated SHA256 hashes (abbreviated, first 16 chars)
    DocType      string // Documentation type (user, technical, feature, api, architecture)
    DocCheckedAt string // ISO 8601 timestamp of last staleness check
    DocStatus    string // DOC_CURRENT, DOC_STALE, DOC_MISSING, DOC_UNHASHED

    // CANARY: REQ=CBIN-146; FEATURE="TokenNamespacing"; ASPECT=Storage; STATUS=IMPL; UPDATED=2025-10-18
    // Multi-project support
    ProjectID string // Project identifier for token isolation
}
    Token represents a parsed CANARY token with extended metadata