Module: Ace::Idea::Atoms::IdeaValidationRules

Defined in:
lib/ace/idea/atoms/idea_validation_rules.rb

Overview

Pure validation predicates and constants for idea health checking. Used by doctor validators to determine correctness of frontmatter, file structure, and scope/status consistency.

Constant Summary collapse

VALID_STATUSES =
%w[pending in-progress done obsolete].freeze
TERMINAL_STATUSES =
%w[done obsolete].freeze
REQUIRED_FIELDS =
%w[id status title].freeze
%w[tags created_at].freeze

Class Method Summary collapse

Class Method Details

Return list of missing recommended fields from frontmatter

Parameters:

  • frontmatter (Hash)

    Parsed frontmatter

Returns:

  • (Array<String>)

    Names of missing recommended fields



81
82
83
84
85
# File 'lib/ace/idea/atoms/idea_validation_rules.rb', line 81

def self.missing_recommended_fields(frontmatter)
  return RECOMMENDED_FIELDS.dup if frontmatter.nil? || !frontmatter.is_a?(Hash)

  RECOMMENDED_FIELDS.select { |field| frontmatter[field].nil? }
end

.missing_required_fields(frontmatter) ⇒ Array<String>

Return list of missing required fields from frontmatter

Parameters:

  • frontmatter (Hash)

    Parsed frontmatter

Returns:

  • (Array<String>)

    Names of missing required fields



72
73
74
75
76
# File 'lib/ace/idea/atoms/idea_validation_rules.rb', line 72

def self.missing_required_fields(frontmatter)
  return REQUIRED_FIELDS.dup if frontmatter.nil? || !frontmatter.is_a?(Hash)

  REQUIRED_FIELDS.select { |field| frontmatter[field].nil? || frontmatter[field].to_s.strip.empty? }
end

.scope_consistent?(status, special_folder) ⇒ Array<Hash>

Check if scope (special folder) is consistent with status

Parameters:

  • status (String)

    Idea status

  • special_folder (String, nil)

    Special folder name (e.g., “_archive”, “_maybe”)

Returns:

  • (Array<Hash>)

    List of inconsistency issues (empty if consistent)



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ace/idea/atoms/idea_validation_rules.rb', line 42

def self.scope_consistent?(status, special_folder)
  issues = []

  if terminal_status?(status) && special_folder != "_archive"
    issues << {
      type: :warning,
      message: "Idea with terminal status '#{status}' not in _archive/"
    }
  end

  if special_folder == "_archive" && !terminal_status?(status) && status
    issues << {
      type: :warning,
      message: "Idea in _archive/ but status is '#{status}' (expected terminal status)"
    }
  end

  if special_folder == "_maybe" && terminal_status?(status)
    issues << {
      type: :warning,
      message: "Idea in _maybe/ with terminal status '#{status}' (should be in _archive/)"
    }
  end

  issues
end

.terminal_status?(status) ⇒ Boolean

Check if a status is terminal (belongs in _archive)

Parameters:

  • status (String)

    Status to check

Returns:

  • (Boolean)


27
28
29
# File 'lib/ace/idea/atoms/idea_validation_rules.rb', line 27

def self.terminal_status?(status)
  TERMINAL_STATUSES.include?(status.to_s)
end

.valid_id?(id) ⇒ Boolean

Check if an ID string is a valid b36ts idea ID

Parameters:

  • id (String)

    ID to validate

Returns:

  • (Boolean)


34
35
36
# File 'lib/ace/idea/atoms/idea_validation_rules.rb', line 34

def self.valid_id?(id)
  IdeaIdFormatter.valid?(id)
end

.valid_status?(status) ⇒ Boolean

Check if a status string is valid

Parameters:

  • status (String)

    Status to validate

Returns:

  • (Boolean)


20
21
22
# File 'lib/ace/idea/atoms/idea_validation_rules.rb', line 20

def self.valid_status?(status)
  VALID_STATUSES.include?(status.to_s)
end