Skip to content

Commit 7b9d81e

Browse files
TSS-27 Add YARD comments to classes, modules, and public/protected methods (#76)
This PR adds YARD documentation to classes, modules, and public/protected methods in the Flex SDK, focusing on the following directories: - app/models/flex - app/lib/flex - app/helpers/flex The documentation follows the existing YARD style in the codebase and includes: - Class and module descriptions - Method parameter documentation - Return value documentation - Usage examples - Related class references --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Loren Yu <loren@navapbc.com>
1 parent 52bd8ba commit 7b9d81e

7 files changed

Lines changed: 163 additions & 5 deletions

File tree

app/helpers/flex/event_manager.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
11
module Flex
2+
# EventManager is a pub/sub system for workflow events.
3+
# It allows components to communicate with each other asynchronously
4+
# through event publishing and subscription.
5+
#
6+
# This class is used throughout the Flex SDK for handling transitions
7+
# between workflow steps and notifying components of state changes.
8+
#
9+
# @example Publishing an event
10+
# Flex::EventManager.publish("FormSubmitted", { form_id: 123 })
11+
#
12+
# @example Subscribing to an event
13+
# subscription = Flex::EventManager.subscribe("FormSubmitted") do |event|
14+
# # Handle the event
15+
# puts "Form #{event[:payload][:form_id]} was submitted"
16+
# end
17+
#
218
class EventManager
319
@@subscriptions = []
420

521
class << self
22+
# Subscribes to an event, registering a callback to be executed when the event occurs.
23+
#
24+
# @param [String] event_key The name of the event to subscribe to
25+
# @param [Proc, Method] callback The callback to execute when the event occurs
26+
# @return [Object] The subscription object, which can be used to unsubscribe
627
def subscribe(event_key, callback)
728
subscription = ActiveSupport::Notifications.subscribe(event_key) do |name, _started, _finished, _unique_id, payload|
829
callback.call({
@@ -15,17 +36,29 @@ def subscribe(event_key, callback)
1536
subscription
1637
end
1738

39+
# Unsubscribes from an event by providing the subscription object.
40+
#
41+
# @param [Object] subscription The subscription object returned by subscribe
1842
def unsubscribe(subscription)
1943
ActiveSupport::Notifications.unsubscribe(subscription)
2044
end
2145

46+
# Unsubscribes from all events that have been registered.
47+
# Used when Zeitwerk is unloading EventManager during class reloading.
48+
#
49+
# @return [void]
2250
def unsubscribe_all
2351
@@subscriptions.each do |subscription|
2452
ActiveSupport::Notifications.unsubscribe(subscription)
2553
end
2654
@@subscriptions.clear
2755
end
2856

57+
# Publishes an event with the given key and payload.
58+
#
59+
# @param [String] event_key The name of the event to publish
60+
# @param [Hash] payload The event payload data
61+
# @return [void]
2962
def publish(event_key, payload = {})
3063
Rails.logger.debug "Event Manager: Publishing event '#{event_key}' with payload: #{payload.inspect}"
3164
ActiveSupport::Notifications.instrument(event_key, payload)

app/helpers/flex/form_builder.rb

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
module Flex
2-
# Custom form builder. Beyond adding USWDS classes, this also
3-
# supports setting the label, hint, and error messages by just
4-
# using the field helpers (i.e text_field, check_box), and adds
2+
# FormBuilder is a custom form builder that provides USWDS-styled form components.
3+
# Beyond adding USWDS classes, this also supports setting the label, hint, and error
4+
# messages by just using the field helpers (i.e text_field, check_box), and adds
55
# additional helpers like fieldset and hint.
6-
# https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html
6+
#
7+
# @see https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html
8+
# @see https://designsystem.digital.gov/components/form-controls/
9+
#
10+
# @example Basic usage
11+
# <%= flex_form_with(model: @user) do |f| %>
12+
# <%= f.text_field :name, label: "Full Name", hint: "Enter your legal name" %>
13+
# <%= f.email_field :email, label: "Email Address" %>
14+
# <%= f.submit "Save" %>
15+
# <% end %>
16+
#
717
class FormBuilder < ActionView::Helpers::FormBuilder
818
standard_helpers = %i[email_field file_field password_field text_area text_field]
919

20+
# Initializes a new FormBuilder instance and sets up the form with USWDS classes.
21+
#
22+
# @param args [Array] Arguments passed to the parent FormBuilder constructor
1023
def initialize(*args)
1124
super
1225
self.options[:html] ||= {}
@@ -55,6 +68,13 @@ def initialize(*args)
5568
end
5669
end
5770

71+
# Renders a checkbox field with USWDS styling.
72+
#
73+
# @param [Symbol] attribute The attribute name
74+
# @param [Hash] options Options for the checkbox
75+
# @param args [Array] Additional arguments for the standard checkbox helper
76+
# @option options [String] :label Custom label text
77+
# @return [String] The rendered HTML for the checkbox
5878
def check_box(attribute, options = {}, *args)
5979
append_to_option(options, :class, " #{us_class_for_field_type(:check_box)}")
6080

@@ -143,6 +163,14 @@ def date_picker(attribute, options = {})
143163
text_field(attribute, options.merge(value: value, group_options: group_options))
144164
end
145165

166+
# Renders a memorable date input with month, day, and year fields.
167+
#
168+
# @param [Symbol] attribute The attribute name
169+
# @param [Hash] options Options for the memorable date
170+
# @option options [String] :legend Custom legend text
171+
# @option options [String] :hint Custom hint text
172+
# @return [String] The rendered HTML for the memorable date input
173+
# @see https://designsystem.digital.gov/components/memorable-date/
146174
def memorable_date(attribute, options = {})
147175
legend_text = options.delete(:legend) || human_name(attribute)
148176
hint_text = options.delete(:hint) || I18n.t("flex.form_builder.memorable_date_hint")

app/lib/flex/attributes.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
module Flex
2+
# Attributes is a module that extends ActiveRecord with custom attribute types.
3+
# It provides a consistent interface for defining specialized attributes like
4+
# memorable dates, names, addresses, and tax IDs.
5+
#
6+
# This module should be included in models that need these custom attribute types.
7+
# See app/lib/flex/attributes/ folder for the list of all available flex attributes.
8+
#
9+
# @example Including Attributes in a model
10+
# class MyModel < ApplicationRecord
11+
# include Flex::Attributes
12+
#
13+
# flex_attribute :birth_date, :memorable_date
14+
# flex_attribute :applicant_name, :name
15+
# end
16+
#
217
module Attributes
318
extend ActiveSupport::Concern
419
include Flex::Attributes::AddressAttribute
@@ -7,6 +22,13 @@ module Attributes
722
include Flex::Attributes::TaxIdAttribute
823

924
class_methods do
25+
# Defines a custom attribute with the specified type.
26+
#
27+
# @param [Symbol] name The name of the attribute
28+
# @param [Symbol] type The type of attribute (:memorable_date, :name, :address, :tax_id)
29+
# @param [Hash] options Options for the attribute
30+
# @raise [ArgumentError] If an unsupported attribute type is provided
31+
# @return [void]
1032
def flex_attribute(name, type, options = {})
1133
case type
1234
when :memorable_date

app/lib/flex/attributes/name_attribute.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
module Flex
22
module Attributes
3+
# NameAttribute provides functionality for handling name fields with first, middle, and last components.
4+
# It uses the Flex::Name value object for storage and manipulation.
5+
#
6+
# This module is automatically included when using Flex::Attributes.
7+
#
8+
# @example Using the name attribute
9+
# class Person < ApplicationRecord
10+
# include Flex::Attributes
11+
#
12+
# flex_attribute :name, :name
13+
# end
14+
#
15+
# person = Person.new
16+
# person.name = Flex::Name.new("John", "A", "Doe")
17+
# puts person.name.first # => "John"
18+
#
319
module NameAttribute
420
extend ActiveSupport::Concern
521

622
class_methods do
23+
# Defines a name attribute with first, middle, and last components.
24+
#
25+
# @param [Symbol] name The base name for the attribute
26+
# @param [Hash] options Options for the attribute
27+
# @return [void]
728
def name_attribute(name, options = {})
829
# Define the base attribute with its subfields
930
attribute "#{name}_first", :string

app/models/flex/application_form.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
module Flex
2+
# ApplicationForm is the base class for all form models in the Flex SDK.
3+
# It provides functionality for tracking form status (in_progress/submitted)
4+
# and prevents modification of submitted forms.
5+
#
6+
# Form models should inherit from this class and add their specific fields.
7+
#
8+
# @example Creating a form model
9+
# class MyApplicationForm < Flex::ApplicationForm
10+
# attribute :name, :string
11+
# attribute :email, :string
12+
# end
13+
#
14+
# Key features:
15+
# - Tracks form status (in_progress/submitted)
16+
# - Prevents modification of submitted forms
17+
# - Publishes events when created and submitted
18+
#
219
class ApplicationForm < ApplicationRecord
320
self.abstract_class = true
421

@@ -11,6 +28,13 @@ class ApplicationForm < ApplicationRecord
1128
after_create :publish_created
1229
before_update :prevent_changes_if_submitted, if: :was_submitted?
1330

31+
# Submits the application form, changing its status to 'submitted'
32+
# and publishing a submission event.
33+
#
34+
# This method should be called when a user submits the form.
35+
# After submission, the form can no longer be modified.
36+
#
37+
# @return [Boolean] True if the submission was successful
1438
def submit_application
1539
puts "Submitting application with ID: #{id}"
1640
self[:status] = :submitted
@@ -20,17 +44,26 @@ def submit_application
2044

2145
protected
2246

47+
# Returns the event payload for publishing events related to this form.
48+
#
49+
# @return [Hash] Payload with application_form_id
2350
def event_payload
2451
{ application_form_id: id }
2552
end
2653

2754
protected
2855

56+
# Creates a case associated with this application form.
57+
#
58+
# @return [Flex::Case] The created case
2959
def create_case
3060
kase = case_class.create!
3161
self[:case_id] = kase.id
3262
end
3363

64+
# Determines the case class corresponding to this application form class.
65+
#
66+
# @return [Class] The case class (ApplicationForm -> Case)
3467
def case_class
3568
self.class.name.sub("ApplicationForm", "Case").constantize
3669
end

app/models/flex/case.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
module Flex
2+
# Case represents an instance of a business process workflow.
3+
# It tracks the current step in the process and the overall status.
4+
#
5+
# Case models should inherit from this class and add their specific fields.
6+
#
7+
# @example Creating a case model
8+
# class MyCase < Flex::Case
9+
# # Add custom attributes or associations
10+
# end
11+
#
12+
# Key features:
13+
# - Tracks the current step in a business process
14+
# - Manages case status (open/closed)
15+
# - Associates with an application form
16+
#
217
class Case < ApplicationRecord
318
self.abstract_class = true
419

@@ -12,11 +27,17 @@ class Case < ApplicationRecord
1227

1328
protected attr_accessor :business_process
1429

30+
# Closes the case, changing its status to 'closed'.
31+
#
32+
# @return [Boolean] True if the save was successful
1533
def close
1634
self[:status] = :closed
1735
save
1836
end
1937

38+
# Reopens a closed case, changing its status to 'open'.
39+
#
40+
# @return [Boolean] True if the save was successful
2041
def reopen
2142
self[:status] = :open
2243
save

spec/dummy/db/schema.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
create_table "passport_cases", force: :cascade do |t|
3939
t.integer "status", default: 0, null: false
40-
t.string "passport_id", null: false
40+
t.string "passport_id", limit: 36, null: false
4141
t.string "business_process_current_step"
4242
t.datetime "created_at", null: false
4343
t.datetime "updated_at", null: false

0 commit comments

Comments
 (0)