Documentation
¶
Overview ¶
Package data provides CLI flag parsing and configuration management integration. It implements command-line arguments using jessevdk/go-flags with support for configuration files, environment variables, and proper precedence handling.
Package data provides data structures and validation for conference talk proposals. It implements the core proposal data model with validation, conflict-of-interest handling, and CSV metadata preservation functionality.
Package data provides session management functionality for conference talk ranking. It implements session state persistence, comparison tracking, and integration with the Elo rating engine for seamless rating updates and convergence tracking.
Package data provides session configuration types and defaults for the confelo application. This implements CLI-only configuration without file loading or environment variable support.
Package data provides file-based persistence functionality for conference talk ranking. It implements CSV input parsing with configurable formats and JSON session serialization with atomic writes, following the KISS principle where CSV is source of truth and delivery.
Index ¶
- Variables
- func DeleteSession(sessionName, storageDir string) error
- func ListSessions(storageDir string) ([]string, error)
- func SanitizeFilename(name string) string
- func ShowHelp(programName string)
- func ValidateInputForNewSession(opts *CLIOptions) error
- func ValidateSessionFile(sessionName, storageDir string) error
- func ValidateSessionName(name string) error
- type CLIOptions
- type CSVConfig
- type CSVParseError
- type CSVParseMetadata
- type CSVParseResult
- type Comparison
- type ComparisonMethod
- type ComparisonState
- type ConvergenceConfig
- type ConvergenceMetrics
- type EloComparisonResult
- type EloConfig
- type EloEngine
- type EloRating
- type EloRatingUpdate
- type EloUpdate
- type ExportConfig
- type FileStorage
- func (fs *FileStorage) LoadProposalsFromCSV(filename string, config CSVConfig) (*CSVParseResult, error)
- func (fs *FileStorage) LoadProposalsFromCSVWithElo(filename string, config CSVConfig, eloConfig *EloConfig) (*CSVParseResult, error)
- func (fs *FileStorage) LoadSession(filename string) (*Session, error)
- func (fs *FileStorage) SaveSession(session *Session, filename string) error
- func (fs *FileStorage) SetAtomicWrites(enabled bool)
- func (fs *FileStorage) UpdateCSVScores(proposals []Proposal, filename string, config CSVConfig, eloConfig *EloConfig) error
- type MatchupHistory
- type Proposal
- func (p *Proposal) AddConflictTag(tag string)
- func (p *Proposal) GetMetadata(key string) (string, bool)
- func (p *Proposal) HasConflictTag(tag string) bool
- func (p *Proposal) RemoveConflictTag(tag string)
- func (p *Proposal) SetMetadata(key, value string)
- func (p *Proposal) UpdateScore(newScore float64)
- func (p *Proposal) Validate(config ValidationConfig) error
- type ProposalCollection
- func (pc *ProposalCollection) AddProposal(proposal Proposal) error
- func (pc *ProposalCollection) Count() int
- func (pc *ProposalCollection) ExcludeByConflictTag(tag string) []Proposal
- func (pc *ProposalCollection) FilterByConflictTag(tag string) []Proposal
- func (pc *ProposalCollection) GetProposalByID(id string) (*Proposal, bool)
- func (pc *ProposalCollection) IDs() []string
- func (pc *ProposalCollection) UpdateProposal(proposal Proposal) error
- type ProposalPair
- type RatingBin
- type Session
- func (s *Session) AddEloUpdate(comparisonID, proposalID string, oldRating, newRating float64, kFactor int) error
- func (s *Session) CancelComparison() error
- func (s *Session) Close() error
- func (s *Session) CompleteComparison(winnerID string, rankings []string, skipped bool, skipReason string) (*Comparison, error)
- func (s *Session) CompleteSession() error
- func (s *Session) GetComparisonHistory() []Comparison
- func (s *Session) GetConvergenceMetrics() *ConvergenceMetrics
- func (s *Session) GetCurrentComparison() *ComparisonState
- func (s *Session) GetMatchupHistory() []MatchupHistory
- func (s *Session) GetOptimalMatchups(count int) []ProposalPair
- func (s *Session) GetProposalByID(id string) (*Proposal, error)
- func (s *Session) GetProposalCount() int
- func (s *Session) GetProposals() []Proposal
- func (s *Session) GetStatus() SessionStatus
- func (s *Session) ProcessMultiProposalComparison(rankings []string, engine EloEngine) error
- func (s *Session) ProcessPairwiseComparison(winnerID, loserID string, engine EloEngine) error
- func (s *Session) RecordMatchup(proposalA, proposalB string, informationGain float64)
- func (s *Session) Save() error
- func (s *Session) SetStorageDirectory(dir string)
- func (s *Session) StartComparison(proposalIDs []string, method ComparisonMethod) error
- func (s *Session) UpdateProposalRating(proposalID string, newRating float64) error
- type SessionConfig
- type SessionDetector
- type SessionInfo
- type SessionMode
- type SessionStatus
- type Storage
- type UIConfig
- type ValidationConfig
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidProposal = errors.New("invalid proposal") ErrDuplicateID = errors.New("duplicate proposal ID") ErrRequiredField = errors.New("required field missing") ErrInvalidScore = errors.New("invalid score value") ErrCSVParsing = errors.New("CSV parsing error") ErrValidationFailed = errors.New("proposal validation failed") )
Error types for proposal validation and processing
var ( ErrSessionNotFound = errors.New("session not found") ErrInvalidSessionState = errors.New("invalid session state") ErrSessionCorrupted = errors.New("session data corrupted") ErrComparisonNotActive = errors.New("no active comparison") ErrInvalidComparison = errors.New("invalid comparison data") ErrAtomicOperationFailed = errors.New("atomic operation failed") ErrModeDetectionFailed = errors.New("session mode detection failed") ErrSessionNameInvalid = errors.New("session name contains invalid characters") )
Error types for session management
var ( ErrInvalidCSVConfig = errors.New("invalid CSV configuration") ErrInvalidEloConfig = errors.New("invalid Elo configuration") ErrInvalidUIConfig = errors.New("invalid UI configuration") ErrInvalidExportConfig = errors.New("invalid export configuration") )
Error types for configuration validation
var ( ErrStorageOperation = errors.New("storage operation failed") ErrCSVFormat = errors.New("CSV format error") ErrJSONSerialization = errors.New("JSON serialization error") ErrAtomicWrite = errors.New("atomic write operation failed") ErrBackupRotation = errors.New("backup rotation failed") ErrCorruptedFile = errors.New("corrupted file detected") )
Error types for storage operations
Functions ¶
func DeleteSession ¶
DeleteSession removes a session and all its backups from storage
func ListSessions ¶
ListSessions returns all available session names in the storage directory
func SanitizeFilename ¶
SanitizeFilename converts a session name into a safe filename
func ShowHelp ¶
func ShowHelp(programName string)
ShowHelp displays comprehensive usage information for the simplified CLI
func ValidateInputForNewSession ¶
func ValidateInputForNewSession(opts *CLIOptions) error
ValidateInputForNewSession validates that input file is provided for new sessions This will be used by the session detector in T011
func ValidateSessionFile ¶
ValidateSessionFile checks if a session file is valid without fully loading it
func ValidateSessionName ¶
ValidateSessionName validates session name for filesystem safety This will be used by the session detector in T011
Types ¶
type CLIOptions ¶
type CLIOptions struct {
// Required session identifier (validation handled in ParseCLI)
SessionName string `long:"session-name" description:"Session name (required). Creates new session if not found, resumes if exists."`
// Optional configuration (required for new sessions, ignored for existing sessions)
Input string `long:"input" short:"i" description:"CSV file path (required for new sessions, ignored when resuming)"`
ComparisonMode string `long:"comparison-mode" description:"Comparison method: pairwise, trio, or quartet" default:"pairwise"`
InitialRating float64 `long:"initial-rating" description:"Starting Elo rating for new proposals" default:"1500.0"`
OutputScale string `long:"output-scale" description:"Rating scale format (e.g., '0-100', '1.0-5.0')" default:"0-100"`
TargetAccepted int `long:"target-accepted" short:"t" description:"Target number of proposals to accept" default:"10"`
// Global options
Verbose bool `long:"verbose" short:"v" description:"Enable detailed logging output"`
Version bool `long:"version" description:"Show version and build information"`
Help bool `long:"help" short:"h" description:"Show this help message"`
}
CLIOptions defines the simplified command-line flags for the confelo application This implements the CLI-only configuration approach specified in the contracts
func ParseCLI ¶
func ParseCLI(args []string) (*CLIOptions, error)
ParseCLI parses the simplified command-line arguments and returns CLI options This implements the CLI-only approach without config file support
type CSVConfig ¶
type CSVConfig struct {
IDColumn string `json:"id_column"` // Column name for proposal ID (required)
TitleColumn string `json:"title_column"` // Column name for title (required)
AbstractColumn string `json:"abstract_column"` // Column name for abstract (optional)
SpeakerColumn string `json:"speaker_column"` // Column name for speaker (optional)
ScoreColumn string `json:"score_column"` // Column name for existing score (optional)
CommentColumn string `json:"comment_column"` // Column name for reviewer comments (optional)
ConflictColumn string `json:"conflict_column"` // Column name for conflict tags (optional)
HasHeader bool `json:"has_header"` // Whether CSV has header row
Delimiter string `json:"delimiter"` // CSV field separator (default comma)
}
CSVConfig defines how to parse input CSV files
func DefaultCSVConfig ¶
func DefaultCSVConfig() CSVConfig
DefaultCSVConfig returns CSV parsing defaults
type CSVParseError ¶
type CSVParseError struct {
RowNumber int `json:"row_number"`
Field string `json:"field"`
Value string `json:"value"`
Message string `json:"error"`
}
CSVParseError represents an error encountered while parsing a CSV row
func (CSVParseError) Error ¶
func (e CSVParseError) Error() string
Error implements the error interface
type CSVParseMetadata ¶
type CSVParseMetadata struct {
Headers []string `json:"headers"`
DetectedColumns map[string]int `json:"detected_columns"`
UnmappedColumns []string `json:"unmapped_columns"`
ParsedAt time.Time `json:"parsed_at"`
}
CSVParseMetadata contains information about the CSV parsing process
type CSVParseResult ¶
type CSVParseResult struct {
Proposals []Proposal `json:"proposals"`
ParseErrors []CSVParseError `json:"parse_errors,omitempty"`
SkippedRows []int `json:"skipped_rows,omitempty"`
TotalRows int `json:"total_rows"`
SuccessfulRows int `json:"successful_rows"`
Metadata CSVParseMetadata `json:"metadata"`
}
CSVParseResult contains the result of parsing CSV data
func ParseCSVFromReader ¶
func ParseCSVFromReader(reader io.Reader, csvConfig CSVConfig, validationConfig ValidationConfig, eloConfig *EloConfig) (*CSVParseResult, error)
ParseCSVFromReader parses proposals from a CSV reader using the given configuration If eloConfig is provided, CSV scores will be converted to Elo scale
type Comparison ¶
type Comparison struct {
ID string `json:"id"` // Unique comparison identifier
SessionName string `json:"session_name"` // Parent session name
ProposalIDs []string `json:"proposal_ids"` // Proposals that were compared
WinnerID string `json:"winner_id"` // Selected best proposal ID (empty if skipped)
Rankings []string `json:"rankings"` // Full ranking order for multi-proposal (optional)
Method ComparisonMethod `json:"method"` // Comparison type
Timestamp time.Time `json:"timestamp"` // When comparison was completed
Duration time.Duration `json:"duration"` // Time spent on comparison
Skipped bool `json:"skipped"` // Whether comparison was skipped
SkipReason string `json:"skip_reason"` // Why comparison was skipped (optional)
EloUpdates []EloUpdate `json:"elo_updates"` // Rating changes from this comparison
}
Comparison records a completed evaluation event between proposals
type ComparisonMethod ¶
type ComparisonMethod string
ComparisonMethod represents the type of comparison being performed
const ( // MethodPairwise compares two proposals at a time MethodPairwise ComparisonMethod = "pairwise" // MethodTrio compares three proposals at a time MethodTrio ComparisonMethod = "trio" // MethodQuartet compares four proposals at a time MethodQuartet ComparisonMethod = "quartet" )
type ComparisonState ¶
type ComparisonState struct {
ID string `json:"id"` // Unique comparison identifier
ProposalIDs []string `json:"proposal_ids"` // Proposals being compared
Method ComparisonMethod `json:"method"` // Comparison type
StartedAt time.Time `json:"started_at"` // When comparison began
PresentedOrder []string `json:"presented_order"` // Order shown to user (for consistency)
}
ComparisonState represents the current active comparison
type ConvergenceConfig ¶
type ConvergenceConfig struct {
TargetAccepted int `json:"target_accepted"` // Number of talks to be accepted (T)
TopTStabilityWindow int `json:"top_t_stability_window"` // Window to check top-T stability
StabilityThreshold float64 `json:"stability_threshold"` // Min rating change to consider stable
MinComparisons int `json:"min_comparisons"` // Minimum comparisons before convergence check
MaxComparisons int `json:"max_comparisons"` // Hard limit on total comparisons
EnableEarlyStopping bool `json:"enable_early_stopping"` // Whether to use convergence detection
ConfidenceThreshold float64 `json:"confidence_threshold"` // Min confidence to recommend stopping
}
ConvergenceConfig holds settings for intelligent stopping criteria
func DefaultConvergenceConfig ¶
func DefaultConvergenceConfig() ConvergenceConfig
DefaultConvergenceConfig returns convergence detection defaults
type ConvergenceMetrics ¶
type ConvergenceMetrics struct {
TotalComparisons int `json:"total_comparisons"` // Number of comparisons performed
AvgRatingChange float64 `json:"avg_rating_change"` // Rolling average of rating changes
RatingVariance float64 `json:"rating_variance"` // Variance in recent rating changes
RankingStability float64 `json:"ranking_stability"` // Percentage of stable top-N positions
CoveragePercentage float64 `json:"coverage_percentage"` // Percentage of meaningful pairs compared
ConvergenceScore float64 `json:"convergence_score"` // Overall convergence indicator 0-1
LastCalculated time.Time `json:"last_calculated"` // When metrics were last updated
RecentRatingChanges []float64 `json:"recent_rating_changes"` // Last N rating changes for variance calc
}
ConvergenceMetrics tracks session progress and convergence indicators
type EloComparisonResult ¶
type EloComparisonResult struct {
Updates []EloRatingUpdate // Rating changes for each affected proposal
Method ComparisonMethod // Type of comparison performed
Timestamp time.Time // When calculation was performed
}
EloComparisonResult represents the result of Elo calculations
type EloConfig ¶
type EloConfig struct {
InitialRating float64 `json:"initial_rating"` // Starting rating for new proposals (default 1500)
KFactor int `json:"k_factor"` // Rating change sensitivity (default 32)
MinRating float64 `json:"min_rating"` // Minimum allowed rating (default 0)
MaxRating float64 `json:"max_rating"` // Maximum allowed rating (default 3000)
OutputMin float64 `json:"output_min"` // Minimum output scale value
OutputMax float64 `json:"output_max"` // Maximum output scale value
UseDecimals bool `json:"use_decimals"` // Whether output uses decimal places
}
EloConfig holds settings for Elo rating calculations
func DefaultEloConfig ¶
func DefaultEloConfig() EloConfig
DefaultEloConfig returns Elo calculation defaults matching constitutional requirements
func (*EloConfig) CalculateExportScore ¶
CalculateExportScore converts an Elo rating to the output scale defined in the configuration It performs linear scaling from [MinRating, MaxRating] to [OutputMin, OutputMax] and respects the UseDecimals setting for formatting
func (*EloConfig) ConvertCSVScoreToElo ¶
ConvertCSVScoreToElo converts a score from CSV (in OutputMin-OutputMax scale) to Elo rating scale This is the inverse of CalculateExportScore, used when loading existing scores from CSV If the CSV score is outside the output scale range, returns InitialRating (invalid score)
type EloEngine ¶
type EloEngine interface {
CalculatePairwise(winner, loser EloRating) (EloRating, EloRating, error)
CalculatePairwiseWithResult(winner, loser EloRating) (EloComparisonResult, error)
}
EloEngine represents the interface to the Elo rating calculation engine
type EloRating ¶
type EloRating struct {
ID string // Unique proposal identifier
Score float64 // Current Elo rating
Confidence float64 // Statistical confidence (0.0-1.0)
Games int // Number of comparisons participated in
}
EloRating represents a proposal's rating for Elo calculations
type EloRatingUpdate ¶
type EloRatingUpdate struct {
ProposalID string // Proposal being updated
OldRating float64 // Rating before comparison
NewRating float64 // Rating after comparison
Delta float64 // Change in rating (NewRating - OldRating)
KFactor int // K-factor used for this update
}
EloRatingUpdate represents an individual rating change
type EloUpdate ¶
type EloUpdate struct {
ID string `json:"id"` // Unique update identifier
ComparisonID string `json:"comparison_id"` // Parent comparison
ProposalID string `json:"proposal_id"` // Affected proposal
OldRating float64 `json:"old_rating"` // Rating before comparison
NewRating float64 `json:"new_rating"` // Rating after comparison
RatingDelta float64 `json:"rating_delta"` // Change amount (NewRating - OldRating)
KFactor int `json:"k_factor"` // K-factor used for this calculation
}
EloUpdate records rating changes from a single comparison
type ExportConfig ¶
type ExportConfig struct {
Format string `json:"format"` // Output format (csv/json/yaml)
IncludeMetadata bool `json:"include_metadata"` // Include original CSV metadata
SortBy string `json:"sort_by"` // Sort criterion (rating/title/speaker)
SortOrder string `json:"sort_order"` // Sort direction (asc/desc)
ScaleOutput bool `json:"scale_output"` // Apply output scaling
RoundDecimals int `json:"round_decimals"` // Decimal places for output
}
ExportConfig holds output format settings
func DefaultExportConfig ¶
func DefaultExportConfig() ExportConfig
DefaultExportConfig returns export format defaults
func (*ExportConfig) Validate ¶
func (e *ExportConfig) Validate() error
Validate checks that export configuration is valid
type FileStorage ¶
type FileStorage struct {
// contains filtered or unexported fields
}
FileStorage implements the Storage interface with file-based operations
func NewFileStorage ¶
func NewFileStorage() *FileStorage
NewFileStorage creates a new FileStorage instance with sensible defaults
func (*FileStorage) LoadProposalsFromCSV ¶
func (fs *FileStorage) LoadProposalsFromCSV(filename string, config CSVConfig) (*CSVParseResult, error)
LoadProposalsFromCSV implements CSV input parsing with configurable formats This is where proposals enter the system (CSV → Proposal structs)
func (*FileStorage) LoadProposalsFromCSVWithElo ¶
func (fs *FileStorage) LoadProposalsFromCSVWithElo(filename string, config CSVConfig, eloConfig *EloConfig) (*CSVParseResult, error)
LoadProposalsFromCSVWithElo implements CSV input parsing with Elo score conversion If eloConfig is provided, scores in the CSV are converted from the output scale to Elo scale
func (*FileStorage) LoadSession ¶
func (fs *FileStorage) LoadSession(filename string) (*Session, error)
LoadSession implements JSON session loading
func (*FileStorage) SaveSession ¶
func (fs *FileStorage) SaveSession(session *Session, filename string) error
SaveSession implements JSON session file serialization with atomic writes JSON is only for session management - CSV remains source of truth
func (*FileStorage) SetAtomicWrites ¶
func (fs *FileStorage) SetAtomicWrites(enabled bool)
SetAtomicWrites enables or disables atomic write operations
func (*FileStorage) UpdateCSVScores ¶
func (fs *FileStorage) UpdateCSVScores(proposals []Proposal, filename string, config CSVConfig, eloConfig *EloConfig) error
UpdateCSVScores updates the score column in the original CSV file with export scores This preserves all original data and only modifies the score column
type MatchupHistory ¶
type MatchupHistory struct {
ProposalA string `json:"proposal_a"` // First proposal ID
ProposalB string `json:"proposal_b"` // Second proposal ID
ComparisonCount int `json:"comparison_count"` // Times this pair has been compared
LastCompared time.Time `json:"last_compared"` // Most recent comparison timestamp
RatingDifferenceHistory []float64 `json:"rating_difference_history"` // Rating gaps at each comparison
InformationGain float64 `json:"information_gain"` // Measured impact on ranking stability
}
MatchupHistory tracks comparison pairings to optimize future matchup selection
type Proposal ¶
type Proposal struct {
ID string `json:"id"` // Unique identifier (from CSV)
Title string `json:"title"` // Talk title
Abstract string `json:"abstract,omitempty"` // Full description (optional)
Speaker string `json:"speaker,omitempty"` // Presenter information (optional)
Score float64 `json:"score"` // Current Elo rating
OriginalScore *float64 `json:"original_score,omitempty"` // Initial rating from CSV (optional)
Metadata map[string]string `json:"metadata,omitempty"` // Additional CSV columns
ConflictTags []string `json:"conflict_tags,omitempty"` // Conflict-of-interest identifiers
CreatedAt time.Time `json:"created_at"` // When proposal was loaded
UpdatedAt time.Time `json:"updated_at"` // Last modification time
}
Proposal represents a single conference talk submission
func NewProposal ¶
func NewProposal(id, title string, config ValidationConfig) (*Proposal, error)
NewProposal creates a new proposal with validation
func (*Proposal) AddConflictTag ¶
AddConflictTag adds a conflict-of-interest tag if not already present
func (*Proposal) GetMetadata ¶
GetMetadata retrieves a metadata value by key
func (*Proposal) HasConflictTag ¶
HasConflictTag checks if the proposal has a specific conflict tag
func (*Proposal) RemoveConflictTag ¶
RemoveConflictTag removes a conflict-of-interest tag
func (*Proposal) SetMetadata ¶
SetMetadata sets a metadata key-value pair
func (*Proposal) UpdateScore ¶
UpdateScore updates the proposal's current score and timestamp
func (*Proposal) Validate ¶
func (p *Proposal) Validate(config ValidationConfig) error
Validate checks that the proposal meets all validation rules
type ProposalCollection ¶
type ProposalCollection struct {
Proposals []Proposal `json:"proposals"`
IDIndex map[string]int `json:"-"` // Internal index for fast ID lookups
ValidationConfig ValidationConfig `json:"-"` // Validation settings
}
ProposalCollection manages a collection of proposals with validation
func NewProposalCollection ¶
func NewProposalCollection(config ValidationConfig) *ProposalCollection
NewProposalCollection creates a new collection with validation config
func (*ProposalCollection) AddProposal ¶
func (pc *ProposalCollection) AddProposal(proposal Proposal) error
AddProposal adds a proposal to the collection with duplicate ID checking
func (*ProposalCollection) Count ¶
func (pc *ProposalCollection) Count() int
Count returns the number of proposals in the collection
func (*ProposalCollection) ExcludeByConflictTag ¶
func (pc *ProposalCollection) ExcludeByConflictTag(tag string) []Proposal
ExcludeByConflictTag returns proposals that do NOT have the specified conflict tag
func (*ProposalCollection) FilterByConflictTag ¶
func (pc *ProposalCollection) FilterByConflictTag(tag string) []Proposal
FilterByConflictTag returns proposals that have the specified conflict tag
func (*ProposalCollection) GetProposalByID ¶
func (pc *ProposalCollection) GetProposalByID(id string) (*Proposal, bool)
GetProposalByID retrieves a proposal by its ID
func (*ProposalCollection) IDs ¶
func (pc *ProposalCollection) IDs() []string
IDs returns all proposal IDs in the collection
func (*ProposalCollection) UpdateProposal ¶
func (pc *ProposalCollection) UpdateProposal(proposal Proposal) error
UpdateProposal updates an existing proposal in the collection
type ProposalPair ¶
type ProposalPair struct {
ProposalA string `json:"proposal_a"`
ProposalB string `json:"proposal_b"`
Priority float64 `json:"priority"`
RatingDistance float64 `json:"rating_distance"`
ComparisonCount int `json:"comparison_count"`
LastCompared time.Time `json:"last_compared"`
}
ProposalPair represents a suggested pairing for comparison
type RatingBin ¶
type RatingBin struct {
BinIndex int `json:"bin_index"` // Numeric bin identifier
MinRating float64 `json:"min_rating"` // Lower bound of rating range
MaxRating float64 `json:"max_rating"` // Upper bound of rating range
ProposalIDs []string `json:"proposal_ids"` // Proposals currently in this bin
LastUpdated time.Time `json:"last_updated"` // When bin assignments were recalculated
}
RatingBin groups proposals by rating ranges for strategic matchup selection
type Session ¶
type Session struct {
// Core identity
Name string `json:"name"` // Unique session name (used as identifier)
Status SessionStatus `json:"status"` // Current session state
CreatedAt time.Time `json:"created_at"` // Session creation timestamp
UpdatedAt time.Time `json:"updated_at"` // Last modification timestamp
// Configuration and data
Config SessionConfig `json:"config"` // Session configuration
Proposals []Proposal `json:"-"` // Collection of proposals (reloaded from CSV, never serialized)
ProposalScores map[string]float64 `json:"proposal_scores"` // Current scores by ID (lightweight persistence)
ProposalIndex map[string]int `json:"-"` // Fast ID lookup (not serialized)
InputCSVPath string `json:"input_csv_path"` // Original input CSV file path for export
// Comparison tracking (lightweight persistence for progress/confidence)
ComparisonCounts map[string]int `json:"comparison_counts"` // Per-proposal comparison count for confidence
TotalComparisons int `json:"total_comparisons"` // Total comparisons performed for progress
CurrentComparison *ComparisonState `json:"-"` // Active comparison state (not persisted)
CompletedComparisons []Comparison `json:"-"` // Historical comparisons (not persisted)
// Analytics and optimization
ConvergenceMetrics *ConvergenceMetrics `json:"convergence_metrics"` // Progress tracking
MatchupHistory []MatchupHistory `json:"matchup_history"` // Pairing optimization data
RatingBins []RatingBin `json:"rating_bins"` // Strategic grouping
// contains filtered or unexported fields
}
Session manages the complete ranking workflow and persistent state
func LoadSession ¶
LoadSession loads an existing session from the storage directory This is a convenience function that uses FileStorage internally
func NewSession ¶
func NewSession(name string, proposals []Proposal, config SessionConfig, inputCSVPath string) (*Session, error)
NewSession creates a new ranking session with the given proposals and configuration inputCSVPath is required - it's used to reload proposals when resuming the session
func (*Session) AddEloUpdate ¶
func (s *Session) AddEloUpdate(comparisonID, proposalID string, oldRating, newRating float64, kFactor int) error
AddEloUpdate records a rating change from a comparison
func (*Session) CancelComparison ¶
CancelComparison aborts the current active comparison
func (*Session) CompleteComparison ¶
func (s *Session) CompleteComparison(winnerID string, rankings []string, skipped bool, skipReason string) (*Comparison, error)
CompleteComparison finishes the current comparison with the specified result Automatically saves the session after completion
func (*Session) CompleteSession ¶
CompleteSession marks the session as complete
func (*Session) GetComparisonHistory ¶
func (s *Session) GetComparisonHistory() []Comparison
GetComparisonHistory returns all completed comparisons (thread-safe copy)
func (*Session) GetConvergenceMetrics ¶
func (s *Session) GetConvergenceMetrics() *ConvergenceMetrics
GetConvergenceMetrics returns current convergence metrics (thread-safe copy)
func (*Session) GetCurrentComparison ¶
func (s *Session) GetCurrentComparison() *ComparisonState
GetCurrentComparison returns the current active comparison (thread-safe copy)
func (*Session) GetMatchupHistory ¶
func (s *Session) GetMatchupHistory() []MatchupHistory
GetMatchupHistory returns matchup optimization data (thread-safe copy)
func (*Session) GetOptimalMatchups ¶
func (s *Session) GetOptimalMatchups(count int) []ProposalPair
GetOptimalMatchups returns suggested proposal pairs for next comparisons
func (*Session) GetProposalByID ¶
GetProposalByID retrieves a proposal by its ID
func (*Session) GetProposalCount ¶
GetProposalCount returns the number of proposals in the session
func (*Session) GetProposals ¶
GetProposals returns a copy of all proposals (thread-safe)
func (*Session) GetStatus ¶
func (s *Session) GetStatus() SessionStatus
GetStatus returns the current session status (thread-safe)
func (*Session) ProcessMultiProposalComparison ¶
ProcessMultiProposalComparison integrates with Elo engine to process trio/quartet comparisons
func (*Session) ProcessPairwiseComparison ¶
ProcessPairwiseComparison integrates with Elo engine to process a pairwise comparison
func (*Session) RecordMatchup ¶
RecordMatchup tracks a pairwise comparison for optimization purposes
func (*Session) SetStorageDirectory ¶
SetStorageDirectory configures where the session should be persisted
func (*Session) StartComparison ¶
func (s *Session) StartComparison(proposalIDs []string, method ComparisonMethod) error
StartComparison initiates a new comparison with the specified proposals
type SessionConfig ¶
type SessionConfig struct {
CSV CSVConfig `json:"csv"`
Elo EloConfig `json:"elo"`
UI UIConfig `json:"ui"`
Export ExportConfig `json:"export"`
Convergence ConvergenceConfig `json:"convergence"`
}
SessionConfig is the top-level configuration for a ranking session
func CreateSessionConfigFromCLI ¶
func CreateSessionConfigFromCLI(opts *CLIOptions) (*SessionConfig, error)
CreateSessionConfigFromCLI creates SessionConfig from CLI options This replaces the file loading approach with CLI-only configuration
func DefaultSessionConfig ¶
func DefaultSessionConfig() SessionConfig
DefaultSessionConfig returns a configuration with sensible defaults
func (*SessionConfig) Validate ¶
func (sc *SessionConfig) Validate() error
Validate checks that the session configuration is valid
type SessionDetector ¶
type SessionDetector struct {
// contains filtered or unexported fields
}
SessionDetector provides session existence detection and mode determination
func NewSessionDetector ¶
func NewSessionDetector(sessionsDir string) *SessionDetector
NewSessionDetector creates a new session detector for the specified sessions directory
func (*SessionDetector) DetectMode ¶
func (sd *SessionDetector) DetectMode(sessionName string) (SessionMode, error)
DetectMode determines whether to start a new session or resume an existing one based on the session name and existing session files
func (*SessionDetector) FindSessionFile ¶
func (sd *SessionDetector) FindSessionFile(sessionName string) (string, error)
FindSessionFile locates a session file by session name Returns empty string if no session file is found
func (*SessionDetector) ValidateSession ¶
func (sd *SessionDetector) ValidateSession(sessionPath string) error
ValidateSession validates the integrity of a session file
type SessionInfo ¶
type SessionInfo struct {
Name string `json:"name"`
Status SessionStatus `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ProposalCount int `json:"proposal_count"`
ComparisonCount int `json:"comparison_count"`
FileSize int64 `json:"file_size"`
LastModified time.Time `json:"last_modified"`
}
SessionInfo provides summary information about a session
func GetSessionInfo ¶
func GetSessionInfo(sessionName, storageDir string) (*SessionInfo, error)
GetSessionInfo returns basic session information without loading the full session
type SessionMode ¶
type SessionMode int
SessionMode represents the detected operational mode for automatic mode detection
const ( // StartMode indicates a new session should be created StartMode SessionMode = iota // ResumeMode indicates an existing session should be resumed ResumeMode )
func (SessionMode) String ¶
func (sm SessionMode) String() string
String returns a string representation of the SessionMode
type SessionStatus ¶
type SessionStatus string
SessionStatus represents the current state of a ranking session
const ( // StatusCreated indicates a newly created session that hasn't started comparisons yet StatusCreated SessionStatus = "created" // StatusActive indicates a session with ongoing comparisons StatusActive SessionStatus = "active" // StatusPaused indicates a temporarily paused session StatusPaused SessionStatus = "paused" // StatusComplete indicates a finished session with final rankings StatusComplete SessionStatus = "complete" )
type Storage ¶
type Storage interface {
// CSV Operations - Source of truth
LoadProposalsFromCSV(filename string, config CSVConfig) (*CSVParseResult, error)
LoadProposalsFromCSVWithElo(filename string, config CSVConfig, eloConfig *EloConfig) (*CSVParseResult, error)
UpdateCSVScores(proposals []Proposal, filename string, config CSVConfig, eloConfig *EloConfig) error
// JSON Operations - Session management only
SaveSession(session *Session, filename string) error
LoadSession(filename string) (*Session, error)
}
Storage interface defines the contract for file-based persistence operations Following KISS principle: CSV in → JSON for sessions → CSV out
type UIConfig ¶
type UIConfig struct {
ComparisonMode string `json:"comparison_mode"` // Default comparison type (pairwise/trio/quartet)
ShowProgress bool `json:"show_progress"` // Display progress indicators
ShowConfidence bool `json:"show_confidence"` // Display rating confidence
}
UIConfig holds terminal interface preferences
func DefaultUIConfig ¶
func DefaultUIConfig() UIConfig
DefaultUIConfig returns TUI interface defaults
type ValidationConfig ¶
type ValidationConfig struct {
RequireTitle bool // Whether title is mandatory (default: true)
MinTitleLength int // Minimum title length (default: 1)
MaxTitleLength int // Maximum title length (default: 500)
MinScore float64 // Minimum allowed score
MaxScore float64 // Maximum allowed score
DefaultScore float64 // Default score for new proposals
}
ValidationConfig holds validation parameters
func DefaultValidationConfig ¶
func DefaultValidationConfig() ValidationConfig
DefaultValidationConfig returns sensible validation defaults