Class: ActiveProject::StatusMapper

Inherits:
Object
  • Object
show all
Defined in:
lib/active_project/status_mapper.rb

Overview

Handles bidirectional status mapping between platform-specific statuses and normalized ActiveProject status symbols.

Supports:

  • Standard status symbols (:open, :in_progress, :closed, :blocked, :on_hold)

  • Platform-specific status preservation

  • Configurable status mappings per adapter

  • Fallback to standard status normalization

Constant Summary collapse

STANDARD_STATUSES =

Standard ActiveProject status symbols with their meanings

{
  open: "New, unstarted work",
  in_progress: "Currently being worked on",
  blocked: "Waiting on external dependency",
  on_hold: "Temporarily paused",
  closed: "Completed or resolved"
}.freeze
DEFAULT_MAPPINGS =

Default mapping rules for common status patterns

{
  # Open/New statuses
  /^(new|open|todo|to do|backlog|ready|created)$/i => :open,

  # In Progress statuses
  /^(in progress|in_progress|active|working|started|doing)$/i => :in_progress,

  # Blocked statuses
  /^(blocked|waiting|pending|on hold|on_hold|paused)$/i => :blocked,

  # Closed statuses
  /^(done|closed|completed|finished|resolved|fixed)$/i => :closed
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter_type, custom_mappings = {}) ⇒ StatusMapper

Returns a new instance of StatusMapper.

Parameters:

  • adapter_type (Symbol)

    The adapter type (:jira, :trello, etc.)

  • custom_mappings (Hash) (defaults to: {})

    Custom status mappings from configuration



41
42
43
44
# File 'lib/active_project/status_mapper.rb', line 41

def initialize(adapter_type, custom_mappings = {})
  @adapter_type = adapter_type
  @custom_mappings = custom_mappings || {}
end

Instance Attribute Details

#adapter_typeObject (readonly)

Returns the value of attribute adapter_type.



37
38
39
# File 'lib/active_project/status_mapper.rb', line 37

def adapter_type
  @adapter_type
end

#custom_mappingsObject (readonly)

Returns the value of attribute custom_mappings.



37
38
39
# File 'lib/active_project/status_mapper.rb', line 37

def custom_mappings
  @custom_mappings
end

Class Method Details

.from_config(adapter_type, config) ⇒ StatusMapper

Creates a status mapper instance from adapter configuration.

Parameters:

Returns:



140
141
142
143
# File 'lib/active_project/status_mapper.rb', line 140

def self.from_config(adapter_type, config)
  status_mappings = config.respond_to?(:status_mappings) ? config.status_mappings : {}
  new(adapter_type, status_mappings)
end

Instance Method Details

#denormalize_status(normalized_status, context = {}) ⇒ String, Symbol

Converts a normalized status symbol back to platform-specific status.

Parameters:

  • normalized_status (Symbol)

    The normalized status symbol

  • context (Hash) (defaults to: {})

    Optional context for platform-specific conversion

Returns:

  • (String, Symbol)

    Platform-specific status representation



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/active_project/status_mapper.rb', line 78

def denormalize_status(normalized_status, context = {})
  # If it's already a standard status, delegate to adapter-specific logic
  return normalized_status if STANDARD_STATUSES.key?(normalized_status.to_sym)

  # Try reverse lookup in custom mappings
  if custom_mappings.is_a?(Hash)
    project_mappings = custom_mappings[context[:project_id]] || custom_mappings

    # Find the platform status that maps to this normalized status
    project_mappings.each do |platform_status, mapped_status|
      return platform_status if mapped_status.to_sym == normalized_status.to_sym
    end
  end

  # Default: return the status as-is for platform handling
  normalized_status
end

#normalize_status(platform_status, context = {}) ⇒ Symbol

Converts a platform-specific status to a normalized status symbol.

Parameters:

  • platform_status (String, Symbol)

    The platform-specific status

  • context (Hash) (defaults to: {})

    Optional context (e.g., project_id for project-specific mappings)

Returns:

  • (Symbol)

    Normalized status symbol



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/active_project/status_mapper.rb', line 50

def normalize_status(platform_status, context = {})
  return platform_status if STANDARD_STATUSES.key?(platform_status.to_sym)

  # Try custom mappings first
  if custom_mappings.is_a?(Hash)
    # Support project-specific mappings (for Trello, GitHub)
    project_mappings = custom_mappings[context[:project_id]] || custom_mappings

    # Check direct mapping
    if project_mappings[platform_status.to_s]
      return project_mappings[platform_status.to_s].to_sym
    end
  end

  # Fall back to pattern matching
  status_str = platform_status.to_s.strip
  DEFAULT_MAPPINGS.each do |pattern, normalized_status|
    return normalized_status if status_str.match?(pattern)
  end

  # If no mapping found, return as symbol for platform-specific handling
  platform_status.to_s.downcase.tr(" -", "_").to_sym
end

#status_known?(status, context = {}) ⇒ Boolean

Checks if a status is known/valid for the given context.

Parameters:

  • status (Symbol, String)

    The status to check

  • context (Hash) (defaults to: {})

    Optional context for validation

Returns:

  • (Boolean)

    true if the status is valid



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/active_project/status_mapper.rb', line 100

def status_known?(status, context = {})
  # Handle nil status
  return false if status.nil?

  # Standard statuses are always known
  return true if STANDARD_STATUSES.key?(status.to_sym)

  # Check custom mappings
  if custom_mappings.is_a?(Hash)
    project_mappings = custom_mappings[context[:project_id]] || custom_mappings
    return true if project_mappings.key?(status.to_s)
  end

  # Check if it matches any default patterns
  status_str = status.to_s.strip
  DEFAULT_MAPPINGS.any? { |pattern, _| status_str.match?(pattern) }
end

#valid_statuses(context = {}) ⇒ Array<Symbol>

Returns all valid statuses for the given context.

Parameters:

  • context (Hash) (defaults to: {})

    Optional context

Returns:

  • (Array<Symbol>)

    Array of valid status symbols



121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/active_project/status_mapper.rb', line 121

def valid_statuses(context = {})
  statuses = STANDARD_STATUSES.keys.dup

  # Add custom mapped statuses
  if custom_mappings.is_a?(Hash)
    project_mappings = custom_mappings[context[:project_id]] || custom_mappings
    project_mappings.each do |platform_status, normalized_status|
      statuses << normalized_status.to_sym
      statuses << platform_status.to_s.downcase.tr(" -", "_").to_sym
    end
  end

  statuses.uniq
end