Showing preview only (3,567K chars total). Download the full file or copy to clipboard to get everything.
Repository: rubyforgood/casa
Branch: main
Commit: 10fb1a929d95
Files: 1723
Total size: 62.6 MB
Directory structure:
gitextract_7qaocwti/
├── .allow_skipping_tests
├── .better-html.yml
├── .browserslistrc
├── .devcontainer/
│ ├── Dockerfile
│ ├── devcontainer.json
│ ├── docker-compose.yml
│ └── post-create.sh
├── .dockerignore
├── .erb_lint.yml
├── .github/
│ ├── CODEOWNERS
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── chore.md
│ │ ├── config.yml
│ │ ├── documentation.md
│ │ ├── feature_request.md
│ │ ├── flaky_test.md
│ │ └── problem_validation.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── autoapproval.yml
│ ├── dependabot.yml
│ ├── instructions/
│ │ ├── copilot-review.instructions.md
│ │ └── ruby.instructions.md
│ ├── labeler.yml
│ └── workflows/
│ ├── add-labels-based-on-column.yml
│ ├── after-deploy.yml
│ ├── codeql-analysis.yml
│ ├── combine_and_report.yml
│ ├── docker.yml
│ ├── erb_lint.yml
│ ├── factory_bot_lint.yml
│ ├── issue-auto-close-done.yml
│ ├── issue-auto-unassign.yml
│ ├── label.yml
│ ├── npm_lint_and_test.yml
│ ├── rake-after_party.yml
│ ├── remove-helped-wanted.yml
│ ├── remove-label-based-on-column.yml
│ ├── rspec.yml
│ ├── ruby_lint.yml
│ ├── security.yml
│ ├── spec_checker.yml
│ ├── stale.yml
│ ├── toc.yml
│ └── yaml_lint.yml
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierrc.yml
├── .rspec
├── .rspec_parallel
├── .rubocop.yml
├── .ruby-gemset
├── .ruby-version
├── .slugignore
├── .standard.yml
├── .standard_todo.yml
├── .tool-versions
├── .yamllint.yml
├── CONTRIBUTING.md
├── DEPLOY_CHECKLIST.md
├── Dockerfile
├── Gemfile
├── LICENSE.md
├── PROSOPITE_TODO.md
├── Procfile
├── Procfile.dev
├── README.md
├── Rakefile
├── SECURITY.md
├── app/
│ ├── assets/
│ │ ├── builds/
│ │ │ └── .keep
│ │ ├── config/
│ │ │ └── manifest.js
│ │ └── stylesheets/
│ │ ├── actiontext.css
│ │ ├── android_app_associations.css
│ │ ├── application.scss
│ │ ├── base/
│ │ │ ├── breakpoints.scss
│ │ │ └── variables.scss
│ │ ├── pages/
│ │ │ ├── all_casa_admin_dashboard.scss
│ │ │ ├── casa_cases.scss
│ │ │ ├── casa_org.scss
│ │ │ ├── case_contacts.scss
│ │ │ ├── case_contacts_form.scss
│ │ │ ├── case_court_reports.scss
│ │ │ ├── court_dates.scss
│ │ │ ├── emancipation.scss
│ │ │ ├── feature_flags.scss
│ │ │ ├── login.scss
│ │ │ ├── password.scss
│ │ │ ├── patch_notes.scss
│ │ │ ├── reimbursements.scss
│ │ │ ├── supervisors.scss
│ │ │ └── volunteers.scss
│ │ └── shared/
│ │ ├── dashboard.scss
│ │ ├── data_tables_overide.scss
│ │ ├── flashes.scss
│ │ ├── footer.scss
│ │ ├── form.scss
│ │ ├── header.scss
│ │ ├── layout.scss
│ │ ├── navbar.scss
│ │ ├── noscript.css
│ │ ├── notifier.scss
│ │ ├── select2_additional_styles.scss
│ │ ├── sidebar.scss
│ │ ├── tomselect_additional_styles.scss
│ │ ├── truncated_text_component.scss
│ │ ├── typography.scss
│ │ ├── utilities.scss
│ │ └── validated_form_component.scss
│ ├── blueprints/
│ │ └── api/
│ │ └── v1/
│ │ └── session_blueprint.rb
│ ├── callbacks/
│ │ └── case_contact_metadata_callback.rb
│ ├── channels/
│ │ └── application_cable/
│ │ ├── channel.rb
│ │ └── connection.rb
│ ├── components/
│ │ ├── badge_component.html.erb
│ │ ├── badge_component.rb
│ │ ├── dropdown_menu_component.html.erb
│ │ ├── dropdown_menu_component.rb
│ │ ├── form/
│ │ │ ├── hour_minute_duration_component.html.erb
│ │ │ ├── hour_minute_duration_component.rb
│ │ │ ├── multiple_select/
│ │ │ │ ├── item_component.html.erb
│ │ │ │ └── item_component.rb
│ │ │ ├── multiple_select_component.html.erb
│ │ │ └── multiple_select_component.rb
│ │ ├── local_time_component.html.erb
│ │ ├── local_time_component.rb
│ │ ├── modal/
│ │ │ ├── body_component.html.erb
│ │ │ ├── body_component.rb
│ │ │ ├── footer_component.html.erb
│ │ │ ├── footer_component.rb
│ │ │ ├── group_component.html.erb
│ │ │ ├── group_component.rb
│ │ │ ├── header_component.html.erb
│ │ │ ├── header_component.rb
│ │ │ ├── open_button_component.html.erb
│ │ │ ├── open_button_component.rb
│ │ │ ├── open_link_component.html.erb
│ │ │ └── open_link_component.rb
│ │ ├── notification_component.html.erb
│ │ ├── notification_component.rb
│ │ ├── sidebar/
│ │ │ ├── group_component.html.erb
│ │ │ ├── group_component.rb
│ │ │ ├── link_component.html.erb
│ │ │ └── link_component.rb
│ │ ├── truncated_text_component.html.erb
│ │ └── truncated_text_component.rb
│ ├── controllers/
│ │ ├── additional_expenses_controller.rb
│ │ ├── all_casa_admins/
│ │ │ ├── casa_admins_controller.rb
│ │ │ ├── casa_orgs_controller.rb
│ │ │ ├── dashboard_controller.rb
│ │ │ ├── patch_notes_controller.rb
│ │ │ └── sessions_controller.rb
│ │ ├── all_casa_admins_controller.rb
│ │ ├── android_app_associations_controller.rb
│ │ ├── api/
│ │ │ └── v1/
│ │ │ ├── base_controller.rb
│ │ │ └── users/
│ │ │ └── sessions_controller.rb
│ │ ├── application_controller.rb
│ │ ├── banners_controller.rb
│ │ ├── bulk_court_dates_controller.rb
│ │ ├── casa_admins_controller.rb
│ │ ├── casa_cases_controller.rb
│ │ ├── casa_org_controller.rb
│ │ ├── case_assignments_controller.rb
│ │ ├── case_contact_reports_controller.rb
│ │ ├── case_contacts/
│ │ │ ├── case_contacts_new_design_controller.rb
│ │ │ ├── followups_controller.rb
│ │ │ └── form_controller.rb
│ │ ├── case_contacts_controller.rb
│ │ ├── case_court_orders_controller.rb
│ │ ├── case_court_reports_controller.rb
│ │ ├── case_groups_controller.rb
│ │ ├── checklist_items_controller.rb
│ │ ├── concerns/
│ │ │ ├── accessible.rb
│ │ │ ├── court_date_params.rb
│ │ │ ├── loads_case_contacts.rb
│ │ │ ├── organizational.rb
│ │ │ └── users/
│ │ │ └── time_zone.rb
│ │ ├── contact_topic_answers_controller.rb
│ │ ├── contact_topics_controller.rb
│ │ ├── contact_type_groups_controller.rb
│ │ ├── contact_types_controller.rb
│ │ ├── court_dates_controller.rb
│ │ ├── custom_org_links_controller.rb
│ │ ├── dashboard_controller.rb
│ │ ├── emancipation_checklists_controller.rb
│ │ ├── emancipations_controller.rb
│ │ ├── error_controller.rb
│ │ ├── followup_reports_controller.rb
│ │ ├── fund_requests_controller.rb
│ │ ├── health_controller.rb
│ │ ├── hearing_types_controller.rb
│ │ ├── imports_controller.rb
│ │ ├── judges_controller.rb
│ │ ├── languages_controller.rb
│ │ ├── learning_hour_topics_controller.rb
│ │ ├── learning_hour_types_controller.rb
│ │ ├── learning_hours/
│ │ │ └── volunteers_controller.rb
│ │ ├── learning_hours_controller.rb
│ │ ├── learning_hours_reports_controller.rb
│ │ ├── mileage_rates_controller.rb
│ │ ├── mileage_reports_controller.rb
│ │ ├── missing_data_reports_controller.rb
│ │ ├── notes_controller.rb
│ │ ├── notifications_controller.rb
│ │ ├── other_duties_controller.rb
│ │ ├── placement_reports_controller.rb
│ │ ├── placement_types_controller.rb
│ │ ├── placements_controller.rb
│ │ ├── preference_sets_controller.rb
│ │ ├── reimbursements_controller.rb
│ │ ├── reports_controller.rb
│ │ ├── static_controller.rb
│ │ ├── supervisor_volunteers_controller.rb
│ │ ├── supervisors_controller.rb
│ │ ├── users/
│ │ │ ├── invitations_controller.rb
│ │ │ ├── passwords_controller.rb
│ │ │ └── sessions_controller.rb
│ │ ├── users_controller.rb
│ │ └── volunteers_controller.rb
│ ├── datatables/
│ │ ├── application_datatable.rb
│ │ ├── case_contact_datatable.rb
│ │ ├── reimbursement_datatable.rb
│ │ ├── supervisor_datatable.rb
│ │ └── volunteer_datatable.rb
│ ├── decorators/
│ │ ├── android_app_association_decorator.rb
│ │ ├── application_decorator.rb
│ │ ├── casa_case_decorator.rb
│ │ ├── case_assignment_decorator.rb
│ │ ├── case_contact_decorator.rb
│ │ ├── case_contacts/
│ │ │ └── form_decorator.rb
│ │ ├── contact_type_decorator.rb
│ │ ├── court_date_decorator.rb
│ │ ├── learning_hour_decorator.rb
│ │ ├── learning_hour_topic_decorator.rb
│ │ ├── other_duty_decorator.rb
│ │ ├── patch_note_decorator.rb
│ │ ├── placement_decorator.rb
│ │ ├── user_decorator.rb
│ │ └── volunteer_decorator.rb
│ ├── documents/
│ │ └── templates/
│ │ ├── default_report_template.docx
│ │ ├── emancipation_checklist_template.docx
│ │ ├── howard_county_report_template.docx
│ │ ├── montgomery_report_template.docx
│ │ ├── montgomery_report_template_062022.docx
│ │ └── prince_george_report_template.docx
│ ├── helpers/
│ │ ├── all_casa_admins/
│ │ │ └── casa_orgs_helper.rb
│ │ ├── api_base_helper.rb
│ │ ├── application_helper.rb
│ │ ├── banner_helper.rb
│ │ ├── case_contacts_helper.rb
│ │ ├── contact_types_helper.rb
│ │ ├── court_dates_helper.rb
│ │ ├── court_orders_helper.rb
│ │ ├── date_helper.rb
│ │ ├── emancipations_helper.rb
│ │ ├── followup_helper.rb
│ │ ├── learning_hours_helper.rb
│ │ ├── mileage_rates_helper.rb
│ │ ├── notifications_helper.rb
│ │ ├── other_duties_helper.rb
│ │ ├── phone_number_helper.rb
│ │ ├── preference_sets_helper.rb
│ │ ├── report_helper.rb
│ │ ├── request_header_helper.rb
│ │ ├── sidebar_helper.rb
│ │ ├── sms_body_helper.rb
│ │ ├── template_helper.rb
│ │ ├── ui_helper.rb
│ │ └── volunteer_helper.rb
│ ├── javascript/
│ │ ├── __mocks__/
│ │ │ ├── fileMock.js
│ │ │ └── styleMock.js
│ │ ├── __tests__/
│ │ │ ├── add_to_calendar_button.test.js
│ │ │ ├── casa_case.test.js
│ │ │ ├── case_button_states.test.js
│ │ │ ├── case_contact.test.js
│ │ │ ├── case_emancipations.test.js
│ │ │ ├── dashboard.test.js
│ │ │ ├── notifier.test.js
│ │ │ ├── password_confirmation.test.js
│ │ │ ├── read_more.test.js
│ │ │ ├── require_communication_preference.test.js
│ │ │ ├── setup-jest.js
│ │ │ ├── time_zone.test.js
│ │ │ ├── two_minute_warning_session_timeout.test.js
│ │ │ ├── type_checker.test.js
│ │ │ └── validated_form.test.js
│ │ ├── all_casa_admin.js
│ │ ├── application.js
│ │ ├── controllers/
│ │ │ ├── alert_controller.js
│ │ │ ├── application.js
│ │ │ ├── autosave_controller.js
│ │ │ ├── casa_nested_form_controller.js
│ │ │ ├── case_contact_form_controller.js
│ │ │ ├── court_order_form_controller.js
│ │ │ ├── disable_form_controller.js
│ │ │ ├── dismiss_controller.js
│ │ │ ├── hello_controller.js
│ │ │ ├── icon_toggle_controller.js
│ │ │ ├── index.js
│ │ │ ├── multiple_select_controller.js
│ │ │ ├── navbar_controller.js
│ │ │ ├── select_all_controller.js
│ │ │ ├── sidebar_controller.js
│ │ │ ├── sidebar_group_controller.js
│ │ │ └── truncated_text_controller.js
│ │ ├── datatable.js
│ │ ├── jQueryGlobalizer.js
│ │ ├── src/
│ │ │ ├── add_to_calendar_button.js
│ │ │ ├── all_casa_admin/
│ │ │ │ ├── patch_notes.js
│ │ │ │ └── tables.js
│ │ │ ├── casa_case.js
│ │ │ ├── casa_org.js
│ │ │ ├── case_contact.js
│ │ │ ├── case_emancipation.js
│ │ │ ├── dashboard.js
│ │ │ ├── display_app_metric.js
│ │ │ ├── emancipations.js
│ │ │ ├── import.js
│ │ │ ├── learning_hours.js
│ │ │ ├── new_casa_case.js
│ │ │ ├── notifier.js
│ │ │ ├── password_confirmation.js
│ │ │ ├── read_more.js
│ │ │ ├── reimbursements.js
│ │ │ ├── reports.js
│ │ │ ├── require_communication_preference.js
│ │ │ ├── select.js
│ │ │ ├── session_timeout_poller.js
│ │ │ ├── sms_reactivation_toggle.js
│ │ │ ├── time_zone.js
│ │ │ ├── tooltip.js
│ │ │ ├── type_checker.js
│ │ │ └── validated_form.js
│ │ └── sweet-alert-confirm.js
│ ├── jobs/
│ │ └── application_job.rb
│ ├── lib/
│ │ └── importers/
│ │ ├── case_importer.rb
│ │ ├── file_importer.rb
│ │ ├── supervisor_importer.rb
│ │ └── volunteer_importer.rb
│ ├── mailers/
│ │ ├── application_mailer.rb
│ │ ├── casa_admin_mailer.rb
│ │ ├── fund_request_mailer.rb
│ │ ├── learning_hours_mailer.rb
│ │ ├── supervisor_mailer.rb
│ │ ├── user_mailer.rb
│ │ └── volunteer_mailer.rb
│ ├── models/
│ │ ├── additional_expense.rb
│ │ ├── address.rb
│ │ ├── all_casa_admin.rb
│ │ ├── all_casa_admins/
│ │ │ └── casa_org_metrics.rb
│ │ ├── api_credential.rb
│ │ ├── application_record.rb
│ │ ├── banner.rb
│ │ ├── casa_admin.rb
│ │ ├── casa_case.rb
│ │ ├── casa_case_contact_type.rb
│ │ ├── casa_case_emancipation_category.rb
│ │ ├── casa_case_emancipation_option.rb
│ │ ├── casa_org.rb
│ │ ├── case_assignment.rb
│ │ ├── case_contact.rb
│ │ ├── case_contact_contact_type.rb
│ │ ├── case_contact_report.rb
│ │ ├── case_court_order.rb
│ │ ├── case_court_report.rb
│ │ ├── case_court_report_context.rb
│ │ ├── case_group.rb
│ │ ├── case_group_membership.rb
│ │ ├── checklist_item.rb
│ │ ├── concerns/
│ │ │ ├── CasaCase/
│ │ │ │ └── validations.rb
│ │ │ ├── api.rb
│ │ │ ├── by_organization_scope.rb
│ │ │ └── roles.rb
│ │ ├── contact_topic.rb
│ │ ├── contact_topic_answer.rb
│ │ ├── contact_type.rb
│ │ ├── contact_type_group.rb
│ │ ├── court_date.rb
│ │ ├── custom_org_link.rb
│ │ ├── emancipation_category.rb
│ │ ├── emancipation_option.rb
│ │ ├── followup.rb
│ │ ├── fund_request.rb
│ │ ├── health.rb
│ │ ├── hearing_type.rb
│ │ ├── judge.rb
│ │ ├── language.rb
│ │ ├── learning_hour.rb
│ │ ├── learning_hour_topic.rb
│ │ ├── learning_hour_type.rb
│ │ ├── learning_hours_report.rb
│ │ ├── login_activity.rb
│ │ ├── mileage_rate.rb
│ │ ├── mileage_report.rb
│ │ ├── missing_data_report.rb
│ │ ├── note.rb
│ │ ├── other_duty.rb
│ │ ├── patch_note.rb
│ │ ├── patch_note_group.rb
│ │ ├── patch_note_type.rb
│ │ ├── placement.rb
│ │ ├── placement_type.rb
│ │ ├── preference_set.rb
│ │ ├── sent_email.rb
│ │ ├── sms_notification_event.rb
│ │ ├── supervisor.rb
│ │ ├── supervisor_volunteer.rb
│ │ ├── user.rb
│ │ ├── user_language.rb
│ │ ├── user_reminder_time.rb
│ │ ├── user_sms_notification_event.rb
│ │ └── volunteer.rb
│ ├── notifications/
│ │ ├── base_notifier.rb
│ │ ├── delivery_methods/
│ │ │ └── sms.rb
│ │ ├── emancipation_checklist_reminder_notifier.rb
│ │ ├── followup_notifier.rb
│ │ ├── followup_resolved_notifier.rb
│ │ ├── reimbursement_complete_notifier.rb
│ │ ├── volunteer_birthday_notifier.rb
│ │ └── youth_birthday_notifier.rb
│ ├── policies/
│ │ ├── additional_expense_policy.rb
│ │ ├── application_policy.rb
│ │ ├── bulk_court_date_policy.rb
│ │ ├── casa_admin_policy.rb
│ │ ├── casa_case_policy.rb
│ │ ├── casa_org_policy.rb
│ │ ├── case_assignment_policy.rb
│ │ ├── case_contact_policy.rb
│ │ ├── case_court_order_policy.rb
│ │ ├── case_court_report_policy.rb
│ │ ├── case_group_policy.rb
│ │ ├── checklist_item_policy.rb
│ │ ├── contact_topic_answer_policy.rb
│ │ ├── contact_topic_policy.rb
│ │ ├── contact_type_group_policy.rb
│ │ ├── contact_type_policy.rb
│ │ ├── court_date_policy.rb
│ │ ├── custom_org_link_policy.rb
│ │ ├── dashboard_policy.rb
│ │ ├── followup_policy.rb
│ │ ├── fund_request_policy.rb
│ │ ├── hearing_type_policy.rb
│ │ ├── import_policy.rb
│ │ ├── judge_policy.rb
│ │ ├── language_policy.rb
│ │ ├── learning_hour_policy.rb
│ │ ├── learning_hour_topic_policy.rb
│ │ ├── learning_hour_type_policy.rb
│ │ ├── nil_class_policy.rb
│ │ ├── note_policy.rb
│ │ ├── notification_policy.rb
│ │ ├── other_duty_policy.rb
│ │ ├── patch_note_policy.rb
│ │ ├── placement_policy.rb
│ │ ├── placement_type_policy.rb
│ │ ├── reimbursement_policy.rb
│ │ ├── supervisor_policy.rb
│ │ ├── supervisor_volunteer_policy.rb
│ │ ├── user_policy.rb
│ │ └── volunteer_policy.rb
│ ├── presenters/
│ │ ├── base_presenter.rb
│ │ └── case_contact_presenter.rb
│ ├── services/
│ │ ├── additional_expense_params_service.rb
│ │ ├── backfill_followupable_service.rb
│ │ ├── casa_case_change_service.rb
│ │ ├── case_contacts_contact_dates.rb
│ │ ├── case_contacts_export_csv_service.rb
│ │ ├── court_report_due_sms_reminder_service.rb
│ │ ├── court_report_format_contact_date.rb
│ │ ├── create_all_casa_admin_service.rb
│ │ ├── create_casa_admin_service.rb
│ │ ├── deployment/
│ │ │ └── backfill_case_contact_started_metadata_service.rb
│ │ ├── emancipation_checklist_download_html.rb
│ │ ├── emancipation_checklist_reminder_service.rb
│ │ ├── failed_import_csv_service.rb
│ │ ├── fdf_inputs_service.rb
│ │ ├── followup_export_csv_service.rb
│ │ ├── followup_service.rb
│ │ ├── inactive_messages_service.rb
│ │ ├── learning_hours_export_csv_service.rb
│ │ ├── mileage_export_csv_service.rb
│ │ ├── missing_data_export_csv_service.rb
│ │ ├── no_contact_made_sms_reminder_service.rb
│ │ ├── placement_export_csv_service.rb
│ │ ├── preference_set_table_state_service.rb
│ │ ├── short_url_service.rb
│ │ ├── sms_reminder_service.rb
│ │ ├── svg_sanitizer_service.rb
│ │ ├── twilio_service.rb
│ │ ├── volunteer_birthday_reminder_service.rb
│ │ └── volunteers_emails_export_csv_service.rb
│ ├── validators/
│ │ ├── casa_org_validator.rb
│ │ ├── court_report_validator.rb
│ │ ├── url_validator.rb
│ │ └── user_validator.rb
│ ├── values/
│ │ ├── all_casa_admin_parameters.rb
│ │ ├── banner_parameters.rb
│ │ ├── casa_admin_parameters.rb
│ │ ├── case_contact_parameters.rb
│ │ ├── supervisor_parameters.rb
│ │ ├── user_parameters.rb
│ │ └── volunteer_parameters.rb
│ └── views/
│ ├── active_storage/
│ │ └── blobs/
│ │ └── _blob.html.erb
│ ├── all_casa_admins/
│ │ ├── casa_admins/
│ │ │ ├── _form.html.erb
│ │ │ ├── edit.html.erb
│ │ │ └── new.html.erb
│ │ ├── casa_orgs/
│ │ │ ├── new.html.erb
│ │ │ └── show.html.erb
│ │ ├── dashboard/
│ │ │ └── show.html.erb
│ │ ├── edit.html.erb
│ │ ├── new.html.erb
│ │ ├── passwords/
│ │ │ └── new.html.erb
│ │ ├── patch_notes/
│ │ │ ├── _patch_note.html.erb
│ │ │ ├── _patch_note.json.jbuilder
│ │ │ ├── index.html.erb
│ │ │ └── index.json.jbuilder
│ │ ├── sessions/
│ │ │ └── new.html.erb
│ │ └── shared/
│ │ └── _links.html.erb
│ ├── banners/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── bulk_court_dates/
│ │ └── new.html.erb
│ ├── casa_admin_mailer/
│ │ ├── account_setup.html.erb
│ │ └── deactivation.html.erb
│ ├── casa_admins/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── casa_cases/
│ │ ├── _calendar_button.html.erb
│ │ ├── _court_dates.html.erb
│ │ ├── _filter.html.erb
│ │ ├── _form.html.erb
│ │ ├── _generate_report_modal.html.erb
│ │ ├── _inactive_case.html.erb
│ │ ├── _placements.html.erb
│ │ ├── _thank_you_modal.html.erb
│ │ ├── _volunteer_assignment.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ ├── show.html.erb
│ │ └── show.xlsx.axlsx
│ ├── casa_org/
│ │ ├── _contact_topics.html.erb
│ │ ├── _contact_type_groups.html.erb
│ │ ├── _contact_types.html.erb
│ │ ├── _custom_org_links.html.erb
│ │ ├── _hearing_types.html.erb
│ │ ├── _judges.html.erb
│ │ ├── _languages.html.erb
│ │ ├── _learning_hour_topics.html.erb
│ │ ├── _learning_hour_types.html.erb
│ │ ├── _placement_types.html.erb
│ │ ├── _sent_emails.html.erb
│ │ └── edit.html.erb
│ ├── case_assignments/
│ │ └── index.html.erb
│ ├── case_contacts/
│ │ ├── _case_contact.html.erb
│ │ ├── _confirm_note_content_dialog.html.erb
│ │ ├── _followup.html.erb
│ │ ├── case_contacts_new_design/
│ │ │ └── index.html.erb
│ │ ├── drafts.html.erb
│ │ ├── form/
│ │ │ ├── _contact_topic_answer.html.erb
│ │ │ ├── _contact_types.html.erb
│ │ │ └── details.html.erb
│ │ └── index.html.erb
│ ├── case_court_reports/
│ │ ├── _generate_docx.html.erb
│ │ └── index.html.erb
│ ├── case_groups/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── checklist_items/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── contact_topics/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── contact_type_groups/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── contact_types/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── court_dates/
│ │ ├── _fields.html.erb
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── new.html.erb
│ │ └── show.html.erb
│ ├── custom_org_links/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── devise/
│ │ ├── invitations/
│ │ │ ├── edit.html.erb
│ │ │ └── new.html.erb
│ │ ├── mailer/
│ │ │ ├── confirmation_instructions.html.erb
│ │ │ ├── email_changed.html.erb
│ │ │ ├── invitation_instructions.html.erb
│ │ │ ├── invitation_instructions.text.erb
│ │ │ ├── password_change.html.erb
│ │ │ ├── reset_password_instructions.html.erb
│ │ │ └── unlock_instructions.html.erb
│ │ ├── passwords/
│ │ │ ├── edit.html.erb
│ │ │ └── new.html.erb
│ │ ├── sessions/
│ │ │ └── new.html.erb
│ │ └── shared/
│ │ └── _links.html.erb
│ ├── emancipation_checklists/
│ │ └── index.html.erb
│ ├── emancipations/
│ │ ├── download.html.erb
│ │ └── show.html.erb
│ ├── error/
│ │ └── index.html.erb
│ ├── fund_request_mailer/
│ │ └── send_request.html.erb
│ ├── fund_requests/
│ │ └── new.html.erb
│ ├── health/
│ │ └── index.html.erb
│ ├── hearing_types/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── imports/
│ │ ├── _cases.html.erb
│ │ ├── _csv_error_modal.html.erb
│ │ ├── _sms_opt_in_modal.html.erb
│ │ ├── _supervisors.html.erb
│ │ ├── _volunteers.html.erb
│ │ └── index.html.erb
│ ├── judges/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── languages/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── layouts/
│ │ ├── _all_casa_admin_sidebar.html.erb
│ │ ├── _banner.html.erb
│ │ ├── _flash_messages.html.erb
│ │ ├── _header.html.erb
│ │ ├── _login_header.html.erb
│ │ ├── _mobile_navbar.html.erb
│ │ ├── _sidebar.html.erb
│ │ ├── action_text/
│ │ │ └── contents/
│ │ │ └── _content.html.erb
│ │ ├── application.html.erb
│ │ ├── components/
│ │ │ └── _notifier.html.erb
│ │ ├── devise.html.erb
│ │ ├── footers/
│ │ │ ├── _logged_in.html.erb
│ │ │ └── _not_logged_in.html.erb
│ │ ├── fund_layout.html.erb
│ │ ├── mailer.html.erb
│ │ └── mailer.text.erb
│ ├── learning_hour_topics/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── learning_hour_types/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── learning_hours/
│ │ ├── _confirm_note.html.erb
│ │ ├── _form.html.erb
│ │ ├── _learning_hours_table.html.erb
│ │ ├── _supervisor_admin_learning_hours.html.erb
│ │ ├── _volunteer_learning_hours.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ ├── show.html.erb
│ │ └── volunteers/
│ │ └── show.html.erb
│ ├── learning_hours_mailer/
│ │ └── learning_hours_report_email.html.erb
│ ├── mileage_rates/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── notes/
│ │ └── edit.html.erb
│ ├── notifications/
│ │ ├── _notification.html.erb
│ │ ├── _patch_notes.html.erb
│ │ └── index.html.erb
│ ├── other_duties/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── placement_types/
│ │ ├── _fields.html.erb
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── placements/
│ │ ├── _fields.html.erb
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ └── show.html.erb
│ ├── reimbursements/
│ │ ├── _datatable.html.erb
│ │ ├── _filter_trigger.html.erb
│ │ ├── _occurred_at_filter_input.html.erb
│ │ ├── _reimbursement_complete.html.erb
│ │ ├── _table.html.erb
│ │ └── index.html.erb
│ ├── reports/
│ │ ├── _filter.html.erb
│ │ └── index.html.erb
│ ├── shared/
│ │ ├── _additional_expense_form.html.erb
│ │ ├── _court_order_form.html.erb
│ │ ├── _court_order_list.erb
│ │ ├── _edit_form.html.erb
│ │ ├── _emancipation_link.html.erb
│ │ ├── _error_messages.html.erb
│ │ ├── _favicons.html.erb
│ │ ├── _invite_login.html.erb
│ │ └── _manage_volunteers.html.erb
│ ├── static/
│ │ └── index.html.erb
│ ├── supervisor_mailer/
│ │ ├── _active_volunteer_info.html.erb
│ │ ├── _active_volunteers.html.erb
│ │ ├── _additional_notes.html.erb
│ │ ├── _no_recent_sign_in.html.erb
│ │ ├── _pending_volunteers.html.erb
│ │ ├── _recently_unassigned_volunteers.html.erb
│ │ ├── _summary_header.html.erb
│ │ ├── account_setup.html.erb
│ │ ├── reimbursement_request_email.html.erb
│ │ └── weekly_digest.html.erb
│ ├── supervisors/
│ │ ├── _manage_active.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── user_mailer/
│ │ └── password_changed_reminder.html.erb
│ ├── users/
│ │ ├── _edit_profile.erb
│ │ ├── _languages.html.erb
│ │ └── edit.html.erb
│ ├── volunteer_mailer/
│ │ ├── account_setup.html.erb
│ │ ├── case_contacts_reminder.html.erb
│ │ └── court_report_reminder.html.erb
│ └── volunteers/
│ ├── _form.html.erb
│ ├── _manage_active.html.erb
│ ├── _manage_cases.erb
│ ├── _manage_supervisor.erb
│ ├── _notes.html.erb
│ ├── _send_reminder_button.html.erb
│ ├── _volunteer_reminder_form.erb
│ ├── edit.html.erb
│ ├── index.html.erb
│ └── new.html.erb
├── app.json
├── babel.config.js
├── bin/
│ ├── asset_bundling_scripts/
│ │ ├── build_js.js
│ │ └── logger.js
│ ├── brakeman
│ ├── bundle
│ ├── delayed_job
│ ├── dev
│ ├── git_hooks/
│ │ ├── README.md
│ │ ├── build-assets
│ │ ├── lint
│ │ ├── logger
│ │ ├── migrate-all
│ │ ├── update-branch
│ │ └── update-dependencies
│ ├── lint
│ ├── login
│ ├── npm
│ ├── rails
│ ├── rake
│ ├── rspec
│ ├── setup
│ ├── spring
│ └── update
├── cc-test-reporter
├── code-of-conduct.md
├── config/
│ ├── application.rb
│ ├── boot.rb
│ ├── brakeman.ignore
│ ├── cable.yml
│ ├── credentials/
│ │ ├── development.key
│ │ ├── development.yml.enc
│ │ ├── production.yml.enc
│ │ ├── qa.key
│ │ ├── qa.yml.enc
│ │ ├── test.key
│ │ └── test.yml.enc
│ ├── database.yml
│ ├── docker.env
│ ├── environment.rb
│ ├── environments/
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── test.rb
│ ├── initializers/
│ │ ├── after_party.rb
│ │ ├── all_casa_admin_access.rb
│ │ ├── application_controller_renderer.rb
│ │ ├── assets.rb
│ │ ├── authtrail.rb
│ │ ├── backtrace_silencers.rb
│ │ ├── blueprinter.rb
│ │ ├── bugsnag.rb
│ │ ├── content_security_policy.rb
│ │ ├── cookies_serializer.rb
│ │ ├── cors.rb
│ │ ├── date_formats.rb
│ │ ├── devise.rb
│ │ ├── extensions.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── flipper.rb
│ │ ├── generators.rb
│ │ ├── inflections.rb
│ │ ├── lograge.rb
│ │ ├── mime_types.rb
│ │ ├── pagy.rb
│ │ ├── permissions_policy.rb
│ │ ├── prosopite.rb
│ │ ├── rack_attack.rb
│ │ ├── rswag_api.rb
│ │ ├── rswag_ui.rb
│ │ ├── sent_email_event.rb
│ │ ├── strong_migrations.rb
│ │ └── wrap_parameters.rb
│ ├── locales/
│ │ ├── devise.en.yml
│ │ ├── devise_invitable.en.yml
│ │ └── en.yml
│ ├── puma.rb
│ ├── routes.rb
│ ├── scout_apm.yml
│ ├── spring.rb
│ └── storage.yml
├── config.ru
├── data/
│ └── inputs_fdf.erb
├── db/
│ ├── migrate/
│ │ ├── 20200329050100_create_casa_cases.rb
│ │ ├── 20200329062155_devise_create_users.rb
│ │ ├── 20200329064203_add_role_to_user.rb
│ │ ├── 20200329071025_change_casa_case_teen_to_required.rb
│ │ ├── 20200329071327_change_casa_case_number_to_required.rb
│ │ ├── 20200329071626_add_unique_index_on_case_case_number.rb
│ │ ├── 20200329074655_create_supervisor_volunteers.rb
│ │ ├── 20200329081206_create_case_assignments.rb
│ │ ├── 20200329085225_create_versions.rb
│ │ ├── 20200329095031_create_casa_orgs.rb
│ │ ├── 20200329095154_add_casa_org_to_user.rb
│ │ ├── 20200329102102_devise_create_all_casa_admins.rb
│ │ ├── 20200329175337_create_case_contacts.rb
│ │ ├── 20200330231711_add_volunteer_reference_to_casa_cases.rb
│ │ ├── 20200405112910_remove_volunteer_id_from_casa_case.rb
│ │ ├── 20200420004403_add_medium_type_and_contact_made_to_case_contacts.rb
│ │ ├── 20200422180727_replace_contact_type_with_contact_types_on_case_contact.rb
│ │ ├── 20200423154018_change_teen_program_to_transition_aged_youth.rb
│ │ ├── 20200423204147_add_name_to_user.rb
│ │ ├── 20200525220759_add_driving_fields_to_case_contact.rb
│ │ ├── 20200726185103_devise_invitable_add_to_users.rb
│ │ ├── 20200729002247_add_casa_org_to_casa_case.rb
│ │ ├── 20200801170524_add_type_to_user.rb
│ │ ├── 20200801192923_remove_role_from_user.rb
│ │ ├── 20200818220659_add_is_active_to_supervisor_volunteers.rb
│ │ ├── 20200830011647_add_notes_to_case_contacts.rb
│ │ ├── 20200905192934_remove_other_type_text_from_case_contacts.rb
│ │ ├── 20200906145045_add_display_name_to_casa_orgs.rb
│ │ ├── 20200906145725_add_address_to_casa_orgs.rb
│ │ ├── 20200906145830_add_footer_links_to_casa_orgs.rb
│ │ ├── 20200906150641_create_casa_org_logos.rb
│ │ ├── 20200906184455_add_banner_color_to_casa_org_logos.rb
│ │ ├── 20200907142411_create_task_records.rb
│ │ ├── 20200917175655_add_default_value_to_case_contact_miles_driven.rb
│ │ ├── 20200918115741_set_miles_driven_as_not_nullable.rb
│ │ ├── 20200922144730_add_birth_month_year_youth_to_casa_cases.rb
│ │ ├── 20200922150754_create_contact_type.rb
│ │ ├── 20200922170308_link_case_contacts_to_contact_types.rb
│ │ ├── 20200924192310_create_casa_case_contact_type.rb
│ │ ├── 20200925180941_add_active_to_contact_type_groups.rb
│ │ ├── 20200925181042_add_active_to_contact_types.rb
│ │ ├── 20200928233606_add_court_report_submitted_to_casa_cases.rb
│ │ ├── 20201002192636_add_court_date_to_casa_cases.rb
│ │ ├── 20201004165322_add_court_report_due_date_to_casa_cases.rb
│ │ ├── 20201005191326_create_hearing_types.rb
│ │ ├── 20201013171632_remove_contact_types_from_case_contacts.rb
│ │ ├── 20201019120548_create_active_storage_tables.active_storage.rb
│ │ ├── 20201020095451_add_hearing_type_to_court_cases.rb
│ │ ├── 20201020220412_create_emancipation_categories.rb
│ │ ├── 20201021024459_create_emancipation_options.rb
│ │ ├── 20201021034012_create_join_table_casa_cases_emancipaton_options.rb
│ │ ├── 20201021143642_add_active_column_to_casa_cases_table.rb
│ │ ├── 20201022034445_add_foreign_key_constraints_to_case_emancipation_join_table.rb
│ │ ├── 20201023233638_create_judges.rb
│ │ ├── 20201023234325_add_active_to_judge.rb
│ │ ├── 20201024003821_add_name_to_judge.rb
│ │ ├── 20201024113046_create_past_court_dates.rb
│ │ ├── 20201025162142_add_judge_to_court_cases.rb
│ │ ├── 20201108142333_add_court_report_status_to_casa_cases.rb
│ │ ├── 20201120103041_remove_remember_created_at_from_users.rb
│ │ ├── 20201120103146_remove_remember_created_at_from_all_casa_admins.rb
│ │ ├── 20201120215756_remove_court_report_submitted_from_casa_cases.rb
│ │ ├── 20201123100716_remove_case_number_index_from_casa_cases.rb
│ │ ├── 20201123112651_add_case_number_index_scoped_by_casa_org_to_casa_cases.rb
│ │ ├── 20201222125441_add_service_name_to_active_storage_blobs.active_storage.rb
│ │ ├── 20201222125442_create_active_storage_variant_records.active_storage.rb
│ │ ├── 20201226024029_create_casa_case_emancipation_categories.rb
│ │ ├── 20210105155534_create_followups.rb
│ │ ├── 20210107181908_add_id_and_timestamps_to_case_emancipation_options_table.rb
│ │ ├── 20210109231411_drop_casa_org_logos_table.rb
│ │ ├── 20210117185614_create_notifications.rb
│ │ ├── 20210223133248_create_case_court_mandates.rb
│ │ ├── 20210308195135_change_is_active_name.rb
│ │ ├── 20210330182538_add_devise_trackable_columns_to_users.rb
│ │ ├── 20210401161710_add_deleted_at_to_case_contacts.rb
│ │ ├── 20210401182359_add_implementation_status_to_edit_case_court_mandates.rb
│ │ ├── 20210502172706_add_devise_invitable_to_all_casa_admins.rb
│ │ ├── 20210521151549_add_casa_case_details_to_past_court_dates.rb
│ │ ├── 20210521194321_add_past_court_date_to_case_court_mandates.rb
│ │ ├── 20210526233058_create_sent_emails.rb
│ │ ├── 20210624125750_add_note_to_followups.rb
│ │ ├── 20210913142024_set_display_name_as_not_nullable.rb
│ │ ├── 20210925140028_add_slug_to_casa_orgs_and_casa_cases.rb
│ │ ├── 20211001204053_rename_court_mandates_to_court_orders.rb
│ │ ├── 20211007144114_add_show_driving_reimbursement_to_casa_orgs.rb
│ │ ├── 20211008170357_add_text_to_case_court_orders.rb
│ │ ├── 20211008170724_migrate_case_court_orders_mandate_text_to_text.rb
│ │ ├── 20211008174527_remove_mandate_text_from_case_court_orders.rb
│ │ ├── 20211011195857_rename_past_court_date_to_court_date.rb
│ │ ├── 20211012180102_change_casa_cases_court_date_to_reference.rb
│ │ ├── 20211023165907_add_reimbursement_complete_to_case_contacts.rb
│ │ ├── 20211024011923_create_mileage_rates.rb
│ │ ├── 20211024060815_create_preference_sets.rb
│ │ ├── 20211025143709_create_healths.rb
│ │ ├── 20211029032305_add_casa_org_to_mileage_rate.rb
│ │ ├── 20211029033530_remove_user_required_from_mileage_rate.rb
│ │ ├── 20211203181342_create_additional_expenses.rb
│ │ ├── 20211230033457_create_delayed_jobs.rb
│ │ ├── 20220105030922_create_feature_flags.rb
│ │ ├── 20220127055733_create_notes.rb
│ │ ├── 20220223035901_remove_null_check_deprecated_field.rb
│ │ ├── 20220226040507_create_fund_request.rb
│ │ ├── 20220303183053_create_other_duty.rb
│ │ ├── 20220323145733_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
│ │ ├── 20220324141758_create_learning_hours.rb
│ │ ├── 20220402201247_add_phone_number_to_users.rb
│ │ ├── 20220406011016_add_sms_notification_preferences_to_users.rb
│ │ ├── 20220406011144_add_email_notification_preferences_to_users.rb
│ │ ├── 20220409184741_add_fund_request.rb
│ │ ├── 20220411180242_add_uniqueness_constraint_to_feature_flag_name.rb
│ │ ├── 20220509224425_add_columns_to_casa_orgs.rb
│ │ ├── 20220513084954_add_date_in_care_to_casa_cases.rb
│ │ ├── 20220513111133_delete_versions.rb
│ │ ├── 20220519210423_create_sms_notification_events.rb
│ │ ├── 20220519233803_create_user_sms_notification_events.rb
│ │ ├── 20220526011848_create_user_reminder_times.rb
│ │ ├── 20220602215632_create_addresses.rb
│ │ ├── 20220607184910_add_hide_old_contacts_to_case_assignment.rb
│ │ ├── 20220610221701_create_checklist_items.rb
│ │ ├── 20220615015056_create_patch_note_types.rb
│ │ ├── 20220616021404_add_checklist_updated_date_to_hearing_types.rb
│ │ ├── 20220618042137_create_patch_note_groups.rb
│ │ ├── 20220622022147_create_patch_notes.rb
│ │ ├── 20220820231119_create_languages.rb
│ │ ├── 20220826130829_create_languages_users_join_table.rb
│ │ ├── 20220924181447_remove_all_empty_languages.rb
│ │ ├── 20221002103627_add_user_foreign_key_to_other_duties.rb
│ │ ├── 20221002103754_validate_add_user_foreign_key_to_other_duties.rb
│ │ ├── 20221003202112_add_court_report_due_date_to_court_dates.rb
│ │ ├── 20221011044911_add_user_languages.rb
│ │ ├── 20221012203806_populate_user_languages_from_languages_users.rb
│ │ ├── 20230121174227_remove_court_data_from_casa_cases.rb
│ │ ├── 20230220210146_add_phone_number_to_all_casa_admin_resource.rb
│ │ ├── 20230316152808_remove_phone_number_from_all_casa_admin_resource.rb
│ │ ├── 20230326225216_create_placement_types.rb
│ │ ├── 20230326225230_create_placements.rb
│ │ ├── 20230327154626_add_confirmable_to_users.rb
│ │ ├── 20230327155053_add_email_confirmation_and_old_emails_to_users.rb
│ │ ├── 20230405202939_remove_email_confirmation_from_users.rb
│ │ ├── 20230412103356_add_casa_case_to_placements.rb
│ │ ├── 20230420212437_add_table_columns_display_to_preference_set.rb
│ │ ├── 20230610153139_add_receive_reimbursement_email_to_users.rb
│ │ ├── 20230615155223_add_twilio_enabled_to_casa_orgs.rb
│ │ ├── 20230621161252_add_additional_expenses_to_casa_orgs.rb
│ │ ├── 20230627210040_add_allow_reimbursement_to_case_assignments.rb
│ │ ├── 20230704123327_add_foreign_key_constraints_to_mileage_rates.rb
│ │ ├── 20230710025852_add_token_to_users.rb
│ │ ├── 20230712080040_add_foreign_key_creator_id_to_note.rb
│ │ ├── 20230728135743_create_action_text_tables.action_text.rb
│ │ ├── 20230728140249_create_banners.rb
│ │ ├── 20230729143126_create_learning_hour_types.rb
│ │ ├── 20230729145310_add_reference_learning_hour_types.rb
│ │ ├── 20230729145351_add_foreign_key_learning_hour_types.rb
│ │ ├── 20230729145419_validate_foreign_key_learning_hour_types.rb
│ │ ├── 20230729154529_create_case_groups.rb
│ │ ├── 20230729154545_create_case_group_memberships.rb
│ │ ├── 20230729213608_remove_hearing_type_id_and_judge_id_from_casa_cases.rb
│ │ ├── 20230730103110_remove_learning_type.rb
│ │ ├── 20230809002819_drop_languages_users.rb
│ │ ├── 20230817144910_create_learning_hour_topics.rb
│ │ ├── 20230819124840_add_learning_hour_topic_id_to_learning_hour.rb
│ │ ├── 20230819132316_add_learning_topic_active_to_casa_org.rb
│ │ ├── 20230822152341_drop_jwt_denylist_table.rb
│ │ ├── 20230902021531_add_monthly_learning_hours_report_to_user.rb
│ │ ├── 20230903182657_add_foreign_key_casa_case_to_placement.rb
│ │ ├── 20231102181027_add_birthdays_to_users.rb
│ │ ├── 20231125150721_status_for_case_contacts.rb
│ │ ├── 20240216013254_add_contact_topics.rb
│ │ ├── 20240415160842_add_followupable_to_followups.rb
│ │ ├── 20240507022441_create_login_activities.rb
│ │ ├── 20240509104733_create_noticed_tables.noticed.rb
│ │ ├── 20240509104734_add_notifications_count_to_noticed_event.noticed.rb
│ │ ├── 20240531172823_add_expires_at_to_banner.rb
│ │ ├── 20240610071054_add_other_duties_enabled_to_casa_org.rb
│ │ ├── 20240621165358_create_flipper_tables.rb
│ │ ├── 20240622020203_drop_feature_flags.rb
│ │ ├── 20240716194609_add_metadata_to_case_contacts.rb
│ │ ├── 20241017050129_remove_contact_topic_answer_contact_topic_id_null_constraint.rb
│ │ ├── 20250207080433_remove_token_from_users.rb
│ │ ├── 20250207080511_create_api_credentials.rb
│ │ ├── 20250208160513_remove_plain_text_tokens_from_api_credentials.rb
│ │ ├── 20250331032424_validate_constraint_mileage_rates.rb
│ │ ├── 20250331033339_validate_constraint_notes.rb
│ │ ├── 20250331033350_validate_constraint_placements.rb
│ │ ├── 20250331033418_remove_duplicate_indexindex_emancipation_options_on_emancipation_category_id.rb
│ │ ├── 20250331033441_remove_duplicate_indexindex_user_languages_on_language_id.rb
│ │ ├── 20250404200715_create_custom_org_links.rb
│ │ ├── 20250507011754_remove_unused_indexes.rb
│ │ ├── 20250528092341_trim_whitespace_from_custom_org_links.rb
│ │ ├── 20250702142004_add_exclude_from_court_report_to_contact_topics.rb
│ │ ├── 20260210233737_rename_casa_cases_emancipaton_options_to_casa_case_emancipaton_options.rb
│ │ ├── 20260211001655_rename_casa_cases_emancipaton_options_to_casa_case_emancipaton_options_follow_up.rb
│ │ └── 20260414132818_add_deleted_at_to_contact_topic_answers.rb
│ ├── schema.rb
│ ├── seeds/
│ │ ├── api_credential_data.rb
│ │ ├── casa_org_populator_presets.rb
│ │ ├── db_populator.rb
│ │ ├── default_contact_topics.yml
│ │ ├── emancipation_data.rb
│ │ ├── emancipation_options_prune.rb
│ │ ├── patch_note_group_data.rb
│ │ ├── patch_note_type_data.rb
│ │ └── placement_data.rb
│ └── seeds.rb
├── doc/
│ ├── API.md
│ ├── CONTRIBUTING.md
│ ├── DOCKER.md
│ ├── LINUX_SETUP.md
│ ├── MAC_SETUP.md
│ ├── NIX_SETUP.md
│ ├── SECURITY.md
│ ├── WSL_SETUP.md
│ ├── architecture-decisions/
│ │ ├── 0001-record-architecture-decisions.md
│ │ ├── 0002-disallow-ui-sign-ups.md
│ │ ├── 0003-multiple-user-tables.md
│ │ ├── 0004-use-bootstrap.md
│ │ ├── 0005-android-app-as-a-pwa.md
│ │ ├── 0006-few-controller-tests.md
│ │ ├── 0007-inline-css-for-email-views.md
│ │ └── 0008-controller-specs.txt
│ ├── casa_db_diagram_patch_notes.kra
│ ├── code-of-conduct.md
│ ├── db_diagram_schema_code/
│ │ ├── part_1.txt
│ │ └── part_2.txt
│ └── productsense.md
├── docker/
│ ├── brakeman
│ ├── build
│ ├── build-assets
│ ├── build-log
│ ├── console
│ ├── nuke
│ ├── nukec
│ ├── run
│ ├── sandbox
│ ├── seed
│ ├── server
│ ├── server-log
│ ├── test
│ └── test-log
├── docker-compose.yml
├── docker-entrypoint.sh
├── flake.nix
├── gemset.nix
├── jest.config.js
├── lib/
│ ├── assets/
│ │ └── .keep
│ ├── ext/
│ │ └── pdf_forms.rb
│ ├── generators/
│ │ └── rails/
│ │ └── policy/
│ │ ├── USAGE
│ │ ├── policy_generator.rb
│ │ └── templates/
│ │ ├── policy.rb.tt
│ │ └── policy_spec.rb.tt
│ ├── mailers/
│ │ ├── debug_preview_mailer.rb
│ │ └── previews/
│ │ ├── casa_admin_mailer_preview.rb
│ │ ├── concerns/
│ │ │ └── mailer_preview.rb
│ │ ├── devise_mailer_preview.rb
│ │ ├── fund_request_mailer_preview.rb
│ │ ├── learning_hours_mailer_preview.rb
│ │ ├── supervisor_mailer_preview.rb
│ │ └── volunteer_mailer_preview.rb
│ └── tasks/
│ ├── auto_annotate_models.rake
│ ├── case_contact_types_reminder.rb
│ ├── check_controller_tests.rake
│ ├── court_report_due_reminder.rake
│ ├── data_post_processors/
│ │ ├── case_contact_populator.rb
│ │ ├── contact_topic_populator.rb
│ │ ├── contact_type_populator.rb
│ │ └── sms_notification_event_populator.rb
│ ├── deployment/
│ │ ├── 20200913155303_populate_missing_display_names.rake
│ │ ├── 20201005203140_populate_contact_type_groups_and_contact_types.rake
│ │ ├── 20201005203405_populate_case_contact_contact_type.rake
│ │ ├── 20201210004047_populate_emancipation_data.rake
│ │ ├── 20201215183231_emancipation_category_options.rake
│ │ ├── 20210415012736_task_name.rake
│ │ ├── 20210507200644_fix_transition_aged_youth_for_nil_birth_month_year_youth.rake
│ │ ├── 20210811052058_update_montgomery_court_report_template.rake
│ │ ├── 20210925143244_populate_slugs_for_orgs_and_cases.rake
│ │ ├── 20220409174149_enable_feature_flag_prince_george_fund_request.rake
│ │ ├── 20220521015108_populate_sms_notification_events.rake
│ │ ├── 20220615020226_create_initial_patch_note_types.rake
│ │ ├── 20220629015841_update_montgomery_court_report_template.rake
│ │ ├── 20220902180609_populate_languages.rake
│ │ ├── 20221003224029_migrate_court_report_due_date_to_court_dates.rake
│ │ ├── 20221009032756_add_medium_type_to_howard_court_report_template.rake
│ │ ├── 20221104005957_create_initial_patch_note_groups.rake
│ │ ├── 20230110000515_update_howard_court_report_template.rake
│ │ ├── 20230114184424_update_howard_court_report_temp2.rake
│ │ ├── 20230114184852_update_howard_court_report_temp3.rake
│ │ ├── 20230208031806_update_howard_court_report_temp4.rake
│ │ ├── 20230409222823_add_confrimation_to_existing_users.rake
│ │ ├── 20230419224330_backfill_user_prefernce_sets.rake
│ │ ├── 20230720000759_update_howard_court_report_fix.rake
│ │ ├── 20231125151610_set_case_contacts_as_active.rake
│ │ ├── 20240416171009_backfill_followup_followupable_id_and_type_from_case_contact_id.rake
│ │ ├── 20240420230126_update_org_templates.rake
│ │ ├── 20240604121427_migrate_notifications.rake
│ │ ├── 20240720232939_backfill_case_contact_started_metadata.rake
│ │ ├── 20250226015042_populate_new_api_and_refresh_token.rake
│ │ └── 99991023145114_store_deploy_time.rake
│ ├── development/
│ │ └── notifications.rake
│ ├── emancipation_checklist_reminder.rake
│ ├── example_recurring_task.rb
│ ├── lint_factory_bot.rake
│ ├── monthly_learning_hours_report.rake
│ ├── no_contact_made_reminder.rb
│ ├── post_gc_stat_to_discord.rake
│ ├── recurring_jobs.rake
│ ├── scheduler.rake
│ ├── send_case_contact_types_reminder.rake
│ ├── send_no_contact_made_reminder.rake
│ ├── send_supervisor_digest.rake
│ ├── supervisor_weekly_digest.rb
│ ├── test_checker.rake
│ ├── volunteer_birthday_reminder.rake
│ └── youth_birthday_reminder.rake
├── log/
│ └── .keep
├── noop
├── package.json
├── postcss.config.js
├── public/
│ ├── 403.html
│ ├── 404.html
│ ├── 406-unsupported-browser.html
│ ├── 422.html
│ ├── 500.html
│ ├── assets/
│ │ ├── css/
│ │ │ ├── lineicons.css
│ │ │ └── main.css
│ │ └── scss/
│ │ ├── _common.scss
│ │ ├── _default.scss
│ │ ├── _mixin.scss
│ │ ├── _sidebar.scss
│ │ ├── _variables.scss
│ │ ├── alerts/
│ │ │ └── _alerts.scss
│ │ ├── auth/
│ │ │ ├── _signin.scss
│ │ │ └── _signup.scss
│ │ ├── buttons/
│ │ │ └── _buttons.scss
│ │ ├── calendar/
│ │ │ └── _calendar.scss
│ │ ├── cards/
│ │ │ └── _cards.scss
│ │ ├── dashboards/
│ │ │ └── _dashboards.scss
│ │ ├── forms/
│ │ │ └── _form-elements.scss
│ │ ├── header/
│ │ │ └── _header.scss
│ │ ├── icons/
│ │ │ └── _icons.scss
│ │ ├── invoice/
│ │ │ └── _invoice.scss
│ │ ├── main.scss
│ │ ├── notification/
│ │ │ └── _notification.scss
│ │ ├── settings/
│ │ │ └── _settings.scss
│ │ ├── tables/
│ │ │ └── _tables.scss
│ │ └── typography/
│ │ └── _typography.scss
│ ├── casa_cases.csv
│ ├── robots.txt
│ ├── sms-terms-conditions.html
│ ├── supervisors.csv
│ └── volunteers.csv
├── scripts/
│ ├── generate_github_issues_for_missing_spec.rb
│ └── import_casa_case_date_of_birth.rb
├── spec/
│ ├── .prosopite_ignore
│ ├── blueprints/
│ │ └── api/
│ │ └── v1/
│ │ └── session_blueprint_spec.rb
│ ├── callbacks/
│ │ └── case_contact_metadata_callback_spec.rb
│ ├── channels/
│ │ └── application_cable/
│ │ ├── channel_spec.rb
│ │ └── connection_spec.rb
│ ├── components/
│ │ ├── badge_component_spec.rb
│ │ ├── dropdown_menu_component_spec.rb
│ │ ├── form/
│ │ │ ├── hour_minute_duration_component_spec.rb
│ │ │ ├── multiple_select/
│ │ │ │ └── item_component_spec.rb
│ │ │ └── multiple_select_component_spec.rb
│ │ ├── local_time_component_spec.rb
│ │ ├── modal/
│ │ │ ├── body_component_spec.rb
│ │ │ ├── footer_component_spec.rb
│ │ │ ├── group_component_spec.rb
│ │ │ ├── header_component_spec.rb
│ │ │ ├── open_button_component_spec.rb
│ │ │ └── open_link_component_spec.rb
│ │ ├── notification_component_spec.rb
│ │ ├── previews/
│ │ │ └── truncated_text_component_preview.rb
│ │ ├── sidebar/
│ │ │ ├── group_component_spec.rb
│ │ │ └── link_component_spec.rb
│ │ └── truncated_text_component_spec.rb
│ ├── config/
│ │ └── initializers/
│ │ └── rack_attack_spec.rb
│ ├── controllers/
│ │ ├── README.md
│ │ ├── application_controller_spec.rb
│ │ ├── concerns/
│ │ │ ├── accessible_spec.rb
│ │ │ ├── court_date_params_spec.rb
│ │ │ ├── loads_case_contacts_spec.rb
│ │ │ ├── organizational_spec.rb
│ │ │ └── users/
│ │ │ └── time_zone_spec.rb
│ │ ├── emancipations_controller_spec.rb
│ │ ├── learning_hours/
│ │ │ └── volunteers_controller_spec.rb
│ │ └── users/
│ │ └── sessions_controller_spec.rb
│ ├── datatables/
│ │ ├── application_datatable_spec.rb
│ │ ├── case_contact_datatable_spec.rb
│ │ ├── reimbursement_datatable_spec.rb
│ │ ├── supervisor_datatable_spec.rb
│ │ └── volunteer_datatable_spec.rb
│ ├── decorators/
│ │ ├── android_app_association_decorator_spec.rb
│ │ ├── application_decorator_spec.rb
│ │ ├── casa_case_decorator_spec.rb
│ │ ├── case_assignment_decorator_spec.rb
│ │ ├── case_contact_decorator_spec.rb
│ │ ├── case_contacts/
│ │ │ └── form_decorator_spec.rb
│ │ ├── contact_type_decorator_spec.rb
│ │ ├── court_date_decorator_spec.rb
│ │ ├── learning_hour_decorator_spec.rb
│ │ ├── learning_hour_topic_decorator_spec.rb
│ │ ├── other_duty_decorator_spec.rb
│ │ ├── patch_note_decorator_spec.rb
│ │ ├── placement_decorator_spec.rb
│ │ ├── user_decorator_spec.rb
│ │ └── volunteer_decorator_spec.rb
│ ├── documents/
│ │ └── templates/
│ │ └── prince_george_report_template_spec.rb
│ ├── factories/
│ │ ├── additional_expenses.rb
│ │ ├── addresses.rb
│ │ ├── all_casa_admins.rb
│ │ ├── api_credential.rb
│ │ ├── banners.rb
│ │ ├── casa_admins.rb
│ │ ├── casa_case_contact_types.rb
│ │ ├── casa_case_emancipation_categories.rb
│ │ ├── casa_case_emancipation_options.rb
│ │ ├── casa_cases.rb
│ │ ├── casa_orgs.rb
│ │ ├── case_assignments.rb
│ │ ├── case_contact_contact_type.rb
│ │ ├── case_contacts.rb
│ │ ├── case_court_orders.rb
│ │ ├── case_court_report_context.rb
│ │ ├── case_group_memberships.rb
│ │ ├── case_groups.rb
│ │ ├── checklist_items.rb
│ │ ├── contact_topic_answers.rb
│ │ ├── contact_topics.rb
│ │ ├── contact_type_group.rb
│ │ ├── contact_types.rb
│ │ ├── court_dates.rb
│ │ ├── custom_org_links.rb
│ │ ├── emancipation_categories.rb
│ │ ├── emancipation_options.rb
│ │ ├── followups.rb
│ │ ├── fund_requests.rb
│ │ ├── healths.rb
│ │ ├── hearing_types.rb
│ │ ├── judges.rb
│ │ ├── languages.rb
│ │ ├── learning_hour_topics.rb
│ │ ├── learning_hour_types.rb
│ │ ├── learning_hours.rb
│ │ ├── login_activities.rb
│ │ ├── mileage_rates.rb
│ │ ├── notes.rb
│ │ ├── notifications.rb
│ │ ├── notifiers.rb
│ │ ├── other_duty.rb
│ │ ├── patch_note_groups.rb
│ │ ├── patch_note_types.rb
│ │ ├── patch_notes.rb
│ │ ├── placement_types.rb
│ │ ├── placements.rb
│ │ ├── preference_sets.rb
│ │ ├── sent_emails.rb
│ │ ├── sms_notification_events.rb
│ │ ├── supervisor_volunteer.rb
│ │ ├── supervisors.rb
│ │ ├── user_languages.rb
│ │ ├── user_reminder_time.rb
│ │ ├── user_sms_notification_events.rb
│ │ ├── users.rb
│ │ └── volunteers.rb
│ ├── fixtures/
│ │ └── files/
│ │ ├── casa_cases.csv
│ │ ├── casa_cases_without_case_number.csv
│ │ ├── default_past_court_date_template.docx
│ │ ├── existing_casa_case.csv
│ │ ├── generic.csv
│ │ ├── no_rows.csv
│ │ ├── sample_report.docx
│ │ ├── supervisor_volunteers.csv
│ │ ├── supervisors.csv
│ │ ├── supervisors_invalid_phone_numbers.csv
│ │ ├── supervisors_without_display_names.csv
│ │ ├── supervisors_without_email.csv
│ │ ├── supervisors_without_phone_numbers.csv
│ │ ├── volunteers.csv
│ │ ├── volunteers_invalid_phone_numbers.csv
│ │ ├── volunteers_without_display_names.csv
│ │ ├── volunteers_without_email.csv
│ │ └── volunteers_without_phone_numbers.csv
│ ├── helpers/
│ │ ├── all_casa_admins/
│ │ │ └── casa_orgs_helper_spec.rb
│ │ ├── api_base_helper_spec.rb
│ │ ├── application_helper_spec.rb
│ │ ├── banner_helper_spec.rb
│ │ ├── case_contacts_helper_spec.rb
│ │ ├── contact_types_helper_spec.rb
│ │ ├── court_dates_helper_spec.rb
│ │ ├── court_orders_helper_spec.rb
│ │ ├── date_helper_spec.rb
│ │ ├── emancipations_helper_spec.rb
│ │ ├── followup_helper_spec.rb
│ │ ├── learning_hours_helper_spec.rb
│ │ ├── mileage_rates_helper_spec.rb
│ │ ├── notifications_helper_spec.rb
│ │ ├── other_duties_helper_spec.rb
│ │ ├── phone_number_helper_spec.rb
│ │ ├── preference_sets_helper_spec.rb
│ │ ├── report_helper_spec.rb
│ │ ├── request_header_helper_spec.rb
│ │ ├── sidebar_helper_spec.rb
│ │ ├── sms_body_helper_spec.rb
│ │ ├── template_helper_spec.rb
│ │ ├── ui_helper_spec.rb
│ │ └── volunteer_helper_spec.rb
│ ├── jobs/
│ │ └── application_job_spec.rb
│ ├── lib/
│ │ ├── importers/
│ │ │ ├── case_importer_spec.rb
│ │ │ ├── file_importer_spec.rb
│ │ │ ├── supervisor_importer_spec.rb
│ │ │ └── volunteer_importer_spec.rb
│ │ └── tasks/
│ │ ├── case_contact_types_reminder_spec.rb
│ │ ├── data_post_processors/
│ │ │ ├── case_contact_populator_spec.rb
│ │ │ ├── contact_topic_populator_spec.rb
│ │ │ └── contact_type_populator_spec.rb
│ │ ├── no_contact_made_reminder_spec.rb
│ │ └── supervisor_weekly_digest_spec.rb
│ ├── mailers/
│ │ ├── application_mailer_spec.rb
│ │ ├── casa_admin_mailer_spec.rb
│ │ ├── fund_request_mailer_spec.rb
│ │ ├── learning_hours_mailer_spec.rb
│ │ ├── previews/
│ │ │ ├── casa_admin_mailer_preview_spec.rb
│ │ │ ├── devise_mailer_preview_spec.rb
│ │ │ ├── supervisor_mailer_preview_spec.rb
│ │ │ └── volunteer_mailer_preview_spec.rb
│ │ ├── supervisor_mailer_spec.rb
│ │ ├── user_mailer_spec.rb
│ │ └── volunteer_mailer_spec.rb
│ ├── models/
│ │ ├── acts_as_paranoid_spec.rb
│ │ ├── additional_expense_spec.rb
│ │ ├── address_spec.rb
│ │ ├── all_casa_admin_spec.rb
│ │ ├── all_casa_admins/
│ │ │ └── casa_org_metrics_spec.rb
│ │ ├── api_credential_spec.rb
│ │ ├── application_record_spec.rb
│ │ ├── banner_spec.rb
│ │ ├── casa_admin_spec.rb
│ │ ├── casa_case_contact_type_spec.rb
│ │ ├── casa_case_emancipation_category_spec.rb
│ │ ├── casa_case_emancipation_option_spec.rb
│ │ ├── casa_case_spec.rb
│ │ ├── casa_org_spec.rb
│ │ ├── case_assignment_spec.rb
│ │ ├── case_contact_contact_type_spec.rb
│ │ ├── case_contact_report_spec.rb
│ │ ├── case_contact_spec.rb
│ │ ├── case_court_order_spec.rb
│ │ ├── case_court_report_context_spec.rb
│ │ ├── case_court_report_spec.rb
│ │ ├── case_group_membership_spec.rb
│ │ ├── case_group_spec.rb
│ │ ├── checklist_item_spec.rb
│ │ ├── concerns/
│ │ │ ├── CasaCase/
│ │ │ │ └── validations_spec.rb
│ │ │ ├── api_spec.rb
│ │ │ ├── by_organization_scope_spec.rb
│ │ │ └── roles_spec.rb
│ │ ├── contact_topic_answer_spec.rb
│ │ ├── contact_topic_spec.rb
│ │ ├── contact_type_group_spec.rb
│ │ ├── contact_type_spec.rb
│ │ ├── court_date_spec.rb
│ │ ├── custom_org_link_spec.rb
│ │ ├── emancipation_category_spec.rb
│ │ ├── emancipation_option_spec.rb
│ │ ├── followup_spec.rb
│ │ ├── fund_request_spec.rb
│ │ ├── health_spec.rb
│ │ ├── hearing_type_spec.rb
│ │ ├── judge_spec.rb
│ │ ├── language_spec.rb
│ │ ├── learning_hour_spec.rb
│ │ ├── learning_hour_topic_spec.rb
│ │ ├── learning_hour_type_spec.rb
│ │ ├── learning_hours_report_spec.rb
│ │ ├── login_activity_spec.rb
│ │ ├── mileage_rate_spec.rb
│ │ ├── mileage_report_spec.rb
│ │ ├── missing_data_report_spec.rb
│ │ ├── note_spec.rb
│ │ ├── other_duty_spec.rb
│ │ ├── patch_note_group_spec.rb
│ │ ├── patch_note_spec.rb
│ │ ├── patch_note_type_spec.rb
│ │ ├── placement_spec.rb
│ │ ├── placement_type_spec.rb
│ │ ├── preference_set_spec.rb
│ │ ├── sent_email_spec.rb
│ │ ├── sms_notification_event_spec.rb
│ │ ├── soft_deleted_model_shared_example_coverage_spec.rb
│ │ ├── supervisor_spec.rb
│ │ ├── supervisor_volunteer_spec.rb
│ │ ├── user_language_spec.rb
│ │ ├── user_reminder_time.rb
│ │ ├── user_sms_notification_event_spec.rb
│ │ ├── user_spec.rb
│ │ └── volunteer_spec.rb
│ ├── notifications/
│ │ ├── base_notifier_spec.rb
│ │ ├── delivery_methods/
│ │ │ └── sms_spec.rb
│ │ ├── emancipation_checklist_reminder_notifier_spec.rb
│ │ ├── followup_notifier_spec.rb
│ │ ├── followup_resolved_notifier_spec.rb
│ │ ├── reimbursement_complete_notifier_spec.rb
│ │ ├── volunteer_birthday_notifier_spec.rb
│ │ └── youth_birthday_notifier_spec.rb
│ ├── policies/
│ │ ├── additional_expense_policy_spec.rb
│ │ ├── application_policy_spec.rb
│ │ ├── bulk_court_date_policy_spec.rb
│ │ ├── casa_admin_policy_spec.rb
│ │ ├── casa_case_policy/
│ │ │ └── scope_spec.rb
│ │ ├── casa_case_policy_spec.rb
│ │ ├── casa_org_policy_spec.rb
│ │ ├── case_assignment_policy_spec.rb
│ │ ├── case_contact_policy_spec.rb
│ │ ├── case_court_order_policy_spec.rb
│ │ ├── case_court_report_policy_spec.rb
│ │ ├── case_group_policy_spec.rb
│ │ ├── checklist_item_policy_spec.rb
│ │ ├── contact_topic_answer_policy_spec.rb
│ │ ├── contact_topic_policy_spec.rb
│ │ ├── contact_type_group_policy_spec.rb
│ │ ├── contact_type_policy_spec.rb
│ │ ├── court_date_policy_spec.rb
│ │ ├── custom_org_link_policy_spec.rb
│ │ ├── dashboard_policy_spec.rb
│ │ ├── followup_policy_spec.rb
│ │ ├── fund_request_policy_spec.rb
│ │ ├── hearing_type_policy_spec.rb
│ │ ├── import_policy_spec.rb
│ │ ├── judge_policy_spec.rb
│ │ ├── language_policy_spec.rb
│ │ ├── learning_hour_policy/
│ │ │ └── scope_spec.rb
│ │ ├── learning_hour_policy_spec.rb
│ │ ├── learning_hour_topic_policy_spec.rb
│ │ ├── learning_hour_type_policy_spec.rb
│ │ ├── nil_class_policy_spec.rb
│ │ ├── note_policy_spec.rb
│ │ ├── notification_policy_spec.rb
│ │ ├── other_duty_policy_spec.rb
│ │ ├── patch_note_policy_spec.rb
│ │ ├── placement_policy_spec.rb
│ │ ├── placement_type_policy_spec.rb
│ │ ├── reimbursement_policy_spec.rb
│ │ ├── supervisor_policy_spec.rb
│ │ ├── supervisor_volunteer_policy_spec.rb
│ │ ├── user_policy/
│ │ │ └── scope_spec.rb
│ │ ├── user_policy_spec.rb
│ │ └── volunteer_policy_spec.rb
│ ├── presenters/
│ │ ├── base_presenter_spec.rb
│ │ └── case_contact_presenter_spec.rb
│ ├── rails_helper.rb
│ ├── requests/
│ │ ├── additional_expenses_spec.rb
│ │ ├── all_casa_admins/
│ │ │ ├── casa_admins_spec.rb
│ │ │ ├── casa_orgs_spec.rb
│ │ │ ├── dashboard_spec.rb
│ │ │ ├── patch_notes_spec.rb
│ │ │ └── sessions_spec.rb
│ │ ├── all_casa_admins_spec.rb
│ │ ├── android_app_associations_spec.rb
│ │ ├── api/
│ │ │ └── v1/
│ │ │ ├── base_spec.rb
│ │ │ └── users/
│ │ │ └── sessions_spec.rb
│ │ ├── banners_spec.rb
│ │ ├── bulk_court_dates_spec.rb
│ │ ├── casa_admins_spec.rb
│ │ ├── casa_cases_spec.rb
│ │ ├── casa_org_spec.rb
│ │ ├── case_assignments_spec.rb
│ │ ├── case_contact_reports_spec.rb
│ │ ├── case_contacts/
│ │ │ ├── case_contacts_new_design_spec.rb
│ │ │ ├── followups_spec.rb
│ │ │ └── form_spec.rb
│ │ ├── case_contacts_spec.rb
│ │ ├── case_court_orders_spec.rb
│ │ ├── case_court_reports_spec.rb
│ │ ├── case_groups_spec.rb
│ │ ├── checklist_items_spec.rb
│ │ ├── contact_topic_answers_spec.rb
│ │ ├── contact_topics_spec.rb
│ │ ├── contact_type_groups_spec.rb
│ │ ├── contact_types_spec.rb
│ │ ├── court_dates_spec.rb
│ │ ├── custom_org_links_spec.rb
│ │ ├── dashboard_spec.rb
│ │ ├── emancipation_checklists_spec.rb
│ │ ├── emancipations_request_spec.rb
│ │ ├── error_spec.rb
│ │ ├── followup_reports_spec.rb
│ │ ├── fund_requests_spec.rb
│ │ ├── health_spec.rb
│ │ ├── hearing_types_spec.rb
│ │ ├── imports_spec.rb
│ │ ├── judges_spec.rb
│ │ ├── languages_spec.rb
│ │ ├── learning_hour_topics_spec.rb
│ │ ├── learning_hour_types_spec.rb
│ │ ├── learning_hours_reports_spec.rb
│ │ ├── learning_hours_spec.rb
│ │ ├── mileage_rates_spec.rb
│ │ ├── mileage_reports_spec.rb
│ │ ├── missing_data_reports_spec.rb
│ │ ├── notes_spec.rb
│ │ ├── notifications_spec.rb
│ │ ├── other_duties_spec.rb
│ │ ├── placement_reports_spec.rb
│ │ ├── placement_types_spec.rb
│ │ ├── placements_spec.rb
│ │ ├── preference_sets_spec.rb
│ │ ├── reimbursements_spec.rb
│ │ ├── reports_spec.rb
│ │ ├── static_spec.rb
│ │ ├── supervisor_volunteers_spec.rb
│ │ ├── supervisors_spec.rb
│ │ ├── users/
│ │ │ ├── invitations_spec.rb
│ │ │ └── passwords_spec.rb
│ │ ├── users_spec.rb
│ │ └── volunteers_spec.rb
│ ├── routing/
│ │ └── all_casa_admins/
│ │ └── patch_notes_routing_spec.rb
│ ├── seeds/
│ │ └── seeds_spec.rb
│ ├── services/
│ │ ├── additional_expense_params_service_spec.rb
│ │ ├── backfill_followupable_service_spec.rb
│ │ ├── casa_case_change_service_spec.rb
│ │ ├── case_contacts_contact_dates_spec.rb
│ │ ├── case_contacts_export_csv_service_spec.rb
│ │ ├── court_report_due_sms_reminder_service_spec.rb
│ │ ├── court_report_format_contact_date_spec.rb
│ │ ├── create_all_casa_admin_service_spec.rb
│ │ ├── create_casa_admin_service_spec.rb
│ │ ├── deployment/
│ │ │ └── backfill_case_contact_started_metadata_service_spec.rb
│ │ ├── emancipation_checklist_download_html_spec.rb
│ │ ├── emancipation_checklist_reminder_service_spec.rb
│ │ ├── failed_import_csv_service_spec.rb
│ │ ├── fdf_inputs_service_spec.rb
│ │ ├── followup_export_csv_service_spec.rb
│ │ ├── followup_service_spec.rb
│ │ ├── inactive_messages_service_spec.rb
│ │ ├── learning_hours_export_csv_service_spec.rb
│ │ ├── mileage_export_csv_service_spec.rb
│ │ ├── missing_data_export_csv_service_spec.rb
│ │ ├── no_contact_made_sms_reminder_service_spec.rb
│ │ ├── placement_export_csv_service_spec.rb
│ │ ├── preference_set_table_state_service_spec.rb
│ │ ├── short_url_service_spec.rb
│ │ ├── sms_reminder_service_spec.rb
│ │ ├── svg_sanitizer_service_spec.rb
│ │ ├── twilio_service_spec.rb
│ │ ├── volunteer_birthday_reminder_service_spec.rb
│ │ └── volunteers_emails_export_csv_service_spec.rb
│ ├── spec_helper.rb
│ ├── support/
│ │ ├── api_helper.rb
│ │ ├── capybara.rb
│ │ ├── case_court_report_helpers.rb
│ │ ├── datatable_helper.rb
│ │ ├── download_helpers.rb
│ │ ├── factory_bot.rb
│ │ ├── fill_in_case_contact_fields.rb
│ │ ├── flipper_helper.rb
│ │ ├── pretender_context.rb
│ │ ├── prosopite.rb
│ │ ├── pundit_helper.rb
│ │ ├── rack_attack.rb
│ │ ├── request_helpers.rb
│ │ ├── rspec_retry.rb
│ │ ├── session_helper.rb
│ │ ├── shared_examples/
│ │ │ ├── shows_court_dates_links.rb
│ │ │ ├── shows_error_for_invalid_phone_numbers.rb
│ │ │ └── soft_deleted_model.rb
│ │ ├── stubbed_requests/
│ │ │ ├── short_io_api.rb
│ │ │ ├── twilio_api.rb
│ │ │ └── webmock_helper.rb
│ │ ├── twilio_helper.rb
│ │ └── user_input_helpers.rb
│ ├── swagger_helper.rb
│ ├── system/
│ │ ├── all_casa_admins/
│ │ │ ├── all_casa_admin_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── password_change_spec.rb
│ │ │ ├── patch_notes/
│ │ │ │ └── index_spec.rb
│ │ │ └── sessions/
│ │ │ └── new_spec.rb
│ │ ├── application/
│ │ │ └── timeout_warning_spec.rb
│ │ ├── banners/
│ │ │ ├── dismiss_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── bulk_court_dates/
│ │ │ └── new_spec.rb
│ │ ├── casa_admins/
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── casa_cases/
│ │ │ ├── additional_index_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── emancipation/
│ │ │ │ └── show_spec.rb
│ │ │ ├── fund_requests/
│ │ │ │ └── new_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ ├── new_spec.rb
│ │ │ ├── show_more_spec.rb
│ │ │ └── show_spec.rb
│ │ ├── casa_org/
│ │ │ └── edit_spec.rb
│ │ ├── case_contacts/
│ │ │ ├── additional_expenses_spec.rb
│ │ │ ├── case_contacts_new_design_spec.rb
│ │ │ ├── contact_topic_answers_spec.rb
│ │ │ ├── drafts_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── followups/
│ │ │ │ ├── create_spec.rb
│ │ │ │ └── resolve_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── case_court_reports/
│ │ │ └── index_spec.rb
│ │ ├── case_groups/
│ │ │ └── case_groups_spec.rb
│ │ ├── checklist_items/
│ │ │ ├── destroy_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── components/
│ │ │ └── truncated_text_component_spec.rb
│ │ ├── contact_types/
│ │ │ ├── edit_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── court_dates/
│ │ │ ├── edit_spec.rb
│ │ │ ├── new_spec.rb
│ │ │ └── view_spec.rb
│ │ ├── dashboard/
│ │ │ └── show_spec.rb
│ │ ├── deep_link/
│ │ │ └── deep_link_spec.rb
│ │ ├── devise/
│ │ │ └── passwords/
│ │ │ └── new_spec.rb
│ │ ├── emancipations/
│ │ │ └── show_spec.rb
│ │ ├── hearing_types/
│ │ │ └── new_spec.rb
│ │ ├── imports/
│ │ │ └── index_spec.rb
│ │ ├── judges/
│ │ │ └── new_spec.rb
│ │ ├── languages/
│ │ │ └── languages_spec.rb
│ │ ├── learning_hours/
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ ├── new_spec.rb
│ │ │ └── volunteers/
│ │ │ └── show_spec.rb
│ │ ├── mileage_rates/
│ │ │ └── mileage_rates_spec.rb
│ │ ├── notifications/
│ │ │ └── index_spec.rb
│ │ ├── other_duties/
│ │ │ └── new_spec.rb
│ │ ├── placements/
│ │ │ ├── destroy_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── reimbursements/
│ │ │ └── reimbursements_spec.rb
│ │ ├── reports/
│ │ │ ├── export_data_spec.rb
│ │ │ └── index_spec.rb
│ │ ├── sessions/
│ │ │ ├── destroy_spec.rb
│ │ │ ├── login_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── static/
│ │ │ └── index_spec.rb
│ │ ├── supervisors/
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── users/
│ │ │ └── edit_spec.rb
│ │ └── volunteers/
│ │ ├── edit_spec.rb
│ │ ├── index_spec.rb
│ │ ├── invite_spec.rb
│ │ ├── new_spec.rb
│ │ └── notes/
│ │ └── edit_spec.rb
│ ├── validators/
│ │ ├── casa_org_validator_spec.rb
│ │ ├── court_report_validator_spec.rb
│ │ ├── url_validator_spec.rb
│ │ └── user_validator_spec.rb
│ ├── values/
│ │ ├── all_casa_admin_parameters_spec.rb
│ │ ├── banner_parameters_spec.rb
│ │ ├── casa_admin_parameters_spec.rb
│ │ ├── case_contact_parameters_spec.rb
│ │ ├── supervisor_parameters_spec.rb
│ │ ├── user_parameters_spec.rb
│ │ └── volunteer_parameters_spec.rb
│ └── views/
│ ├── all_casa_admins/
│ │ ├── casa_orgs/
│ │ │ ├── new.html.erb_spec.rb
│ │ │ └── show.html.erb_spec.rb
│ │ ├── edit.html.erb_spec.rb
│ │ └── patch_notes/
│ │ └── index.html.erb_spec.rb
│ ├── banners/
│ │ └── new.html.erb_spec.rb
│ ├── bulk_court_date/
│ │ └── new.html.erb_spec.rb
│ ├── casa_admins/
│ │ ├── admins_table.html.erb_spec.rb
│ │ └── edit.html.erb_spec.rb
│ ├── casa_cases/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── index.html.erb_spec.rb
│ │ ├── new.html.erb_spec.rb
│ │ └── show.html.erb_spec.rb
│ ├── casa_orgs/
│ │ └── edit.html.erb_spec.rb
│ ├── case_contacts/
│ │ ├── case_contact.html.erb_spec.rb
│ │ └── index.html.erb_spec.rb
│ ├── case_court_reports/
│ │ └── index.html.erb_spec.rb
│ ├── checklist_items/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── court_dates/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── new.html.erb_spec.rb
│ │ └── show.html.erb_spec.rb
│ ├── devise/
│ │ ├── invitations/
│ │ │ ├── edit.html.erb_spec.rb
│ │ │ └── new.html.erb_spec.rb
│ │ └── passwords/
│ │ └── new.html.erb_spec.rb
│ ├── emancipations/
│ │ └── show.html.erb_spec.rb
│ ├── hearing_types/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── judges/
│ │ └── new.html.erb_spec.rb
│ ├── layouts/
│ │ ├── application.html.erb_spec.rb
│ │ ├── footer.html.erb_spec.rb
│ │ ├── header.html.erb_spec.rb
│ │ └── sidebar.html.erb_spec.rb
│ ├── mileage_rates/
│ │ └── index.html.erb_spec.rb
│ ├── notifications/
│ │ └── index.html.erb_spec.rb
│ ├── other_duties/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── placement_types/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── placements/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── index.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── reimbursements/
│ │ └── index.html.erb_spec.rb
│ ├── supervisor_mailer/
│ │ └── weekly_digest.html.erb_spec.rb
│ ├── supervisors/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── index.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── templates/
│ │ └── email_templates_spec.rb
│ └── volunteers/
│ ├── edit.html.erb_spec.rb
│ ├── index.html.erb_spec.rb
│ └── new.html.erb_spec.rb
├── storage/
│ └── .keep
├── swagger/
│ └── v1/
│ └── swagger.yaml
└── vendor/
├── .keep
└── pdftk/
├── bin/
│ └── pdftk
└── lib/
└── libgcj.so.12
================================================
FILE CONTENTS
================================================
================================================
FILE: .allow_skipping_tests
================================================
================================================
FILE: .better-html.yml
================================================
# defaults
================================================
FILE: .browserslistrc
================================================
defaults
================================================
FILE: .devcontainer/Dockerfile
================================================
FROM mcr.microsoft.com/devcontainers/ruby:dev-3.3-bookworm
RUN apt-get update && apt-get install -y vim curl gpg postgresql postgresql-contrib tzdata imagemagick
================================================
FILE: .devcontainer/devcontainer.json
================================================
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/postgres
{
"dockerComposeFile": "docker-compose.yml",
"forwardPorts": [3000, 5432],
"workspaceFolder": "/workspaces/casa",
"service": "app",
"customizations": {
"vscode": {
"extensions": ["Shopify.ruby-extensions-pack"],
"settings": {
"rubyLsp.rubyVersionManager": {
"identifier": "rvm"
}
}
}
},
"containerEnv": {
"DATABASE_HOST": "postgres",
"POSTGRES_USER": "postgres",
"POSTGRES_PASSWORD": "postgres"
},
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "latest"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "24.13.0"
}
},
"postCreateCommand": ".devcontainer/post-create.sh"
}
================================================
FILE: .devcontainer/docker-compose.yml
================================================
version: "3.8"
services:
app:
build:
context: ..
dockerfile: .devcontainer/Dockerfile
volumes:
- ../..:/workspaces:cached
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
networks:
- default
postgres:
image: postgres:latest
restart: always
networks:
- default
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
# Note that these ports are ignored by the devcontainer.
# Instead, the ports are specified in .devcontainer/devcontainer.json.
# ports:
# - "5432:5432"
volumes:
postgres-data:
================================================
FILE: .devcontainer/post-create.sh
================================================
RUBY_VERSION="$(cat .ruby-version | tr -d '\n')"
# copy the file only if it doesn't already exist
cp -n .devcontainer/.env.codespaces .env
# If the project's required ruby version changes from 4.0.2, this command
# will download and compile the correct version, but it will take a long time.
if [ "$RUBY_VERSION" != "4.0.2" ]; then
rvm install $RUBY_VERSION
rvm use $RUBY_VERSION
echo "Ruby $RUBY_VERSION installed"
fi
bin/setup
================================================
FILE: .dockerignore
================================================
/.bundle
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
/storage/*
!/storage/.keep
/public/assets
.byebug_history
/config/master.key
/public/packs
/public/packs-test
/node_modules
/npm-debug.log
/npm-error.log
================================================
FILE: .erb_lint.yml
================================================
EnableDefaultLinters: true
exclude:
- '**/vendor/**/*'
linters:
ErbSafety:
enabled: true
better_html_config: .better-html.yml
Rubocop:
enabled: true
rubocop_config:
Layout/LineLength:
Enabled: false
only:
- Layout/LineLength
================================================
FILE: .github/CODEOWNERS
================================================
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
* @compwron @FireLemons @elasticspoon
/app/javascript/ @schoork @FireLemons @elasticspoon
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [rubyforgood]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: 🪲Bug report
about: 🔨What needs fixing? ✨
title: "Bug: "
labels: ["Type: Bug", "Help Wanted"]
---
## Impacted User Types
- volunteers?
- supervisors?
- admins?
- all casa admins?
## Environment
ex: staging, desktop web, Safari
## Current Behavior
ex: When I click "generate report," no report is generated.
_Please include a screenshot!_
## Expected Behavior
ex: When I click "generate report", a downloadable report should be generated.
## How to Replicate
ex:
1. - Log in as an admin or supervisor.
2. - Click on "Generate Reports" in the left sidebar menu.
3. - Filter by a volunteer who has logged at least one case contact.
4. - Click "Generate report" at the bottom of the page.
## How to access the QA site
_Login Details:_
[Link to QA site](https://casa-qa.herokuapp.com/)
Login Emails:
- volunteer1@example.com view site as a volunteer
- supervisor1@example.com view site as a supervisor
- casa_admin1@example.com view site as an admin
- all_casa_admin1@example.com view site as an all casa admin
- go to `/all_casa_admins/sign_in`
password for all users: 12345678
### Questions? Join Slack!
We highly recommend that you join us in [slack](https:https://join.slack.com/t/rubyforgood/shared_invite/zt-35218k86r-vlIiWqig54c9t~_LkGpQ7Q) #casa channel to ask questions quickly. And [discord](https://discord.gg/qJcw2RZH8Q) for office hours (currently Tuesday 5-7pm Pacific), stakeholder news, and upcoming new issues.
================================================
FILE: .github/ISSUE_TEMPLATE/chore.md
================================================
**Description**
**Existing gem(s), file(s) needing updating, changing or deleting**
**New file(s) needing creating**
### Questions? Join Slack!
We highly recommend that you join us in [slack](https:https://join.slack.com/t/rubyforgood/shared_invite/zt-35218k86r-vlIiWqig54c9t~_LkGpQ7Q) #casa channel to ask questions quickly and hear about office hours (currently Tuesday 5-7pm Pacific), stakeholder news, and upcoming new issues.
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: 📄Documentation addition/change
about: 🔨What needs documenting? ✨
url: https://github.com/rubyforgood/casa/issues/new?template=documentation.md&projects=rubyforgood/casa/1
- name: 🧹Chore
about: 🔨What needs updating or removing? ✨
url: https://github.com/rubyforgood/casa/issues/new?template=chore.md&projects=rubyforgood/casa/1
- name: 🙏Problem Validation
about: 🔨Describe a stakeholder's issue✨
url: https://github.com/rubyforgood/casa/issues/new?template=problem_validation.md&projects=rubyforgood/casa/1
================================================
FILE: .github/ISSUE_TEMPLATE/documentation.md
================================================
**Description**
**Existing file(s) needing changing**
**New file(s) needing creating**
### Questions? Join Slack!
We highly recommend that you join us in [slack](https:https://join.slack.com/t/rubyforgood/shared_invite/zt-35218k86r-vlIiWqig54c9t~_LkGpQ7Q) #casa channel to ask questions quickly and hear about office hours (currently Tuesday 5-7pm Pacific), stakeholder news, and upcoming new issues.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: 💡Feature request
about: 🔨What needs building? ✨
labels: ["✨ New Feature", "Help Wanted"]
---
## What type(s) of user does this feature affect?
- volunteers?
- supervisors?
- admins?
- all casa admins?
## Description
## Screenshots of current behavior, if any
You can paste images on the clipboard here
## How to access the QA site
_Login Details:_
[Link to QA site](https://casa-qa.herokuapp.com/)
Login Emails:
- volunteer1@example.com view site as a volunteer
- supervisor1@example.com view site as a supervisor
- casa_admin1@example.com view site as an admin
- all_casa_admin1@example.com view site as an all casa admin
- go to `/all_casa_admins/sign_in`
password for all users: 12345678
### Questions? Join Slack!
We highly recommend that you join us in [slack](https:https://join.slack.com/t/rubyforgood/shared_invite/zt-35218k86r-vlIiWqig54c9t~_LkGpQ7Q) #casa channel to ask questions quickly. And [discord](https://discord.gg/qJcw2RZH8Q) for office hours (currently Tuesday 5-7pm Pacific), stakeholder news, and upcoming new issues.
================================================
FILE: .github/ISSUE_TEMPLATE/flaky_test.md
================================================
---
name: Flaky Test
about: one of the tests is inconsistent and likely producing false positives
title: "Bug: Flaky Test"
labels: ["Type: Bug", "Help Wanted"]
---
Flaky tests are defined as tests that return both passes and failures despite no changes to the code or the test itself
Fix the test so it runs consistently.
### CI Workflow
rspec or rspec in docker?
### Sample Error Output:
```
```
### Questions? Join Slack!
We highly recommend that you join us in [slack](https:https://join.slack.com/t/rubyforgood/shared_invite/zt-35218k86r-vlIiWqig54c9t~_LkGpQ7Q) #casa channel to ask questions quickly and hear about office hours (currently Tuesday 5-7pm Pacific), stakeholder news, and upcoming new issues.
================================================
FILE: .github/ISSUE_TEMPLATE/problem_validation.md
================================================
Please use this template to document problems mentioned by CASA stakeholders so we make the best decisions for the solution.
**Which role has this problem (AllCasaAdmin, CasaAdmin, Supervisor, Volunteer)?**
**What is the problem they are facing? (short description)**
**When does the problem happen? At what moment in the workflow or after how long?**
**Attach a design mockup if possible**
### Questions? Join Slack!
We highly recommend that you join us in [slack](https:https://join.slack.com/t/rubyforgood/shared_invite/zt-35218k86r-vlIiWqig54c9t~_LkGpQ7Q) #casa channel to ask questions quickly and hear about office hours (currently Tuesday 5-7pm Pacific), stakeholder news, and upcoming new issues.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
### What github issue is this PR for, if any?
Resolves #XXXX
### What changed, and _why_?
### How is this **tested**? (please write rspec and jest tests!) 💖💪
_Note: if you see a flake in your test build in github actions, please post in slack #casa "Flaky test: <link to failed build>" :) 💪_
_Note: We love [capybara](https://rubydoc.info/github/teamcapybara/capybara) tests! If you are writing both haml/js and ruby, please try to test your work with tests at every level including system tests like https://github.com/rubyforgood/casa/tree/main/spec/system_
### Screenshots please :)
_Run your local server and take a screenshot of your work! Try to include the URL of the page as well as the contents of the page._
### Feelings gif (optional)
_What gif best describes your feeling working on this issue? https://giphy.com/
How to embed:_
``
================================================
FILE: .github/autoapproval.yml
================================================
from_owner:
- dependabot-preview
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# Basic set up for three package managers
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
ignore:
# Keep this locked to 1.77.6 until
# bootstrap 5.3.4 is out to silence
# sass deprecation warnings
# https://getbootstrap.com/docs/versions/
- dependency-name: "sass"
versions: ["1.77.*", "1.78.*"]
- package-ecosystem: "bundler"
directory: "/"
schedule:
interval: "weekly"
================================================
FILE: .github/instructions/copilot-review.instructions.md
================================================
---
applyTo: "**"
---
# CASA Code Review Instructions
You are reviewing pull requests for CASA (Court Appointed Special Advocates), a Ruby on Rails application that helps CASA volunteers track their work with youth in foster care. This is an open-source project maintained by Ruby for Good with contributors of all experience levels. Be constructive and kind.
## Tech Stack
- **Backend**: Rails 7.2, Ruby 3.x, PostgreSQL
- **Frontend**: Stimulus (Hotwire) + Turbo, Bootstrap 5, ESBuild
- **Auth**: Devise + Devise-Invitable (no UI sign-ups; admin invitation only)
- **Authorization**: Pundit (policy-based)
- **Background Jobs**: Delayed Job
- **Feature Flags**: Flipper
- **Testing**: RSpec + Capybara (Ruby), Jest (JavaScript)
- **Linting**: Standard.rb (Ruby), StandardJS (JavaScript), erb-lint (ERB)
- **View Layer**: ERB templates, ViewComponent, Draper decorators
## Architecture Rules
### Authorization & Multi-Tenancy
- All controller actions must be authorized via Pundit (`authorize` / `policy_scope`).
- Data must be scoped to the current user's `casa_org`. Never allow cross-organization data access.
- User roles: `AllCasaAdmin`, `CasaAdmin`, `Supervisor`, `Volunteer`. Each has a separate model (not STI).
- Permission changes must include or update the corresponding Pundit policy file in `app/policies/`.
### Controllers
- Controllers should be thin. Complex logic belongs in service objects or models.
- Controllers must call `authorize` and typically use `after_action :verify_authorized`.
- Use `policy_scope` for index actions to scope records to the current org/user.
### Models
- Models use `include ByOrganizationScope` for org-scoped queries where applicable.
- Prefer scopes over class methods for query logic.
- Soft deletes via the Paranoia gem: `destroy` marks records deleted, does not hard-delete.
- Use Strong Migrations: flag any unsafe migration operations (e.g., removing a column without `safety_assured`, adding an index without `algorithm: :concurrently`).
### Views & Frontend
- Use ERB (not HAML). Complex view logic should live in a Draper decorator (`app/decorators/`), not in the template.
- Use ViewComponent (`app/components/`) for reusable UI elements.
- Style with Bootstrap 5 utility classes and existing project SCSS. UI changes should match the rest of the site.
- JavaScript should use Stimulus controllers. Avoid inline `<script>` tags or jQuery for new code.
- Email views require inline CSS (email client compatibility — see ADR 0007).
### Services & Decorators
- Service objects live in `app/services/` and follow the pattern: `ServiceName.new(args).perform`.
- Decorators live in `app/decorators/` and handle presentation logic that doesn't belong in models or views.
## Review Checklist
### Security
- [ ] No mass-assignment vulnerabilities: strong parameters used for all user input.
- [ ] No raw SQL interpolation — use parameterized queries or ActiveRecord methods.
- [ ] No `html_safe` or `raw` on user-supplied content (XSS risk).
- [ ] Pundit authorization is present on all controller actions.
- [ ] Data is scoped to the user's organization — no cross-tenant leaks.
- [ ] File uploads validated (type, size) before storage.
- [ ] Secrets and credentials are not committed.
### Testing
- [ ] New features have tests. Bug fixes include a test that would fail without the fix.
- [ ] System tests (Capybara) are preferred for UI changes over controller tests (see ADR 0006).
- [ ] Factories use traits for scenario variations (e.g., `create(:casa_case, :active)`).
- [ ] Tests cover edge cases: nil/empty values, missing optional fields, special characters.
- [ ] No `sleep` calls in tests — use Capybara's built-in waiting/retry mechanisms.
- [ ] Flaky tests are disabled with a tracking issue, not deleted.
### Code Quality
- [ ] Follows Standard.rb style (Ruby) and StandardJS style (JavaScript).
- [ ] No N+1 queries introduced — use `includes`, `preload`, or `eager_load` as needed.
- [ ] ActiveRecord collections iterated with `find_each` instead of `each` for large sets.
- [ ] Multi-record writes wrapped in `ActiveRecord::Base.transaction`.
- [ ] No business logic in controllers or views — delegate to models, services, or decorators.
- [ ] Dead code and unused variables removed.
### Pull Request Quality
- [ ] PR references a GitHub issue (`Resolves #XXXX`).
- [ ] Small, focused diff. Multiple small PRs preferred over one large PR.
- [ ] Migrations are reversible and safe (no data loss, follows Strong Migrations).
- [ ] No unrelated formatting changes that inflate the diff.
## What to Flag
- **Authorization gaps**: Any controller action missing `authorize` or `policy_scope`.
- **Cross-org data access**: Queries that don't scope to `casa_org`.
- **Missing tests**: New behavior without corresponding test coverage.
- **N+1 queries**: Loading associations inside loops without eager loading.
- **Unsafe migrations**: Column removals, type changes, or index additions without safety guards.
- **XSS vectors**: `html_safe`, `raw`, or `sanitize` misuse on user content.
- **Large PRs**: Suggest splitting if the diff touches many unrelated areas.
## What NOT to Flag
- Older migration files (2020–2024) — these are excluded from linting intentionally.
- Minor style issues already handled by Standard.rb or StandardJS linters.
- Lack of TypeScript — this project uses plain JavaScript with Stimulus.
- jQuery usage in existing code — new code should use Stimulus, but don't flag legacy jQuery.
## Tone
This is a volunteer-driven open-source project. Contributors range from first-time open source contributors to experienced Rails developers. Be encouraging, explain the "why" behind suggestions, and link to relevant docs or examples in the codebase when possible. Avoid nitpicks on subjective style — trust the linters for formatting.
================================================
FILE: .github/instructions/ruby.instructions.md
================================================
---
applyTo: "**/*.rb"
---
# Ruby / Rails Review Instructions
## Authorization (Pundit)
Every controller action that reads or writes data must be authorized.
```ruby
# Required pattern
def index
authorize Model
@records = policy_scope(current_organization.models)
end
def show
authorize @record
end
```
- Controllers must include `after_action :verify_authorized` (with exceptions listed in `except:`).
- Index actions must use `policy_scope` to scope records to the current organization.
- Custom policy methods are called with `authorize @record, :custom_action?`.
- Policy files live in `app/policies/`. Permission changes must update the corresponding policy.
- Policies define `permitted_attributes` that return role-based field lists — check that new fields are added there when models gain attributes.
Flag: any controller action missing `authorize` or `policy_scope`.
## Multi-Tenancy
All data access must be scoped to the user's `casa_org`.
- Models include `ByOrganizationScope` which provides `.by_organization(casa_org)`.
- Policy scopes must filter by organization: `scope.by_organization(user.casa_org)`.
- `current_organization` (from the `Organizational` concern) returns the signed-in user's org.
Flag: queries that could return records from another organization.
## Controllers
- Keep controllers thin. Business logic belongs in models or service objects (`app/services/`).
- Complex view logic belongs in Draper decorators (`app/decorators/`), not controllers or ERB.
- Use parameter objects (`app/values/`) for strong params when the logic is non-trivial. They follow a builder pattern: `FooParameters.new(params).with_password(pw).without_active`.
- Standard flash pattern:
```ruby
if @record.save
redirect_to path, notice: "Record created successfully."
else
render :new, status: :unprocessable_content
end
```
- Use `respond_to` blocks when supporting multiple formats (HTML, JSON, CSV).
- Set up models with `before_action :set_model` and list exceptions in `except:`.
## Models
- Prefer scopes over class methods for query logic.
- Scope naming: descriptive, chainable (`.active`, `.by_organization`, `.with_assigned_cases`).
- Use `find_each` (not `each`) when iterating over ActiveRecord collections.
- Wrap multi-record writes in `ActiveRecord::Base.transaction`.
- Enums use the prefix syntax: `enum :status, {active: 0, inactive: 1}, prefix: :status`.
- Soft deletes via Paranoia — `destroy` marks as deleted, does not hard-delete.
- Extract complex validations into concern modules (e.g., `CasaCase::Validations`).
- Associations with conditions use lambdas:
```ruby
has_many :active_assignments, -> { active }, class_name: "CaseAssignment"
```
- `accepts_nested_attributes_for` with `reject_if` guards for blank entries.
## Services
Service objects follow a consistent pattern:
```ruby
class MyService
def initialize(args)
@args = args
end
def perform
# single responsibility logic
end
end
```
Called as `MyService.new(args).perform`. Services should preload associations to avoid N+1 queries.
## Decorators
- Draper decorators in `app/decorators/` handle presentation logic.
- Access view helpers via `h.helper_method` inside decorators.
- Called via `.decorate` on model instances or collections.
Flag: presentation logic (formatting dates, conditional display text) in models or controllers.
## Concerns
- Use `extend ActiveSupport::Concern` for shared behavior.
- `included do ... end` block for validations, scopes, callbacks.
- Place model concerns in `app/models/concerns/`, controller concerns in `app/controllers/concerns/`.
## Migrations
- Must be reversible.
- Use Strong Migrations: flag unsafe operations (removing columns without `safety_assured`, adding indexes without `algorithm: :concurrently` on large tables, changing column types).
- New columns with NOT NULL constraints need a default value or a multi-step migration.
## Common Anti-Patterns to Flag
- **N+1 queries**: Loading associations inside loops without `includes`, `preload`, or `eager_load`.
- **Cross-org data leaks**: Queries missing organization scope.
- **Business logic in views**: ERB files with complex conditionals or calculations — should be in a decorator.
- **Fat controllers**: More than a few lines of logic — extract to a service or model method.
- **Raw SQL interpolation**: Use parameterized queries or ActiveRecord methods.
- **`html_safe` / `raw` on user input**: XSS risk.
- **Missing authorization**: Controller actions without `authorize`.
- **`.each` on AR collections**: Use `find_each` for batch processing.
- **Unscoped `destroy`**: Verify soft-delete behavior is intended; Paranoia intercepts `destroy`.
## Testing (RSpec)
- System tests (Capybara) are preferred for UI flows over controller tests.
- Model tests use shoulda-matchers for associations and validations:
```ruby
it { is_expected.to have_many(:case_assignments).dependent(:destroy) }
it { is_expected.to validate_uniqueness_of(:case_number).scoped_to(:casa_org_id) }
```
- Use `build` for unit tests, `create` only when persistence is needed.
- Use `let` for lazy evaluation, `let!` when the record must exist before the test runs.
- Factory traits for scenario variations: `create(:casa_case, :active)`.
- Context blocks describe the scenario: `context "when the user is a supervisor"`.
- Test edge cases: nil values, empty strings, special characters, missing optional fields.
- No `sleep` in tests — use Capybara's built-in waiting.
- Flaky tests are disabled with a tracking issue (`xit` + comment), never deleted.
## Style
This project uses Standard.rb (not vanilla RuboCop). Do not flag style issues that Standard.rb handles automatically (spacing, string quotes, trailing commas). Focus review on logic, security, and architecture.
================================================
FILE: .github/labeler.yml
================================================
# Configuration for the Labeler action
# The action is set up in ./workflows/label.yml
# See https://github.com/actions/labeler for more details
#
# Warning - Testing changes to this file can be tricky
# At the time of writing, you need to have changes committed to master for the
# Action to use them. This isn't ideal for rapid iteration. If you want to make
# changes to this file and experiment with changes, please consider testing the
# changes in a fork of this repo first. This allows you to add changes to
# master as needed and also create multiple Pull Requests to confirm labels are
# properly added.
ruby:
- changed-files:
- any-glob-to-any-file: "**/*.rb"
erb:
- changed-files:
- any-glob-to-any-file: "**/*.erb"
javascript:
- changed-files:
- any-glob-to-any-file: ["**/*.js", "package*.json", "package-lock.json"]
Tests! 🎉💖👏:
- changed-files:
- any-glob-to-any-file: ["app/javascript/__tests__/**.test.js", "spec/**/*_spec.rb"]
dependencies:
- changed-files:
- any-glob-to-any-file: ["Gemfile*", "package*.json", "package-lock.json"]
================================================
FILE: .github/workflows/add-labels-based-on-column.yml
================================================
on:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 * * * *'
workflow_dispatch: # Enable manual runs of the bot
jobs:
add_help_wanted_labels:
runs-on: ubuntu-latest
name: Add help wanted labels
steps:
- name: Add help wanted labels
uses: rubyforgood/add-label-to-cards@v3.3
id: add-help-wanted-labels
with:
columns_labels: >
[
{
"column_name": "Not ready to build",
"labels": ["not-ready-to-build"],
"project_name": "CASA Volunteer Portal"
},
{
"column_name": "To do",
"labels": ["Help Wanted"],
"project_name": "CASA Volunteer Portal"
},
{
"column_name": "To do",
"labels": ["Stakeholder-Feature"],
"project_name": "Stakeholder Requested Features"
},
{
"column_name": "In progress",
"labels": ["Stakeholder-Feature"],
"project_name": "Stakeholder Requested Features"
},
{
"column_name": "Done",
"labels": ["Stakeholder-Feature"],
"project_name": "Stakeholder Requested Features"
}
]
token: ${{secrets.GITHUB_TOKEN}}
================================================
FILE: .github/workflows/after-deploy.yml
================================================
on:
schedule:
- cron: '0 7 * * *' # Run every day at 7AM UTC
workflow_dispatch: # Enable Manual Runs
jobs:
on_deploy:
runs-on: ubuntu-latest
name: On Deploy
steps:
- name: After Deploy
uses: Firelemons/on-deploy@v2.2.1
with:
project_name: "CASA Volunteer Portal"
done_column_card_limit: "16"
done_column_name: "Done (in prod!)"
QA_column_name: "Merged to QA"
token: ${{secrets.GITHUB_TOKEN}}
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: CodeQL
on:
push:
branches:
- main
paths-ignore:
- 'doc/**'
- '**/*.md'
pull_request:
# The branches below must be a subset of the branches above
branches:
- main
- rfg-event-2025
paths-ignore:
- 'doc/**'
- '**/*.md'
schedule:
- cron: '36 22 * * 3'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: ['javascript']
# CodeQL supports ['cpp', 'csharp', 'go', 'java', 'javascript', 'python']
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
================================================
FILE: .github/workflows/combine_and_report.yml
================================================
on:
workflow_call:
jobs:
combine_and_report:
runs-on: ubuntu-latest
env:
AZURE_STORAGE_KEY: ${{ secrets.STORAGE_ACCESS_KEY }}
AZURE_STORAGE_ACCOUNT: ${{ secrets.ACCOUNT_NAME }}
STORAGE_CONTAINER: ${{ secrets.STORAGE_CONTAINER }}
steps:
- name: Checkout Project
if: ${{ !cancelled() }}
uses: actions/checkout@v6
- name: Download artifacts
if: ${{ !cancelled() }}
uses: actions/download-artifact@v8
with:
path: artifacts
- name: Decompress chunk test reports
if: ${{ !cancelled() }}
run: |
find artifacts -name "test_reports*.zip" -exec unzip -d test_reports {} \;
find test_reports -name "**/test_reports*.zip" -exec unzip -d test_reports {} \;
- name: Merge parallel runtime log parts
if: ${{ !cancelled() && env.AZURE_STORAGE_KEY != '' }}
run: |
cat artifacts/**/parallel_runtime_rspec*.log > parallel_runtime.log
- name: Upload log file to Azure Blob Storage
if: ${{ !cancelled() && env.AZURE_STORAGE_KEY != '' }}
run: |
az storage blob upload \
-c $STORAGE_CONTAINER \
--file parallel_runtime.log \
-n parallel_runtime.log \
--overwrite true
- name: Test Summary
id: test_summary
uses: test-summary/action@v2
with:
paths: |
test_reports/**/rspec*.xml
- name: Set job status
if: ${{ steps.test_summary.outputs.failed > 0 }}
uses: actions/github-script@v9
with:
script: |
core.setFailed('There are test failures')
================================================
FILE: .github/workflows/docker.yml
================================================
name: docker
on:
push:
branches:
- main
paths-ignore:
- "doc/**"
- "**/*.md"
pull_request:
branches:
- main
- rfg-event-2025
paths-ignore:
- "doc/**"
- "**/*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
docker:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
RAILS_ENV: test
TEST_MAX_DURATION: 60
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Create downloads folder
run: |
mkdir -p tmp/downloads
chmod 777 tmp tmp/downloads
- name: docker UP
run: docker compose up -d
- name: db:setup
run: docker compose exec -T web rails db:setup
- name: compile assets
run: docker compose exec -T web bundle exec rails assets:precompile
- name: Test
run: docker compose exec -T web bundle exec rspec spec --fail-fast
- name: Archive selenium screenshots
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: selenium-screenshots
path: |
${{ github.workspace }}/tmp/capybara/*.png
${{ github.workspace }}/tmp/capybara/*.html
================================================
FILE: .github/workflows/erb_lint.yml
================================================
name: ERB lint
on:
push:
branches:
- main
paths:
- '**/*.erb'
- '**/*.html'
pull_request:
branches:
- main
- rfg-event-2025
paths:
- '**/*.erb'
- '**/*.html'
jobs:
erb_lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: ERB lint
run: bundle exec erb_lint --lint-all
================================================
FILE: .github/workflows/factory_bot_lint.yml
================================================
name: factory bot lint
on:
push:
branches:
- main
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
pull_request:
branches:
- main
- rfg-event-2025
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
jobs:
lint:
runs-on: ubuntu-latest
services:
db:
image: postgres:12.3
env:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install PostgreSQL client
run: |
sudo apt-get -yqq install libpq-dev
- name: factory_bot:lint
env:
POSTGRES_HOST: localhost
DATABASE_HOST: localhost
POSTGRES_USER: postgres
CASA_DATABASE_PASSWORD: password
POSTGRES_PASSWORD: password
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_PORT: 5432
PGHOST: localhost
PGUSER: postgres
RAILS_ENV: test
run: |
bundle exec rake db:create
bundle exec rake db:schema:load
bundle exec rake factory_bot:lint
================================================
FILE: .github/workflows/issue-auto-close-done.yml
================================================
name: 'Close issue when Done'
on:
project_card:
types: [moved]
jobs:
set-state:
runs-on: ubuntu-latest
steps:
- uses: dessant/issue-states@v3
with:
github-token: ${{secrets.GITHUB_TOKEN}}
open-issue-columns: ''
closed-issue-columns: 'Done'
================================================
FILE: .github/workflows/issue-auto-unassign.yml
================================================
on:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 0 * * *'
workflow_dispatch: # Enable manual runs of the bot
jobs:
unassign_issues:
runs-on: ubuntu-latest
name: Unassign issues
steps:
- name: Unassign issues
uses: rubyforgood/unassign-issues@v1.3
id: unassign_issues
with:
token: ${{secrets.GITHUB_TOKEN}}
unassign_inactive_in_hours: 360 # 15 days
warning_inactive_in_hours: 240 # 10 days
office_hours: 'Tuesdays 6-8 PM PST'
warning_inactive_message: 'If you are still working on this, comment here to tell the bot to give you more time'
- name: Print the unassigned issues
run: echo "Unassigned issues = ${{steps.unassign_issues.outputs.unassigned_issues}}"
- name: Print the warned issues
run: echo "Warned issues = ${{steps.unassign_issues.outputs.warned_issues}}"
- name: Move unassigned issues from In Progress to To Do
uses: bjthompson805/move-issues@v1
id: move_issues
with:
token: ${{secrets.GITHUB_TOKEN}}
issues: ${{steps.unassign_issues.outputs.unassigned_issues}}
from_column: '8461148'
to_column: '15690587'
- name: Print moved issues
run: echo "Moved issues = ${{steps.move_issues.outputs.moved_issues}}"
================================================
FILE: .github/workflows/label.yml
================================================
# This workflow will triage pull requests and apply a label based on the
# paths that are modified in the pull request.
#
# See ../labeler.yml for mapping of files and labels
# See https://github.com/actions/labeler for more details on the action
name: filetype labeler
on:
- pull_request_target
jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
================================================
FILE: .github/workflows/npm_lint_and_test.yml
================================================
name: npm lint
on:
push:
branches:
- main
paths:
- '**/*.js'
- '**/*.json'
- '**/*.jsx'
- 'package.lock.json'
- '.github/workflows/*.yml'
pull_request:
branches:
- main
- rfg-event-2025
paths:
- '**/*.js'
- '**/*.json'
- '**/*.jsx'
- 'package.lock.json'
- '.github/workflows/*.yml'
jobs:
npm_lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
- run: npm ci
- run: npm run lint
- run: npm run test
================================================
FILE: .github/workflows/rake-after_party.yml
================================================
name: Run rake after_party
on:
push:
branches:
- main
paths-ignore:
- "doc/**"
- "**/*.md"
- "bin/**"
pull_request:
branches:
- main
- rfg-event-2025
paths-ignore:
- "doc/**"
- "**/*.md"
- "bin/**"
jobs:
rake-after_party:
runs-on: ubuntu-latest
services:
db:
image: postgres:12.3
env:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Install PostgreSQL client
run: |
sudo apt-get -yqq install libpq-dev
- name: Build App and run rake after_party
env:
POSTGRES_HOST: localhost
DATABASE_HOST: localhost
POSTGRES_USER: postgres
CASA_DATABASE_PASSWORD: password
POSTGRES_PASSWORD: password
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_PORT: 5432
PGHOST: localhost
PGUSER: postgres
RAILS_ENV: test
run: |
bundle exec rake db:create
bundle exec rake db:schema:load
bundle exec rake after_party:run
================================================
FILE: .github/workflows/remove-helped-wanted.yml
================================================
name: Remove Help Wanted Label on Issue Assignment
on:
issues:
types: [assigned]
jobs:
automate-issues-labels:
runs-on: ubuntu-latest
steps:
- uses: andymckay/labeler@master
with:
remove-labels: "Help Wanted"
================================================
FILE: .github/workflows/remove-label-based-on-column.yml
================================================
on:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 * * * *'
workflow_dispatch: # Enable manual runs of the bot
jobs:
remove_help_wanted_labels:
runs-on: ubuntu-latest
name: Remove help wanted labels based on column
steps:
- name: Remove help wanted labels based on column
uses: rubyforgood/remove-label-from-cards@2.0
id: remove-help-wanted-labels
with:
token: ${{secrets.GITHUB_TOKEN}}
columns_labels: >
[
{
"column_name": "Done (in prod!)",
"labels": ["Help Wanted"],
"project_name": "CASA Volunteer Portal"
},
{
"column_id": "47fc9ee4",
"labels": ["Help Wanted"]
},
{
"column_name": "Merged to QA",
"labels": ["Help Wanted"],
"project_name": "CASA Volunteer Portal"
},
{
"column_name": "Not ready to build",
"labels": ["Help Wanted"],
"project_name": "CASA Volunteer Portal"
},
{
"column_name": "Requires Design / Issues To Be",
"labels": ["Help Wanted"],
"project_name": "CASA Volunteer Portal"
}
]
================================================
FILE: .github/workflows/rspec.yml
================================================
name: rspec
on:
push:
branches:
- main
paths-ignore:
- "doc/**"
- "**/*.md"
pull_request:
branches:
- main
- rfg-event-2025
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
rspec:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
RAILS_ENV: test
TEST_MAX_DURATION: 60
services:
db:
image: postgres:14.8
env:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Set up JS
uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: "npm"
- run: npm ci
- name: Install PostgreSQL client
run: |
sudo apt-get -yqq install libpq-dev
- name: Build App
env:
POSTGRES_HOST: localhost
DATABASE_HOST: localhost
POSTGRES_USER: postgres
CASA_DATABASE_PASSWORD: password
POSTGRES_PASSWORD: password
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_PORT: 5432
run: |
bundle exec rake db:create
bundle exec rake db:schema:load
bundle exec rails assets:precompile
- name: Run rspec
env:
DATABASE_HOST: localhost
POSTGRES_USER: postgres
CASA_DATABASE_PASSWORD: password
POSTGRES_HOST_AUTH_METHOD: trust
RUN_SIMPLECOV: true
run: |
RUBYOPT='-W:no-deprecated -W:no-experimental' bundle exec rspec
- uses: qltysh/qlty-action/coverage@v2
with:
token: ${{ secrets.QLTY_COVERAGE_TOKEN }}
files: coverage/.resultset.json
- name: Archive selenium screenshots
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: selenium-screenshots
path: |
${{ github.workspace }}/tmp/capybara/*.png
${{ github.workspace }}/tmp/capybara/*.html
================================================
FILE: .github/workflows/ruby_lint.yml
================================================
name: standardrb lint
on:
push:
branches:
- main
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
pull_request:
branches:
- main
- rfg-event-2025
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
jobs:
ruby_lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: lint
run: bundle exec standardrb
================================================
FILE: .github/workflows/security.yml
================================================
name: brakeman
on:
push:
branches:
- main
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
pull_request:
branches:
- main
- rfg-event-2025
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
jobs:
brakeman:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: brakeman
run: bundle exec brakeman
================================================
FILE: .github/workflows/spec_checker.yml
================================================
name: spec checker
on:
push:
branches:
- main
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
pull_request:
branches:
- main
- rfg-event-2025
paths-ignore:
- 'doc/**'
- '**/*.md'
- 'bin/**'
jobs:
spec_checker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: rake test_checker
run: bundle exec rake test_checker
================================================
FILE: .github/workflows/stale.yml
================================================
name: Mark stale issues and pull requests
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "This issue has been open without changes for a long time! What's up?"
stale-pr-message: "This PR has been open for a long time without any pushes or comments! What's up?"
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
days-before-issue-close: 9999 # don't do it
days-before-pr-close: 30
================================================
FILE: .github/workflows/toc.yml
================================================
on:
push:
branches:
- main
name: TOC Generator
jobs:
generateTOC:
name: TOC Generator
runs-on: ubuntu-latest
steps:
- uses: technote-space/toc-generator@v4
with:
CREATE_PR: true
================================================
FILE: .github/workflows/yaml_lint.yml
================================================
name: Yaml Lint
on:
push:
branches:
- main
paths-ignore:
- 'doc/**'
- '**/*.md'
pull_request:
# The branches below must be a subset of the branches above
branches:
- main
paths-ignore:
- 'doc/**'
- '**/*.md'
jobs:
lintAllTheThings:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: yaml-lint
uses: ibiqlik/action-yamllint@v3
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'
# Ignore bundler config.
/.bundle
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
.DS_Store
.env
# Ignore uploaded files in development.
/storage/*
!/storage/.keep
.byebug_history
# Ignore master key for decrypting credentials and more.
/config/master.key
/config/credentials/production.key
/config/credentials.yml.enc
# intellij IDE
*.iml
/public/packs
/public/packs-test
/node_modules
/yarn-error.log
yarn-debug.log*
.yarn-integrity
.rails_routes*
.vscode
coverage/
.idea/
vendor/bundle/
.generators
# produced by tests (?)
.rakeTasks
.*.swp
# Used for local developmen on Nix systems
.direnv/
.envrc
default.nix
npm-debug.log
# Ignore compiled assets
/app/assets/builds/*
# In case we want to keep something in the compiled assets directory
!/app/assets/builds/.keep
.aider*
================================================
FILE: .npmrc
================================================
engine-strict=true
================================================
FILE: .nvmrc
================================================
lts/krypton
================================================
FILE: .prettierrc.yml
================================================
printWidth: 100
================================================
FILE: .rspec
================================================
--require spec_helper
================================================
FILE: .rspec_parallel
================================================
--format RspecJunitFormatter --out tmp/reports/rspec_<%= ENV["GROUPS_UNDERSCORE"] %>_<%= ENV["TEST_ENV_NUMBER"] %>.xml
--format ParallelTests::RSpec::SummaryLogger
--format ParallelTests::RSpec::RuntimeLogger --out tmp/parallel_runtime.log
--format ParallelTests::RSpec::FailuresLogger --out tmp/failing_specs.log
================================================
FILE: .rubocop.yml
================================================
require:
- standard
plugins:
- rubocop-capybara
- rubocop-factory_bot
- rubocop-rspec
- rubocop-rspec_rails
inherit_gem:
pundit: config/rubocop-rspec.yml
================================================
FILE: .ruby-gemset
================================================
casa
================================================
FILE: .ruby-version
================================================
4.0.2
================================================
FILE: .slugignore
================================================
*.md
/docs
/spec
================================================
FILE: .standard.yml
================================================
extend_config:
- .rubocop.yml
plugins:
- standard-rails
ignore:
- 'storage/**/*'
- 'db/migrate/2020*.rb'
- 'db/migrate/2021*.rb'
- 'db/migrate/2022*.rb'
- 'db/migrate/2023*.rb'
- 'db/migrate/202405*.rb'
- 'db/migrate/202406*.rb'
- 'lib/tasks/deployment/2020*'
- 'lib/tasks/deployment/2021*'
- 'lib/tasks/deployment/2022*'
- 'lib/tasks/deployment/2023*'
================================================
FILE: .standard_todo.yml
================================================
# Auto generated files with errors to ignore.
# Remove from this list as you refactor files.
---
ignore:
- app/controllers/all_casa_admins/sessions_controller.rb:
- Layout/EmptyLinesAfterModuleInclusion
- Rails/LexicallyScopedActionFilter
- app/controllers/api/v1/base_controller.rb:
- Rails/LexicallyScopedActionFilter
- app/controllers/casa_cases_controller.rb:
- Rails/TimeZone
- Style/EmptyStringInsideInterpolation
- app/controllers/case_contacts/followups_controller.rb:
- Layout/EmptyLineAfterGuardClause
- app/controllers/case_contacts_controller.rb:
- Rails/LexicallyScopedActionFilter
- Style/HashSlice
- app/controllers/checklist_items_controller.rb:
- Rails/TimeZone
- app/controllers/court_dates_controller.rb:
- Rails/TimeZone
- app/controllers/emancipation_checklists_controller.rb:
- Layout/EmptyLinesAfterModuleInclusion
- app/controllers/imports_controller.rb:
- Layout/EmptyLinesAfterModuleInclusion
- app/controllers/other_duties_controller.rb:
- Layout/EmptyLineAfterGuardClause
- app/controllers/reimbursements_controller.rb:
- Rails/TimeZone
- app/controllers/users/sessions_controller.rb:
- Layout/EmptyLinesAfterModuleInclusion
- Rails/LexicallyScopedActionFilter
- app/datatables/volunteer_datatable.rb:
- Rails/CompactBlank
- Style/EmptyStringInsideInterpolation
- app/decorators/casa_case_decorator.rb:
- Layout/EmptyLineAfterGuardClause
- Rails/Date
- app/decorators/case_assignment_decorator.rb:
- Rails/Date
- app/decorators/contact_type_decorator.rb:
- Layout/EmptyLinesAfterModuleInclusion
- app/helpers/banner_helper.rb:
- Rails/TimeZone
- app/helpers/followup_helper.rb:
- Layout/EmptyLineAfterGuardClause
- app/helpers/phone_number_helper.rb:
- Rails/Blank
- Style/RedundantRegexpEscape
- app/helpers/sidebar_helper.rb:
- Layout/EmptyLineAfterGuardClause
- app/mailers/fund_request_mailer.rb:
- Rails/Date
- app/mailers/learning_hours_mailer.rb:
- Rails/Date
- app/mailers/supervisor_mailer.rb:
- Rails/Date
- app/models/casa_case.rb:
- Rails/IgnoredColumnsAssignment
- Rails/Date
- Rails/PluckInWhere
- app/models/casa_case_contact_type.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/casa_case_emancipation_category.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/casa_org.rb:
- Layout/EmptyLinesAfterModuleInclusion
- Rails/UniqueValidationWithoutIndex
- app/models/case_assignment.rb:
- Rails/UniqueValidationWithoutIndex
- Rails/RedundantPresenceValidationOnBelongsTo
- app/models/case_contact.rb:
- Layout/EmptyLinesAfterModuleInclusion
- Rails/FindEach
- app/models/case_contact_contact_type.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/case_group.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/concerns/CasaCase/validations.rb:
- Rails/TimeZone
- app/models/concerns/api.rb:
- Layout/EmptyLinesAfterModuleInclusion
- app/models/contact_type.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/contact_type_group.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/hearing_type.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/judge.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/language.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/learning_hour.rb:
- Rails/Date
- app/models/learning_hour_topic.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/learning_hour_type.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/mileage_rate.rb:
- Rails/IgnoredColumnsAssignment
- app/models/supervisor_volunteer.rb:
- Rails/UniqueValidationWithoutIndex
- app/models/user.rb:
- Rails/Date
- app/models/volunteer.rb:
- Rails/WhereEquals
- Layout/EmptyLineAfterGuardClause
- app/notifications/delivery_methods/sms.rb:
- Layout/EmptyLinesAfterModuleInclusion
- app/policies/user_policy.rb:
- Layout/EmptyLineAfterGuardClause
- app/services/casa_case_change_service.rb:
- Rails/Pluck
- Layout/EmptyLineAfterGuardClause
- app/services/case_contacts_export_csv_service.rb:
- Layout/EmptyLineAfterGuardClause
- app/services/fdf_inputs_service.rb:
- Layout/EmptyLineAfterGuardClause
- Rails/Blank
- Rails/RootPathnameMethods
- app/services/learning_hours_export_csv_service.rb:
- Layout/EmptyLineAfterGuardClause
- app/services/short_url_service.rb:
- Layout/EmptyLinesAfterModuleInclusion
- app/validators/user_validator.rb:
- Rails/Blank
- config/application.rb:
- Style/RedundantInterpolation
- config/initializers/bugsnag.rb:
- Style/FileNull
- db/migrate/20250507011754_remove_unused_indexes.rb:
- Rails/ReversibleMigration
- db/seeds/db_populator.rb:
- Layout/EmptyLineAfterGuardClause
- Rails/TimeZone
- Rails/FindEach
- Rails/Date
- lib/mailers/debug_preview_mailer.rb:
- Rails/ApplicationMailer
- lib/mailers/previews/devise_mailer_preview.rb:
- Rails/Date
- lib/mailers/previews/fund_request_mailer_preview.rb:
- Rails/Date
- lib/mailers/previews/volunteer_mailer_preview.rb:
- Rails/Date
- lib/tasks/case_contact_types_reminder.rb:
- Layout/EmptyLineAfterGuardClause
- Rails/ActiveRecordAliases
- lib/tasks/data_post_processors/contact_topic_populator.rb:
- Rails/FindEach
- lib/tasks/data_post_processors/contact_type_populator.rb:
- Rails/FindEach
- lib/tasks/deployment/20240604121427_migrate_notifications.rake:
- Rails/ApplicationRecord
- lib/tasks/deployment/99991023145114_store_deploy_time.rake:
- Rails/TimeZone
- lib/tasks/example_recurring_task.rb:
- Layout/EmptyLinesAfterModuleInclusion
- lib/tasks/lint_factory_bot.rake:
- Layout/EmptyLineAfterGuardClause
- lib/tasks/no_contact_made_reminder.rb:
- Rails/ActiveRecordAliases
- lib/tasks/supervisor_weekly_digest.rb:
- Rails/TimeZone
- lib/tasks/test_checker.rake:
- Layout/EmptyLineAfterGuardClause
- scripts/import_casa_case_date_of_birth.rb:
- Layout/EmptyLineAfterGuardClause
- spec/controllers/concerns/accessible_spec.rb:
- Layout/EmptyLinesAfterModuleInclusion
- spec/datatables/reimbursement_datatable_spec.rb:
- Rails/TimeZone
- spec/decorators/casa_case_decorator_spec.rb:
- Rails/TimeZone
- spec/decorators/user_decorator_spec.rb:
- Rails/TimeZone
- spec/factories/healths.rb:
- Rails/TimeZone
- spec/factories/users.rb:
- Rails/TimeZone
- spec/helpers/notifications_helper_spec.rb:
- Rails/TimeZone
- spec/lib/tasks/data_post_processors/contact_topic_populator_spec.rb:
- Rails/FindEach
- spec/lib/tasks/data_post_processors/contact_type_populator_spec.rb:
- Rails/FindEach
- spec/mailers/learning_hours_mailer_spec.rb:
- Rails/Date
- spec/mailers/supervisor_mailer_spec.rb:
- Rails/Date
- spec/models/casa_case_spec.rb:
- Rails/TimeZone
- spec/models/casa_org_spec.rb:
- Style/RedundantInterpolation
- Rails/Date
- spec/models/case_contact_report_spec.rb:
- Performance/Count
- spec/models/case_contact_spec.rb:
- Rails/TimeZone
- spec/models/case_court_report_spec.rb:
- Layout/EmptyLinesAfterModuleInclusion
- spec/models/learning_hours_report_spec.rb:
- Layout/EmptyLineAfterGuardClause
- spec/requests/bulk_court_dates_spec.rb:
- Rails/Date
- spec/requests/casa_cases_spec.rb:
- Rails/Date
- Rails/TimeZone
- spec/requests/case_contact_reports_spec.rb:
- Rails/Date
- spec/requests/case_court_reports_spec.rb:
- Layout/EmptyLinesAfterModuleInclusion
- spec/requests/court_dates_spec.rb:
- Layout/EmptyLinesAfterModuleInclusion
- spec/requests/notifications_spec.rb:
- Rails/Date
- spec/system/casa_cases/edit_spec.rb:
- Rails/Date
- spec/system/casa_cases/new_spec.rb:
- Rails/Date
- spec/system/case_contacts/new_spec.rb:
- Rails/Date
- spec/system/checklist_items/destroy_spec.rb:
- Rails/TimeZone
- spec/system/checklist_items/edit_spec.rb:
- Rails/TimeZone
- spec/system/checklist_items/new_spec.rb:
- Rails/TimeZone
- spec/system/learning_hours/edit_spec.rb:
- Rails/Date
- spec/system/other_duties/new_spec.rb:
- Rails/Date
- spec/system/reports/index_spec.rb:
- Rails/Date
- spec/system/volunteers/edit_spec.rb:
- Rails/Date
- spec/views/casa_orgs/edit.html.erb_spec.rb:
- Style/RedundantInterpolation
- spec/views/templates/email_templates_spec.rb:
- Rails/RootPathnameMethods
================================================
FILE: .tool-versions
================================================
ruby 4.0.2
nodejs 24.13.0
================================================
FILE: .yamllint.yml
================================================
extends: default
ignore:
- .standard_todo.yml # generated by standard
- .git
- node_modules
rules:
document-start:
present: false
# 80 chars should be enough, but don't fail if a line is longer
line-length:
max: 80
level: warning
allow-non-breakable-words: true
allow-non-breakable-inline-mappings: true
indentation:
spaces: 2
indent-sequences: consistent
check-multi-line-strings: false
comments:
require-starting-space: true
================================================
FILE: CONTRIBUTING.md
================================================
[Please press here if you want to contribute!](./doc/CONTRIBUTING.md)
================================================
FILE: DEPLOY_CHECKLIST.md
================================================
See https://github.com/rubyforgood/casa/wiki/deploy-checklist
================================================
FILE: Dockerfile
================================================
ARG ROOT=/usr/src/app/
# available alpine packages: https://pkgs.alpinelinux.org/packages
FROM node:24-alpine AS node-source
FROM ruby:4.0.2-alpine AS build
ARG ROOT
WORKDIR $ROOT
RUN apk update && apk upgrade && apk add --update --no-cache \
build-base \
curl-dev \
libffi-dev \
yaml-dev \
linux-headers \
postgresql-dev \
tzdata
RUN bundle config set force_ruby_platform true
COPY Gemfile* $ROOT
RUN bundle install
FROM ruby:4.0.2-alpine
ARG ROOT
WORKDIR $ROOT
RUN apk update && apk upgrade && apk add --update --no-cache \
bash \
build-base \
curl \
imagemagick \
postgresql-client \
tzdata \
vim \
&& rm -rf /var/cache/apk/*
COPY . .
COPY --from=node-source /usr/local/bin/node /usr/local/bin/node
COPY --from=node-source /usr/local/lib/node_modules /usr/local/lib/node_modules
RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm
RUN npm ci
COPY --from=build /usr/local/bundle/ /usr/local/bundle/
EXPOSE 3000
ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["bin/rails", "s", "-b", "0.0.0.0"]
================================================
FILE: Gemfile
================================================
# frozen_string_literal: true
source "https://rubygems.org"
ruby "4.0.2"
gem "rails", "~> 7.2"
gem "after_party" # Post-deployment tasks
gem "amazing_print" # Easier console reading
gem "authtrail" # Track Devise login activity
gem "azure-storage-blob", require: false
gem "blueprinter" # JSON serialization
gem "bugsnag" # Error tracking in production
gem "caxlsx", "~> 4.4" # Excel spreadsheets - TODO can we remove this version restriction?
gem "caxlsx_rails", "~> 0.6.4" # Excel spreadsheets - TODO can we remove this version restriction?
gem "cssbundling-rails", "~> 1.4" # CSS compilation
gem "delayed_job_active_record" # Background job processing
gem "devise" # Authentication
gem "devise_invitable" # User invitation system for Devise
gem "draper" # Decorators for cleaner presentation logic
gem "filterrific" # Filtering and sorting of models
gem "flipper" # Feature flag management
gem "flipper-active_record" # Active Record adapter for Flipper
gem "flipper-ui" # Web UI for managing feature flags
gem "friendly_id", "~> 5.6.0" # Allows us to use a slug instead of CASA case IDs in their URLs
gem "groupdate" # Group data by time periods
gem "httparty" # HTTP network requests
gem "image_processing", "~> 1.14" # Image processing helpers
gem "jbuilder" # JSON API builder
gem "jsbundling-rails" # JavaScript bundling
gem "lograge" # Log less so Heroku Papertrail quits rate limiting our logs
gem "net-imap" # Ruby 3.1+ requires explicit inclusion of standard library gems
gem "net-pop" # Ruby 3.1+ requires explicit inclusion of standard library gems
gem "net-smtp", require: false # Ruby 3.1+ requires explicit inclusion of standard library gems
gem "noticed" # Notifications
gem "oj" # Faster JSON parsing
gem "pagy" # Fast and lightweight pagination
gem "paranoia" # Soft-delete support for Active Record models
gem "pdf-forms" # Filling in fund request PDFs with user input
gem "pg" # Use PostgreSQL as the database for Active Record
gem "pghero" # PostgreSQL performance monitoring and query insights
gem "pg_query" # PostgreSQL query parser
gem "pretender" # Allows admins to impersonate users
gem "puma", "~> 8.0" # Use Puma as the app server
gem "pundit" # Authorization management based on user.role field
gem "rack-attack" # Blocking & throttling abusive requests
gem "rack-cors" # Cross-origin resource sharing
gem "request_store" # Per-request global storage for thread-safe data
gem "rexml" # PDF-forms needs this to deploy to Heroku
gem "rswag-api" # Swagger API documentation
gem "rswag-ui" # Swagger UI
gem "sablon" # Word document templating tool for Case Court Reports
gem "scout_apm" # Application performance monitoring
gem "scout_apm_logging", "~> 2.1" # Scout APM logging integration
gem "sprockets-rails" # Asset pipeline for Rails
gem "stimulus-rails" # Stimulus JavaScript framework
gem "strong_migrations" # Catch unsafe database migrations
gem "turbo-rails", "~> 2.0" # Turbo framework for Rails
gem "twilio-ruby" # Twilio helper functions
gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] # Windows does not include zoneinfo files
gem "view_component" # View components for reusability
gem "wicked" # Multi-step form wizard for Rails
group :development, :test, :production do
gem "brakeman" # Security inspection
gem "prosopite" # N+1 query detection via SQL pattern analysis
gem "byebug", platforms: %i[mri mingw x64_mingw] # Debugger console
gem "dotenv-rails" # Environment variable management
gem "erb_lint", require: false # ERB linter
gem "factory_bot_rails" # Test data factories
gem "faker" # Creates realistic seed data, valuable for staging and demos
gem "parallel_tests" # Run tests in parallel
gem "pry" # Enhanced Ruby console
gem "pry-byebug" # Pry debugger integration
gem "rspec_junit_formatter" # JUnit XML formatter for RSpec
gem "rspec-rails" # RSpec testing framework
gem "rubocop-capybara", require: false # Capybara linting rules
gem "rubocop-factory_bot", require: false # FactoryBot linting rules
gem "rubocop-performance", require: false # Performance linting rules
gem "rubocop-rspec", require: false # RSpec linting rules
gem "rubocop-rspec_rails", require: false # RSpec Rails linting rules
gem "rswag-specs" # Swagger spec generation
gem "shoulda-matchers" # RSpec matchers for common Rails functionality
gem "standard", require: false # Ruby style guide
gem "standard-rails", require: false # Rails-specific style guide
end
group :development do
gem "annotate" # Adds database field listings to models as comments
gem "bundler-audit" # Checks for security issues in gems
gem "letter_opener" # Opens emails in new tab for easier testing
gem "simplecov-mcp" # SimpleCov MCP integration
gem "spring" # Speeds up development by keeping your application running in the background
gem "spring-commands-rspec" # Spring integration for RSpec
gem "traceroute" # Finds unused routes
gem "web-console", "~> 4.0" # Interactive console on exception pages
end
group :test do
gem "capybara" # Integration testing framework
gem "capybara-screenshot" # Automatic screenshot on test failure
gem "database_cleaner-active_record" # Database cleaning strategies for tests
gem "docx" # For testing Word document generation
gem "email_spec" # Email testing helpers
gem "rails-controller-testing" # Controller testing helpers
gem "rspec-retry" # Retries flaky tests
gem "selenium-webdriver" # Browser automation for system tests
gem "simplecov", require: false # Code coverage analysis
gem "webmock" # HTTP request stubber
end
================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
Copyright (c) 2020 Ruby for Good
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: PROSOPITE_TODO.md
================================================
# Prosopite N+1 Query Issues
Issues detected by Prosopite during test suite run. Fix by adding eager loading (`includes`, `preload`) or restructuring queries.
## High Priority (20+ occurrences)
### app/decorators/casa_case_decorator.rb:34
- **Method:** `map` in decorator
- **Likely fix:** Add `includes` for associated records being accessed in iteration
### app/models/user.rb:84
- **Method:** `create_preference_set`
- **Query:** `SELECT "preference_sets".* FROM "preference_sets" WHERE "preference_sets"."user_id" = $1`
- **Likely fix:** Check if preference_set already loaded before querying
### app/models/concerns/api.rb:11
- **Method:** `initialize_api_credentials`
- **Query:** `SELECT "api_credentials".* FROM "api_credentials" WHERE "api_credentials"."user_id" = $1`
- **Likely fix:** Check if api_credentials already loaded before querying
### app/lib/importers/file_importer.rb:50
- **Method:** `create_user_record`
- **Queries:** Multiple user lookups during import
- **Likely fix:** Batch lookups or use `Prosopite.pause` for intentional import operations
## Medium Priority (10-19 occurrences)
### app/validators/user_validator.rb:56
- **Method:** `validate_uniqueness`
- **Query:** `SELECT "users".* FROM "users" WHERE "users"."type" = $1 AND "users"."email" = $2`
- **Likely fix:** Consider if validation is necessary during bulk operations
### app/lib/importers/supervisor_importer.rb:47
- **Method:** `block in assign_volunteers`
- **Query:** `SELECT "users".* FROM "users" INNER JOIN "supervisor_volunteers"...`
- **Likely fix:** Preload volunteers before assignment loop
### app/lib/importers/supervisor_importer.rb:51
- **Method:** `block in assign_volunteers`
- **Query:** `SELECT "users".* FROM "users" WHERE "users"."id" = $1`
- **Likely fix:** Batch load users by ID before iteration
### app/controllers/case_contacts/form_controller.rb:156
- **Method:** `block in create_additional_case_contacts`
- **Likely fix:** Eager load case contact associations
## Lower Priority (5-9 occurrences)
### app/models/court_date.rb:32
- **Method:** `associated_reports`
- **Likely fix:** Add `includes` for court report associations
### app/lib/importers/supervisor_importer.rb:23
- **Method:** `block in import_supervisors`
- **Query:** `SELECT "users".* FROM "users" WHERE "users"."type" = $1 AND "users"."email" = $2`
- **Likely fix:** Batch check existing supervisors before import loop
## Lower Priority (2-4 occurrences)
### app/lib/importers/file_importer.rb:57
- **Method:** `email_addresses_to_users`
- **Likely fix:** Batch load users by email
### app/lib/importers/case_importer.rb:41
- **Method:** `create_casa_case`
- **Likely fix:** Preload or batch casa_case lookups
### app/decorators/contact_type_decorator.rb:14
- **Method:** `last_time_used_with_cases`
- **Likely fix:** Eager load case associations
### app/datatables/reimbursement_datatable.rb:25
- **Method:** `block in data`
- **Query:** `SELECT "addresses".* FROM "addresses" WHERE "addresses"."user_id" = $1`
- **Likely fix:** Add `includes(:address)` to reimbursement query
### app/services/volunteer_birthday_reminder_service.rb:7
- **Method:** `block in send_reminders`
- **Likely fix:** Eager load volunteer associations
### app/models/contact_topic.rb:27
- **Method:** `block in generate_for_org!`
- **Likely fix:** Batch operations or use `Prosopite.pause` for setup
### app/models/casa_org.rb:82
- **Method:** `user_count`
- **Likely fix:** Use counter cache or single count query
### app/models/casa_org.rb:62
- **Method:** `case_contacts_count`
- **Likely fix:** Use counter cache or single count query
### app/lib/importers/volunteer_importer.rb:23
- **Method:** `block in import_volunteers`
- **Likely fix:** Batch check existing volunteers before import loop
### app/lib/importers/case_importer.rb:20
- **Method:** `block in import_cases`
- **Likely fix:** Batch check existing cases before import loop
### app/controllers/case_contacts/form_controller.rb:26
- **Method:** `block (2 levels) in update`
- **Likely fix:** Eager load contact associations
## Single Occurrence
### app/services/missing_data_export_csv_service.rb:40
- **Method:** `full_data`
### app/policies/contact_topic_answer_policy.rb:18
- **Method:** `create?`
### app/models/casa_case.rb:152
- **Method:** `next_court_date`
### app/models/all_casa_admins/casa_org_metrics.rb:16
- **Method:** `map`
### config/initializers/sent_email_event.rb:7
- **Method:** `block in <top (required)>`
- **Query:** `SELECT "casa_orgs".* FROM "casa_orgs" WHERE "casa_orgs"."id" = $1`
- **Note:** Initializer callback - consider caching org lookup
## Notes
- **Importers:** Many N+1s occur in import code. Consider wrapping entire import operations in `Prosopite.pause { }` if the N+1 pattern is intentional for per-record processing, or batch-load records before iteration.
- **Decorators:** Add `includes` at the controller/query level before passing to decorators.
- **Callbacks:** User model callbacks (`create_preference_set`, `initialize_api_credentials`) fire on each create. Consider if these can be optimized or if the N+1 is acceptable for single-record operations.
## How to Fix
```ruby
# Before (N+1)
users.each { |u| u.orders.count }
# After (eager loading)
users.includes(:orders).each { |u| u.orders.count }
# For intentional batch operations
Prosopite.pause do
records.each { |r| process_individually(r) }
end
```
================================================
FILE: Procfile
================================================
release: bundle exec rake db:migrate && bundle exec rake after_party:run
web: bundle exec puma
custom_web: bundle exec puma
================================================
FILE: Procfile.dev
================================================
web: bin/rails server -p 3000 -b 0.0.0.0
js: npm run build:dev --watch
css: npm run build:css:dev --watch
================================================
FILE: README.md
================================================
# CASA Project and Organization Overview
[](https://github.com/rubyforgood/casa/actions/workflows/rspec.yml)
[](https://github.com/rubyforgood/casa/actions/workflows/erb_lint.yml)
[](https://github.com/rubyforgood/casa/actions/workflows/ruby_lint.yml)
[](https://github.com/rubyforgood/casa/actions/workflows/security.yml)
[](https://github.com/rubyforgood/casa/actions/workflows/npm_lint_and_test.yml)
[](https://codeclimate.com/github/rubyforgood/casa/trends/technical_debt)
[](https://codeclimate.com/github/rubyforgood/casa/trends/test_coverage_total)
[](https://snyk.io/test/github/rubyforgood/casa)
[](http://isitmaintained.com/project/rubyforgood/casa "Average time to resolve an issue")
A CASA (Court Appointed Special Advocate) is a role where a volunteer advocates on behalf of a youth in their county's foster care system. CASA is also the namesake role of the national organization, CASA, which exists to cultivate and supervise volunteers carrying out this work – with county level chapters (operating relatively independently of each other) across the country.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Welcome contributors!](#welcome-contributors)
- [Communication and Collaboration](#communication-and-collaboration)
- [About this project](#about-this-project)
- [Developing! ✨🛠✨](#developing-)
- [How to Contribute](#how-to-contribute)
- [Installation](#installation)
- [Getting Started (Codespaces - EXPERIMENTAL) 🛠️](#getting-started-codespaces---experimental-)
- [Local Setup Instructions](#local-setup-instructions)
- [Platform Specific Installation Instructions](#platform-specific-installation-instructions)
- [Common issues](#common-issues)
- [Running the App / Verifying Installation](#running-the-app--verifying-installation)
- [Other Documentation](#other-documentation)
- [Acknowledgements](#acknowledgements)
- [Feedback](#feedback)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Welcome contributors!
We are very happy to have you! CASA and Ruby for Good are committed to welcoming new contributors of all skill levels.
Find issues to work on [here](https://github.com/rubyforgood/casa/issues?q=is%3Aissue+is%3Aopen+no%3Aassignee) on the issue board. Issues on the [project's](https://github.com/rubyforgood/casa/projects/1) TODO column are another way to browse issues. Check to see that no one is assigned to the issue. Then comment on it to claim the issue. Commenting on an issue doesn't automatically get the issue assigned so double check the comments on an issue to see that no one is requesting assignment.
Pull requests which are not for an issue but which improve the codebase are also welcome! Feel free to make GitHub issues for bugs and improvements. A maintainer will be keeping an eye on issues and PRs every day or three.
### Communication and Collaboration
We highly recommend that you join us in [slack](https://join.slack.com/t/rubyforgood/shared_invite/zt-34b5p4vk3-NWIw6hKs2ma~wm7mYSe0_A) in the #casa channel so you can get fast help for any questions you may have.
Check out [our google calendar](https://bit.ly/casacal) to see when office hours and stakeholder meetings are.
You can also open an issue or comment on an issue on GitHub and a maintainer will reply to you.
### About this project
CASA is a national organization with many regional chapters. We currently work with [Prince George's County CASA in Maryland](https://pgcasa.org/), [Montgomery CASA Maryland](https://casaspeaks4kids.com), and [Howard County Maryland](https://marylandcasa.org/programs/howard-county/)
This system provides value by:
- providing volunteers with a portal for logging activity
- allow supervisors to oversee volunteer activity
- generate reports on volunteer activity for admins to use in grant proposals
Read about the [product sense](doc/productsense.md) that guides our approach to this work.
**How CASA works:**
- A foster youth is represented as a **CASA case**.
- The **CASA case** is assigned to a **volunteer**.
- The **volunteer** records their efforts spent on the CASA case as **case contacts**.
- **Supervisors** oversee CASA **volunteers** by monitoring, tracking, and advising them on **CASA case** activities.
- At PG CASA, the minimum volunteer commitment is one year (this varies by CASA chapter, in San Francisco the minimum commitment is ~ two years). A volunteer's lifecycle is very long, so there's a lot of activity for chapters to organize.
**Project Considerations**
- PG CASA is operating under a very tight budget. Right now, they manually input volunteer data into [a volunteer management software built specifically for CASA](http://www.simplyoptima.com/), but upgrading their account for multiple user licenses to allow volunteers to self-log activity data is beyond their budget. Hence why we are building as lightweight a solution as possible that can sustain itself with Ruby for Good's support.
- While the scope of this platform's use is currently for PG County CASA and Montgomery county CASA, we are building with a mind toward multitenancy so this platform could prospectively be used by other CASA chapters across the country.
**More information:**
The complete [role description of a CASA volunteer](https://pgcasa.org/volunteer-description/) in Prince George's County.
# Developing! ✨🛠✨
## How to Contribute
See our [contributing guide](./doc/CONTRIBUTING.md) 💖 ✨
## Installation
### Getting Started (Codespaces - EXPERIMENTAL) 🛠️
[](https://codespaces.new/rubyforgood/casa/tree/main?quickstart=1)
1. Follow the link above or follow instructions to [create a new Codespace.](https://docs.github.com/en/codespaces/developing-in-a-codespace/creating-a-codespace-for-a-repository); You can use the web editor, or even better open the Codespace in VSCode
2. Wait for the container to start. This will take a few (10-15) minutes since Ruby needs to be installed, the database needs to be created, and the `bin/setup` script needs to run
3. Run `bin/dev` and visit the URL that pops in VSCode up to see the CASA page
4. Login as a sample user with these default credentials (which also work for [QA](https://casa-qa.herokuapp.com/)):
### Local Setup Instructions
**Downloading the Project**
(*on a Mac or Linux machine*)
1. `git clone https://github.com/rubyforgood/casa.git` clone the repo to your local machine.
2. You can ask a [maintainer](https://github.com/rubyforgood/casa/wiki/Who's-who%3F) for permission to make a branch on this repo.
3. You can also [create a fork on GitHub](https://docs.github.com/en/get-started/quickstart/fork-a-repo) and make a pull request from the fork.
**Ruby**
1. Install a ruby version manager: [rvm](https://rvm.io/) or [rbenv](https://github.com/rbenv/rbenv)
1. when you cd into the project directory, let your version manager install the ruby version in `.ruby-version`. Right now that's Ruby 4.0.2
1. `gem install bundler`
**node.js**
1. (Recommended) Install [nvm](https://github.com/nvm-sh/nvm#installing-and-updating), which is a **n**ode **v**ersion **m**anager.
- If you use asdf, the node version from `.tool-versions` will be used, but may be out of sync with the codename version in `.nvmrc`. To use the version from `.nvmrc`, see one of these options: [legacy file codename support](https://github.com/asdf-vm/asdf-nodejs?tab=readme-ov-file#partial-and-codename-versions) or [installing via custom script](https://github.com/asdf-vm/asdf-nodejs/issues/382#issuecomment-2258647554).
1. Install a current LTS version of Node. Running `nvm install` from this directory will read the `.nvmrc` file to install the correct version.
**PostgreSQL ("postgres")**
1. Make sure that postgres is installed.
- If you're on Ubuntu/WSL, use `sudo apt-get install libpq-dev` so the gem can install. [Use the Postgres repo for Ubuntu or WSL to get the server and client tools](https://www.postgresql.org/download/linux/ubuntu/).
- If you're on Fedora/Cent Os use `sudo dnf install libpq-devel`. [If you prefer choose package of libpq-devel via rpm](https://pkgs.org/download/libpq-devel)
- If you're on Windows, use the official [installer](https://www.postgresql.org/download/windows/) and accept all defaults. Alternatively, a [Chocolatey](https://chocolatey.org/packages/postgresql) package is available with `choco install postgresql`.
**Chrome Browser**
1. The Spec tests uses Chrome Browser and Chromedriver for some of the tests. A current version of chromedriver will be installed when `bundle install` is run. TO install Chrome, see [Chrome Install](https://support.google.com/chrome/answer/95346?hl=en&ref_topic=7439538).
Another option is to install the Chromium browser for your operating system so the browser-based Ruby feature/integration tests can run. Installing `chromium-browser` is enough, including for many WSL (Windows subsystem for Linux) distributions.
If you are using Ubuntu on WSL and receive the following message when trying to run the test suite...
> Command '/usr/bin/chromium-browser' requires the chromium snap to be installed. Please install it with:
> `snap install chromium`
...check out the instructions on [installing google-chrome and chromedriver for WSL Ubuntu](https://github.com/rubyforgood/casa/blob/main/doc/WSL_SETUP.md#google-chrome).
### Platform Specific Installation Instructions
- [Docker](doc/DOCKER.md)
- [Linux](doc/LINUX_SETUP.md)
- [Mac](doc/MAC_SETUP.md)
- Windows(Help Wanted)
- [Windows Subsystem for Linux(WSL)](https://github.com/rubyforgood/casa/blob/main/doc/WSL_SETUP.md)
- [Nix](doc/NIX_SETUP.md)
### Common issues
1. If your rails/rake commands hang forever instead of running, try: `rails app:update:bin`
1. There is currently no option for a user to sign up and create an account through the UI. This is intentional. If you want to log in, use a pre-seeded user account and its credentials.
1. If you are on windows and see the error "Requirements support for mingw is not implemented yet" then use https://rubyinstaller.org/ instead
1. Install imagemagick to see images locally. Instructions: https://imagemagick.org/script/download.php
1. _If you are running on an M1 mac, run the following command before you start the installation process:_
1. _Set the architecture_: `$env /usr/bin/arch -arm64 /bin/zsh ---login`
1. _Remove all gems before you proceed_: `gem uninstall -aIx`
1. If `bin/setup` fails with a credentials error:
1. Open the `.env` file.
1. Update the values of `POSTGRES_USER` and `POSTGRES_PASSWORD`to match your PostgreSQL credentials.
1. Run `bin/setup`
## Running the App / Verifying Installation
1. `cd casa/`
1. Run `bin/setup`
1. Run `bin/dev` and visit http://localhost:3000/ to see the app running.
**Logging in with seed users**
Login as a regular user at http://localhost:3000/users/sign_in. Some example seed users:
- volunteer1@example.com view site as a volunteer
- supervisor1@example.com view site as a supervisor
- casa_admin1@example.com view site as an admin
- casa_admin2-1@example.com view site as admin from a different org
Login as an all CASA admin at http://localhost:3000/all_casa_admins/sign_in. An example seed user:
- allcasaadmin@example.com view site as an all CASA admin
The password for all seed users is `12345678`
**Local email**
We are using [Letter Opener](https://github.com/ryanb/letter_opener) in
development to receive mail. All emails sent in development should open in a
new tab in the browser.
To see local email previews, check out http://localhost:3000/rails/mailers
**Running Tests**
- run the ruby test suite `bin/rails spec`
- run the javascript test suite `npm run test`
If you have trouble running tests, check out CI scripts in [`.github/workflows/`](.github/workflows/) for sample commands.
Test coverage is run by simplecov on all builds and aggregated by CodeClimate
**Cleaning up before you pull request**
Run `bin/lint` to run all linters and fix issues. This will run:
1. `bundle exec standardrb --fix` auto-fix Ruby linting issues [more linter info](https://github.com/testdouble/standard)
1. `bundle exec erb_lint --lint-all --autocorrect` [ERB linter](https://github.com/Shopify/erb-lint)
1. `npm run lint:fix` to run the [JS linter](https://standardjs.com/index.html) and fix issues
1. `rake factory_bot:lint` if you have been editing factories and want to find factories and traits which produce invalid objects
If additional work arises from your pull request that is outside the scope of the issue it resolves, please open a new issue.
**Stimulus**
[Issue 5016](https://github.com/rubyforgood/casa/issues/5016) started a refactor of Javascript to use
[Hotwire's Stimulus](https://stimulus.hotwired.dev/handbook/origin). To see if it's working for you, go to
`/casa_cases` and see **Stimulus is working!** in your browser console.
**Post-deployment tasks**
We are using [After Party](https://github.com/theSteveMitchell/after_party) to
run post-deployment tasks. These tasks may include one-time necessary updates to the
database. Run the tasks manually by:
```
bundle exec rake after_party:run
```
Alternatively, every time you pull the main branch, run:
```
bin/update
```
which will run any database migrations, update gems and node packages, and run
the after party post-deployment tasks.
# Other Documentation
Check out [the wiki](https://github.com/rubyforgood/casa/wiki)
There is a `doc` directory at the top level that includes:
* an `architecture-decisions` directory containing important architectural decisions and entity relationship diagrams of various models
(see the article [Architectural Decision Records](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions) describing this approach).
* [Code of Conduct](doc/code-of-conduct.md)
* [productsense.md](doc/productsense.md)(for team leads & product interested contributors)
* [SECURITY.md](doc/SECURITY.md)
# Acknowledgements
Thank you to [Scout](https://ter.li/h8k29r) for letting us use their dashboard for free!
[<img src="https://user-images.githubusercontent.com/578159/165240278-c2c0ac30-c86f-4b67-9da6-e6a5e4ab4c37.png" width="400" height="400" />](https://ter.li/h8k29r)
Join info for all public meetings is posted in the rubyforgood slack in the #casa channel
# Feedback
We are very interested in your feedback! Please give us some :) https://forms.gle/1D5ACNgTs2u9gSdh9
================================================
FILE: Rakefile
================================================
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative "config/application"
Rails.application.load_tasks
if Rails.env.development?
require "bundler/audit/task"
Bundler::Audit::Task.new
end
================================================
FILE: SECURITY.md
================================================
See [doc/SECURITY.md](./doc/SECURITY.md) 💖
================================================
FILE: app/assets/builds/.keep
================================================
================================================
FILE: app/assets/config/manifest.js
================================================
//= link_directory ../builds .css
//= link_directory ../builds .js
//= link_tree ../images
//= link_tree ../fonts
//= link shared/noscript.css
================================================
FILE: app/assets/stylesheets/actiontext.css
================================================
/*
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
* inclusion directly in any other asset bundle and remove this file.
*
*= require trix
*/
/*
* We need to override trix.css’s image gallery styles to accommodate the
* <action-text-attachment> element we wrap around attachments. Otherwise,
* images in galleries will be squished by the max-width: 33%; rule.
*/
.trix-content .attachment-gallery > action-text-attachment,
.trix-content .attachment-gallery > .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}
.trix-content .attachment-gallery.attachment-gallery--2 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--2 > .attachment, .trix-content .attachment-gallery.attachment-gallery--4 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--4 > .attachment {
flex-basis: 50%;
max-width: 50%;
}
.trix-content action-text-attachment .attachment {
padding: 0 !important;
max-width: 100% !important;
}
================================================
FILE: app/assets/stylesheets/android_app_associations.css
================================================
/*
Place all the styles related to the matching controller here.
They will automatically be included in application.css.
*/
================================================
FILE: app/assets/stylesheets/application.scss
================================================
// links to stylesheets inside node_modules
@use "bootstrap/scss/bootstrap.scss" with (
$primary: #00447c
);
@use "bootstrap-datepicker/dist/css/bootstrap-datepicker";
@use "datatables.net-dt/css/jquery.dataTables";
@use "@fortawesome/fontawesome-free/scss/fontawesome";
@use "@fortawesome/fontawesome-free/scss/solid";
@use "select2/dist/css/select2";
@use "tom-select/dist/css/tom-select.bootstrap5.css";
// custom css for the app
@use "base/breakpoints";
@use "shared/notifier";
@use "shared/dashboard";
@use "shared/data_tables_overide";
@use "shared/flashes";
@use "shared/footer";
@use "shared/form";
@use "shared/layout";
@use "shared/navbar";
@use "shared/noscript";
@use "shared/select2_additional_styles";
@use "shared/sidebar";
@use "shared/tomselect_additional_styles.scss";
@use "shared/typography";
@use "shared/utilities";
@use "shared/validated_form_component";
@use "shared/truncated_text_component";
@use "pages/all_casa_admin_dashboard";
@use "pages/casa_cases";
@use "pages/casa_org";
@use "pages/case_contacts";
@use "pages/case_contacts_form";
@use "pages/court_dates";
@use "pages/emancipation";
@use "pages/login";
@use "pages/password";
@use "pages/patch_notes";
@use "pages/reimbursements";
@use "pages/supervisors";
@use "pages/volunteers";
@use "trix/dist/trix.css";
@use "actiontext";
================================================
FILE: app/assets/stylesheets/base/breakpoints.scss
================================================
$small: 640px;
$medium: 1024px;
$large: 1200px;
// If you adjust this breakpoint, you also need to adjust the breakpoint value in app/javascript/controllers/sidebar-controller.js
$mobile: 768px;
================================================
FILE: app/assets/stylesheets/base/variables.scss
================================================
$primary: #00447c;
$red: #dc3545;
// ======== Sidebar colors
$sidebar-inactive: #9AA4CA;
$sidebar-active: #365CF5;
$sidebar-dark: #1A2142;
:root {
--casa-red: #D50100;
--casa-primary-blue: #4A6CF7;
--gunmetal: #262D3F;
--dark-gunmetal: #212529;
--dark: #262d3f;
--dark-electric-blue: #5D657B;
--gray: #5d657b;
--dark-gray: #AAAAAA;
--gray-80: #CCCCCC;
--silver: #D9D9D9;
--inactive: #9AA4CA;
--input-placeholder-text: var(--gray);
--input-border-color: var(--gray-80);
}
================================================
FILE: app/assets/stylesheets/pages/all_casa_admin_dashboard.scss
================================================
.dashboard, .all_casa_admins-dashboard {
.container {
@media (max-width: 1200px) {
max-width: 95%;
}
}
.dashboard-table-header {
h1 {
display: inline-block;
margin-right: 15px;
vertical-align: middle;
}
a {
display: inline-block;
}
}
.cases {
background: lightgrey;
padding: 10px;
}
.dropdown {
margin-left: 8px;
}
.button {
border: 1px black solid;
padding: 10px;
background-color: #00447c;
}
.button > a {
color: white;
&:visited {
color: white;
}
}
}
================================================
FILE: app/assets/stylesheets/pages/casa_cases.scss
================================================
@use "../base/breakpoints.scss" as screen-sizes;
body.casa_cases {
.form-header {
h1 {
display: inline-block;
margin-right: 15px;
vertical-align: middle;
}
a {
display: inline-block;
}
}
.a2cldr {
width: 190px;
}
.a2cldr .a2cldr-btn {
width: 190px;
text-align: center;
}
.a2cldr-list {
position: absolute;
width: 100%;
}
.cal-btn {
display: inline-block;
}
.court-date-row {
display: flex;
align-items: center;
gap: 10px;
.court-date-link {
flex: 1;
}
.cal-btn {
flex-shrink: 0;
.a2cldr {
width: 120px !important;
.a2cldr-btn {
width: 120px !important;
font-size: 12px;
padding: 4px 8px;
text-align: center;
}
}
}
}
#cc-check {
p {
display: flex;
align-items: center;
}
#with_cc {
margin-right: 5px;
}
}
#reminder_button {
margin-left: 30px;
margin-bottom: 0;
}
.case-contact-list {
margin-bottom: 20px;
}
.datetime-year-month select.date-input {
width: 130px;
padding-bottom: 15px;
}
.court-orders {
textarea {
display: block;
margin-bottom: 5px;
}
textarea, .add-court-order {
width: 500px;
}
.implementation-status {
align-self: flex-start;
min-height: 38px;
}
.remove-court-order-button {
align-self: flex-start;
}
}
.court-order-entry {
display: flex;
gap: 8px;
align-items: center;
}
select {
padding: 5px;
}
.emancipation-btn {
padding: 5px 10px;
font-size: 10px;
line-height: 16px;
vertical-align: middle;
}
}
@media only screen and (max-width: screen-sizes.$small) {
body.casa_cases {
.court-orders {
textarea, .add-court-orders {
width: 100%;
}
}
.court-order-entry {
display: grid;
grid-template-columns: minmax(100px, 100%) 1fr;
gap: 2px;
.implementation-status {
grid-row: 2;
}
margin: 1em 1em 2em 1em;
}
}
}
body.casa_cases-show {
.past-court-dates.add-container {
display: block;
}
}
#generate-docx-report-modal {
.dates-container {
display: flex;
}
.docx-report__modal-body {
display: flex;
flex-direction: column;
row-gap: 1rem;
}
.modal-footer {
[data-bs-dismiss="modal"] {
padding-block: 11px;
}
}
}
.generate-report-button {
display: flex;
flex-direction: row;
width: 100%;
border: solid 1px var(--silver);
padding: 1.2rem;
column-gap: 1.2rem;
&:hover {
border-color: black;
}
svg {
min-inline-size: 40px;
width: 40px;
height: auto;
}
div {
text-align: left;
h3 {
margin-block-end: .25rem;
}
p {
}
}
}
.card-text {
ul {
display: flex;
flex-direction: column;
gap: .2rem;
}
}
#case-selection:required, .select2.select2-container {
background: transparent;
border: 1px solid #e5e5e5;
border-radius: 10px;
padding: 8px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
// removes select2 dropdown default border
span.select2-selection.select2-selection--single {
border: none;
}
// removes select2 dropdown default arrow
.select2-selection__arrow {
display: none;
}
.select-wrapper {
display: flex;
flex-direction: column;
gap: 8px;
}
span[role=combobox] {
padding-top: 2px;
}
================================================
FILE: app/assets/stylesheets/pages/casa_org.scss
================================================
#casa_org_logo{
height: 2.7rem;
overflow: hidden;
}
================================================
FILE: app/assets/stylesheets/pages/case_contacts.scss
================================================
.slide-container {
padding: 0rem 1rem;
}
.slider {
display: inline;
}
.slider-row {
margin: 0px;
}
.dataTables_scrollHeadInner {
width: 100% !important;
}
.followup-button {
min-width: max-content;
}
.flex-container {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
}
.field-card {
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0,0,0,0.125);
border-radius: .25rem;
padding: 1rem;
box-shadow: 0 4px 12px 5px rgba(0, 0, 0, 0.08);
}
.pr-6 {
padding-right: 1.5rem !important;
}
.red-letter {
color: #d50100;
font-weight: 900;
display: inline;
}
.label-font-weight {
font-weight: 900;
}
.cc-field {
height: calc(1.5em + .75rem + 2px);
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
.expense-container {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
gap: .5rem;
justify-content: flex-end;
}
.expense-container {
& > *:last-child {
width: 80%;
};
.field_with_errors {
input {
width: 100%;
}
}
}
.other-expenses li {
margin-bottom: .2rem;
}
.other-expense-amount {
width: 20%;
margin-left: .4rem;
color: #5D657B !important;
}
.add-expense-link {
margin-top: -.5rem;
margin-bottom: .5rem;
display: block;
padding-left: .8rem;
text-decoration: underline;
}
#add-another-expense {
cursor: pointer;
}
.dollar-sign {
margin: 0px 10px 0 0;
display: flex;
align-items: center;
}
.dollar-sign .other-expense-amount {
position: relative;
padding-left: 32px;
}
.dollar-sign input::placeholder {
color: #5D657B;
}
.dollar-sign:before {
position: absolute;
top: 17px;
content: "$";
left: 28px;
z-index: 100;
}
.pr-7 {
padding-right: 1.5rem !important;
padding-left: 2.5rem !important;
}
.pr-9 {
padding-left: 3.1rem !important;
}
.wide_button {
width: 100%;
height: 3rem;
font-weight: 900;
}
.cc-italic {
font-style: italic;
}
.expand-toggle {
display: inline-block;
cursor: pointer;
background: none;
border: 0;
padding: 0;
transition: transform 0.3s;
&.expanded {
transform: rotate(180deg);
}
}
.expanded-content {
padding: 0.75rem 1rem;
.expanded-topic {
margin-bottom: 0.75rem;
strong {
display: block;
}
p {
margin: 0.25rem 0 0;
}
}
}
.expanded-empty {
padding: 0.75rem 1rem;
margin: 0;
}
================================================
FILE: app/assets/stylesheets/pages/case_contacts_form.scss
================================================
@use "../base/breakpoints.scss" as screen-sizes;
#case-contact-form {
color: var(--gunmetal);
& section {
background: var(--white, #FFFFFF);
border: 1px solid var(--form-element-stroke, #E5E5E5);
border-radius: 10px;
box-shadow: 0px 0px 5px 0px #1A252F0D;
margin-bottom: 30px;
padding: 30px 20px;
}
& h2 {
font-size: 28px;
margin-bottom: 24px;
}
& h3 {
font-size: 16px;
}
& legend {
font-size: 16px;
font-weight: 400;
line-height: 19px;
color: var(--dark-electric-blue);
}
& label {
font-size: 16px;
font-weight: 500;
line-height: 19px;
}
& input,
textarea,
select {
border: 1px solid var(--input-border-color);
&::placeholder {
color: var(--input-placeholder-text);
opacity: 1;
}
}
& input[type="text"],
input[type="date"],
input[type="number"],
textarea,
select {
padding: 16px;
}
& .form-check {
margin-left: 0px;
padding-left: 0px;
& input {
width: 20px;
height: 20px;
margin-left: 0px;
margin-right: 3px;
float: none;
&:checked {
background-color: var(--casa-primary-blue);
border-color: var(--casa-primary-blue);
}
&[type="checkbox"] + label {
padding-top: 5px;
font-weight: 300;
}
&[type="radio"] + label {
padding-top: 1px;
font-size: 16px;
font-weight: 300;
line-height: 25px;
color: var(--dark-electric-blue)
}
}
label {
font-size: 16px;
font-weight: 600;
}
}
& button {
--bs-link-color: var(--casa-primary-blue);
&.btn-link {
text-decoration: none;
padding: 0px;
}
}
& .row {
--bs-gutter-x: .5rem;
}
& #contact-form-types {
--group-width: 250px;
columns: var(--group-width);
& fieldset {
display: inline-block;
width: var(--group-width);
margin-bottom: .25rem;
& .form-check {
& label {
display: inline;
color: var(--dark);
font-weight: 400;
color: var(--dark-gunmetal);
}
& small {
display: block;
margin-left: 28px;
font-style: italic;
font-weight: 300;
color: var(--dark-electric-blue);
}
}
}
}
& .input-group-text {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
& #contact-form-action-buttons {
display: flex;
justify-content: flex-end;
gap: 10px;
@media only screen and (max-width: screen-sizes.$mobile) {
& > a, & > button {
flex-grow: 1;
}
}
}
}
================================================
FILE: app/assets/stylesheets/pages/case_court_reports.scss
================================================
================================================
FILE: app/assets/stylesheets/pages/court_dates.scss
================================================
body.court_dates {
.court-orders {
textarea {
display: block;
margin-bottom: 5px;
}
textarea, .add-court-order {
width: 500px;
}
}
.court-order-entry {
display: flex;
gap: 8px;
align-items: center;
}
select {
padding: 5px;
}
}
================================================
FILE: app/assets/stylesheets/pages/emancipation.scss
================================================
.category-options {
margin-left: 2em;
input[type="checkbox"], input[type="radio"] {
pointer-events: none
}
}
.check-item.disabled {
cursor: default;
label {
color: #757575
}
}
.check-item {
label {
width: 80%;
vertical-align: middle;
}
}
.emancipation-category {
border-bottom: 2px solid #bfe3ff;
margin: 0;
padding: 0 .5em;
display: flex;
justify-content: space-between;
align-items: center;
input[type="checkbox"] {
pointer-events: none
}
label {
margin: 0;
padding: .5em;
vertical-align: middle;
}
span {
color: #00447c;
font-weight: bold;
font-size: 18pt
}
}
.emancipation-category:hover {
background-color: #f5f5f5;
cursor: pointer;
input[type="checkbox"], label{
cursor: pointer
}
}
.emancipation-category.disabled {
cursor: default;
span, label{
color: #757575
}
}
.emancipation-category.disabled:hover{
background-color: unset
}
.no-select {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome, Edge, Opera and Firefox */
}
.emacipation-category-input-label-pair {
display: flex;
}
================================================
FILE: app/assets/stylesheets/pages/feature_flags.scss
================================================
#feature-flags {
padding-top: 1em;
h1 {
padding-bottom: 1em;
}
.flag-name {
padding-right: 2em;
}
}
================================================
FILE: app/assets/stylesheets/pages/login.scss
================================================
body.devise-sessions-new, body.users-sessions-new, body.devise-passwords-new {
.container {
max-width: none;
}
.login-email-link {
font-size: small;
}
aside {
background-position: right;
background-image: url("login.jpg");
min-height: 700px;
background-repeat: no-repeat;
background-size: cover;
}
}
================================================
FILE: app/assets/stylesheets/pages/password.scss
================================================
@use "../base/variables.scss" as globals;
.password-box {
width: 80%;
margin: 10% auto;
text-align: center;
border-radius: 25px;
border: 2px solid globals.$primary;
form#edit_user.edit_user div.field {
margin: 0 auto;
width: 90%;
max-width: 90%;
flex: none;
}
input#user_password {
margin: 10px 0 10px;
width: 100%;
}
input#user_password_confirmation {
margin: 10px 0 10px;
width: 100%;
}
form#edit_user.edit_user div.actions input {
color: #fff;
background-color: #002f56;
border-color: #002849;
margin: 10px;
}
}
body.devise-invitations.devise-invitations-edit footer {
width: 100%;
}
body.devise-passwords.devise-passwords-edit div.password-box {
div.row {
margin: 0 0;
div.col-sm-6 {
flex: none;
margin: 0 auto;
max-width: 90%;
padding: 0;
}
}
a.btn.btn-info {
margin-bottom: 10px;
}
}
================================================
FILE: app/assets/stylesheets/pages/patch_notes.scss
================================================
#patch-notes {
display: flex;
#patch-note-list {
width: 50%;
h1 {
text-align: left;
}
.patch-note-list-item {
& .card-body>* {
margin: 0.25em 0;
}
&.new {
background-color: #ffecb3;
}
textarea {
width: 100%;
}
.label-and-select {
display: flex;
label {
padding-right: 0.5rem;
}
select {
flex-grow: 1
}
}
.patch-note-button-controls {
display: flex;
button {
flex-grow: 1;
&:nth-child(2) {
margin-left: 0.5em
};
&.button-cancel {
flex-grow: 3
}
}
}
};
};
}
================================================
FILE: app/assets/stylesheets/pages/reimbursements.scss
================================================
.reimbursements-index {
.select2-container {
.select2-selection {
max-height: 60px;
overflow-y: auto;
overflow-x: hidden;
}
}
}
================================================
FILE: app/assets/stylesheets/pages/supervisors.scss
================================================
$indictator_negative_color: #f44336;
$indicator_positive_color: #4caf50;
.supervisor_case_contact_stats {
display: flex;
div {
&:first-child {
display: flex;
margin-right: 1em;
flex-grow: 1;
}
span {
border-radius: 0.25em;
padding-top: .25em;
text-align: center;
&.attempted-contact {
background-color: $indicator_positive_color;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
& + span.no-attempted-contact {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
& + span.attempted-contact-end {
background-color: $indicator_positive_color;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
width: 0.25em;
}
}
&.no-attempted-contact {
background-color: $indictator_negative_color;
}
&.no-volunteers {
background-color: #ccc;
}
&:last-child {
margin-left: 0.5em;
background-color: #cfd8dc;
border-radius: 100vw;
padding: 0.2em 1em;
}
}
}
&.legend {
align-items: center;
margin-bottom: 0.25rem;
margin-top: 1em;
span {
&:last-child {
padding: .5em;
}
padding: .5em 1em;
flex-grow: 1;
}
}
}
.supervisor_table_row {
display: flex;
td:nth-of-type(1), th:nth-of-type(1) {
flex: 3;
}
td:nth-of-type(2), th:nth-of-type(2) {
flex: 3;
}
td:nth-of-type(3), th:nth-of-type(3) {
flex: 1;
}
}
================================================
FILE: app/assets/stylesheets/pages/volunteers.scss
================================================
@use "../base/breakpoints.scss" as screen-sizes;
body.volunteers {
@media only screen and (max-width: screen-sizes.$mobile) {
table#volunteers {
tbody tr {
padding-bottom: 2.5rem;
border-bottom: none;
td {
border-left: none;
border-right: none;
}
td:last-child {
border-bottom: none;
}
}
}
}
}
table#volunteers.dataTable.hover tbody tr.selected > * {
background-color: rgba(54, 92, 245, 0.1);
box-shadow: none;
color: inherit;
}
table#volunteers.dataTable.hover > tbody > tr.selected:hover > * {
background-color: rgba(54, 92, 245, 0.15);
box-shadow: none !important;
color: inherit;
}
.form-check-input {
border: 1px solid #757575;
}
================================================
FILE: app/assets/stylesheets/shared/dashboard.scss
================================================
.dashboard-table-header {
h1,h2,h3,h4,h5,h6 {
display: inline-block;
margin-right: 15px;
vertical-align: middle;
}
a.btn {
display: inline-block;
}
}
.dropdown-menu {
li {
input[type="checkbox"] {
transform: scale(1.5);
margin: 0 8px;
}
&:not(:last-child) {
margin-bottom: 7px;
}
}
padding: 8px;
}
.supervisor-options {
min-width: 15rem;
}
.language-icon {
cursor: context-menu;
font-size: 1.5rem;
display: flex;
justify-content: center;
}
================================================
FILE: app/assets/stylesheets/shared/data_tables_overide.scss
================================================
/**
Needed to display the prev, next, number, and ellipsis buttons on the same line. This causes issues on mobile with
lots of pages, but there is no current way to change the number of pages in a view or in JS based on window size.
*/
.dataTables_paginate {
white-space: nowrap !important;
span {
display: inline-block !important;
}
}
================================================
FILE: app/assets/stylesheets/shared/flashes.scss
================================================
.notice {
text-align: center;
padding: 8px;
margin: 12px 0;
list-style-position: inside;
}
.alert-dismissible .close {
padding: 0.5rem 0.75rem;
}
================================================
FILE: app/assets/stylesheets/shared/footer.scss
================================================
//@use "../base/variables" as globals;
//@use "../base/breakpoints.scss" as screen-sizes;
//
//footer {
// padding: 2rem 0;
// text-align: center;
// background-color: globals.$primary;
// color: #fff;
//
// .default-footer {
// a.rfglink {
// color: #fff;
// }
//
// .rfglogo {
// max-height: 3em;
// }
// }
// .terms-conditions-link {
// color:#fff;
// }
//
// .footer-logos {
// .rfglink {
// .rfglogo {
// max-height: 6em;
// }
// }
// }
//
// ul {
// list-style: none;
// padding-left: 0;
// margin-top: 2rem;
// }
//
// li {
// display: inline-block;
//
// a, a:hover {
// color: white;
// }
// }
//
// li:not(:first-child):before {
// content: " | ";
// }
//
// .address {
// margin-bottom: 2rem;
// }
//
// .copyright {
// font-size: 18px;
// font-weight: 700;
// }
//}
//
//.footer.container-fluid {
// min-height: calc(100vh - 45px);
//}
//
//footer.logged-in {
// position: relative;
// height: 40px;
// left: 0px;
// bottom: 0px;
// background: #F8F8F8;
// box-shadow: 0px -2px 12px rgba(0, 0, 0, 0.25);
// padding: 2rem;
// padding-top: 1rem;
// padding-left: 2%;
// margin-left: 320px;
// width: calc(100% - 320px);
//
// span {
// font-family: 'Montserrat';
// font-style: normal;
// font-weight: 400;
// font-size: 14px;
// line-height: 140%;
// color: #2E2E2E;
// }
//
// a {
// white-space: nowrap;
// }
//
// @media only screen and (max-width: screen-sizes.$mobile) {
// width: 100%;
// margin-left: 0;
// padding-bottom: 1rem;
// height: 100px;
// }
//}
================================================
FILE: app/assets/stylesheets/shared/form.scss
================================================
@use "../base/variables.scss" as globals;
form {
.field_with_errors {
label {
@extend .text-danger !optional;
@extend .font-weight-bold !optional;
}
input {
border: 1px solid globals.$red;
}
}
.read-more {
display: inline;
}
.alert.alert-danger {
ul {
margin-bottom: 0;
}
}
#with_cc {
margin-left: 20px;
}
}
#cc-check {
margin-left: 30px;
display: initial;
}
================================================
FILE: app/assets/stylesheets/shared/header.scss
================================================
@use "../base/breakpoints.scss" as screen-sizes;
.header {
.header-left {
.menu-toggle-btn {
display: none;
.main-btn {
border-radius: 4px !important;
}
}
}
}
@media only screen and (max-width: screen-sizes.$mobile) {
.header {
.header-left {
.menu-toggle-btn {
display: block;
}
}
}
}
================================================
FILE: app/assets/stylesheets/shared/layout.scss
================================================
@use "../base/variables.scss" as globals;
@use "../base/breakpoints.scss" as screen-sizes;
body {
background-color: #f4f7fa;
min-width: 320px;
}
.content {
margin-left: 320px;
padding: 2%;
position: relative;
overflow: auto;
}
.casa-case-scroll {
width: 13rem;
height: auto;
overflow-y: auto;
}
// This may effect other pages than the case contact form!!!
h5 label {
font-weight: 500;
}
.unbold {
font-weight: 100;
}
.fa-car {
color: globals.$primary;
}
div.row div.col-sm-12.form-header h1 {
display: inline-block;
margin-right: 15px;
vertical-align: middle;
}
div.row.volunteer-filters {
margin-top: 2rem;
}
.card.card-container {
box-shadow: 0 4px 12px 5px rgba(0, 0, 0, 0.08);
margin-bottom: 1.5rem;
}
.casa-case-button {
margin: 0 10px 10px 0;
}
.card-title {
&__hint {
font-size: 11px;
font-style: italic;
}
}
/* ASSUMPTION: default screen size is desktop view (> 1024px) */
/* As 'mobile-label' class is mobile only, not display them on desktop view */
@media only screen and (min-width: screen-sizes.$mobile) {
table.table {
span.mobile-label {
display: none;
}
}
}
#dropdownMenuButton {
margin-bottom: 0.5em;
}
@media only screen and (max-width: screen-sizes.$mobile) {
.login-header {
font-size: 0.75em !important;
}
.content {
padding: 3rem 0;
margin-left: 0;
}
.card-body {
padding: 0.5rem;
}
table.table {
thead {
display: none;
}
tr {
display: table;
width: 100%;
border-bottom: 1px solid #efefef;
> * {
display: block;
}
}
th,
td {
border-top: none;
font-size: 1.25rem;
span.mobile-label {
color: #757575;
display: block;
font-size: 0.9rem;
}
}
}
}
================================================
FILE: app/assets/stylesheets/shared/navbar.scss
================================================
@use "../base/breakpoints.scss" as screen-sizes;
.navbar {
color: #fff;
background: #00447c;
box-shadow: 0 0 4px 4px rgba(0,0,0,0.28);
height: 80px;
justify-content: space-between;
padding: 16px;
width: 100%;
z-index: 3;
}
.navbar strong {
font-size: 2rem;
}
.navbar.mobile {
display: none;
}
.mobile-icon {
top: -2px;
width: 40px;
}
@media only screen and (max-width: screen-sizes.$mobile) {
.navbar.mobile {
display: flex;
position: sticky;
top: 0;
}
}
================================================
FILE: app/assets/stylesheets/shared/noscript.css
================================================
.noscript {
position: fixed;
left: 50%;
top: 25%;
transform: translateX(-50%);
padding: 5vw;
z-index: 99;
}
================================================
FILE: app/assets/stylesheets/shared/notifier.scss
================================================
@keyframes spin {
0% {
transform: rotate(0deg)
}
100% {
transform: rotate(360deg)
}
}
#notifications {
align-items: end;
bottom: 0;
display: flex;
flex-direction: column;
font-weight: 900;
max-height: 100vh;
max-width: 40%;
overflow-y: auto;
pointer-events: none;
position: fixed;
right: 2em;
z-index: 100;
&>* {
pointer-events: auto;
}
div {
border-radius: .25em;
margin-bottom: .5em;
margin-left: auto;
margin-right: 0;
padding: .5em;
span {
display: inline
}
}
.danger-notification {
background-color: #b71c1c;
color: white
}
.messages {
margin-bottom: 0;
padding: 0;
pointer-events: none;
&>* {
pointer-events: auto;
}
div {
display: flex;
width: fit-content;
}
}
.success-notification {
background-color: #28a745;
color: white
}
.warning-notification {
background-color: #ffc107;
}
#async-waiting-indicator {
background-color: #007bff;
color: white;
.load-spinner {
animation: spin 1.5s linear infinite;
border: .25em solid #f3f3f3;
border-top: .25em solid #3498db;
border-radius: 50%;
display: inline-block;
height: 1em;
margin: 0;
padding: 0;
width: 1em
}
}
#toggle-minimize-notifications {
background-color: #333;
border: 0;
border-radius: 10px 10px 0 0;
color: white;
padding: 0.25em 1em;
width: fit-content;
span {
display: inline;
}
}
}
================================================
FILE: app/assets/stylesheets/shared/select2_additional_styles.scss
================================================
.select2 {
input {
min-width: 250px;
}
}
================================================
FILE: app/assets/stylesheets/shared/sidebar.scss
================================================
@use "../base/variables.scss" as globals;
@use "../base/breakpoints.scss" as screen-sizes;
#wrapper {
overflow-x: hidden;
}
.sidebar-wrapper {
background: rgba(0,0,0,0.25);
display: flex;
flex-direction: column;
max-height: 100vh;
position: fixed;
width: 320px;
overflow: auto;
}
.sidebar-wrapper .sidebar-heading {
position: sticky;
top: 0;
z-index: 10;
background: globals.$primary;
border-bottom: 1px solid #103862;
font-size: 1.2rem;
padding-bottom: 16px;
padding: 0.875rem 1.25rem;
}
.sidebar-wrapper .list-group {
width: 100%;
.list-group-item {
background: none;
color: #fff;
padding: 1.25rem 1.75rem;
text-decoration: none;
&:hover {
text-decoration: none;
}
}
}
#page-content-wrapper {
width: 100%;
}
.sidebar-container {
background: globals.$primary;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100vh;
overflow-y: auto;
}
.logo-div {
height: 80px;
}
// Stops weird text wrapping when opening and closing sidebar
.nav-item {
width: 250px;
}
.nav-item > a {
color: globals.$sidebar-inactive !important;
height: 44px;
&:hover {
color: globals.$sidebar-active !important;
span {
color: globals.$sidebar-dark !important;
}
}
}
.nav-item.active > a {
color: globals.$sidebar-dark !important;
}
.btn-sidebar {
color: #fff !important;
background-color: globals.$sidebar-active !important;
}
.sidebar-wrapper .sidebar-menu {
margin-top: 24px;
.list-group-item {
border: none;
border-left: 6px solid transparent;
padding: 1.25rem 1.75rem;
a {
color: #fff;
text-decoration: none;
}
&:hover {
border-left: 6px solid #fff;
}
&.active {
background: #103862;
border-left: 6px solid #fff;
font-weight: bold;
}
}
}
.sidebar-wrapper .sidebar-footer {
.list-group.account-details {
padding-bottom: 1rem;
.list-group-item {
border: none;
padding: 1rem 2rem;
> * {
font-size: 0.9em;
}
.label {
color: #729DCB;
display: block;
}
.value, a {
color: #fff;
}
}
}
.list-group.footer-nav {
background: #103862;
padding: 1rem 0 5rem;
width: 100%;
a.list-group-item {
background: none !important;
border: none;
color: #fff;
font-size: 0.9em;
padding: 1rem 1.75rem;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
.group-actions {
&:hover::before {
opacity: 1 !important;
visibility: visible !important;
}
&::before {
opacity: 0 !important;
visibility: hidden !important;
}
}
// Media Queries
@media only screen and (max-width: screen-sizes.$mobile) {
.sidebar-wrapper {
display: none;
width: 100%;
&.sidebar-open {
display: inherit;
z-index: 1;
}
}
.sidebar-container {
height: calc(100vh - 72px);
width: 320px;
}
.sidebar-heading {
display: none;
}
#wrapper.toggled .sidebar-wrapper {
margin-left: -15rem;
}
.footer-nav #mobile-space {
margin-top: 72px;
}
}
// These overrides are for larger than mobile screens
@media only screen and (min-width: screen-sizes.$mobile) {
.sidebar-nav-wrapper {
-webkit-transform: translateX(0px) !important;
-moz-transform: translateX(0px) !important;
-ms-transform: translateX(0px) !important;
-o-transform: translateX(0px) !important;
transform: translateX(0px) !important;
&.active {
width: 66px;
-webkit-transform: translateX(0px) !important;
-moz-transform: translateX(0px) !important;
-ms-transform: translateX(0px) !important;
-o-transform: translateX(0px) !important;
transform: translateX(0px) !important;
}
}
.main-wrapper {
margin-left: 250px !important;
&.active {
margin-left: 66px !important;
}
}
}
================================================
FILE: app/assets/stylesheets/shared/tomselect_additional_styles.scss
================================================
.ts-dropdown [data-selectable] .highlight {
display: inline-block;
}
================================================
FILE: app/assets/stylesheets/shared/truncated_text_component.scss
================================================
.truncation-container {
display: flex;
a {
min-width: fit-content;
margin-inline-start: auto;
}
}
================================================
FILE: app/assets/stylesheets/shared/typography.scss
================================================
// TODO check in css so tests can run without internet
@use "../base/variables.scss" as globals;
@import url(https://fonts.googleapis.com/css?family=Montserrat:400,700);
body {
font-family: "Montserrat";
}
option {
font-family: Helvetica, Arial, sans-serif;
}
.content-1 {
font-family: Inter;
font-size: 16px;
font-weight: 500;
line-height: 19px;
color: var(--dark);
}
.content-2 {
font-family: Inter;
font-size: 14px;
font-weight: 500;
line-height: 22px;
color: var(--gray)
}
.content-3 {
font-family: Inter;
font-size: 14px;
font-weight: 400;
}
.pre-line {
white-space: pre-line;
}
================================================
FILE: app/assets/stylesheets/shared/utilities.scss
================================================
@use "../base/variables.scss" as globals;
.pull-left {
float: left;
}
.pull-right {
float: right;
}
.vertically-center {
display: flex;
align-items: center;
}
.add-container {
display: flex;
justify-content: flex-start;
align-items: center;
gap: 10px;
.add-button {
color: white;
border: none;
background-color: #{globals.$primary};
padding: 0.25em 1.5em;
border-radius: 10px;
font-size: 1.25em;
:hover {
cursor: pointer;
}
}
}
.hidden {
display: none;
}
.line-clamp-1 {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
================================================
FILE: app/assets/stylesheets/shared/validated_form_component.scss
================================================
.warning-required-checkbox {
background-color: #ffc107;
padding: 0.5em;
input[type="checkbox"] {
width: 18px;
height: 18px;
margin-right: 0.5em;
}
}
================================================
FILE: app/blueprints/api/v1/session_blueprint.rb
================================================
class Api::V1::SessionBlueprint < Blueprinter::Base
field :user do |user|
{
id: user.id,
display_name: user.display_name,
email: user.email,
refresh_token_expires_at: user.api_credential&.refresh_token_expires_at,
token_expires_at: user.api_credential&.token_expires_at
}
end
field :api_token do |user|
token = user.api_credential
token.return_new_api_token![:api_token]
end
field :refresh_token do |user, options|
token = user.api_credential
if options[:remember_me]
token.return_new_refresh_token!(true)[:refresh_token]
else
token.return_new_refresh_token!(false)[:refresh_token]
end
end
end
================================================
FILE: app/callbacks/case_contact_metadata_callback.rb
================================================
class CaseContactMetadataCallback
def after_commit(case_contact)
changes = case_contact.saved_changes
set_status(changes, case_contact) if changes["id"]
update_status(changes, case_contact) if changes["status"] && changes["id"].nil?
end
private
def set_status(changes, case_contact)
metadata = {"status" => {case_contact.status => case_contact.created_at}}
update_metadata(case_contact, metadata)
end
def update_status(changes, case_contact)
metadata = {"status" => {changes["status"].last => Time.zone.now}}
update_metadata(case_contact, metadata)
end
def update_metadata(record, new_data)
metadata = record.metadata.deep_merge(new_data)
record.update_columns(metadata: metadata)
end
end
================================================
FILE: app/channels/application_cable/channel.rb
================================================
module ApplicationCable
class Channel < ActionCable::Channel::Base; end
end
================================================
FILE: app/channels/application_cable/connection.rb
================================================
module ApplicationCable
class Connection < ActionCable::Connection::Base; end
end
================================================
FILE: app/components/badge_component.html.erb
================================================
<span class='badge <%= style %> text-uppercase display-1'>
<%= text %>
</span>
================================================
FILE: app/components/badge_component.rb
================================================
class BadgeComponent < ViewComponent::Base
DARK_TEXT_TYPES = [:warning, :light]
attr_reader :text
def initialize(text:, type:, rounded: false, margin: true)
@text = text
@type = type.to_sym
@rounded = rounded ? "rounded-pill" : nil
@margin = margin ? "my-1" : nil
end
def style
badge_style = ["bg-#{@type}", @rounded, @margin]
badge_style.push("text-dark") if DARK_TEXT_TYPES.include?(@type)
badge_style.compact.join(" ")
end
end
================================================
FILE: app/components/dropdown_menu_component.html.erb
================================================
<div class="dropdown <%= @class %>">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<% if icon? %>
<%= render_icon %>
<% else %>
<svg width="5" height="20" viewBox="0 0 5 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<title><%= @menu_title %></title>
<path d="M2.5 0.9375C1.82292 0.9375 1.23698 1.17188 0.742187 1.64063C0.247396 2.10938 -7.68364e-08 2.69531 -1.07571e-07 3.39844C-1.38306e-07 4.10156 0.247396 4.70052 0.742187 5.19531C1.23698 5.6901 1.82292 5.9375 2.5 5.9375C3.17708 5.9375 3.76302 5.6901 4.25781 5.19531C4.7526 4.70052 5 4.10156 5 3.39844C5 2.69531 4.7526 2.10938 4.25781 1.64063C3.76302 1.17188 3.17708 0.9375 2.5 0.9375ZM2.5 7.5C1.82292 7.5 1.23698 7.7474 0.742187 8.24219C0.247395 8.73698 -3.66538e-07 9.32292 -3.96134e-07 10C-4.25731e-07 10.6771 0.247395 11.263 0.742187 11.7578C1.23698 12.2526 1.82292 12.5 2.5 12.5C3.17708 12.5 3.76302 12.2526 4.25781 11.7578C4.7526 11.263 5 10.6771 5 10C5 9.32292 4.7526 8.73698 4.25781 8.24219C3.76302 7.7474 3.17708 7.5 2.5 7.5ZM2.5 14.0625C1.82292 14.0625 1.23698 14.3099 0.742187 14.8047C0.247395 15.2995 -6.53963e-07 15.8984 -6.84698e-07 16.6016C-7.15432e-07 17.3047 0.247395 17.8906 0.742187 18.3594C1.23698 18.8281 1.82292 19.0625 2.5 19.0625C3.17708 19.0625 3.76302 18.8281 4.25781 18.3594C4.7526 17.8906 5 17.3047 5 16.6016C5 15.8984 4.7526 15.2995 4.25781 14.8047C3.76302 14.3099 3.17708 14.0625 2.5 14.0625Z" fill="#5D657B" />
</svg>
<% end %>
<%= button_label %>
</button>
<ul class="dropdown-menu">
<%= content %>
</ul>
</div>
================================================
FILE: app/components/dropdown_menu_component.rb
================================================
# frozen_string_literal: true
class DropdownMenuComponent < ViewComponent::Base
renders_one :icon
def initialize(menu_title:, icon_name: nil, hide_label: false, render_check: true, klass: nil)
@menu_title = menu_title
@render_check = render_check
@hide_label = hide_label
@icon_name = icon_name
@class = klass
end
def render_icon
return icon if icon.present?
content_tag(:i, nil, class: "lni mr-10 lni-#{@icon_name}")
end
def icon?
icon.present? || @icon_name.present?
end
def render?
@render_check && @menu_title.present? && content.present?
end
def button_label
content_tag(:span, @menu_title, class: @hide_label ? "sr-only" : nil)
end
end
================================================
FILE: app/components/form/hour_minute_duration_component.html.erb
================================================
<div class="row input-style-1">
<div class="col-12 col-md">
<%= @form.label :duration_hours, "Hour(s)" %>
<%= @form.number_field :duration_hours,
min: 0,
class: "form-control",
style: "background:white",
value: @hour_value,
required: true %>
</div>
<div class="col-12 col-md">
<%= @form.label :duration_minutes, "Minute(s)" %>
<%= @form.number_field :duration_minutes,
min: 0,
class: "form-control",
style: "background:white",
value: @minute_value,
required: true %>
</div>
</div>
================================================
FILE: app/components/form/hour_minute_duration_component.rb
================================================
# frozen_string_literal: true
class Form::HourMinuteDurationComponent < ViewComponent::Base
def initialize(form:, hour_value:, minute_value:)
@form = form
if hour_value.is_a?(String)
begin
hour_value = Integer(hour_value)
rescue ArgumentError
raise ArgumentError.new("Could not convert parameter hour_value to an integer")
end
end
if hour_value.is_a?(Integer) && hour_value < 0
raise RangeError.new("Parameter hour_value must be positive")
end
if hour_value.nil?
@hour_value = 0
elsif hour_value.is_a?(Integer)
@hour_value = hour_value
else
raise TypeError.new("Parameter hour_value must be an integer")
end
if minute_value.is_a?(String)
begin
minute_value = Integer(minute_value)
rescue ArgumentError
raise ArgumentError.new("Could not convert parameter minute_value to an integer")
end
end
if minute_value.is_a?(Integer) && minute_value < 0
raise RangeError.new("Parameter minute_value must be positive")
end
if minute_value.nil?
@minute_value = 0
elsif minute_value.is_a?(Integer)
@minute_value = minute_value
else
raise TypeError.new("Parameter minute_value must be an integer")
end
end
end
================================================
FILE: app/components/form/multiple_select/item_component.html.erb
================================================
<div class="badge rounded-pill bg-primary active px-3">
${escape(data.text)}
</div>
================================================
FILE: app/components/form/multiple_select/item_component.rb
================================================
# frozen_string_literal: true
class Form::MultipleSelect::ItemComponent < ViewComponent::Base
strip_trailing_whitespace
end
================================================
FILE: app/components/form/multiple_select_component.html.erb
================================================
<div class="select-style-1 mr-8"
data-controller="multiple-select"
data-multiple-select-options-value="<%= @options %>"
data-multiple-select-selected-items-value="<%= @selected_items %>"
data-multiple-select-placeholder-term-value="<%= @placeholder_term %>"
data-multiple-select-show-all-option-value="<%= @show_all_option %>"
data-multiple-select-with-options-value="true">
<template data-multiple-select-target="option">
<div class="d-flex align-items-baseline">
<span class='mr-5'>DATA_LABEL</span>
<% if @render_option_subtext %>
<small class="fst-italic fw-lighter"><em>DATA_SUB_TEXT</em></small>
<% end %>
</div>
</template>
<template data-multiple-select-target="item">
<div class="badge rounded-pill bg-primary active px-3">DATA_LABEL</div>
</template>
<%# not needed, but want to be explicit when including this markup %>
<% if @show_all_option %>
<template data-multiple-select-target="hiddenItem">
<div class="d-none"></div>
</template>
<template data-multiple-select-target="selectAllOption">
<div class="d-flex align-items-baseline">
<span data-test="select-all-input" class='mr-5'>DATA_LABEL</span>
</div>
</template>
<% end %>
<%= @form.select @name, {}, { multiple: true } , {
data: { "multiple-select-target": "select", } , class: "form-control-lg form-select form-select-lg input-group-lg"
} %>
</div>
================================================
FILE: app/components/form/multiple_select_component.rb
================================================
# frozen_string_literal: true
class Form::MultipleSelectComponent < ViewComponent::Base
def initialize(form:, name:, options:, selected_items:, render_option_subtext: false, placeholder_term: nil, show_all_option: false)
@form = form
@name = name
@options = options.to_json
@selected_items = selected_items
@render_option_subtext = render_option_subtext
@placeholder_term = placeholder_term
@show_all_option = show_all_option
end
end
================================================
FILE: app/components/local_time_component.html.erb
================================================
<span title="<%= specific_time %>"><%= local_time %></span>
================================================
FILE: app/components/local_time_component.rb
================================================
# frozen_string_literal: true
class LocalTimeComponent < ViewComponent::Base
attr_reader :format, :unix_timestamp, :time_zone
def initialize(format:, unix_timestamp:, time_zone:)
@format = format
@time_zone = time_zone
@unix_timestamp = unix_timestamp
end
def local_time
time = Time.at(unix_timestamp).in_time_zone(@time_zone)
time.strftime(@format)
end
def specific_time
Time.at(unix_timestamp).in_time_zone(@time_zone).strftime("%b %d, %Y, %l:%M %p %Z")
end
end
================================================
FILE: app/components/modal/body_component.html.erb
================================================
<div class="modal-body <%= @class %>">
<%= body_content %>
</div>
================================================
FILE: app/components/modal/body_component.rb
================================================
# frozen_string_literal: true
class Modal::BodyComponent < ViewComponent::Base
def initialize(text: nil, klass: nil, render_check: true)
@text = text
@render_check = render_check
@class = klass
end
def body_content
return content if content.present?
Array.wrap(@text).map do |text|
content_tag :p, text
end.join.html_safe
end
def render?
@render_check && (@text.present? || content.present?)
end
end
================================================
FILE: app/components/modal/footer_component.html.erb
================================================
<div class="modal-footer <%= @class %>">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Close</button>
<%= content %>
</div>
================================================
FILE: app/components/modal/footer_component.rb
================================================
# frozen_string_literal: true
class Modal::FooterComponent < ViewComponent::Base
def initialize(klass: nil, render_check: true)
@render_check = render_check
@class = klass
end
def render?
@render_check && content.present?
end
end
================================================
FILE: app/components/modal/group_component.html.erb
================================================
<div class="modal fade <%= @class %>" id="<%= @id %>" tabindex="-1" aria-labelledby="<%= @id %>-label" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<%= header %>
<%= body %>
<%= footer %>
</div>
</div>
</div>
================================================
FILE: app/components/modal/group_component.rb
================================================
# frozen_string_literal: true
class Modal::GroupComponent < ViewComponent::Base
renders_one :header, Modal::HeaderComponent
renders_one :body, Modal::BodyComponent
renders_one :footer, Modal::FooterComponent
def initialize(id:, klass: nil, render_check: true)
@id = id
@class = klass
@render_check = render_check
end
def render?
@render_check && (body.present? || header.present?)
end
end
================================================
FILE: app/components/modal/header_component.html.erb
================================================
<div class="modal-header <%= @class %>">
<%= header_content %>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
================================================
FILE: app/components/modal/header_component.rb
================================================
# frozen_string_literal: true
class Modal::HeaderComponent < ViewComponent::Base
def initialize(id:, text: nil, icon: nil, klass: nil, render_check: true)
@text = text
@id = id
@icon = icon
@render_check = render_check
@class = klass
end
def header_content
return content if content.present?
content_tag :h1, class: "modal-title fs-5", id: "#{@id}-label" do
concat(content_tag(:i, nil, class: "lni mr-10 lni-#{@icon}")) if @icon.present?
concat(@text)
end
end
def render?
@render_check && (@text.present? || content.present?)
end
end
================================================
FILE: app/components/modal/open_button_component.html.erb
================================================
<button type="button" class="<%= @class %>" data-bs-toggle="modal" data-bs-target="<%= "##{@target}" %>">
<% if @icon %>
<i class="lni mr-10 lni-<%= @icon %>"></i>
<% end %>
<%= open_button %>
</button>
================================================
FILE: app/components/modal/open_button_component.rb
================================================
# frozen_string_literal: true
class Modal::OpenButtonComponent < ViewComponent::Base
def initialize(target:, text: nil, klass: nil, icon: nil, render_check: true)
@target = target
@text = text
@icon = icon
@render_check = render_check
@class = klass
end
def open_button
return content if content.present?
@text
end
def render?
@render_check && (@text.present? || content.present?)
end
end
================================================
FILE: app/components/modal/open_link_component.html.erb
================================================
<a href="#" role="button" class="btn <%= @class %>" data-bs-toggle="modal" data-bs-target="<%= "##{@target}" %>">
<% if @icon %>
<i class="lni mr-10 lni-<%= @icon %>"></i>
<% end %>
<%= open_link %>
</a>
================================================
FILE: app/components/modal/open_link_component.rb
================================================
# frozen_string_literal: true
class Modal::OpenLinkComponent < ViewComponent::Base
def initialize(target:, text: nil, icon: nil, klass: nil, render_check: true)
@target = target
@text = text
@icon = icon
@class = klass
@render_check = render_check
end
def open_link
return content if content.present?
@text
end
def render?
@render_check && (@text.present? || content.present?)
end
end
================================================
FILE: app/components/notification_component.html.erb
================================================
<a
href="<%= mark_as_read_notification_path(notification) %>"
class="<%= muted_display %> list-group-item list-group-item-action flex-column align-items-start"
data-method="post">
<div class="d-flex flex-row">
<div class="d-flex-shrink-0">
<% unless notification.read? %>
<i class='fas fa-bell'></i>
<% end %>
</div>
<div class="ml-2 flex-grow-1">
<div class="d-flex justify-content-between">
<h5 class="mb-1"><%= notification.event.title %></h5>
<small><%= time_ago_in_words(notification.created_at) %> ago</small>
</div>
<div class="my-1">
<%= simple_format notification.event.message %>
</div>
</div>
</div>
</a>
================================================
FILE: app/components/notification_component.rb
================================================
# frozen_string_literal: true
class NotificationComponent < ViewComponent::Base
attr_reader :notification
def initialize(notification:)
@notification = notification
end
def muted_display
"bg-light text-muted" if notification.read?
end
end
================================================
FILE: app/components/sidebar/group_component.html.erb
================================================
<li class="nav-item nav-item-has-children group-item" data-sidebar-target="groupList" data-controller="sidebar-group">
<a
href="#0"
class="<%= @class %>"
data-bs-toggle="collapse"
data-bs-target="#ddmenu_<%= @identifier %>"
aria-controls="ddmenu_<%= @identifier %>"
aria-expanded="true"
aria-label="Toggle navigation"
data-sidebar-group-target="title">
<span class="icon">
<i class="lni mr-10 lni-<%= @icon %>"></i>
</span>
<span data-sidebar-target="linkTitle"><%= @title %></span>
</a>
<ul id="ddmenu_<%= @identifier %>" class="collapse dropdown-nav" data-sidebar-group-target="list">
<% links.each do |link| %>
<%= link %>
<% end %>
</ul>
</li>
================================================
FILE: app/components/sidebar/group_component.rb
================================================
# frozen_string_literal: true
class Sidebar::GroupComponent < ViewComponent::Base
renders_many :links, Sidebar::LinkComponent
# @param title [String] the title/label for the link
# @param icon [String] the lni icon, pass just the name of the icon (ie. for lni-star --> icon: "star")
# @param render_check [Boolean] whether or not to display the link
def initialize(title:, icon:, render_check: true)
@title = title
@icon = icon
@render_check = render_check
@identifier = title.downcase.tr(" ", "-")
@class = "#{@identifier} collapsed"
end
# If there are no links or all links fail their render_check, then don't render this group
# @return [Boolean]
def render?
@render_check && !links.empty? && !links.select(&:render?).empty?
end
end
================================================
FILE: app/components/sidebar/link_component.html.erb
================================================
<li class="<%= @class %>" data-sidebar-group-target="link">
<%= link_to @path do %>
<% if @icon %>
<i class="lni mr-10 lni-<%= @icon %>"></i>
<% end %>
<span data-sidebar-target="linkTitle" class="sidebar-link"><%= @title %></span>
<% end %>
</li>
================================================
FILE: app/components/sidebar/link_component.rb
================================================
# frozen_string_literal: true
class Sidebar::LinkComponent < ViewComponent::Base
include SidebarHelper
# @param title [String] the title/label for the link
# @param path [String] the path to navigate to
# @param icon [String] the lni icon, pass just the name of the icon (ie. for lni-star --> icon: "star")
# @param nav_item [Boolean] whether or not the link should have the nav-item class
# @param render_check [Boolean] whether or not to display the link
def initialize(title:, path:, icon: nil, nav_item: true, render_check: true)
@title = title
@icon = icon
@path = path
@nav_item = nav_item
@render_check = render_check
end
# Must be moved to this method in order to use the SidebarHelper
def before_render
@class = @nav_item ? "nav-item #{active_class(@path)}" : ""
end
# @return [Boolean]
def render?
@render_check
end
end
================================================
FILE: app/components/truncated_text_component.html.erb
================================================
<div class="truncation-container" data-controller="truncated-text">
<div class="line-clamp-1" data-truncated-text-target="text">
<% if label %>
<span class="text-bold d-inline"><%= label %>:</span>
<% end %>
<%= text %>
</div>
<a
role="button"
href="#"
data-truncated-text-target="hideButton"
data-action="truncated-text#toggle:prevent"
class="d-none">[hide]</a>
<a
role="button"
href="#"
data-truncated-text-target="moreButton"
data-action="truncated-text#toggle:prevent">[read more]</a>
</div>
================================================
FILE: app/components/truncated_text_component.rb
================================================
# frozen_string_literal: true
class TruncatedTextComponent < ViewComponent::Base
attr_reader :text, :label
def initialize(text = nil, label: nil)
@text = text
@label = label
end
end
================================================
FILE: app/controllers/additional_expenses_controller.rb
================================================
class AdditionalExpensesController < ApplicationController
before_action :force_json_format
def create
@additional_expense = AdditionalExpense.new(additional_expense_params)
authorize @additional_expense
if @additional_expense.save
render json: @additional_expense.as_json, status: :created
else
render json: @additional_expense.errors.as_json, status: :unprocessable_content
end
end
def destroy
@additional_expense = AdditionalExpense.find(params[:id])
authorize @additional_expense
@additional_expense.destroy!
head :no_content
end
private
def additional_expense_params
params.require(:additional_expense)
.permit(:case_contact_id, :other_expense_amount, :other_expenses_describe)
end
end
================================================
FILE: app/controllers/all_casa_admins/casa_admins_controller.rb
================================================
class AllCasaAdmins::CasaAdminsController < AllCasaAdminsController
before_action :set_casa_org
def new
@casa_admin = CasaAdmin.new
end
def create
service = ::CreateCasaAdminService.new(@casa_org, params, current_user)
@casa_admin = service.build
begin
service.create!
redirect_to all_casa_admins_casa_org_path(@casa_org), notice: "New admin created successfully"
rescue ActiveRecord::RecordInvalid
render :new, status: :unprocessable_content
end
end
def edit
@casa_admin = CasaAdmin.find(params[:id])
end
def update
@casa_admin = CasaAdmin.find(params[:id])
if @casa_admin.update(all_casa_admin_params)
notice = check_unconfirmed_email_notice(@casa_admin)
@casa_admin.filter_old_emails!(@casa_admin.email)
redirect_to edit_all_casa_admins_casa_org_casa_admin_path(@casa_org), notice: notice
else
render :edit, status: :unprocessable_content
end
end
def activate
@casa_admin = CasaAdmin.find(params[:id])
if @casa_admin.activate
CasaAdminMailer.account_setup(@casa_admin).deliver
redirect_to edit_all_casa_admins_casa_org_casa_admin_path, notice: "Admin was activated. They have been sent an email."
else
render :edit, status: :unprocessable_content
end
end
def deactivate
@casa_admin = CasaAdmin.find(params[:id])
if @casa_admin.deactivate
CasaAdminMailer.deactivation(@casa_admin).deliver
redirect_to edit_all_casa_admins_casa_org_casa_admin_path, notice: "Admin was deactivated."
else
render :edit, status: :unprocessable_content
end
end
private
def set_casa_org
@casa_org = CasaOrg.find(params[:casa_org_id])
# @casa_org = CasaOrg.find_by(slug: params[:casa_org_id]) # TODO when using slugs
end
end
================================================
FILE: app/controllers/all_casa_admins/casa_orgs_controller.rb
================================================
class AllCasaAdmins::CasaOrgsController < AllCasaAdminsController
def show
@casa_org = CasaOrg.find(params[:id])
@casa_org_metrics = AllCasaAdmins::CasaOrgMetrics.new(@casa_org).metrics
end
def new
@casa_org = CasaOrg.new
end
def create
@casa_org = CasaOrg.new(casa_org_params)
if @casa_org.save
@casa_org.generate_defaults
respond_to do |format|
format.html do
redirect_to all_casa_admins_casa_org_path(@casa_org),
notice: "CASA Organization was successfully created."
end
format.json do
render json: @casa_org, status: :created
end
end
else
respond_to do |format|
format.html { render :new, status: :unprocessable_content }
format.json { render json: @casa_org.errors.full_messages, status: :unprocessable_content }
end
end
end
private
def casa_org_params
params.require(:casa_org).permit(:name, :display_name, :address)
end
end
================================================
FILE: app/controllers/all_casa_admins/dashboard_controller.rb
================================================
class AllCasaAdmins::DashboardController < AllCasaAdminsController
def show
@organizations = CasaOrg.all
end
end
================================================
FILE: app/controllers/all_casa_admins/patch_notes_controller.rb
================================================
class AllCasaAdmins::PatchNotesController < AllCasaAdminsController
# GET /patch_notes or /patch_notes.json
def index
@patch_note_groups = PatchNoteGroup.all
@patch_note_types = PatchNoteType.all
@patch_notes = PatchNote.order(created_at: :desc)
end
# POST /patch_notes or /patch_notes.json
def create
@patch_note = PatchNote.new(patch_note_params)
if @patch_note.save
render json: {status: :created, id: @patch_note.id}, status: :created
else
render json: {errors: @patch_note.errors.full_messages.to_json}, status: :unprocessable_content
end
end
# PATCH/PUT /patch_notes/1 or /patch_notes/1.json
def update
@patch_note = PatchNote.find(params[:id])
if @patch_note.update(patch_note_params)
render json: {status: :ok}
else
render json: {errors: @patch_note.errors.full_messages.to_json}, status: :unprocessable_content
end
end
# DELETE /patch_notes/1 or /patch_notes/1.json
def destroy
@patch_note = PatchNote.find(params[:id])
if @patch_note.destroy
render json: {status: :ok}
else
render json: {errors: @patch_note.errors.full_messages.to_json}, status: :unprocessable_content
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_patch_note
@patch_note = PatchNote.find(params[:id])
end
# Only allow a list of trusted parameters through.
def patch_note_params
params.permit(:note, :patch_note_group_id, :patch_note_type_id)
end
end
================================================
FILE: app/controllers/all_casa_admins/sessions_controller.rb
================================================
# frozen_string_literal: true
class AllCasaAdmins::SessionsController < Devise::SessionsController
include Accessible
skip_before_action :check_user, only: :destroy
end
================================================
FILE: app/controllers/all_casa_admins_controller.rb
================================================
class AllCasaAdminsController < ApplicationController
skip_before_action :authenticate_user!
before_action :authenticate_all_casa_admin!
before_action :set_custom_error_heading, only: [:update_password]
after_action :reset_custom_error_heading, only: [:update_password]
skip_after_action :verify_authorized
def new
@all_casa_admin = AllCasaAdmin.new
end
def edit
@user = current_all_casa_admin
end
def create
service = ::CreateAllCasaAdminService.new(params, current_user)
@all_casa_admin = service.build
begin
service.create!
respond_to do |format|
format.html do
redirect_to authenticated_all_casa_admin_root_path,
notice: "New All CASA admin created successfully"
end
format.json { render json: @all_casa_admin, status: :created }
end
rescue ActiveRecord::RecordInvalid
respond_to do |format|
format.html { render :new, status: :unprocessable_content }
format.json do
render json: @all_casa_admin.errors.full_messages, status: :unprocessable_content
end
end
end
end
def update
@user = current_all_casa_admin
if @user.update(all_casa_admin_params)
respond_to do |format|
format.html do
flash[:success] = "Profile was successfully updated."
redirect_to edit_all_casa_admins_path
end
format.json { render json: @user, status: :ok }
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @user.errors.full_messages, status: :unprocessable_content }
end
end
end
def update_password
@user = current_all_casa_admin
if @user.update(password_params)
bypass_sign_in(@user)
UserMailer.password_changed_reminder(@user).deliver
respond_to do |format|
format.html do
flash[:success] = "Password was successfully updated."
redirect_to edit_all_casa_admins_path
end
format.json { render json: "Password was successfully updated.", status: :ok }
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @user.errors.full_messages, status: :unprocessable_content }
end
end
end
private
def all_casa_admin_params
params.require(:all_casa_admin).permit(:email)
end
def password_params
params.require(:all_casa_admin).permit(:password, :password_confirmation)
end
def set_custom_error_heading
@custom_error_header = "password change"
end
def reset_custom_error_heading
@custom_error_header = nil
end
end
================================================
FILE: app/controllers/android_app_associations_controller.rb
================================================
class AndroidAppAssociationsController < ApplicationController
skip_before_action :authenticate_user!
def index
android_asset_link_data = [
{
relation: ["delegate_permission/common.handle_all_urls"],
target: {
namespace: "android_app",
package_name: "org.rubyforgood.casa",
sha256_cert_fingerprints: [ENV["ANDROID_CERTIFICATE_FINGERPRINT"]]
}
}
]
render json: android_asset_link_data.to_json
end
end
================================================
FILE: app/controllers/api/v1/base_controller.rb
================================================
class Api::V1::BaseController < ActionController::API
rescue_from ActiveRecord::RecordNotFound, with: :not_found
before_action :authenticate_user!, except: [:create, :destroy]
def authenticate_user!
api_token, options = ActionController::HttpAuthentication::Token.token_and_options(request)
user = User.find_by(email: options[:email])
if user && api_token && ActiveSupport::SecurityUtils.secure_compare(user.api_credential.api_token_digest, Digest::SHA256.hexdigest(api_token))
@current_user = user
else
render json: {message: "Incorrect email or password."}, status: 401
end
end
def not_found
api_error(status: 404, errors: "Not found")
end
end
================================================
FILE: app/controllers/api/v1/users/sessions_controller.rb
================================================
class Api::V1::Users::SessionsController < Api::V1::BaseController
def create
load_resource
if @user
render json: Api::V1::SessionBlueprint.render(@user, remember_me: user_params[:remember_me]), status: 201
else
render json: {message: "Incorrect email or password."}, status: 401
end
end
def destroy
# fetch access token from request header
api_token = request.headers["Authorization"]&.split(" ")&.last
# find user's api credentials by access token
api_credential = ApiCredential.find_by(api_token_digest: Digest::SHA256.hexdigest(api_token))
# set api and refresh tokens to nil; otherwise render 401
if api_credential
api_credential.revoke_api_token
api_credential.revoke_refresh_token
render json: {message: "Signed out successfully."}, status: 200
else
render json: {message: "An error occured when signing out."}, status: 401
nil
end
end
private
def user_params
params.permit(:email, :password, :remember_me)
end
def load_resource
@user = User.find_by(email: user_params[:email])
unless @user&.valid_password?(user_params[:password])
@user = nil
end
end
end
================================================
FILE: app/controllers/application_controller.rb
================================================
class ApplicationController < ActionController::Base
include Pundit::Authorization
include Pagy::Backend
include Organizational
include Users::TimeZone
protect_from_forgery
before_action :store_user_location!, if: :storable_location?
before_action :authenticate_user!
before_action :set_current_user
before_action :set_timeout_duration
before_action :set_current_organization
before_action :set_active_banner
after_action :verify_authorized, except: :index, unless: :devise_controller?
# after_action :verify_policy_scoped, only: :index
KNOWN_ERRORS = [Pundit::NotAuthorizedError, Organizational::UnknownOrganization]
rescue_from StandardError, with: :log_and_reraise
rescue_from Pundit::NotAuthorizedError, with: :not_authorized
rescue_from Organizational::UnknownOrganization, with: :not_authorized
rescue_from ActionController::UnknownFormat, with: :unsupported_media_type
impersonates :user
def after_sign_in_path_for(resource_or_scope)
stored_location_for(resource_or_scope) || super
end
def after_sign_out_path_for(resource_or_scope)
session[:user_return_to] = nil
if resource_or_scope == :all_casa_admin
new_all_casa_admin_session_path
else
root_path
end
end
def set_active_banner
return nil unless request.format.html?
return nil unless current_organization
@active_banner = current_organization.banners.active.first
@active_banner = nil if session[:dismissed_banner] == @active_banner&.id
@active_banner = nil if @active_banner&.expired?
end
protected
def handle_short_url(url_list)
hash_of_short_urls = {}
url_list.each_with_index { |val, index|
# call short io service to shorten url
# create an entry in hash if api is success
short_io_service = ShortUrlService.new
response = short_io_service.create_short_url(val)
short_url = short_io_service.short_url
hash_of_short_urls[index] = (response.code == 201 || response.code == 200) ? short_url : nil
}
hash_of_short_urls
end
# volunteer/supervisor/casa_admin controller uses to send SMS
# returns appropriate flash notice for SMS
def deliver_sms_to(resource, body_msg)
if resource.phone_number.blank? || !resource.casa_org.twilio_enabled?
return "blank"
end
body = body_msg
to = resource.phone_number
from = current_user.casa_org.twilio_phone_number
@twilio = TwilioService.new(current_user.casa_org)
req_params = {
From: from,
Body: body,
To: to
}
begin
twilio_res = @twilio.send_sms(req_params)
twilio_res.error_code.nil? ? "sent" : "error"
rescue Twilio::REST::RestError => error
@error = error
"error"
rescue # unverfied error isnt picked up by Twilio::Rest::RestError
# https://www.twilio.com/docs/errors/21608
@error = "Phone number is unverifiied"
"error"
end
end
def sms_acct_creation_notice(resource_name, sms_status)
case sms_status
when "blank"
"New #{resource_name} created successfully."
when "error"
"New #{resource_name} created successfully. SMS not sent. Error: #{@error}."
when "sent"
"New #{resource_name} created successfully. SMS has been sent!"
end
end
def store_referring_location
if request.referer && !request.referer.end_with?("users/sign_in") && params[:ignore_referer].blank?
session[:return_to] = request.referer
end
end
def redirect_back_to_referer(fallback_location:)
redirect_to(session[:return_to] || fallback_location)
end
private
# Allows us to not specify respond_to formats in json-only controller or action.
# Same behavior as when a request format is not defined in a respond_to block.
def force_json_format
raise ActionController::UnknownFormat unless request.format.json?
end
def store_user_location!
# the current URL can be accessed from a session
store_location_for(:user, request.fullpath)
end
def storable_location?
request.get? && is_navigational_format? && !devise_controller? && !request.xhr?
end
def set_current_user
RequestStore.store[:current_user] = current_user
end
def set_timeout_duration
return unless current_user
@timeout_duration = current_user.timeout_in
end
def set_current_organization
RequestStore.store[:current_organization] = current_organization
end
def not_authorized
message = "Sorry, you are not authorized to perform this action."
respond_to do |format|
format.json do
render json: {error: message}, status: :unauthorized
end
format.any do
session[:user_return_to] = nil
flash[:notice] = message
redirect_to(root_url)
end
end
end
def unsupported_media_type
respond_to do |format|
format.json do
render json: {error: "json unsupported"}, status: :unsupported_media_type
end
format.any do
flash[:alert] = "Page not found"
redirect_back_or_to root_url
end
end
end
def log_and_reraise(error)
unless KNOWN_ERRORS.include?(error.class)
Bugsnag.notify(error)
end
raise
end
def check_unconfirmed_email_notice(user)
notice = "#{user.role} was successfully updated."
if user.saved_changes.include?("unconfirmed_email")
notice += " Confirmation Email Sent."
end
notice
end
end
================================================
FILE: app/controllers/banners_controller.rb
================================================
class BannersController < ApplicationController
after_action :verify_authorized, except: %i[dismiss]
before_action :set_banner, only: %i[edit update destroy dismiss]
def index
authorize :application, :admin_or_supervisor?
@banners = current_organization.banners.includes(:user)
end
def new
authorize :application, :admin_or_supervisor?
@banner = Banner.new
end
def edit
authorize :application, :admin_or_supervisor?
end
def dismiss
session[:dismissed_banner] = @banner.id
render json: {status: :ok}
end
def create
authorize :application, :admin_or_supervisor?
@banner = current_organization.banners.build(banner_params)
Banner.transaction do
deactivate_alternate_active_banner
@banner.save!
end
redirect_to banners_path
rescue
render :new, status: :unprocessable_content
end
def update
authorize :application, :admin_or_supervisor?
Banner.transaction do
deactivate_alternate_active_banner
@banner.update!(banner_params)
end
redirect_to banners_path
rescue
render :edit, status: :unprocessable_content
end
def destroy
authorize :application, :admin_or_supervisor?
@banner.destroy
redirect_to banners_path
end
private
def set_banner
@banner = current_organization.banners.find(params[:id])
end
def banner_params
BannerParameters.new(params, current_user, browser_time_zone)
end
def deactivate_alternate_active_banner
if banner_params[:active].to_i == 1
alternate_active_banner = current_organization.banners.where(active: true).where.not(id: @banner.id).first
alternate_active_banner&.update!(active: false)
end
end
end
================================================
FILE: app/controllers/bulk_court_dates_controller.rb
================================================
class BulkCourtDatesController < ApplicationController
include CourtDateParams
before_action :require_organization!
def new
authorize :bulk_court_date, :new?
@court_date = CourtDate.new
end
def create
authorize :bulk_court_date, :create?
case_group_id = params[:court_date][:case_group_id]
if case_group_id.empty?
@court_date = build_court_date_with_error_message
render :new, status: :unprocessable_content
return
end
case_group = current_organization.case_groups.find(case_group_id)
court_dates = build_court_dates(case_group)
court_date_with_error = create_court_dates(court_dates)
if court_date_with_error
@court_date = court_date_with_error
render :new, status: :unprocessable_content
else
redirect_to new_bulk_court_date_path, notice: "#{court_dates.size} #{"court date".pluralize(court_dates.size)} created!"
end
end
private
def build_court_date_with_error_message
court_date = CourtDate.new(court_date_params(nil))
court_date.errors.add(:base, "Case group must be selected.")
court_date
end
def build_court_dates(case_group)
case_group.casa_cases.map do |casa_case|
CourtDate.new(court_date_params(casa_case).merge(casa_case: casa_case))
end
end
def create_court_dates(court_dates)
court_date_with_error = nil
ActiveRecord::Base.transaction do
court_dates.each do |court_date|
if !court_date.save
court_date_with_error = court_date
raise ActiveRecord::Rollback
end
end
end
court_date_with_error
end
end
================================================
FILE: app/controllers/casa_admins_controller.rb
================================================
class CasaAdminsController < ApplicationController
include SmsBodyHelper
before_action :set_admin, except: [:index, :new, :create]
before_action :require_organization!
after_action :verify_authorized
def index
authorize CasaAdmin
@admins = policy_scope(current_organization.casa_admins)
end
def edit
authorize @casa_admin
end
def update
authorize @casa_admin
if @casa_admin.update(update_casa_admin_params)
notice = check_unconfirmed_email_notice(@casa_admin)
@casa_admin.filter_old_emails!(@casa_admin.email)
respond_to do |format|
format.html { redirect_to edit_casa_admin_path(@casa_admin), notice: notice }
format.json { render json: @casa_admin, status: :ok }
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @casa_admin.errors.full_messages, status: :unprocessable_content }
end
end
end
def new
authorize CasaAdmin
@casa_admin = CasaAdmin.new
end
def create
service = ::CreateCasaAdminService.new(current_organization, params, current_user)
@casa_admin = service.build
authorize @casa_admin
sms_status = "blank"
begin
casa_admin = service.create!
if !casa_admin.phone_number.blank?
raw_token = casa_admin.raw_invitation_token
base_domain = request.base_url + "/users/edit"
invitation_url = Rails.application.routes.url_helpers.accept_user_invitation_url(invitation_token: raw_token, host: request.base_url)
hash_of_short_urls = handle_short_url([invitation_url, base_domain])
body_msg = account_activation_msg("admin", hash_of_short_urls)
sms_status = deliver_sms_to casa_admin, body_msg
end
respond_to do |format|
format.html { redirect_to casa_admins_path, notice: sms_acct_creation_notice("admin", sms_status) }
format.json { render json: @casa_admin, status: :created }
end
rescue ActiveRecord::RecordInvalid
respond_to do |format|
format.html { render :new, status: :unprocessable_content }
format.json { render json: service.casa_admin.errors.full_messages, status: :unprocessable_content }
end
end
end
def activate
authorize @casa_admin
if @casa_admin.activate
CasaAdminMailer.account_setup(@casa_admin).deliver
respond_to do |format|
format.html do
redirect_to edit_casa_admin_path(@casa_admin),
notice: "Admin was activated. They have been sent an email."
end
format.json { render json: @casa_admin, status: :ok }
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @casa_admin.errors.full_messages, status: :unprocessable_content }
end
end
rescue Errno::ECONNREFUSED => error
redirect_to_casa_admin_edition_page(error)
end
def deactivate
authorize @casa_admin
if @casa_admin.deactivate
CasaAdminMailer.deactivation(@casa_admin).deliver
respond_to do |format|
format.html { redirect_to edit_casa_admin_path(@casa_admin), notice: "Admin was deactivated." }
format.json { render json: @casa_admin, status: :ok }
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @casa_admin.errors.full_messages, status: :unprocessable_content }
end
end
rescue Errno::ECONNREFUSED => error
redirect_to_casa_admin_edition_page(error)
end
def resend_invitation
authorize @casa_admin
@casa_admin.invite!
redirect_to edit_casa_admin_path(@casa_admin), notice: "Invitation sent"
end
def change_to_supervisor
authorize @casa_admin
@casa_admin.change_to_supervisor!
redirect_to edit_supervisor_path(@casa_admin), notice: "Admin was changed to Supervisor."
end
private
def redirect_to_casa_admin_edition_page(error)
Bugsnag.notify(error)
redirect_to edit_casa_admin_path(@casa_admin), alert: "Email not sent."
end
def set_admin
@casa_admin = CasaAdmin.find(params[:id])
end
def update_casa_admin_params
CasaAdminParameters.new(params).with_only(:email, :display_name, :phone_number, :date_of_birth, :monthly_learning_hours_report)
end
def learning_hours_checked?
ActiveModel::Type::Boolean.new.cast(params[:monthly_learning_hours_report])
end
end
================================================
FILE: app/controllers/casa_cases_controller.rb
================================================
class CasaCasesController < ApplicationController
before_action :set_casa_case, only: %i[show edit update deactivate reactivate copy_court_orders]
before_action :set_contact_types, only: %i[new edit update create deactivate reactivate]
before_action :require_organization!
after_action :verify_authorized
def index
authorize CasaCase
org_cases = current_user.casa_org.casa_cases.includes(:assigned_volunteers)
@casa_cases = policy_scope(org_cases).includes([:hearing_type, :judge])
@casa_cases_filter_id = policy(CasaCase).can_see_filters? ? "casa-cases" : ""
@duties = OtherDuty.where(creator_id: current_user.id)
end
def show
authorize @casa_case
respond_to do |format|
format.html {}
format.csv do
case_contacts = @casa_case.decorate.case_contacts_ordered_by_occurred_at
csv = CaseContactsExportCsvService.new(case_contacts, CaseContactReport::COLUMNS).perform
send_data csv, filename: case_contact_csv_name(case_contacts)
end
format.xlsx do
filename = @casa_case.case_number + "-case-contacts-" + Time.now.strftime("%Y-%m-%d") + ".xlsx"
response.headers["Content-Disposition"] = "attachment; filename=#{filename}"
end
end
end
def new
@casa_case = CasaCase.new(casa_org: current_organization)
authorize @casa_case
end
def edit
@siblings_casa_cases = CasaCasePolicy::Scope.new(current_user, @casa_case).sibling_cases
authorize @casa_case
end
def create
@casa_case = CasaCase.new(
casa_case_create_params.merge(
casa_org: current_organization
)
)
authorize @casa_case
@casa_case.validate_contact_type = true
if @casa_case.save
respond_to do |format|
format.html { redirect_to @casa_case, notice: "CASA case was successfully created." }
format.json { render json: @casa_case, status: :created }
end
else
set_contact_types
@empty_court_date = court_date_unknown?
respond_to do |format|
format.html { render :new, status: :unprocessable_content }
format.json { render json: @casa_case.errors.full_messages, status: :unprocessable_content }
end
end
end
def update
authorize @casa_case
original_attributes = @casa_case.full_attributes_hash
@casa_case.validate_contact_type = true unless current_role == "Volunteer"
if @casa_case.update_cleaning_contact_types(casa_case_update_params)
updated_attributes = @casa_case.full_attributes_hash
changed_attributes_list = CasaCaseChangeService.new(original_attributes, updated_attributes).calculate
respond_to do |format|
format.html { redirect_to edit_casa_case_path, notice: "CASA case was successfully updated.#{changed_attributes_list}" }
format.json { render json: @casa_case, status: :ok }
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @casa_case.errors.full_messages, status: :unprocessable_content }
end
end
end
def deactivate
authorize @casa_case, :update_case_status?
if @casa_case.deactivate
respond_to do |format|
format.html do
flash_message = "Case #{@casa_case.case_number} has been deactivated."
redirect_to edit_casa_case_path(@casa_case), notice: flash_message
end
format.json do
render json: "Case #{@casa_case.case_number} has been deactivated.", status: :ok
end
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @casa_case.errors.full_messages, status: :unprocessable_content }
end
end
end
def reactivate
authorize @casa_case, :update_case_status?
if @casa_case.reactivate
respond_to do |format|
format.html do
flash_message = "Case #{@casa_case.case_number} has been reactivated."
redirect_to edit_casa_case_path(@casa_case), notice: flash_message
end
format.json do
render json: "Case #{@casa_case.case_number} has been reactivated.", status: :ok
end
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @casa_case.errors.full_messages, status: :unprocessable_content }
end
end
end
def copy_court_orders
authorize @casa_case, :update_court_orders?
CasaCase.find_by_case_number(params[:case_number_cp]).case_court_orders.each do |court_order|
dup_court_order = court_order.dup
dup_court_order.save
@casa_case.case_court_orders.append dup_court_order
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_casa_case
@casa_case = current_organization.casa_cases.friendly.find(params[:id])
rescue ActiveRecord::RecordNotFound
respond_to do |format|
format.html { redirect_to casa_cases_path, notice: "Sorry, you are not authorized to perform this action." }
format.json { render json: {error: "Sorry, you are not authorized to perform this action."}, status: :not_found }
end
end
# Only allow a list of trusted parameters through.
def casa_case_params
params.require(:casa_case).permit(
:case_number,
:birth_month_year_youth,
:date_in_care,
:court_report_due_date,
:empty_court_date,
contact_type_ids: [],
court_dates_attributes: [:date],
case_assignments_attributes: [:volunteer_id]
)
end
def casa_case_create_params
create_params = casa_case_params
create_params = create_params.except(:court_dates_attributes) if court_date_unknown?
create_params.except(:empty_court_date)
end
# Separate params so only admins can update the case_number
def casa_case_update_params
params.require(:casa_case).permit(policy(@casa_case).permitted_attributes)
end
def set_contact_types
@contact_types = current_organization.contact_types
@selected_contact_type_ids = (!@casa_case.nil?) ? @casa_case.contact_type_ids : []
end
def case_contact_csv_name(case_contacts)
casa_case_number = case_contacts&.first&.casa_case&.case_number
current_date = Time.now.strftime("%Y-%m-%d")
"#{casa_case_number.nil? ? "" : casa_case_number + "-"}case-contacts-#{current_date}.csv"
end
def court_date_unknown?
casa_case_params[:empty_court_date] == "1"
end
end
================================================
FILE: app/controllers/casa_org_controller.rb
================================================
class CasaOrgController < ApplicationController
before_action :set_casa_org, only: %i[edit update]
before_action :set_contact_type_data, only: %i[edit update]
before_action :set_hearing_types, only: %i[edit update]
before_action :set_judges, only: %i[edit update]
before_action :set_learning_hour_types, only: %i[edit update]
before_action :set_learning_hour_topics, only: %i[edit update]
before_action :set_sent_emails, only: %i[edit update]
before_action :set_contact_topics, only: %i[edit update]
before_action :set_custom_org_links, only: %i[edit update]
before_action :set_placement_types, only: %i[edit update]
before_action :require_organization!
after_action :verify_authorized
before_action :set_active_storage_url_options, only: %i[edit update]
def edit
authorize @casa_org
end
def update
authorize @casa_org
if @casa_org.update(casa_org_update_params)
respond_to do |format|
format.html do
redirect_to edit_casa_org_path, notice: "CASA organization was successfully updated."
end
format.json { render json: @casa_org, status: :ok }
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @casa_org.errors.full_messages, status: :unprocessable_content }
end
end
end
private
def set_casa_org
@casa_org = current_organization
rescue ActiveRecord::RecordNotFound
head :not_found
end
def casa_org_update_params
params.require(:casa_org).permit(
:name,
:display_name,
:address,
:logo,
:court_report_template,
:show_driving_reimbursement,
:additional_expenses_enabled,
:other_duties_enabled,
:twilio_account_sid,
:twilio_phone_number,
:twilio_api_key_sid,
:twilio_api_key_secret,
:twilio_enabled,
:learning_topic_active
)
end
def set_contact_type_data
@contact_type_groups = @casa_org.contact_type_groups.order(:name)
@contact_types = ContactType.for_organization(@casa_org).order(:name)
end
def set_hearing_types
@hearing_types = HearingType.for_organization(@casa_org)
end
def set_judges
@judges = Judge.for_organization(@casa_org)
end
def set_learning_hour_types
@learning_hour_types = LearningHourType.for_organization(@casa_org)
end
def set_sent_emails
@sent_emails = SentEmail.for_organization(@casa_org).order("created_at DESC").limit(10)
end
def set_learning_hour_topics
@learning_hour_topics = LearningHourTopic.for_organization(@casa_org)
end
def set_contact_topics
@contact_topics = @casa_org.contact_topics.where(soft_delete: false)
end
def set_custom_org_links
@custom_org_links = @casa_org.custom_org_links
end
def set_placement_types
@placement_types = @casa_org.placement_types
end
def set_active_storage_url_options
ActiveStorage::Current.url_options = {host: request.base_url}
end
end
================================================
FILE: app/controllers/case_assignments_controller.rb
================================================
class CaseAssignmentsController < ApplicationController
before_action :load_case_assignment, only: %i[destroy unassign show_hide_contacts reimbursement]
after_action :verify_authorized
def create
authorize CaseAssignment
if existing_case_assignment.present?
if existing_case_assignment.update(active: true)
handle_successful_assignment("Volunteer reassigned to case")
else
errors = existing_case_assignment.errors.full_messages.join(". ")
handle_failed_assignment("Unable to reassign volunteer to case: #{errors}.")
end
else
case_assignment = case_assignment_parent.case_assignments.new(case_assignment_params)
if case_assignment.save
handle_successful_assignment("Volunteer assigned to case")
else
errors = case_assignment.errors.full_messages.join(". ")
handle_failed_assignment("Unable to assign volunteer to case: #{errors}.")
end
end
respond_to do |format|
format.html { redirect_to after_action_path(case_assignment_parent) }
format.json { render json: @message, status: @status }
end
end
# TODO don't delete this, just deactivate it
def destroy
authorize @case_assignment
@case_assignment.destroy
redirect_to after_action_path(case_assignment_parent)
end
def unassign
authorize @case_assignment, :unassign?
casa_case = @case_assignment.casa_case
volunteer = @case_assignment.volunteer
message = "Volunteer was unassigned from Case #{casa_case.case_number}."
if @case_assignment.update(active: false)
if params[:redirect_to_path] == "volunteer"
redirect_to edit_volunteer_path(volunteer), notice: message
else
respond_to do |format|
format.html { redirect_to after_action_path(casa_case), notice: message }
format.json { render json: message, status: :ok }
end
end
else
respond_to do |format|
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @case_assignment.errors.full_messages, status: :unprocessable_content }
end
end
end
def show_hide_contacts
authorize @case_assignment, :show_or_hide_contacts?
casa_case = @case_assignment.casa_case
volunteer = @case_assignment.volunteer
flash_message = "Old Case Contacts created by #{volunteer.display_name} #{@case_assignment.hide_old_contacts? ? "are now visible" : "were successfully hidden"}."
@case_assignment.toggle!(:hide_old_contacts)
redirect_to after_action_path(casa_case), notice: flash_message
end
def reimbursement
casa_case = @case_assignment.casa_case
message = "Volunteer allow reimbursement changed from Case #{casa_case.case_number}."
authorize @case_assignment, :reimbursement?
if @case_assignment.update(allow_reimbursement: !@case_assignment.allow_reimbursement)
redirect_to after_action_path(casa_case), notice: message
end
end
private
def case_assignment_parent
if params[:volunteer_id]
User.find(params[:volunteer_id])
else
CasaCase.friendly.find(params[:casa_case_id])
end
end
def after_action_path(resource)
if resource.is_a? User
edit_volunteer_path(resource)
else
edit_casa_case_path(resource)
end
end
def case_assignment_params
params.require(:case_assignment).permit(:casa_case_id, :volunteer_id, :reimbursement)
end
def load_case_assignment
@case_assignment =
CaseAssignment
.joins(:casa_case)
.where(casa_cases: {casa_org_id: current_organization.id})
.find(params[:id])
rescue ActiveRecord::RecordNotFound
head :not_found
end
def load_existing_case_assignment
case_assignments = case_assignment_parent.case_assignments
if params[:volunteer_id]
case_assignments.where(casa_case_id: case_assignment_params[:casa_case_id], active: false).first
else
case_assignments.where(volunteer_id: case_assignment_params[:volunteer_id], active: false).first
end
end
def existing_case_assignment
@existing_case_assignment ||= load_existing_case_assignment
end
def handle_successful_assignment(msg)
@message = msg
flash.notice = msg
@status = :ok
end
def handle_failed_assignment(msg)
@message = msg
flash.alert = msg
@status = :unprocessable_content
end
end
================================================
FILE: app/controllers/case_contact_reports_controller.rb
================================================
require "csv"
class CaseContactReportsController < ApplicationController
after_action :verify_authorized
def index
authorize :application, :see_reports_page?
case_contact_report = CaseContactReport.new(report_params)
respond_to do |format|
format.csv do
send_data case_contact_report.to_csv,
filename: "case-contacts-report-#{Time.zone.now.to_i}.csv"
end
end
end
private
def report_params
parameters = params.require(:report).permit(
:start_date,
:end_date,
:contact_made,
:has_transitioned,
:want_driving_reimbursement,
:other_expense_amount,
:other_expenses_describe,
contact_type_ids: [],
contact_type_group_ids: [],
creator_ids: [],
supervisor_ids: [],
casa_case_ids: [],
filtered_csv_cols: {}
).merge(casa_org_id: current_organization.id)
convert_radio_options_to_boolean(parameters)
parameters
end
def convert_radio_options_to_boolean(parameters)
parameters[:contact_made] = string_to_boolean(parameters[:contact_made])
parameters[:has_transitioned] = string_to_boolean(parameters[:has_transitioned])
parameters[:want_driving_reimbursement] = string_to_boolean(parameters[:want_driving_reimbursement])
end
def string_to_boolean(value)
if value == "true"
true
else
((value == "false") ? false : "")
end
end
end
================================================
FILE: app/controllers/case_contacts/case_contacts_new_design_controller.rb
================================================
class CaseContacts::CaseContactsNewDesignController < ApplicationController
include LoadsCaseContacts
before_action :check_feature_flag
def index
load_case_contacts
end
def datatable
authorize CaseContact
case_contacts = policy_scope(current_organization.case_contacts)
datatable = CaseContactDatatable.new(case_contacts, params, current_user)
render json: datatable
end
private
def check_feature_flag
unless Flipper.enabled?(:new_case_contact_table)
redirect_to case_contacts_path, alert: "This feature is not available."
end
end
end
================================================
FILE: app/controllers/case_contacts/followups_controller.rb
================================================
class CaseContacts::FollowupsController < ApplicationController
after_action :verify_authorized
def create
authorize Followup
case_contact = CaseContact.find(params[:case_contact_id])
note = simple_followup_params[:note]
FollowupService.create_followup(case_contact, current_user, note)
respond_to do |format|
format.html { redirect_to casa_case_path(case_contact.casa_case) }
format.json { head :no_content }
end
end
def resolve
@followup = Followup.find(params[:id])
authorize @followup
@followup.resolved!
create_notification
respond_to do |format|
format.html { redirect_to casa_case_path(@followup.case_contact.casa_case) }
format.json { head :no_content }
end
end
private
def simple_followup_params
params.permit(:note)
end
def create_notification
return if current_user == @followup.creator
FollowupResolvedNotifier
.with(followup: @followup, created_by: current_user)
.deliver(@followup.creator)
end
end
================================================
FILE: app/controllers/case_contacts/form_controller.rb
================================================
class CaseContacts::FormController < ApplicationController
include Wicked::Wizard
before_action :require_organization!
before_action :set_case_contact, only: [:show, :update]
after_action :verify_authorized
steps :details
def show
authorize @case_contact
prepare_form
render_wizard
end
def update
authorize @case_contact
remove_nil_draft_ids
respond_to do |format|
format.html do
params[:case_contact][:status] = CaseContact.statuses[step] if !@case_contact.active?
if @case_contact.update(case_contact_params)
finish_editing
else
prepare_form
render step
end
end
format.json do
if @case_contact.update(case_contact_params)
render json: @case_contact, status: :ok
else
render json: @case_contact.errors.full_messages, status: :unprocessable_content
end
end
end
end
private
def set_case_contact
@case_contact = CaseContact
.includes(:creator, :contact_topic_answers)
.find(params[:case_contact_id])
end
def prepare_form
@casa_cases = get_casa_cases
contact_types = get_contact_types.decorate
@grouped_contact_types = group_contact_types_by_name(contact_types)
@contact_topics = get_contact_topics
if !@case_contact.active? && @case_contact.contact_topic_answers.empty?
if @contact_topics.present?
@case_contact.contact_topic_answers.create
end
end
end
def get_casa_cases
casa_cases = policy_scope(current_organization.casa_cases).includes([:volunteers])
casa_cases = casa_cases.where(id: @case_contact.casa_case_id) if @case_contact.active?
casa_cases
end
def get_contact_types
gitextract_7qaocwti/
├── .allow_skipping_tests
├── .better-html.yml
├── .browserslistrc
├── .devcontainer/
│ ├── Dockerfile
│ ├── devcontainer.json
│ ├── docker-compose.yml
│ └── post-create.sh
├── .dockerignore
├── .erb_lint.yml
├── .github/
│ ├── CODEOWNERS
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── chore.md
│ │ ├── config.yml
│ │ ├── documentation.md
│ │ ├── feature_request.md
│ │ ├── flaky_test.md
│ │ └── problem_validation.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── autoapproval.yml
│ ├── dependabot.yml
│ ├── instructions/
│ │ ├── copilot-review.instructions.md
│ │ └── ruby.instructions.md
│ ├── labeler.yml
│ └── workflows/
│ ├── add-labels-based-on-column.yml
│ ├── after-deploy.yml
│ ├── codeql-analysis.yml
│ ├── combine_and_report.yml
│ ├── docker.yml
│ ├── erb_lint.yml
│ ├── factory_bot_lint.yml
│ ├── issue-auto-close-done.yml
│ ├── issue-auto-unassign.yml
│ ├── label.yml
│ ├── npm_lint_and_test.yml
│ ├── rake-after_party.yml
│ ├── remove-helped-wanted.yml
│ ├── remove-label-based-on-column.yml
│ ├── rspec.yml
│ ├── ruby_lint.yml
│ ├── security.yml
│ ├── spec_checker.yml
│ ├── stale.yml
│ ├── toc.yml
│ └── yaml_lint.yml
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierrc.yml
├── .rspec
├── .rspec_parallel
├── .rubocop.yml
├── .ruby-gemset
├── .ruby-version
├── .slugignore
├── .standard.yml
├── .standard_todo.yml
├── .tool-versions
├── .yamllint.yml
├── CONTRIBUTING.md
├── DEPLOY_CHECKLIST.md
├── Dockerfile
├── Gemfile
├── LICENSE.md
├── PROSOPITE_TODO.md
├── Procfile
├── Procfile.dev
├── README.md
├── Rakefile
├── SECURITY.md
├── app/
│ ├── assets/
│ │ ├── builds/
│ │ │ └── .keep
│ │ ├── config/
│ │ │ └── manifest.js
│ │ └── stylesheets/
│ │ ├── actiontext.css
│ │ ├── android_app_associations.css
│ │ ├── application.scss
│ │ ├── base/
│ │ │ ├── breakpoints.scss
│ │ │ └── variables.scss
│ │ ├── pages/
│ │ │ ├── all_casa_admin_dashboard.scss
│ │ │ ├── casa_cases.scss
│ │ │ ├── casa_org.scss
│ │ │ ├── case_contacts.scss
│ │ │ ├── case_contacts_form.scss
│ │ │ ├── case_court_reports.scss
│ │ │ ├── court_dates.scss
│ │ │ ├── emancipation.scss
│ │ │ ├── feature_flags.scss
│ │ │ ├── login.scss
│ │ │ ├── password.scss
│ │ │ ├── patch_notes.scss
│ │ │ ├── reimbursements.scss
│ │ │ ├── supervisors.scss
│ │ │ └── volunteers.scss
│ │ └── shared/
│ │ ├── dashboard.scss
│ │ ├── data_tables_overide.scss
│ │ ├── flashes.scss
│ │ ├── footer.scss
│ │ ├── form.scss
│ │ ├── header.scss
│ │ ├── layout.scss
│ │ ├── navbar.scss
│ │ ├── noscript.css
│ │ ├── notifier.scss
│ │ ├── select2_additional_styles.scss
│ │ ├── sidebar.scss
│ │ ├── tomselect_additional_styles.scss
│ │ ├── truncated_text_component.scss
│ │ ├── typography.scss
│ │ ├── utilities.scss
│ │ └── validated_form_component.scss
│ ├── blueprints/
│ │ └── api/
│ │ └── v1/
│ │ └── session_blueprint.rb
│ ├── callbacks/
│ │ └── case_contact_metadata_callback.rb
│ ├── channels/
│ │ └── application_cable/
│ │ ├── channel.rb
│ │ └── connection.rb
│ ├── components/
│ │ ├── badge_component.html.erb
│ │ ├── badge_component.rb
│ │ ├── dropdown_menu_component.html.erb
│ │ ├── dropdown_menu_component.rb
│ │ ├── form/
│ │ │ ├── hour_minute_duration_component.html.erb
│ │ │ ├── hour_minute_duration_component.rb
│ │ │ ├── multiple_select/
│ │ │ │ ├── item_component.html.erb
│ │ │ │ └── item_component.rb
│ │ │ ├── multiple_select_component.html.erb
│ │ │ └── multiple_select_component.rb
│ │ ├── local_time_component.html.erb
│ │ ├── local_time_component.rb
│ │ ├── modal/
│ │ │ ├── body_component.html.erb
│ │ │ ├── body_component.rb
│ │ │ ├── footer_component.html.erb
│ │ │ ├── footer_component.rb
│ │ │ ├── group_component.html.erb
│ │ │ ├── group_component.rb
│ │ │ ├── header_component.html.erb
│ │ │ ├── header_component.rb
│ │ │ ├── open_button_component.html.erb
│ │ │ ├── open_button_component.rb
│ │ │ ├── open_link_component.html.erb
│ │ │ └── open_link_component.rb
│ │ ├── notification_component.html.erb
│ │ ├── notification_component.rb
│ │ ├── sidebar/
│ │ │ ├── group_component.html.erb
│ │ │ ├── group_component.rb
│ │ │ ├── link_component.html.erb
│ │ │ └── link_component.rb
│ │ ├── truncated_text_component.html.erb
│ │ └── truncated_text_component.rb
│ ├── controllers/
│ │ ├── additional_expenses_controller.rb
│ │ ├── all_casa_admins/
│ │ │ ├── casa_admins_controller.rb
│ │ │ ├── casa_orgs_controller.rb
│ │ │ ├── dashboard_controller.rb
│ │ │ ├── patch_notes_controller.rb
│ │ │ └── sessions_controller.rb
│ │ ├── all_casa_admins_controller.rb
│ │ ├── android_app_associations_controller.rb
│ │ ├── api/
│ │ │ └── v1/
│ │ │ ├── base_controller.rb
│ │ │ └── users/
│ │ │ └── sessions_controller.rb
│ │ ├── application_controller.rb
│ │ ├── banners_controller.rb
│ │ ├── bulk_court_dates_controller.rb
│ │ ├── casa_admins_controller.rb
│ │ ├── casa_cases_controller.rb
│ │ ├── casa_org_controller.rb
│ │ ├── case_assignments_controller.rb
│ │ ├── case_contact_reports_controller.rb
│ │ ├── case_contacts/
│ │ │ ├── case_contacts_new_design_controller.rb
│ │ │ ├── followups_controller.rb
│ │ │ └── form_controller.rb
│ │ ├── case_contacts_controller.rb
│ │ ├── case_court_orders_controller.rb
│ │ ├── case_court_reports_controller.rb
│ │ ├── case_groups_controller.rb
│ │ ├── checklist_items_controller.rb
│ │ ├── concerns/
│ │ │ ├── accessible.rb
│ │ │ ├── court_date_params.rb
│ │ │ ├── loads_case_contacts.rb
│ │ │ ├── organizational.rb
│ │ │ └── users/
│ │ │ └── time_zone.rb
│ │ ├── contact_topic_answers_controller.rb
│ │ ├── contact_topics_controller.rb
│ │ ├── contact_type_groups_controller.rb
│ │ ├── contact_types_controller.rb
│ │ ├── court_dates_controller.rb
│ │ ├── custom_org_links_controller.rb
│ │ ├── dashboard_controller.rb
│ │ ├── emancipation_checklists_controller.rb
│ │ ├── emancipations_controller.rb
│ │ ├── error_controller.rb
│ │ ├── followup_reports_controller.rb
│ │ ├── fund_requests_controller.rb
│ │ ├── health_controller.rb
│ │ ├── hearing_types_controller.rb
│ │ ├── imports_controller.rb
│ │ ├── judges_controller.rb
│ │ ├── languages_controller.rb
│ │ ├── learning_hour_topics_controller.rb
│ │ ├── learning_hour_types_controller.rb
│ │ ├── learning_hours/
│ │ │ └── volunteers_controller.rb
│ │ ├── learning_hours_controller.rb
│ │ ├── learning_hours_reports_controller.rb
│ │ ├── mileage_rates_controller.rb
│ │ ├── mileage_reports_controller.rb
│ │ ├── missing_data_reports_controller.rb
│ │ ├── notes_controller.rb
│ │ ├── notifications_controller.rb
│ │ ├── other_duties_controller.rb
│ │ ├── placement_reports_controller.rb
│ │ ├── placement_types_controller.rb
│ │ ├── placements_controller.rb
│ │ ├── preference_sets_controller.rb
│ │ ├── reimbursements_controller.rb
│ │ ├── reports_controller.rb
│ │ ├── static_controller.rb
│ │ ├── supervisor_volunteers_controller.rb
│ │ ├── supervisors_controller.rb
│ │ ├── users/
│ │ │ ├── invitations_controller.rb
│ │ │ ├── passwords_controller.rb
│ │ │ └── sessions_controller.rb
│ │ ├── users_controller.rb
│ │ └── volunteers_controller.rb
│ ├── datatables/
│ │ ├── application_datatable.rb
│ │ ├── case_contact_datatable.rb
│ │ ├── reimbursement_datatable.rb
│ │ ├── supervisor_datatable.rb
│ │ └── volunteer_datatable.rb
│ ├── decorators/
│ │ ├── android_app_association_decorator.rb
│ │ ├── application_decorator.rb
│ │ ├── casa_case_decorator.rb
│ │ ├── case_assignment_decorator.rb
│ │ ├── case_contact_decorator.rb
│ │ ├── case_contacts/
│ │ │ └── form_decorator.rb
│ │ ├── contact_type_decorator.rb
│ │ ├── court_date_decorator.rb
│ │ ├── learning_hour_decorator.rb
│ │ ├── learning_hour_topic_decorator.rb
│ │ ├── other_duty_decorator.rb
│ │ ├── patch_note_decorator.rb
│ │ ├── placement_decorator.rb
│ │ ├── user_decorator.rb
│ │ └── volunteer_decorator.rb
│ ├── documents/
│ │ └── templates/
│ │ ├── default_report_template.docx
│ │ ├── emancipation_checklist_template.docx
│ │ ├── howard_county_report_template.docx
│ │ ├── montgomery_report_template.docx
│ │ ├── montgomery_report_template_062022.docx
│ │ └── prince_george_report_template.docx
│ ├── helpers/
│ │ ├── all_casa_admins/
│ │ │ └── casa_orgs_helper.rb
│ │ ├── api_base_helper.rb
│ │ ├── application_helper.rb
│ │ ├── banner_helper.rb
│ │ ├── case_contacts_helper.rb
│ │ ├── contact_types_helper.rb
│ │ ├── court_dates_helper.rb
│ │ ├── court_orders_helper.rb
│ │ ├── date_helper.rb
│ │ ├── emancipations_helper.rb
│ │ ├── followup_helper.rb
│ │ ├── learning_hours_helper.rb
│ │ ├── mileage_rates_helper.rb
│ │ ├── notifications_helper.rb
│ │ ├── other_duties_helper.rb
│ │ ├── phone_number_helper.rb
│ │ ├── preference_sets_helper.rb
│ │ ├── report_helper.rb
│ │ ├── request_header_helper.rb
│ │ ├── sidebar_helper.rb
│ │ ├── sms_body_helper.rb
│ │ ├── template_helper.rb
│ │ ├── ui_helper.rb
│ │ └── volunteer_helper.rb
│ ├── javascript/
│ │ ├── __mocks__/
│ │ │ ├── fileMock.js
│ │ │ └── styleMock.js
│ │ ├── __tests__/
│ │ │ ├── add_to_calendar_button.test.js
│ │ │ ├── casa_case.test.js
│ │ │ ├── case_button_states.test.js
│ │ │ ├── case_contact.test.js
│ │ │ ├── case_emancipations.test.js
│ │ │ ├── dashboard.test.js
│ │ │ ├── notifier.test.js
│ │ │ ├── password_confirmation.test.js
│ │ │ ├── read_more.test.js
│ │ │ ├── require_communication_preference.test.js
│ │ │ ├── setup-jest.js
│ │ │ ├── time_zone.test.js
│ │ │ ├── two_minute_warning_session_timeout.test.js
│ │ │ ├── type_checker.test.js
│ │ │ └── validated_form.test.js
│ │ ├── all_casa_admin.js
│ │ ├── application.js
│ │ ├── controllers/
│ │ │ ├── alert_controller.js
│ │ │ ├── application.js
│ │ │ ├── autosave_controller.js
│ │ │ ├── casa_nested_form_controller.js
│ │ │ ├── case_contact_form_controller.js
│ │ │ ├── court_order_form_controller.js
│ │ │ ├── disable_form_controller.js
│ │ │ ├── dismiss_controller.js
│ │ │ ├── hello_controller.js
│ │ │ ├── icon_toggle_controller.js
│ │ │ ├── index.js
│ │ │ ├── multiple_select_controller.js
│ │ │ ├── navbar_controller.js
│ │ │ ├── select_all_controller.js
│ │ │ ├── sidebar_controller.js
│ │ │ ├── sidebar_group_controller.js
│ │ │ └── truncated_text_controller.js
│ │ ├── datatable.js
│ │ ├── jQueryGlobalizer.js
│ │ ├── src/
│ │ │ ├── add_to_calendar_button.js
│ │ │ ├── all_casa_admin/
│ │ │ │ ├── patch_notes.js
│ │ │ │ └── tables.js
│ │ │ ├── casa_case.js
│ │ │ ├── casa_org.js
│ │ │ ├── case_contact.js
│ │ │ ├── case_emancipation.js
│ │ │ ├── dashboard.js
│ │ │ ├── display_app_metric.js
│ │ │ ├── emancipations.js
│ │ │ ├── import.js
│ │ │ ├── learning_hours.js
│ │ │ ├── new_casa_case.js
│ │ │ ├── notifier.js
│ │ │ ├── password_confirmation.js
│ │ │ ├── read_more.js
│ │ │ ├── reimbursements.js
│ │ │ ├── reports.js
│ │ │ ├── require_communication_preference.js
│ │ │ ├── select.js
│ │ │ ├── session_timeout_poller.js
│ │ │ ├── sms_reactivation_toggle.js
│ │ │ ├── time_zone.js
│ │ │ ├── tooltip.js
│ │ │ ├── type_checker.js
│ │ │ └── validated_form.js
│ │ └── sweet-alert-confirm.js
│ ├── jobs/
│ │ └── application_job.rb
│ ├── lib/
│ │ └── importers/
│ │ ├── case_importer.rb
│ │ ├── file_importer.rb
│ │ ├── supervisor_importer.rb
│ │ └── volunteer_importer.rb
│ ├── mailers/
│ │ ├── application_mailer.rb
│ │ ├── casa_admin_mailer.rb
│ │ ├── fund_request_mailer.rb
│ │ ├── learning_hours_mailer.rb
│ │ ├── supervisor_mailer.rb
│ │ ├── user_mailer.rb
│ │ └── volunteer_mailer.rb
│ ├── models/
│ │ ├── additional_expense.rb
│ │ ├── address.rb
│ │ ├── all_casa_admin.rb
│ │ ├── all_casa_admins/
│ │ │ └── casa_org_metrics.rb
│ │ ├── api_credential.rb
│ │ ├── application_record.rb
│ │ ├── banner.rb
│ │ ├── casa_admin.rb
│ │ ├── casa_case.rb
│ │ ├── casa_case_contact_type.rb
│ │ ├── casa_case_emancipation_category.rb
│ │ ├── casa_case_emancipation_option.rb
│ │ ├── casa_org.rb
│ │ ├── case_assignment.rb
│ │ ├── case_contact.rb
│ │ ├── case_contact_contact_type.rb
│ │ ├── case_contact_report.rb
│ │ ├── case_court_order.rb
│ │ ├── case_court_report.rb
│ │ ├── case_court_report_context.rb
│ │ ├── case_group.rb
│ │ ├── case_group_membership.rb
│ │ ├── checklist_item.rb
│ │ ├── concerns/
│ │ │ ├── CasaCase/
│ │ │ │ └── validations.rb
│ │ │ ├── api.rb
│ │ │ ├── by_organization_scope.rb
│ │ │ └── roles.rb
│ │ ├── contact_topic.rb
│ │ ├── contact_topic_answer.rb
│ │ ├── contact_type.rb
│ │ ├── contact_type_group.rb
│ │ ├── court_date.rb
│ │ ├── custom_org_link.rb
│ │ ├── emancipation_category.rb
│ │ ├── emancipation_option.rb
│ │ ├── followup.rb
│ │ ├── fund_request.rb
│ │ ├── health.rb
│ │ ├── hearing_type.rb
│ │ ├── judge.rb
│ │ ├── language.rb
│ │ ├── learning_hour.rb
│ │ ├── learning_hour_topic.rb
│ │ ├── learning_hour_type.rb
│ │ ├── learning_hours_report.rb
│ │ ├── login_activity.rb
│ │ ├── mileage_rate.rb
│ │ ├── mileage_report.rb
│ │ ├── missing_data_report.rb
│ │ ├── note.rb
│ │ ├── other_duty.rb
│ │ ├── patch_note.rb
│ │ ├── patch_note_group.rb
│ │ ├── patch_note_type.rb
│ │ ├── placement.rb
│ │ ├── placement_type.rb
│ │ ├── preference_set.rb
│ │ ├── sent_email.rb
│ │ ├── sms_notification_event.rb
│ │ ├── supervisor.rb
│ │ ├── supervisor_volunteer.rb
│ │ ├── user.rb
│ │ ├── user_language.rb
│ │ ├── user_reminder_time.rb
│ │ ├── user_sms_notification_event.rb
│ │ └── volunteer.rb
│ ├── notifications/
│ │ ├── base_notifier.rb
│ │ ├── delivery_methods/
│ │ │ └── sms.rb
│ │ ├── emancipation_checklist_reminder_notifier.rb
│ │ ├── followup_notifier.rb
│ │ ├── followup_resolved_notifier.rb
│ │ ├── reimbursement_complete_notifier.rb
│ │ ├── volunteer_birthday_notifier.rb
│ │ └── youth_birthday_notifier.rb
│ ├── policies/
│ │ ├── additional_expense_policy.rb
│ │ ├── application_policy.rb
│ │ ├── bulk_court_date_policy.rb
│ │ ├── casa_admin_policy.rb
│ │ ├── casa_case_policy.rb
│ │ ├── casa_org_policy.rb
│ │ ├── case_assignment_policy.rb
│ │ ├── case_contact_policy.rb
│ │ ├── case_court_order_policy.rb
│ │ ├── case_court_report_policy.rb
│ │ ├── case_group_policy.rb
│ │ ├── checklist_item_policy.rb
│ │ ├── contact_topic_answer_policy.rb
│ │ ├── contact_topic_policy.rb
│ │ ├── contact_type_group_policy.rb
│ │ ├── contact_type_policy.rb
│ │ ├── court_date_policy.rb
│ │ ├── custom_org_link_policy.rb
│ │ ├── dashboard_policy.rb
│ │ ├── followup_policy.rb
│ │ ├── fund_request_policy.rb
│ │ ├── hearing_type_policy.rb
│ │ ├── import_policy.rb
│ │ ├── judge_policy.rb
│ │ ├── language_policy.rb
│ │ ├── learning_hour_policy.rb
│ │ ├── learning_hour_topic_policy.rb
│ │ ├── learning_hour_type_policy.rb
│ │ ├── nil_class_policy.rb
│ │ ├── note_policy.rb
│ │ ├── notification_policy.rb
│ │ ├── other_duty_policy.rb
│ │ ├── patch_note_policy.rb
│ │ ├── placement_policy.rb
│ │ ├── placement_type_policy.rb
│ │ ├── reimbursement_policy.rb
│ │ ├── supervisor_policy.rb
│ │ ├── supervisor_volunteer_policy.rb
│ │ ├── user_policy.rb
│ │ └── volunteer_policy.rb
│ ├── presenters/
│ │ ├── base_presenter.rb
│ │ └── case_contact_presenter.rb
│ ├── services/
│ │ ├── additional_expense_params_service.rb
│ │ ├── backfill_followupable_service.rb
│ │ ├── casa_case_change_service.rb
│ │ ├── case_contacts_contact_dates.rb
│ │ ├── case_contacts_export_csv_service.rb
│ │ ├── court_report_due_sms_reminder_service.rb
│ │ ├── court_report_format_contact_date.rb
│ │ ├── create_all_casa_admin_service.rb
│ │ ├── create_casa_admin_service.rb
│ │ ├── deployment/
│ │ │ └── backfill_case_contact_started_metadata_service.rb
│ │ ├── emancipation_checklist_download_html.rb
│ │ ├── emancipation_checklist_reminder_service.rb
│ │ ├── failed_import_csv_service.rb
│ │ ├── fdf_inputs_service.rb
│ │ ├── followup_export_csv_service.rb
│ │ ├── followup_service.rb
│ │ ├── inactive_messages_service.rb
│ │ ├── learning_hours_export_csv_service.rb
│ │ ├── mileage_export_csv_service.rb
│ │ ├── missing_data_export_csv_service.rb
│ │ ├── no_contact_made_sms_reminder_service.rb
│ │ ├── placement_export_csv_service.rb
│ │ ├── preference_set_table_state_service.rb
│ │ ├── short_url_service.rb
│ │ ├── sms_reminder_service.rb
│ │ ├── svg_sanitizer_service.rb
│ │ ├── twilio_service.rb
│ │ ├── volunteer_birthday_reminder_service.rb
│ │ └── volunteers_emails_export_csv_service.rb
│ ├── validators/
│ │ ├── casa_org_validator.rb
│ │ ├── court_report_validator.rb
│ │ ├── url_validator.rb
│ │ └── user_validator.rb
│ ├── values/
│ │ ├── all_casa_admin_parameters.rb
│ │ ├── banner_parameters.rb
│ │ ├── casa_admin_parameters.rb
│ │ ├── case_contact_parameters.rb
│ │ ├── supervisor_parameters.rb
│ │ ├── user_parameters.rb
│ │ └── volunteer_parameters.rb
│ └── views/
│ ├── active_storage/
│ │ └── blobs/
│ │ └── _blob.html.erb
│ ├── all_casa_admins/
│ │ ├── casa_admins/
│ │ │ ├── _form.html.erb
│ │ │ ├── edit.html.erb
│ │ │ └── new.html.erb
│ │ ├── casa_orgs/
│ │ │ ├── new.html.erb
│ │ │ └── show.html.erb
│ │ ├── dashboard/
│ │ │ └── show.html.erb
│ │ ├── edit.html.erb
│ │ ├── new.html.erb
│ │ ├── passwords/
│ │ │ └── new.html.erb
│ │ ├── patch_notes/
│ │ │ ├── _patch_note.html.erb
│ │ │ ├── _patch_note.json.jbuilder
│ │ │ ├── index.html.erb
│ │ │ └── index.json.jbuilder
│ │ ├── sessions/
│ │ │ └── new.html.erb
│ │ └── shared/
│ │ └── _links.html.erb
│ ├── banners/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── bulk_court_dates/
│ │ └── new.html.erb
│ ├── casa_admin_mailer/
│ │ ├── account_setup.html.erb
│ │ └── deactivation.html.erb
│ ├── casa_admins/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── casa_cases/
│ │ ├── _calendar_button.html.erb
│ │ ├── _court_dates.html.erb
│ │ ├── _filter.html.erb
│ │ ├── _form.html.erb
│ │ ├── _generate_report_modal.html.erb
│ │ ├── _inactive_case.html.erb
│ │ ├── _placements.html.erb
│ │ ├── _thank_you_modal.html.erb
│ │ ├── _volunteer_assignment.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ ├── show.html.erb
│ │ └── show.xlsx.axlsx
│ ├── casa_org/
│ │ ├── _contact_topics.html.erb
│ │ ├── _contact_type_groups.html.erb
│ │ ├── _contact_types.html.erb
│ │ ├── _custom_org_links.html.erb
│ │ ├── _hearing_types.html.erb
│ │ ├── _judges.html.erb
│ │ ├── _languages.html.erb
│ │ ├── _learning_hour_topics.html.erb
│ │ ├── _learning_hour_types.html.erb
│ │ ├── _placement_types.html.erb
│ │ ├── _sent_emails.html.erb
│ │ └── edit.html.erb
│ ├── case_assignments/
│ │ └── index.html.erb
│ ├── case_contacts/
│ │ ├── _case_contact.html.erb
│ │ ├── _confirm_note_content_dialog.html.erb
│ │ ├── _followup.html.erb
│ │ ├── case_contacts_new_design/
│ │ │ └── index.html.erb
│ │ ├── drafts.html.erb
│ │ ├── form/
│ │ │ ├── _contact_topic_answer.html.erb
│ │ │ ├── _contact_types.html.erb
│ │ │ └── details.html.erb
│ │ └── index.html.erb
│ ├── case_court_reports/
│ │ ├── _generate_docx.html.erb
│ │ └── index.html.erb
│ ├── case_groups/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── checklist_items/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── contact_topics/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── contact_type_groups/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── contact_types/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── court_dates/
│ │ ├── _fields.html.erb
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── new.html.erb
│ │ └── show.html.erb
│ ├── custom_org_links/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── devise/
│ │ ├── invitations/
│ │ │ ├── edit.html.erb
│ │ │ └── new.html.erb
│ │ ├── mailer/
│ │ │ ├── confirmation_instructions.html.erb
│ │ │ ├── email_changed.html.erb
│ │ │ ├── invitation_instructions.html.erb
│ │ │ ├── invitation_instructions.text.erb
│ │ │ ├── password_change.html.erb
│ │ │ ├── reset_password_instructions.html.erb
│ │ │ └── unlock_instructions.html.erb
│ │ ├── passwords/
│ │ │ ├── edit.html.erb
│ │ │ └── new.html.erb
│ │ ├── sessions/
│ │ │ └── new.html.erb
│ │ └── shared/
│ │ └── _links.html.erb
│ ├── emancipation_checklists/
│ │ └── index.html.erb
│ ├── emancipations/
│ │ ├── download.html.erb
│ │ └── show.html.erb
│ ├── error/
│ │ └── index.html.erb
│ ├── fund_request_mailer/
│ │ └── send_request.html.erb
│ ├── fund_requests/
│ │ └── new.html.erb
│ ├── health/
│ │ └── index.html.erb
│ ├── hearing_types/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── imports/
│ │ ├── _cases.html.erb
│ │ ├── _csv_error_modal.html.erb
│ │ ├── _sms_opt_in_modal.html.erb
│ │ ├── _supervisors.html.erb
│ │ ├── _volunteers.html.erb
│ │ └── index.html.erb
│ ├── judges/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── languages/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── layouts/
│ │ ├── _all_casa_admin_sidebar.html.erb
│ │ ├── _banner.html.erb
│ │ ├── _flash_messages.html.erb
│ │ ├── _header.html.erb
│ │ ├── _login_header.html.erb
│ │ ├── _mobile_navbar.html.erb
│ │ ├── _sidebar.html.erb
│ │ ├── action_text/
│ │ │ └── contents/
│ │ │ └── _content.html.erb
│ │ ├── application.html.erb
│ │ ├── components/
│ │ │ └── _notifier.html.erb
│ │ ├── devise.html.erb
│ │ ├── footers/
│ │ │ ├── _logged_in.html.erb
│ │ │ └── _not_logged_in.html.erb
│ │ ├── fund_layout.html.erb
│ │ ├── mailer.html.erb
│ │ └── mailer.text.erb
│ ├── learning_hour_topics/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── learning_hour_types/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── learning_hours/
│ │ ├── _confirm_note.html.erb
│ │ ├── _form.html.erb
│ │ ├── _learning_hours_table.html.erb
│ │ ├── _supervisor_admin_learning_hours.html.erb
│ │ ├── _volunteer_learning_hours.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ ├── show.html.erb
│ │ └── volunteers/
│ │ └── show.html.erb
│ ├── learning_hours_mailer/
│ │ └── learning_hours_report_email.html.erb
│ ├── mileage_rates/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── notes/
│ │ └── edit.html.erb
│ ├── notifications/
│ │ ├── _notification.html.erb
│ │ ├── _patch_notes.html.erb
│ │ └── index.html.erb
│ ├── other_duties/
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── placement_types/
│ │ ├── _fields.html.erb
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── placements/
│ │ ├── _fields.html.erb
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ └── show.html.erb
│ ├── reimbursements/
│ │ ├── _datatable.html.erb
│ │ ├── _filter_trigger.html.erb
│ │ ├── _occurred_at_filter_input.html.erb
│ │ ├── _reimbursement_complete.html.erb
│ │ ├── _table.html.erb
│ │ └── index.html.erb
│ ├── reports/
│ │ ├── _filter.html.erb
│ │ └── index.html.erb
│ ├── shared/
│ │ ├── _additional_expense_form.html.erb
│ │ ├── _court_order_form.html.erb
│ │ ├── _court_order_list.erb
│ │ ├── _edit_form.html.erb
│ │ ├── _emancipation_link.html.erb
│ │ ├── _error_messages.html.erb
│ │ ├── _favicons.html.erb
│ │ ├── _invite_login.html.erb
│ │ └── _manage_volunteers.html.erb
│ ├── static/
│ │ └── index.html.erb
│ ├── supervisor_mailer/
│ │ ├── _active_volunteer_info.html.erb
│ │ ├── _active_volunteers.html.erb
│ │ ├── _additional_notes.html.erb
│ │ ├── _no_recent_sign_in.html.erb
│ │ ├── _pending_volunteers.html.erb
│ │ ├── _recently_unassigned_volunteers.html.erb
│ │ ├── _summary_header.html.erb
│ │ ├── account_setup.html.erb
│ │ ├── reimbursement_request_email.html.erb
│ │ └── weekly_digest.html.erb
│ ├── supervisors/
│ │ ├── _manage_active.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ ├── user_mailer/
│ │ └── password_changed_reminder.html.erb
│ ├── users/
│ │ ├── _edit_profile.erb
│ │ ├── _languages.html.erb
│ │ └── edit.html.erb
│ ├── volunteer_mailer/
│ │ ├── account_setup.html.erb
│ │ ├── case_contacts_reminder.html.erb
│ │ └── court_report_reminder.html.erb
│ └── volunteers/
│ ├── _form.html.erb
│ ├── _manage_active.html.erb
│ ├── _manage_cases.erb
│ ├── _manage_supervisor.erb
│ ├── _notes.html.erb
│ ├── _send_reminder_button.html.erb
│ ├── _volunteer_reminder_form.erb
│ ├── edit.html.erb
│ ├── index.html.erb
│ └── new.html.erb
├── app.json
├── babel.config.js
├── bin/
│ ├── asset_bundling_scripts/
│ │ ├── build_js.js
│ │ └── logger.js
│ ├── brakeman
│ ├── bundle
│ ├── delayed_job
│ ├── dev
│ ├── git_hooks/
│ │ ├── README.md
│ │ ├── build-assets
│ │ ├── lint
│ │ ├── logger
│ │ ├── migrate-all
│ │ ├── update-branch
│ │ └── update-dependencies
│ ├── lint
│ ├── login
│ ├── npm
│ ├── rails
│ ├── rake
│ ├── rspec
│ ├── setup
│ ├── spring
│ └── update
├── cc-test-reporter
├── code-of-conduct.md
├── config/
│ ├── application.rb
│ ├── boot.rb
│ ├── brakeman.ignore
│ ├── cable.yml
│ ├── credentials/
│ │ ├── development.key
│ │ ├── development.yml.enc
│ │ ├── production.yml.enc
│ │ ├── qa.key
│ │ ├── qa.yml.enc
│ │ ├── test.key
│ │ └── test.yml.enc
│ ├── database.yml
│ ├── docker.env
│ ├── environment.rb
│ ├── environments/
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── test.rb
│ ├── initializers/
│ │ ├── after_party.rb
│ │ ├── all_casa_admin_access.rb
│ │ ├── application_controller_renderer.rb
│ │ ├── assets.rb
│ │ ├── authtrail.rb
│ │ ├── backtrace_silencers.rb
│ │ ├── blueprinter.rb
│ │ ├── bugsnag.rb
│ │ ├── content_security_policy.rb
│ │ ├── cookies_serializer.rb
│ │ ├── cors.rb
│ │ ├── date_formats.rb
│ │ ├── devise.rb
│ │ ├── extensions.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── flipper.rb
│ │ ├── generators.rb
│ │ ├── inflections.rb
│ │ ├── lograge.rb
│ │ ├── mime_types.rb
│ │ ├── pagy.rb
│ │ ├── permissions_policy.rb
│ │ ├── prosopite.rb
│ │ ├── rack_attack.rb
│ │ ├── rswag_api.rb
│ │ ├── rswag_ui.rb
│ │ ├── sent_email_event.rb
│ │ ├── strong_migrations.rb
│ │ └── wrap_parameters.rb
│ ├── locales/
│ │ ├── devise.en.yml
│ │ ├── devise_invitable.en.yml
│ │ └── en.yml
│ ├── puma.rb
│ ├── routes.rb
│ ├── scout_apm.yml
│ ├── spring.rb
│ └── storage.yml
├── config.ru
├── data/
│ └── inputs_fdf.erb
├── db/
│ ├── migrate/
│ │ ├── 20200329050100_create_casa_cases.rb
│ │ ├── 20200329062155_devise_create_users.rb
│ │ ├── 20200329064203_add_role_to_user.rb
│ │ ├── 20200329071025_change_casa_case_teen_to_required.rb
│ │ ├── 20200329071327_change_casa_case_number_to_required.rb
│ │ ├── 20200329071626_add_unique_index_on_case_case_number.rb
│ │ ├── 20200329074655_create_supervisor_volunteers.rb
│ │ ├── 20200329081206_create_case_assignments.rb
│ │ ├── 20200329085225_create_versions.rb
│ │ ├── 20200329095031_create_casa_orgs.rb
│ │ ├── 20200329095154_add_casa_org_to_user.rb
│ │ ├── 20200329102102_devise_create_all_casa_admins.rb
│ │ ├── 20200329175337_create_case_contacts.rb
│ │ ├── 20200330231711_add_volunteer_reference_to_casa_cases.rb
│ │ ├── 20200405112910_remove_volunteer_id_from_casa_case.rb
│ │ ├── 20200420004403_add_medium_type_and_contact_made_to_case_contacts.rb
│ │ ├── 20200422180727_replace_contact_type_with_contact_types_on_case_contact.rb
│ │ ├── 20200423154018_change_teen_program_to_transition_aged_youth.rb
│ │ ├── 20200423204147_add_name_to_user.rb
│ │ ├── 20200525220759_add_driving_fields_to_case_contact.rb
│ │ ├── 20200726185103_devise_invitable_add_to_users.rb
│ │ ├── 20200729002247_add_casa_org_to_casa_case.rb
│ │ ├── 20200801170524_add_type_to_user.rb
│ │ ├── 20200801192923_remove_role_from_user.rb
│ │ ├── 20200818220659_add_is_active_to_supervisor_volunteers.rb
│ │ ├── 20200830011647_add_notes_to_case_contacts.rb
│ │ ├── 20200905192934_remove_other_type_text_from_case_contacts.rb
│ │ ├── 20200906145045_add_display_name_to_casa_orgs.rb
│ │ ├── 20200906145725_add_address_to_casa_orgs.rb
│ │ ├── 20200906145830_add_footer_links_to_casa_orgs.rb
│ │ ├── 20200906150641_create_casa_org_logos.rb
│ │ ├── 20200906184455_add_banner_color_to_casa_org_logos.rb
│ │ ├── 20200907142411_create_task_records.rb
│ │ ├── 20200917175655_add_default_value_to_case_contact_miles_driven.rb
│ │ ├── 20200918115741_set_miles_driven_as_not_nullable.rb
│ │ ├── 20200922144730_add_birth_month_year_youth_to_casa_cases.rb
│ │ ├── 20200922150754_create_contact_type.rb
│ │ ├── 20200922170308_link_case_contacts_to_contact_types.rb
│ │ ├── 20200924192310_create_casa_case_contact_type.rb
│ │ ├── 20200925180941_add_active_to_contact_type_groups.rb
│ │ ├── 20200925181042_add_active_to_contact_types.rb
│ │ ├── 20200928233606_add_court_report_submitted_to_casa_cases.rb
│ │ ├── 20201002192636_add_court_date_to_casa_cases.rb
│ │ ├── 20201004165322_add_court_report_due_date_to_casa_cases.rb
│ │ ├── 20201005191326_create_hearing_types.rb
│ │ ├── 20201013171632_remove_contact_types_from_case_contacts.rb
│ │ ├── 20201019120548_create_active_storage_tables.active_storage.rb
│ │ ├── 20201020095451_add_hearing_type_to_court_cases.rb
│ │ ├── 20201020220412_create_emancipation_categories.rb
│ │ ├── 20201021024459_create_emancipation_options.rb
│ │ ├── 20201021034012_create_join_table_casa_cases_emancipaton_options.rb
│ │ ├── 20201021143642_add_active_column_to_casa_cases_table.rb
│ │ ├── 20201022034445_add_foreign_key_constraints_to_case_emancipation_join_table.rb
│ │ ├── 20201023233638_create_judges.rb
│ │ ├── 20201023234325_add_active_to_judge.rb
│ │ ├── 20201024003821_add_name_to_judge.rb
│ │ ├── 20201024113046_create_past_court_dates.rb
│ │ ├── 20201025162142_add_judge_to_court_cases.rb
│ │ ├── 20201108142333_add_court_report_status_to_casa_cases.rb
│ │ ├── 20201120103041_remove_remember_created_at_from_users.rb
│ │ ├── 20201120103146_remove_remember_created_at_from_all_casa_admins.rb
│ │ ├── 20201120215756_remove_court_report_submitted_from_casa_cases.rb
│ │ ├── 20201123100716_remove_case_number_index_from_casa_cases.rb
│ │ ├── 20201123112651_add_case_number_index_scoped_by_casa_org_to_casa_cases.rb
│ │ ├── 20201222125441_add_service_name_to_active_storage_blobs.active_storage.rb
│ │ ├── 20201222125442_create_active_storage_variant_records.active_storage.rb
│ │ ├── 20201226024029_create_casa_case_emancipation_categories.rb
│ │ ├── 20210105155534_create_followups.rb
│ │ ├── 20210107181908_add_id_and_timestamps_to_case_emancipation_options_table.rb
│ │ ├── 20210109231411_drop_casa_org_logos_table.rb
│ │ ├── 20210117185614_create_notifications.rb
│ │ ├── 20210223133248_create_case_court_mandates.rb
│ │ ├── 20210308195135_change_is_active_name.rb
│ │ ├── 20210330182538_add_devise_trackable_columns_to_users.rb
│ │ ├── 20210401161710_add_deleted_at_to_case_contacts.rb
│ │ ├── 20210401182359_add_implementation_status_to_edit_case_court_mandates.rb
│ │ ├── 20210502172706_add_devise_invitable_to_all_casa_admins.rb
│ │ ├── 20210521151549_add_casa_case_details_to_past_court_dates.rb
│ │ ├── 20210521194321_add_past_court_date_to_case_court_mandates.rb
│ │ ├── 20210526233058_create_sent_emails.rb
│ │ ├── 20210624125750_add_note_to_followups.rb
│ │ ├── 20210913142024_set_display_name_as_not_nullable.rb
│ │ ├── 20210925140028_add_slug_to_casa_orgs_and_casa_cases.rb
│ │ ├── 20211001204053_rename_court_mandates_to_court_orders.rb
│ │ ├── 20211007144114_add_show_driving_reimbursement_to_casa_orgs.rb
│ │ ├── 20211008170357_add_text_to_case_court_orders.rb
│ │ ├── 20211008170724_migrate_case_court_orders_mandate_text_to_text.rb
│ │ ├── 20211008174527_remove_mandate_text_from_case_court_orders.rb
│ │ ├── 20211011195857_rename_past_court_date_to_court_date.rb
│ │ ├── 20211012180102_change_casa_cases_court_date_to_reference.rb
│ │ ├── 20211023165907_add_reimbursement_complete_to_case_contacts.rb
│ │ ├── 20211024011923_create_mileage_rates.rb
│ │ ├── 20211024060815_create_preference_sets.rb
│ │ ├── 20211025143709_create_healths.rb
│ │ ├── 20211029032305_add_casa_org_to_mileage_rate.rb
│ │ ├── 20211029033530_remove_user_required_from_mileage_rate.rb
│ │ ├── 20211203181342_create_additional_expenses.rb
│ │ ├── 20211230033457_create_delayed_jobs.rb
│ │ ├── 20220105030922_create_feature_flags.rb
│ │ ├── 20220127055733_create_notes.rb
│ │ ├── 20220223035901_remove_null_check_deprecated_field.rb
│ │ ├── 20220226040507_create_fund_request.rb
│ │ ├── 20220303183053_create_other_duty.rb
│ │ ├── 20220323145733_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
│ │ ├── 20220324141758_create_learning_hours.rb
│ │ ├── 20220402201247_add_phone_number_to_users.rb
│ │ ├── 20220406011016_add_sms_notification_preferences_to_users.rb
│ │ ├── 20220406011144_add_email_notification_preferences_to_users.rb
│ │ ├── 20220409184741_add_fund_request.rb
│ │ ├── 20220411180242_add_uniqueness_constraint_to_feature_flag_name.rb
│ │ ├── 20220509224425_add_columns_to_casa_orgs.rb
│ │ ├── 20220513084954_add_date_in_care_to_casa_cases.rb
│ │ ├── 20220513111133_delete_versions.rb
│ │ ├── 20220519210423_create_sms_notification_events.rb
│ │ ├── 20220519233803_create_user_sms_notification_events.rb
│ │ ├── 20220526011848_create_user_reminder_times.rb
│ │ ├── 20220602215632_create_addresses.rb
│ │ ├── 20220607184910_add_hide_old_contacts_to_case_assignment.rb
│ │ ├── 20220610221701_create_checklist_items.rb
│ │ ├── 20220615015056_create_patch_note_types.rb
│ │ ├── 20220616021404_add_checklist_updated_date_to_hearing_types.rb
│ │ ├── 20220618042137_create_patch_note_groups.rb
│ │ ├── 20220622022147_create_patch_notes.rb
│ │ ├── 20220820231119_create_languages.rb
│ │ ├── 20220826130829_create_languages_users_join_table.rb
│ │ ├── 20220924181447_remove_all_empty_languages.rb
│ │ ├── 20221002103627_add_user_foreign_key_to_other_duties.rb
│ │ ├── 20221002103754_validate_add_user_foreign_key_to_other_duties.rb
│ │ ├── 20221003202112_add_court_report_due_date_to_court_dates.rb
│ │ ├── 20221011044911_add_user_languages.rb
│ │ ├── 20221012203806_populate_user_languages_from_languages_users.rb
│ │ ├── 20230121174227_remove_court_data_from_casa_cases.rb
│ │ ├── 20230220210146_add_phone_number_to_all_casa_admin_resource.rb
│ │ ├── 20230316152808_remove_phone_number_from_all_casa_admin_resource.rb
│ │ ├── 20230326225216_create_placement_types.rb
│ │ ├── 20230326225230_create_placements.rb
│ │ ├── 20230327154626_add_confirmable_to_users.rb
│ │ ├── 20230327155053_add_email_confirmation_and_old_emails_to_users.rb
│ │ ├── 20230405202939_remove_email_confirmation_from_users.rb
│ │ ├── 20230412103356_add_casa_case_to_placements.rb
│ │ ├── 20230420212437_add_table_columns_display_to_preference_set.rb
│ │ ├── 20230610153139_add_receive_reimbursement_email_to_users.rb
│ │ ├── 20230615155223_add_twilio_enabled_to_casa_orgs.rb
│ │ ├── 20230621161252_add_additional_expenses_to_casa_orgs.rb
│ │ ├── 20230627210040_add_allow_reimbursement_to_case_assignments.rb
│ │ ├── 20230704123327_add_foreign_key_constraints_to_mileage_rates.rb
│ │ ├── 20230710025852_add_token_to_users.rb
│ │ ├── 20230712080040_add_foreign_key_creator_id_to_note.rb
│ │ ├── 20230728135743_create_action_text_tables.action_text.rb
│ │ ├── 20230728140249_create_banners.rb
│ │ ├── 20230729143126_create_learning_hour_types.rb
│ │ ├── 20230729145310_add_reference_learning_hour_types.rb
│ │ ├── 20230729145351_add_foreign_key_learning_hour_types.rb
│ │ ├── 20230729145419_validate_foreign_key_learning_hour_types.rb
│ │ ├── 20230729154529_create_case_groups.rb
│ │ ├── 20230729154545_create_case_group_memberships.rb
│ │ ├── 20230729213608_remove_hearing_type_id_and_judge_id_from_casa_cases.rb
│ │ ├── 20230730103110_remove_learning_type.rb
│ │ ├── 20230809002819_drop_languages_users.rb
│ │ ├── 20230817144910_create_learning_hour_topics.rb
│ │ ├── 20230819124840_add_learning_hour_topic_id_to_learning_hour.rb
│ │ ├── 20230819132316_add_learning_topic_active_to_casa_org.rb
│ │ ├── 20230822152341_drop_jwt_denylist_table.rb
│ │ ├── 20230902021531_add_monthly_learning_hours_report_to_user.rb
│ │ ├── 20230903182657_add_foreign_key_casa_case_to_placement.rb
│ │ ├── 20231102181027_add_birthdays_to_users.rb
│ │ ├── 20231125150721_status_for_case_contacts.rb
│ │ ├── 20240216013254_add_contact_topics.rb
│ │ ├── 20240415160842_add_followupable_to_followups.rb
│ │ ├── 20240507022441_create_login_activities.rb
│ │ ├── 20240509104733_create_noticed_tables.noticed.rb
│ │ ├── 20240509104734_add_notifications_count_to_noticed_event.noticed.rb
│ │ ├── 20240531172823_add_expires_at_to_banner.rb
│ │ ├── 20240610071054_add_other_duties_enabled_to_casa_org.rb
│ │ ├── 20240621165358_create_flipper_tables.rb
│ │ ├── 20240622020203_drop_feature_flags.rb
│ │ ├── 20240716194609_add_metadata_to_case_contacts.rb
│ │ ├── 20241017050129_remove_contact_topic_answer_contact_topic_id_null_constraint.rb
│ │ ├── 20250207080433_remove_token_from_users.rb
│ │ ├── 20250207080511_create_api_credentials.rb
│ │ ├── 20250208160513_remove_plain_text_tokens_from_api_credentials.rb
│ │ ├── 20250331032424_validate_constraint_mileage_rates.rb
│ │ ├── 20250331033339_validate_constraint_notes.rb
│ │ ├── 20250331033350_validate_constraint_placements.rb
│ │ ├── 20250331033418_remove_duplicate_indexindex_emancipation_options_on_emancipation_category_id.rb
│ │ ├── 20250331033441_remove_duplicate_indexindex_user_languages_on_language_id.rb
│ │ ├── 20250404200715_create_custom_org_links.rb
│ │ ├── 20250507011754_remove_unused_indexes.rb
│ │ ├── 20250528092341_trim_whitespace_from_custom_org_links.rb
│ │ ├── 20250702142004_add_exclude_from_court_report_to_contact_topics.rb
│ │ ├── 20260210233737_rename_casa_cases_emancipaton_options_to_casa_case_emancipaton_options.rb
│ │ ├── 20260211001655_rename_casa_cases_emancipaton_options_to_casa_case_emancipaton_options_follow_up.rb
│ │ └── 20260414132818_add_deleted_at_to_contact_topic_answers.rb
│ ├── schema.rb
│ ├── seeds/
│ │ ├── api_credential_data.rb
│ │ ├── casa_org_populator_presets.rb
│ │ ├── db_populator.rb
│ │ ├── default_contact_topics.yml
│ │ ├── emancipation_data.rb
│ │ ├── emancipation_options_prune.rb
│ │ ├── patch_note_group_data.rb
│ │ ├── patch_note_type_data.rb
│ │ └── placement_data.rb
│ └── seeds.rb
├── doc/
│ ├── API.md
│ ├── CONTRIBUTING.md
│ ├── DOCKER.md
│ ├── LINUX_SETUP.md
│ ├── MAC_SETUP.md
│ ├── NIX_SETUP.md
│ ├── SECURITY.md
│ ├── WSL_SETUP.md
│ ├── architecture-decisions/
│ │ ├── 0001-record-architecture-decisions.md
│ │ ├── 0002-disallow-ui-sign-ups.md
│ │ ├── 0003-multiple-user-tables.md
│ │ ├── 0004-use-bootstrap.md
│ │ ├── 0005-android-app-as-a-pwa.md
│ │ ├── 0006-few-controller-tests.md
│ │ ├── 0007-inline-css-for-email-views.md
│ │ └── 0008-controller-specs.txt
│ ├── casa_db_diagram_patch_notes.kra
│ ├── code-of-conduct.md
│ ├── db_diagram_schema_code/
│ │ ├── part_1.txt
│ │ └── part_2.txt
│ └── productsense.md
├── docker/
│ ├── brakeman
│ ├── build
│ ├── build-assets
│ ├── build-log
│ ├── console
│ ├── nuke
│ ├── nukec
│ ├── run
│ ├── sandbox
│ ├── seed
│ ├── server
│ ├── server-log
│ ├── test
│ └── test-log
├── docker-compose.yml
├── docker-entrypoint.sh
├── flake.nix
├── gemset.nix
├── jest.config.js
├── lib/
│ ├── assets/
│ │ └── .keep
│ ├── ext/
│ │ └── pdf_forms.rb
│ ├── generators/
│ │ └── rails/
│ │ └── policy/
│ │ ├── USAGE
│ │ ├── policy_generator.rb
│ │ └── templates/
│ │ ├── policy.rb.tt
│ │ └── policy_spec.rb.tt
│ ├── mailers/
│ │ ├── debug_preview_mailer.rb
│ │ └── previews/
│ │ ├── casa_admin_mailer_preview.rb
│ │ ├── concerns/
│ │ │ └── mailer_preview.rb
│ │ ├── devise_mailer_preview.rb
│ │ ├── fund_request_mailer_preview.rb
│ │ ├── learning_hours_mailer_preview.rb
│ │ ├── supervisor_mailer_preview.rb
│ │ └── volunteer_mailer_preview.rb
│ └── tasks/
│ ├── auto_annotate_models.rake
│ ├── case_contact_types_reminder.rb
│ ├── check_controller_tests.rake
│ ├── court_report_due_reminder.rake
│ ├── data_post_processors/
│ │ ├── case_contact_populator.rb
│ │ ├── contact_topic_populator.rb
│ │ ├── contact_type_populator.rb
│ │ └── sms_notification_event_populator.rb
│ ├── deployment/
│ │ ├── 20200913155303_populate_missing_display_names.rake
│ │ ├── 20201005203140_populate_contact_type_groups_and_contact_types.rake
│ │ ├── 20201005203405_populate_case_contact_contact_type.rake
│ │ ├── 20201210004047_populate_emancipation_data.rake
│ │ ├── 20201215183231_emancipation_category_options.rake
│ │ ├── 20210415012736_task_name.rake
│ │ ├── 20210507200644_fix_transition_aged_youth_for_nil_birth_month_year_youth.rake
│ │ ├── 20210811052058_update_montgomery_court_report_template.rake
│ │ ├── 20210925143244_populate_slugs_for_orgs_and_cases.rake
│ │ ├── 20220409174149_enable_feature_flag_prince_george_fund_request.rake
│ │ ├── 20220521015108_populate_sms_notification_events.rake
│ │ ├── 20220615020226_create_initial_patch_note_types.rake
│ │ ├── 20220629015841_update_montgomery_court_report_template.rake
│ │ ├── 20220902180609_populate_languages.rake
│ │ ├── 20221003224029_migrate_court_report_due_date_to_court_dates.rake
│ │ ├── 20221009032756_add_medium_type_to_howard_court_report_template.rake
│ │ ├── 20221104005957_create_initial_patch_note_groups.rake
│ │ ├── 20230110000515_update_howard_court_report_template.rake
│ │ ├── 20230114184424_update_howard_court_report_temp2.rake
│ │ ├── 20230114184852_update_howard_court_report_temp3.rake
│ │ ├── 20230208031806_update_howard_court_report_temp4.rake
│ │ ├── 20230409222823_add_confrimation_to_existing_users.rake
│ │ ├── 20230419224330_backfill_user_prefernce_sets.rake
│ │ ├── 20230720000759_update_howard_court_report_fix.rake
│ │ ├── 20231125151610_set_case_contacts_as_active.rake
│ │ ├── 20240416171009_backfill_followup_followupable_id_and_type_from_case_contact_id.rake
│ │ ├── 20240420230126_update_org_templates.rake
│ │ ├── 20240604121427_migrate_notifications.rake
│ │ ├── 20240720232939_backfill_case_contact_started_metadata.rake
│ │ ├── 20250226015042_populate_new_api_and_refresh_token.rake
│ │ └── 99991023145114_store_deploy_time.rake
│ ├── development/
│ │ └── notifications.rake
│ ├── emancipation_checklist_reminder.rake
│ ├── example_recurring_task.rb
│ ├── lint_factory_bot.rake
│ ├── monthly_learning_hours_report.rake
│ ├── no_contact_made_reminder.rb
│ ├── post_gc_stat_to_discord.rake
│ ├── recurring_jobs.rake
│ ├── scheduler.rake
│ ├── send_case_contact_types_reminder.rake
│ ├── send_no_contact_made_reminder.rake
│ ├── send_supervisor_digest.rake
│ ├── supervisor_weekly_digest.rb
│ ├── test_checker.rake
│ ├── volunteer_birthday_reminder.rake
│ └── youth_birthday_reminder.rake
├── log/
│ └── .keep
├── noop
├── package.json
├── postcss.config.js
├── public/
│ ├── 403.html
│ ├── 404.html
│ ├── 406-unsupported-browser.html
│ ├── 422.html
│ ├── 500.html
│ ├── assets/
│ │ ├── css/
│ │ │ ├── lineicons.css
│ │ │ └── main.css
│ │ └── scss/
│ │ ├── _common.scss
│ │ ├── _default.scss
│ │ ├── _mixin.scss
│ │ ├── _sidebar.scss
│ │ ├── _variables.scss
│ │ ├── alerts/
│ │ │ └── _alerts.scss
│ │ ├── auth/
│ │ │ ├── _signin.scss
│ │ │ └── _signup.scss
│ │ ├── buttons/
│ │ │ └── _buttons.scss
│ │ ├── calendar/
│ │ │ └── _calendar.scss
│ │ ├── cards/
│ │ │ └── _cards.scss
│ │ ├── dashboards/
│ │ │ └── _dashboards.scss
│ │ ├── forms/
│ │ │ └── _form-elements.scss
│ │ ├── header/
│ │ │ └── _header.scss
│ │ ├── icons/
│ │ │ └── _icons.scss
│ │ ├── invoice/
│ │ │ └── _invoice.scss
│ │ ├── main.scss
│ │ ├── notification/
│ │ │ └── _notification.scss
│ │ ├── settings/
│ │ │ └── _settings.scss
│ │ ├── tables/
│ │ │ └── _tables.scss
│ │ └── typography/
│ │ └── _typography.scss
│ ├── casa_cases.csv
│ ├── robots.txt
│ ├── sms-terms-conditions.html
│ ├── supervisors.csv
│ └── volunteers.csv
├── scripts/
│ ├── generate_github_issues_for_missing_spec.rb
│ └── import_casa_case_date_of_birth.rb
├── spec/
│ ├── .prosopite_ignore
│ ├── blueprints/
│ │ └── api/
│ │ └── v1/
│ │ └── session_blueprint_spec.rb
│ ├── callbacks/
│ │ └── case_contact_metadata_callback_spec.rb
│ ├── channels/
│ │ └── application_cable/
│ │ ├── channel_spec.rb
│ │ └── connection_spec.rb
│ ├── components/
│ │ ├── badge_component_spec.rb
│ │ ├── dropdown_menu_component_spec.rb
│ │ ├── form/
│ │ │ ├── hour_minute_duration_component_spec.rb
│ │ │ ├── multiple_select/
│ │ │ │ └── item_component_spec.rb
│ │ │ └── multiple_select_component_spec.rb
│ │ ├── local_time_component_spec.rb
│ │ ├── modal/
│ │ │ ├── body_component_spec.rb
│ │ │ ├── footer_component_spec.rb
│ │ │ ├── group_component_spec.rb
│ │ │ ├── header_component_spec.rb
│ │ │ ├── open_button_component_spec.rb
│ │ │ └── open_link_component_spec.rb
│ │ ├── notification_component_spec.rb
│ │ ├── previews/
│ │ │ └── truncated_text_component_preview.rb
│ │ ├── sidebar/
│ │ │ ├── group_component_spec.rb
│ │ │ └── link_component_spec.rb
│ │ └── truncated_text_component_spec.rb
│ ├── config/
│ │ └── initializers/
│ │ └── rack_attack_spec.rb
│ ├── controllers/
│ │ ├── README.md
│ │ ├── application_controller_spec.rb
│ │ ├── concerns/
│ │ │ ├── accessible_spec.rb
│ │ │ ├── court_date_params_spec.rb
│ │ │ ├── loads_case_contacts_spec.rb
│ │ │ ├── organizational_spec.rb
│ │ │ └── users/
│ │ │ └── time_zone_spec.rb
│ │ ├── emancipations_controller_spec.rb
│ │ ├── learning_hours/
│ │ │ └── volunteers_controller_spec.rb
│ │ └── users/
│ │ └── sessions_controller_spec.rb
│ ├── datatables/
│ │ ├── application_datatable_spec.rb
│ │ ├── case_contact_datatable_spec.rb
│ │ ├── reimbursement_datatable_spec.rb
│ │ ├── supervisor_datatable_spec.rb
│ │ └── volunteer_datatable_spec.rb
│ ├── decorators/
│ │ ├── android_app_association_decorator_spec.rb
│ │ ├── application_decorator_spec.rb
│ │ ├── casa_case_decorator_spec.rb
│ │ ├── case_assignment_decorator_spec.rb
│ │ ├── case_contact_decorator_spec.rb
│ │ ├── case_contacts/
│ │ │ └── form_decorator_spec.rb
│ │ ├── contact_type_decorator_spec.rb
│ │ ├── court_date_decorator_spec.rb
│ │ ├── learning_hour_decorator_spec.rb
│ │ ├── learning_hour_topic_decorator_spec.rb
│ │ ├── other_duty_decorator_spec.rb
│ │ ├── patch_note_decorator_spec.rb
│ │ ├── placement_decorator_spec.rb
│ │ ├── user_decorator_spec.rb
│ │ └── volunteer_decorator_spec.rb
│ ├── documents/
│ │ └── templates/
│ │ └── prince_george_report_template_spec.rb
│ ├── factories/
│ │ ├── additional_expenses.rb
│ │ ├── addresses.rb
│ │ ├── all_casa_admins.rb
│ │ ├── api_credential.rb
│ │ ├── banners.rb
│ │ ├── casa_admins.rb
│ │ ├── casa_case_contact_types.rb
│ │ ├── casa_case_emancipation_categories.rb
│ │ ├── casa_case_emancipation_options.rb
│ │ ├── casa_cases.rb
│ │ ├── casa_orgs.rb
│ │ ├── case_assignments.rb
│ │ ├── case_contact_contact_type.rb
│ │ ├── case_contacts.rb
│ │ ├── case_court_orders.rb
│ │ ├── case_court_report_context.rb
│ │ ├── case_group_memberships.rb
│ │ ├── case_groups.rb
│ │ ├── checklist_items.rb
│ │ ├── contact_topic_answers.rb
│ │ ├── contact_topics.rb
│ │ ├── contact_type_group.rb
│ │ ├── contact_types.rb
│ │ ├── court_dates.rb
│ │ ├── custom_org_links.rb
│ │ ├── emancipation_categories.rb
│ │ ├── emancipation_options.rb
│ │ ├── followups.rb
│ │ ├── fund_requests.rb
│ │ ├── healths.rb
│ │ ├── hearing_types.rb
│ │ ├── judges.rb
│ │ ├── languages.rb
│ │ ├── learning_hour_topics.rb
│ │ ├── learning_hour_types.rb
│ │ ├── learning_hours.rb
│ │ ├── login_activities.rb
│ │ ├── mileage_rates.rb
│ │ ├── notes.rb
│ │ ├── notifications.rb
│ │ ├── notifiers.rb
│ │ ├── other_duty.rb
│ │ ├── patch_note_groups.rb
│ │ ├── patch_note_types.rb
│ │ ├── patch_notes.rb
│ │ ├── placement_types.rb
│ │ ├── placements.rb
│ │ ├── preference_sets.rb
│ │ ├── sent_emails.rb
│ │ ├── sms_notification_events.rb
│ │ ├── supervisor_volunteer.rb
│ │ ├── supervisors.rb
│ │ ├── user_languages.rb
│ │ ├── user_reminder_time.rb
│ │ ├── user_sms_notification_events.rb
│ │ ├── users.rb
│ │ └── volunteers.rb
│ ├── fixtures/
│ │ └── files/
│ │ ├── casa_cases.csv
│ │ ├── casa_cases_without_case_number.csv
│ │ ├── default_past_court_date_template.docx
│ │ ├── existing_casa_case.csv
│ │ ├── generic.csv
│ │ ├── no_rows.csv
│ │ ├── sample_report.docx
│ │ ├── supervisor_volunteers.csv
│ │ ├── supervisors.csv
│ │ ├── supervisors_invalid_phone_numbers.csv
│ │ ├── supervisors_without_display_names.csv
│ │ ├── supervisors_without_email.csv
│ │ ├── supervisors_without_phone_numbers.csv
│ │ ├── volunteers.csv
│ │ ├── volunteers_invalid_phone_numbers.csv
│ │ ├── volunteers_without_display_names.csv
│ │ ├── volunteers_without_email.csv
│ │ └── volunteers_without_phone_numbers.csv
│ ├── helpers/
│ │ ├── all_casa_admins/
│ │ │ └── casa_orgs_helper_spec.rb
│ │ ├── api_base_helper_spec.rb
│ │ ├── application_helper_spec.rb
│ │ ├── banner_helper_spec.rb
│ │ ├── case_contacts_helper_spec.rb
│ │ ├── contact_types_helper_spec.rb
│ │ ├── court_dates_helper_spec.rb
│ │ ├── court_orders_helper_spec.rb
│ │ ├── date_helper_spec.rb
│ │ ├── emancipations_helper_spec.rb
│ │ ├── followup_helper_spec.rb
│ │ ├── learning_hours_helper_spec.rb
│ │ ├── mileage_rates_helper_spec.rb
│ │ ├── notifications_helper_spec.rb
│ │ ├── other_duties_helper_spec.rb
│ │ ├── phone_number_helper_spec.rb
│ │ ├── preference_sets_helper_spec.rb
│ │ ├── report_helper_spec.rb
│ │ ├── request_header_helper_spec.rb
│ │ ├── sidebar_helper_spec.rb
│ │ ├── sms_body_helper_spec.rb
│ │ ├── template_helper_spec.rb
│ │ ├── ui_helper_spec.rb
│ │ └── volunteer_helper_spec.rb
│ ├── jobs/
│ │ └── application_job_spec.rb
│ ├── lib/
│ │ ├── importers/
│ │ │ ├── case_importer_spec.rb
│ │ │ ├── file_importer_spec.rb
│ │ │ ├── supervisor_importer_spec.rb
│ │ │ └── volunteer_importer_spec.rb
│ │ └── tasks/
│ │ ├── case_contact_types_reminder_spec.rb
│ │ ├── data_post_processors/
│ │ │ ├── case_contact_populator_spec.rb
│ │ │ ├── contact_topic_populator_spec.rb
│ │ │ └── contact_type_populator_spec.rb
│ │ ├── no_contact_made_reminder_spec.rb
│ │ └── supervisor_weekly_digest_spec.rb
│ ├── mailers/
│ │ ├── application_mailer_spec.rb
│ │ ├── casa_admin_mailer_spec.rb
│ │ ├── fund_request_mailer_spec.rb
│ │ ├── learning_hours_mailer_spec.rb
│ │ ├── previews/
│ │ │ ├── casa_admin_mailer_preview_spec.rb
│ │ │ ├── devise_mailer_preview_spec.rb
│ │ │ ├── supervisor_mailer_preview_spec.rb
│ │ │ └── volunteer_mailer_preview_spec.rb
│ │ ├── supervisor_mailer_spec.rb
│ │ ├── user_mailer_spec.rb
│ │ └── volunteer_mailer_spec.rb
│ ├── models/
│ │ ├── acts_as_paranoid_spec.rb
│ │ ├── additional_expense_spec.rb
│ │ ├── address_spec.rb
│ │ ├── all_casa_admin_spec.rb
│ │ ├── all_casa_admins/
│ │ │ └── casa_org_metrics_spec.rb
│ │ ├── api_credential_spec.rb
│ │ ├── application_record_spec.rb
│ │ ├── banner_spec.rb
│ │ ├── casa_admin_spec.rb
│ │ ├── casa_case_contact_type_spec.rb
│ │ ├── casa_case_emancipation_category_spec.rb
│ │ ├── casa_case_emancipation_option_spec.rb
│ │ ├── casa_case_spec.rb
│ │ ├── casa_org_spec.rb
│ │ ├── case_assignment_spec.rb
│ │ ├── case_contact_contact_type_spec.rb
│ │ ├── case_contact_report_spec.rb
│ │ ├── case_contact_spec.rb
│ │ ├── case_court_order_spec.rb
│ │ ├── case_court_report_context_spec.rb
│ │ ├── case_court_report_spec.rb
│ │ ├── case_group_membership_spec.rb
│ │ ├── case_group_spec.rb
│ │ ├── checklist_item_spec.rb
│ │ ├── concerns/
│ │ │ ├── CasaCase/
│ │ │ │ └── validations_spec.rb
│ │ │ ├── api_spec.rb
│ │ │ ├── by_organization_scope_spec.rb
│ │ │ └── roles_spec.rb
│ │ ├── contact_topic_answer_spec.rb
│ │ ├── contact_topic_spec.rb
│ │ ├── contact_type_group_spec.rb
│ │ ├── contact_type_spec.rb
│ │ ├── court_date_spec.rb
│ │ ├── custom_org_link_spec.rb
│ │ ├── emancipation_category_spec.rb
│ │ ├── emancipation_option_spec.rb
│ │ ├── followup_spec.rb
│ │ ├── fund_request_spec.rb
│ │ ├── health_spec.rb
│ │ ├── hearing_type_spec.rb
│ │ ├── judge_spec.rb
│ │ ├── language_spec.rb
│ │ ├── learning_hour_spec.rb
│ │ ├── learning_hour_topic_spec.rb
│ │ ├── learning_hour_type_spec.rb
│ │ ├── learning_hours_report_spec.rb
│ │ ├── login_activity_spec.rb
│ │ ├── mileage_rate_spec.rb
│ │ ├── mileage_report_spec.rb
│ │ ├── missing_data_report_spec.rb
│ │ ├── note_spec.rb
│ │ ├── other_duty_spec.rb
│ │ ├── patch_note_group_spec.rb
│ │ ├── patch_note_spec.rb
│ │ ├── patch_note_type_spec.rb
│ │ ├── placement_spec.rb
│ │ ├── placement_type_spec.rb
│ │ ├── preference_set_spec.rb
│ │ ├── sent_email_spec.rb
│ │ ├── sms_notification_event_spec.rb
│ │ ├── soft_deleted_model_shared_example_coverage_spec.rb
│ │ ├── supervisor_spec.rb
│ │ ├── supervisor_volunteer_spec.rb
│ │ ├── user_language_spec.rb
│ │ ├── user_reminder_time.rb
│ │ ├── user_sms_notification_event_spec.rb
│ │ ├── user_spec.rb
│ │ └── volunteer_spec.rb
│ ├── notifications/
│ │ ├── base_notifier_spec.rb
│ │ ├── delivery_methods/
│ │ │ └── sms_spec.rb
│ │ ├── emancipation_checklist_reminder_notifier_spec.rb
│ │ ├── followup_notifier_spec.rb
│ │ ├── followup_resolved_notifier_spec.rb
│ │ ├── reimbursement_complete_notifier_spec.rb
│ │ ├── volunteer_birthday_notifier_spec.rb
│ │ └── youth_birthday_notifier_spec.rb
│ ├── policies/
│ │ ├── additional_expense_policy_spec.rb
│ │ ├── application_policy_spec.rb
│ │ ├── bulk_court_date_policy_spec.rb
│ │ ├── casa_admin_policy_spec.rb
│ │ ├── casa_case_policy/
│ │ │ └── scope_spec.rb
│ │ ├── casa_case_policy_spec.rb
│ │ ├── casa_org_policy_spec.rb
│ │ ├── case_assignment_policy_spec.rb
│ │ ├── case_contact_policy_spec.rb
│ │ ├── case_court_order_policy_spec.rb
│ │ ├── case_court_report_policy_spec.rb
│ │ ├── case_group_policy_spec.rb
│ │ ├── checklist_item_policy_spec.rb
│ │ ├── contact_topic_answer_policy_spec.rb
│ │ ├── contact_topic_policy_spec.rb
│ │ ├── contact_type_group_policy_spec.rb
│ │ ├── contact_type_policy_spec.rb
│ │ ├── court_date_policy_spec.rb
│ │ ├── custom_org_link_policy_spec.rb
│ │ ├── dashboard_policy_spec.rb
│ │ ├── followup_policy_spec.rb
│ │ ├── fund_request_policy_spec.rb
│ │ ├── hearing_type_policy_spec.rb
│ │ ├── import_policy_spec.rb
│ │ ├── judge_policy_spec.rb
│ │ ├── language_policy_spec.rb
│ │ ├── learning_hour_policy/
│ │ │ └── scope_spec.rb
│ │ ├── learning_hour_policy_spec.rb
│ │ ├── learning_hour_topic_policy_spec.rb
│ │ ├── learning_hour_type_policy_spec.rb
│ │ ├── nil_class_policy_spec.rb
│ │ ├── note_policy_spec.rb
│ │ ├── notification_policy_spec.rb
│ │ ├── other_duty_policy_spec.rb
│ │ ├── patch_note_policy_spec.rb
│ │ ├── placement_policy_spec.rb
│ │ ├── placement_type_policy_spec.rb
│ │ ├── reimbursement_policy_spec.rb
│ │ ├── supervisor_policy_spec.rb
│ │ ├── supervisor_volunteer_policy_spec.rb
│ │ ├── user_policy/
│ │ │ └── scope_spec.rb
│ │ ├── user_policy_spec.rb
│ │ └── volunteer_policy_spec.rb
│ ├── presenters/
│ │ ├── base_presenter_spec.rb
│ │ └── case_contact_presenter_spec.rb
│ ├── rails_helper.rb
│ ├── requests/
│ │ ├── additional_expenses_spec.rb
│ │ ├── all_casa_admins/
│ │ │ ├── casa_admins_spec.rb
│ │ │ ├── casa_orgs_spec.rb
│ │ │ ├── dashboard_spec.rb
│ │ │ ├── patch_notes_spec.rb
│ │ │ └── sessions_spec.rb
│ │ ├── all_casa_admins_spec.rb
│ │ ├── android_app_associations_spec.rb
│ │ ├── api/
│ │ │ └── v1/
│ │ │ ├── base_spec.rb
│ │ │ └── users/
│ │ │ └── sessions_spec.rb
│ │ ├── banners_spec.rb
│ │ ├── bulk_court_dates_spec.rb
│ │ ├── casa_admins_spec.rb
│ │ ├── casa_cases_spec.rb
│ │ ├── casa_org_spec.rb
│ │ ├── case_assignments_spec.rb
│ │ ├── case_contact_reports_spec.rb
│ │ ├── case_contacts/
│ │ │ ├── case_contacts_new_design_spec.rb
│ │ │ ├── followups_spec.rb
│ │ │ └── form_spec.rb
│ │ ├── case_contacts_spec.rb
│ │ ├── case_court_orders_spec.rb
│ │ ├── case_court_reports_spec.rb
│ │ ├── case_groups_spec.rb
│ │ ├── checklist_items_spec.rb
│ │ ├── contact_topic_answers_spec.rb
│ │ ├── contact_topics_spec.rb
│ │ ├── contact_type_groups_spec.rb
│ │ ├── contact_types_spec.rb
│ │ ├── court_dates_spec.rb
│ │ ├── custom_org_links_spec.rb
│ │ ├── dashboard_spec.rb
│ │ ├── emancipation_checklists_spec.rb
│ │ ├── emancipations_request_spec.rb
│ │ ├── error_spec.rb
│ │ ├── followup_reports_spec.rb
│ │ ├── fund_requests_spec.rb
│ │ ├── health_spec.rb
│ │ ├── hearing_types_spec.rb
│ │ ├── imports_spec.rb
│ │ ├── judges_spec.rb
│ │ ├── languages_spec.rb
│ │ ├── learning_hour_topics_spec.rb
│ │ ├── learning_hour_types_spec.rb
│ │ ├── learning_hours_reports_spec.rb
│ │ ├── learning_hours_spec.rb
│ │ ├── mileage_rates_spec.rb
│ │ ├── mileage_reports_spec.rb
│ │ ├── missing_data_reports_spec.rb
│ │ ├── notes_spec.rb
│ │ ├── notifications_spec.rb
│ │ ├── other_duties_spec.rb
│ │ ├── placement_reports_spec.rb
│ │ ├── placement_types_spec.rb
│ │ ├── placements_spec.rb
│ │ ├── preference_sets_spec.rb
│ │ ├── reimbursements_spec.rb
│ │ ├── reports_spec.rb
│ │ ├── static_spec.rb
│ │ ├── supervisor_volunteers_spec.rb
│ │ ├── supervisors_spec.rb
│ │ ├── users/
│ │ │ ├── invitations_spec.rb
│ │ │ └── passwords_spec.rb
│ │ ├── users_spec.rb
│ │ └── volunteers_spec.rb
│ ├── routing/
│ │ └── all_casa_admins/
│ │ └── patch_notes_routing_spec.rb
│ ├── seeds/
│ │ └── seeds_spec.rb
│ ├── services/
│ │ ├── additional_expense_params_service_spec.rb
│ │ ├── backfill_followupable_service_spec.rb
│ │ ├── casa_case_change_service_spec.rb
│ │ ├── case_contacts_contact_dates_spec.rb
│ │ ├── case_contacts_export_csv_service_spec.rb
│ │ ├── court_report_due_sms_reminder_service_spec.rb
│ │ ├── court_report_format_contact_date_spec.rb
│ │ ├── create_all_casa_admin_service_spec.rb
│ │ ├── create_casa_admin_service_spec.rb
│ │ ├── deployment/
│ │ │ └── backfill_case_contact_started_metadata_service_spec.rb
│ │ ├── emancipation_checklist_download_html_spec.rb
│ │ ├── emancipation_checklist_reminder_service_spec.rb
│ │ ├── failed_import_csv_service_spec.rb
│ │ ├── fdf_inputs_service_spec.rb
│ │ ├── followup_export_csv_service_spec.rb
│ │ ├── followup_service_spec.rb
│ │ ├── inactive_messages_service_spec.rb
│ │ ├── learning_hours_export_csv_service_spec.rb
│ │ ├── mileage_export_csv_service_spec.rb
│ │ ├── missing_data_export_csv_service_spec.rb
│ │ ├── no_contact_made_sms_reminder_service_spec.rb
│ │ ├── placement_export_csv_service_spec.rb
│ │ ├── preference_set_table_state_service_spec.rb
│ │ ├── short_url_service_spec.rb
│ │ ├── sms_reminder_service_spec.rb
│ │ ├── svg_sanitizer_service_spec.rb
│ │ ├── twilio_service_spec.rb
│ │ ├── volunteer_birthday_reminder_service_spec.rb
│ │ └── volunteers_emails_export_csv_service_spec.rb
│ ├── spec_helper.rb
│ ├── support/
│ │ ├── api_helper.rb
│ │ ├── capybara.rb
│ │ ├── case_court_report_helpers.rb
│ │ ├── datatable_helper.rb
│ │ ├── download_helpers.rb
│ │ ├── factory_bot.rb
│ │ ├── fill_in_case_contact_fields.rb
│ │ ├── flipper_helper.rb
│ │ ├── pretender_context.rb
│ │ ├── prosopite.rb
│ │ ├── pundit_helper.rb
│ │ ├── rack_attack.rb
│ │ ├── request_helpers.rb
│ │ ├── rspec_retry.rb
│ │ ├── session_helper.rb
│ │ ├── shared_examples/
│ │ │ ├── shows_court_dates_links.rb
│ │ │ ├── shows_error_for_invalid_phone_numbers.rb
│ │ │ └── soft_deleted_model.rb
│ │ ├── stubbed_requests/
│ │ │ ├── short_io_api.rb
│ │ │ ├── twilio_api.rb
│ │ │ └── webmock_helper.rb
│ │ ├── twilio_helper.rb
│ │ └── user_input_helpers.rb
│ ├── swagger_helper.rb
│ ├── system/
│ │ ├── all_casa_admins/
│ │ │ ├── all_casa_admin_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── password_change_spec.rb
│ │ │ ├── patch_notes/
│ │ │ │ └── index_spec.rb
│ │ │ └── sessions/
│ │ │ └── new_spec.rb
│ │ ├── application/
│ │ │ └── timeout_warning_spec.rb
│ │ ├── banners/
│ │ │ ├── dismiss_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── bulk_court_dates/
│ │ │ └── new_spec.rb
│ │ ├── casa_admins/
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── casa_cases/
│ │ │ ├── additional_index_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── emancipation/
│ │ │ │ └── show_spec.rb
│ │ │ ├── fund_requests/
│ │ │ │ └── new_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ ├── new_spec.rb
│ │ │ ├── show_more_spec.rb
│ │ │ └── show_spec.rb
│ │ ├── casa_org/
│ │ │ └── edit_spec.rb
│ │ ├── case_contacts/
│ │ │ ├── additional_expenses_spec.rb
│ │ │ ├── case_contacts_new_design_spec.rb
│ │ │ ├── contact_topic_answers_spec.rb
│ │ │ ├── drafts_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── followups/
│ │ │ │ ├── create_spec.rb
│ │ │ │ └── resolve_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── case_court_reports/
│ │ │ └── index_spec.rb
│ │ ├── case_groups/
│ │ │ └── case_groups_spec.rb
│ │ ├── checklist_items/
│ │ │ ├── destroy_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── components/
│ │ │ └── truncated_text_component_spec.rb
│ │ ├── contact_types/
│ │ │ ├── edit_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── court_dates/
│ │ │ ├── edit_spec.rb
│ │ │ ├── new_spec.rb
│ │ │ └── view_spec.rb
│ │ ├── dashboard/
│ │ │ └── show_spec.rb
│ │ ├── deep_link/
│ │ │ └── deep_link_spec.rb
│ │ ├── devise/
│ │ │ └── passwords/
│ │ │ └── new_spec.rb
│ │ ├── emancipations/
│ │ │ └── show_spec.rb
│ │ ├── hearing_types/
│ │ │ └── new_spec.rb
│ │ ├── imports/
│ │ │ └── index_spec.rb
│ │ ├── judges/
│ │ │ └── new_spec.rb
│ │ ├── languages/
│ │ │ └── languages_spec.rb
│ │ ├── learning_hours/
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ ├── new_spec.rb
│ │ │ └── volunteers/
│ │ │ └── show_spec.rb
│ │ ├── mileage_rates/
│ │ │ └── mileage_rates_spec.rb
│ │ ├── notifications/
│ │ │ └── index_spec.rb
│ │ ├── other_duties/
│ │ │ └── new_spec.rb
│ │ ├── placements/
│ │ │ ├── destroy_spec.rb
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── reimbursements/
│ │ │ └── reimbursements_spec.rb
│ │ ├── reports/
│ │ │ ├── export_data_spec.rb
│ │ │ └── index_spec.rb
│ │ ├── sessions/
│ │ │ ├── destroy_spec.rb
│ │ │ ├── login_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── static/
│ │ │ └── index_spec.rb
│ │ ├── supervisors/
│ │ │ ├── edit_spec.rb
│ │ │ ├── index_spec.rb
│ │ │ └── new_spec.rb
│ │ ├── users/
│ │ │ └── edit_spec.rb
│ │ └── volunteers/
│ │ ├── edit_spec.rb
│ │ ├── index_spec.rb
│ │ ├── invite_spec.rb
│ │ ├── new_spec.rb
│ │ └── notes/
│ │ └── edit_spec.rb
│ ├── validators/
│ │ ├── casa_org_validator_spec.rb
│ │ ├── court_report_validator_spec.rb
│ │ ├── url_validator_spec.rb
│ │ └── user_validator_spec.rb
│ ├── values/
│ │ ├── all_casa_admin_parameters_spec.rb
│ │ ├── banner_parameters_spec.rb
│ │ ├── casa_admin_parameters_spec.rb
│ │ ├── case_contact_parameters_spec.rb
│ │ ├── supervisor_parameters_spec.rb
│ │ ├── user_parameters_spec.rb
│ │ └── volunteer_parameters_spec.rb
│ └── views/
│ ├── all_casa_admins/
│ │ ├── casa_orgs/
│ │ │ ├── new.html.erb_spec.rb
│ │ │ └── show.html.erb_spec.rb
│ │ ├── edit.html.erb_spec.rb
│ │ └── patch_notes/
│ │ └── index.html.erb_spec.rb
│ ├── banners/
│ │ └── new.html.erb_spec.rb
│ ├── bulk_court_date/
│ │ └── new.html.erb_spec.rb
│ ├── casa_admins/
│ │ ├── admins_table.html.erb_spec.rb
│ │ └── edit.html.erb_spec.rb
│ ├── casa_cases/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── index.html.erb_spec.rb
│ │ ├── new.html.erb_spec.rb
│ │ └── show.html.erb_spec.rb
│ ├── casa_orgs/
│ │ └── edit.html.erb_spec.rb
│ ├── case_contacts/
│ │ ├── case_contact.html.erb_spec.rb
│ │ └── index.html.erb_spec.rb
│ ├── case_court_reports/
│ │ └── index.html.erb_spec.rb
│ ├── checklist_items/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── court_dates/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── new.html.erb_spec.rb
│ │ └── show.html.erb_spec.rb
│ ├── devise/
│ │ ├── invitations/
│ │ │ ├── edit.html.erb_spec.rb
│ │ │ └── new.html.erb_spec.rb
│ │ └── passwords/
│ │ └── new.html.erb_spec.rb
│ ├── emancipations/
│ │ └── show.html.erb_spec.rb
│ ├── hearing_types/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── judges/
│ │ └── new.html.erb_spec.rb
│ ├── layouts/
│ │ ├── application.html.erb_spec.rb
│ │ ├── footer.html.erb_spec.rb
│ │ ├── header.html.erb_spec.rb
│ │ └── sidebar.html.erb_spec.rb
│ ├── mileage_rates/
│ │ └── index.html.erb_spec.rb
│ ├── notifications/
│ │ └── index.html.erb_spec.rb
│ ├── other_duties/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── placement_types/
│ │ ├── edit.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── placements/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── index.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── reimbursements/
│ │ └── index.html.erb_spec.rb
│ ├── supervisor_mailer/
│ │ └── weekly_digest.html.erb_spec.rb
│ ├── supervisors/
│ │ ├── edit.html.erb_spec.rb
│ │ ├── index.html.erb_spec.rb
│ │ └── new.html.erb_spec.rb
│ ├── templates/
│ │ └── email_templates_spec.rb
│ └── volunteers/
│ ├── edit.html.erb_spec.rb
│ ├── index.html.erb_spec.rb
│ └── new.html.erb_spec.rb
├── storage/
│ └── .keep
├── swagger/
│ └── v1/
│ └── swagger.yaml
└── vendor/
├── .keep
└── pdftk/
├── bin/
│ └── pdftk
└── lib/
└── libgcj.so.12
SYMBOL INDEX (2395 symbols across 604 files)
FILE: app/blueprints/api/v1/session_blueprint.rb
class Api::V1::SessionBlueprint (line 1) | class Api::V1::SessionBlueprint < Blueprinter::Base
FILE: app/callbacks/case_contact_metadata_callback.rb
class CaseContactMetadataCallback (line 1) | class CaseContactMetadataCallback
method after_commit (line 2) | def after_commit(case_contact)
method set_status (line 11) | def set_status(changes, case_contact)
method update_status (line 16) | def update_status(changes, case_contact)
method update_metadata (line 21) | def update_metadata(record, new_data)
FILE: app/channels/application_cable/channel.rb
type ApplicationCable (line 1) | module ApplicationCable
class Channel (line 2) | class Channel < ActionCable::Channel::Base; end
FILE: app/channels/application_cable/connection.rb
type ApplicationCable (line 1) | module ApplicationCable
class Connection (line 2) | class Connection < ActionCable::Connection::Base; end
FILE: app/components/badge_component.rb
class BadgeComponent (line 1) | class BadgeComponent < ViewComponent::Base
method initialize (line 6) | def initialize(text:, type:, rounded: false, margin: true)
method style (line 13) | def style
FILE: app/components/dropdown_menu_component.rb
class DropdownMenuComponent (line 3) | class DropdownMenuComponent < ViewComponent::Base
method initialize (line 6) | def initialize(menu_title:, icon_name: nil, hide_label: false, render_...
method render_icon (line 14) | def render_icon
method icon? (line 20) | def icon?
method render? (line 24) | def render?
method button_label (line 28) | def button_label
FILE: app/components/form/hour_minute_duration_component.rb
class Form::HourMinuteDurationComponent (line 3) | class Form::HourMinuteDurationComponent < ViewComponent::Base
method initialize (line 4) | def initialize(form:, hour_value:, minute_value:)
FILE: app/components/form/multiple_select/item_component.rb
class Form::MultipleSelect::ItemComponent (line 3) | class Form::MultipleSelect::ItemComponent < ViewComponent::Base
FILE: app/components/form/multiple_select_component.rb
class Form::MultipleSelectComponent (line 3) | class Form::MultipleSelectComponent < ViewComponent::Base
method initialize (line 4) | def initialize(form:, name:, options:, selected_items:, render_option_...
FILE: app/components/local_time_component.rb
class LocalTimeComponent (line 3) | class LocalTimeComponent < ViewComponent::Base
method initialize (line 6) | def initialize(format:, unix_timestamp:, time_zone:)
method local_time (line 12) | def local_time
method specific_time (line 17) | def specific_time
FILE: app/components/modal/body_component.rb
class Modal::BodyComponent (line 3) | class Modal::BodyComponent < ViewComponent::Base
method initialize (line 4) | def initialize(text: nil, klass: nil, render_check: true)
method body_content (line 10) | def body_content
method render? (line 18) | def render?
FILE: app/components/modal/footer_component.rb
class Modal::FooterComponent (line 3) | class Modal::FooterComponent < ViewComponent::Base
method initialize (line 4) | def initialize(klass: nil, render_check: true)
method render? (line 9) | def render?
FILE: app/components/modal/group_component.rb
class Modal::GroupComponent (line 3) | class Modal::GroupComponent < ViewComponent::Base
method initialize (line 8) | def initialize(id:, klass: nil, render_check: true)
method render? (line 14) | def render?
FILE: app/components/modal/header_component.rb
class Modal::HeaderComponent (line 3) | class Modal::HeaderComponent < ViewComponent::Base
method initialize (line 4) | def initialize(id:, text: nil, icon: nil, klass: nil, render_check: true)
method header_content (line 12) | def header_content
method render? (line 21) | def render?
FILE: app/components/modal/open_button_component.rb
class Modal::OpenButtonComponent (line 3) | class Modal::OpenButtonComponent < ViewComponent::Base
method initialize (line 4) | def initialize(target:, text: nil, klass: nil, icon: nil, render_check...
method open_button (line 12) | def open_button
method render? (line 18) | def render?
FILE: app/components/modal/open_link_component.rb
class Modal::OpenLinkComponent (line 3) | class Modal::OpenLinkComponent < ViewComponent::Base
method initialize (line 4) | def initialize(target:, text: nil, icon: nil, klass: nil, render_check...
method open_link (line 12) | def open_link
method render? (line 18) | def render?
FILE: app/components/notification_component.rb
class NotificationComponent (line 3) | class NotificationComponent < ViewComponent::Base
method initialize (line 6) | def initialize(notification:)
method muted_display (line 10) | def muted_display
FILE: app/components/sidebar/group_component.rb
class Sidebar::GroupComponent (line 3) | class Sidebar::GroupComponent < ViewComponent::Base
method initialize (line 9) | def initialize(title:, icon:, render_check: true)
method render? (line 19) | def render?
FILE: app/components/sidebar/link_component.rb
class Sidebar::LinkComponent (line 3) | class Sidebar::LinkComponent < ViewComponent::Base
method initialize (line 11) | def initialize(title:, path:, icon: nil, nav_item: true, render_check:...
method before_render (line 20) | def before_render
method render? (line 25) | def render?
FILE: app/components/truncated_text_component.rb
class TruncatedTextComponent (line 3) | class TruncatedTextComponent < ViewComponent::Base
method initialize (line 5) | def initialize(text = nil, label: nil)
FILE: app/controllers/additional_expenses_controller.rb
class AdditionalExpensesController (line 1) | class AdditionalExpensesController < ApplicationController
method create (line 4) | def create
method destroy (line 15) | def destroy
method additional_expense_params (line 26) | def additional_expense_params
FILE: app/controllers/all_casa_admins/casa_admins_controller.rb
class AllCasaAdmins::CasaAdminsController (line 1) | class AllCasaAdmins::CasaAdminsController < AllCasaAdminsController
method new (line 4) | def new
method create (line 8) | def create
method edit (line 19) | def edit
method update (line 23) | def update
method activate (line 35) | def activate
method deactivate (line 46) | def deactivate
method set_casa_org (line 59) | def set_casa_org
FILE: app/controllers/all_casa_admins/casa_orgs_controller.rb
class AllCasaAdmins::CasaOrgsController (line 1) | class AllCasaAdmins::CasaOrgsController < AllCasaAdminsController
method show (line 2) | def show
method new (line 7) | def new
method create (line 11) | def create
method casa_org_params (line 36) | def casa_org_params
FILE: app/controllers/all_casa_admins/dashboard_controller.rb
class AllCasaAdmins::DashboardController (line 1) | class AllCasaAdmins::DashboardController < AllCasaAdminsController
method show (line 2) | def show
FILE: app/controllers/all_casa_admins/patch_notes_controller.rb
class AllCasaAdmins::PatchNotesController (line 1) | class AllCasaAdmins::PatchNotesController < AllCasaAdminsController
method index (line 3) | def index
method create (line 10) | def create
method update (line 21) | def update
method destroy (line 31) | def destroy
method set_patch_note (line 44) | def set_patch_note
method patch_note_params (line 49) | def patch_note_params
FILE: app/controllers/all_casa_admins/sessions_controller.rb
class AllCasaAdmins::SessionsController (line 3) | class AllCasaAdmins::SessionsController < Devise::SessionsController
FILE: app/controllers/all_casa_admins_controller.rb
class AllCasaAdminsController (line 1) | class AllCasaAdminsController < ApplicationController
method new (line 8) | def new
method edit (line 12) | def edit
method create (line 16) | def create
method update (line 42) | def update
method update_password (line 62) | def update_password
method all_casa_admin_params (line 89) | def all_casa_admin_params
method password_params (line 93) | def password_params
method set_custom_error_heading (line 97) | def set_custom_error_heading
method reset_custom_error_heading (line 101) | def reset_custom_error_heading
FILE: app/controllers/android_app_associations_controller.rb
class AndroidAppAssociationsController (line 1) | class AndroidAppAssociationsController < ApplicationController
method index (line 4) | def index
FILE: app/controllers/api/v1/base_controller.rb
class Api::V1::BaseController (line 1) | class Api::V1::BaseController < ActionController::API
method authenticate_user! (line 5) | def authenticate_user!
method not_found (line 15) | def not_found
FILE: app/controllers/api/v1/users/sessions_controller.rb
class Api::V1::Users::SessionsController (line 1) | class Api::V1::Users::SessionsController < Api::V1::BaseController
method create (line 2) | def create
method destroy (line 11) | def destroy
method user_params (line 29) | def user_params
method load_resource (line 33) | def load_resource
FILE: app/controllers/application_controller.rb
class ApplicationController (line 1) | class ApplicationController < ActionController::Base
method after_sign_in_path_for (line 25) | def after_sign_in_path_for(resource_or_scope)
method after_sign_out_path_for (line 29) | def after_sign_out_path_for(resource_or_scope)
method set_active_banner (line 38) | def set_active_banner
method handle_short_url (line 50) | def handle_short_url(url_list)
method deliver_sms_to (line 65) | def deliver_sms_to(resource, body_msg)
method sms_acct_creation_notice (line 94) | def sms_acct_creation_notice(resource_name, sms_status)
method store_referring_location (line 105) | def store_referring_location
method redirect_back_to_referer (line 111) | def redirect_back_to_referer(fallback_location:)
method force_json_format (line 119) | def force_json_format
method store_user_location! (line 123) | def store_user_location!
method storable_location? (line 128) | def storable_location?
method set_current_user (line 132) | def set_current_user
method set_timeout_duration (line 136) | def set_timeout_duration
method set_current_organization (line 142) | def set_current_organization
method not_authorized (line 146) | def not_authorized
method unsupported_media_type (line 160) | def unsupported_media_type
method log_and_reraise (line 172) | def log_and_reraise(error)
method check_unconfirmed_email_notice (line 179) | def check_unconfirmed_email_notice(user)
FILE: app/controllers/banners_controller.rb
class BannersController (line 1) | class BannersController < ApplicationController
method index (line 5) | def index
method new (line 11) | def new
method edit (line 17) | def edit
method dismiss (line 21) | def dismiss
method create (line 26) | def create
method update (line 41) | def update
method destroy (line 54) | def destroy
method set_banner (line 63) | def set_banner
method banner_params (line 67) | def banner_params
method deactivate_alternate_active_banner (line 71) | def deactivate_alternate_active_banner
FILE: app/controllers/bulk_court_dates_controller.rb
class BulkCourtDatesController (line 1) | class BulkCourtDatesController < ApplicationController
method new (line 6) | def new
method create (line 12) | def create
method build_court_date_with_error_message (line 37) | def build_court_date_with_error_message
method build_court_dates (line 43) | def build_court_dates(case_group)
method create_court_dates (line 49) | def create_court_dates(court_dates)
FILE: app/controllers/casa_admins_controller.rb
class CasaAdminsController (line 1) | class CasaAdminsController < ApplicationController
method index (line 8) | def index
method edit (line 13) | def edit
method update (line 17) | def update
method new (line 35) | def new
method create (line 40) | def create
method activate (line 68) | def activate
method deactivate (line 92) | def deactivate
method resend_invitation (line 111) | def resend_invitation
method change_to_supervisor (line 118) | def change_to_supervisor
method redirect_to_casa_admin_edition_page (line 127) | def redirect_to_casa_admin_edition_page(error)
method set_admin (line 133) | def set_admin
method update_casa_admin_params (line 137) | def update_casa_admin_params
method learning_hours_checked? (line 141) | def learning_hours_checked?
FILE: app/controllers/casa_cases_controller.rb
class CasaCasesController (line 1) | class CasaCasesController < ApplicationController
method index (line 7) | def index
method show (line 15) | def show
method new (line 32) | def new
method edit (line 37) | def edit
method create (line 42) | def create
method update (line 68) | def update
method deactivate (line 88) | def deactivate
method reactivate (line 110) | def reactivate
method copy_court_orders (line 132) | def copy_court_orders
method set_casa_case (line 144) | def set_casa_case
method casa_case_params (line 154) | def casa_case_params
method casa_case_create_params (line 167) | def casa_case_create_params
method casa_case_update_params (line 174) | def casa_case_update_params
method set_contact_types (line 178) | def set_contact_types
method case_contact_csv_name (line 183) | def case_contact_csv_name(case_contacts)
method court_date_unknown? (line 190) | def court_date_unknown?
FILE: app/controllers/casa_org_controller.rb
class CasaOrgController (line 1) | class CasaOrgController < ApplicationController
method edit (line 16) | def edit
method update (line 20) | def update
method set_casa_org (line 41) | def set_casa_org
method casa_org_update_params (line 47) | def casa_org_update_params
method set_contact_type_data (line 66) | def set_contact_type_data
method set_hearing_types (line 71) | def set_hearing_types
method set_judges (line 75) | def set_judges
method set_learning_hour_types (line 79) | def set_learning_hour_types
method set_sent_emails (line 83) | def set_sent_emails
method set_learning_hour_topics (line 87) | def set_learning_hour_topics
method set_contact_topics (line 91) | def set_contact_topics
method set_custom_org_links (line 95) | def set_custom_org_links
method set_placement_types (line 99) | def set_placement_types
method set_active_storage_url_options (line 103) | def set_active_storage_url_options
FILE: app/controllers/case_assignments_controller.rb
class CaseAssignmentsController (line 1) | class CaseAssignmentsController < ApplicationController
method create (line 5) | def create
method destroy (line 32) | def destroy
method unassign (line 39) | def unassign
method show_hide_contacts (line 62) | def show_hide_contacts
method reimbursement (line 73) | def reimbursement
method case_assignment_parent (line 84) | def case_assignment_parent
method after_action_path (line 92) | def after_action_path(resource)
method case_assignment_params (line 100) | def case_assignment_params
method load_case_assignment (line 104) | def load_case_assignment
method load_existing_case_assignment (line 114) | def load_existing_case_assignment
method existing_case_assignment (line 123) | def existing_case_assignment
method handle_successful_assignment (line 127) | def handle_successful_assignment(msg)
method handle_failed_assignment (line 133) | def handle_failed_assignment(msg)
FILE: app/controllers/case_contact_reports_controller.rb
class CaseContactReportsController (line 3) | class CaseContactReportsController < ApplicationController
method index (line 6) | def index
method report_params (line 20) | def report_params
method convert_radio_options_to_boolean (line 40) | def convert_radio_options_to_boolean(parameters)
method string_to_boolean (line 46) | def string_to_boolean(value)
FILE: app/controllers/case_contacts/case_contacts_new_design_controller.rb
class CaseContacts::CaseContactsNewDesignController (line 1) | class CaseContacts::CaseContactsNewDesignController < ApplicationController
method index (line 6) | def index
method datatable (line 10) | def datatable
method check_feature_flag (line 20) | def check_feature_flag
FILE: app/controllers/case_contacts/followups_controller.rb
class CaseContacts::FollowupsController (line 1) | class CaseContacts::FollowupsController < ApplicationController
method create (line 4) | def create
method resolve (line 16) | def resolve
method simple_followup_params (line 31) | def simple_followup_params
method create_notification (line 35) | def create_notification
FILE: app/controllers/case_contacts/form_controller.rb
class CaseContacts::FormController (line 1) | class CaseContacts::FormController < ApplicationController
method show (line 10) | def show
method update (line 18) | def update
method set_case_contact (line 45) | def set_case_contact
method prepare_form (line 51) | def prepare_form
method get_casa_cases (line 64) | def get_casa_cases
method get_contact_types (line 70) | def get_contact_types
method get_contact_topics (line 86) | def get_contact_topics
method group_contact_types_by_name (line 93) | def group_contact_types_by_name(contact_types)
method finish_editing (line 97) | def finish_editing
method send_reimbursement_email (line 118) | def send_reimbursement_email(case_contact)
method update_volunteer_address (line 124) | def update_volunteer_address(case_contact)
method create_additional_case_contacts (line 137) | def create_additional_case_contacts(case_contact)
method case_contact_params (line 160) | def case_contact_params
method remove_nil_draft_ids (line 164) | def remove_nil_draft_ids
FILE: app/controllers/case_contacts_controller.rb
class CaseContactsController (line 3) | class CaseContactsController < ApplicationController
method index (line 11) | def index
method drafts (line 15) | def drafts
method new (line 21) | def new
method edit (line 38) | def edit
method destroy (line 43) | def destroy
method restore (line 57) | def restore
method leave (line 66) | def leave
method update_or_create_additional_expense (line 72) | def update_or_create_additional_expense(all_ae_params, cc)
method set_contact_types (line 86) | def set_contact_types
method additional_expense_params (line 90) | def additional_expense_params
method set_case_contact (line 94) | def set_case_contact
method build_draft_case_ids (line 99) | def build_draft_case_ids(params, casa_cases)
FILE: app/controllers/case_court_orders_controller.rb
class CaseCourtOrdersController (line 1) | class CaseCourtOrdersController < ApplicationController
method destroy (line 6) | def destroy
method set_case_court_order (line 13) | def set_case_court_order
FILE: app/controllers/case_court_reports_controller.rb
class CaseCourtReportsController (line 3) | class CaseCourtReportsController < ApplicationController
method index (line 7) | def index
method show (line 12) | def show
method generate (line 29) | def generate
method date_range_params (line 57) | def date_range_params
method case_params (line 61) | def case_params
method set_casa_case (line 65) | def set_casa_case
method assigned_cases (line 69) | def assigned_cases
method generate_report_to_string (line 77) | def generate_report_to_string(casa_case, time_range)
method save_report (line 96) | def save_report(report_data, casa_case)
method generate_error (line 106) | def generate_error(message)
FILE: app/controllers/case_groups_controller.rb
class CaseGroupsController (line 1) | class CaseGroupsController < ApplicationController
method index (line 5) | def index
method new (line 10) | def new
method edit (line 15) | def edit
method create (line 19) | def create
method update (line 30) | def update
method destroy (line 40) | def destroy
method case_group_params (line 49) | def case_group_params
method set_case_group (line 54) | def set_case_group
FILE: app/controllers/checklist_items_controller.rb
class ChecklistItemsController (line 1) | class ChecklistItemsController < ApplicationController
method new (line 6) | def new
method create (line 10) | def create
method edit (line 20) | def edit
method update (line 23) | def update
method destroy (line 32) | def destroy
method set_checklist_updated_date (line 44) | def set_checklist_updated_date(hearing_type)
method authorize_checklist_item (line 48) | def authorize_checklist_item
method set_hearing_type (line 52) | def set_hearing_type
method set_checklist_item (line 56) | def set_checklist_item
method checklist_item_params (line 60) | def checklist_item_params
FILE: app/controllers/concerns/accessible.rb
type Accessible (line 1) | module Accessible
function check_user (line 10) | def check_user
FILE: app/controllers/concerns/court_date_params.rb
type CourtDateParams (line 1) | module CourtDateParams
function sanitized_court_date_params (line 4) | def sanitized_court_date_params(casa_case)
function court_date_params (line 16) | def court_date_params(casa_case)
FILE: app/controllers/concerns/loads_case_contacts.rb
type LoadsCaseContacts (line 1) | module LoadsCaseContacts
function load_case_contacts (line 6) | def load_case_contacts
function current_organization_groups (line 27) | def current_organization_groups
function all_case_contacts (line 35) | def all_case_contacts
FILE: app/controllers/concerns/organizational.rb
type Organizational (line 1) | module Organizational
class UnknownOrganization (line 4) | class UnknownOrganization < StandardError
function require_organization! (line 7) | def require_organization!
function current_organization (line 11) | def current_organization
function current_role (line 15) | def current_role
FILE: app/controllers/concerns/users/time_zone.rb
type Users (line 1) | module Users
type TimeZone (line 2) | module TimeZone
function browser_time_zone (line 10) | def browser_time_zone
function to_user_timezone (line 17) | def to_user_timezone(time_date)
function user_timezone (line 26) | def user_timezone
FILE: app/controllers/contact_topic_answers_controller.rb
class ContactTopicAnswersController (line 1) | class ContactTopicAnswersController < ApplicationController
method create (line 4) | def create
method destroy (line 15) | def destroy
method contact_topic_answer_params (line 26) | def contact_topic_answer_params
FILE: app/controllers/contact_topics_controller.rb
class ContactTopicsController (line 1) | class ContactTopicsController < ApplicationController
method new (line 6) | def new
method edit (line 12) | def edit
method create (line 17) | def create
method update (line 29) | def update
method soft_delete (line 40) | def soft_delete
method set_contact_topic (line 53) | def set_contact_topic
method contact_topic_params (line 58) | def contact_topic_params
FILE: app/controllers/contact_type_groups_controller.rb
class ContactTypeGroupsController (line 1) | class ContactTypeGroupsController < ApplicationController
method new (line 5) | def new
method create (line 10) | def create
method edit (line 21) | def edit
method update (line 25) | def update
method contact_type_group_params (line 36) | def contact_type_group_params
method set_contact_type_group (line 40) | def set_contact_type_group
FILE: app/controllers/contact_types_controller.rb
class ContactTypesController (line 1) | class ContactTypesController < ApplicationController
method new (line 5) | def new
method create (line 10) | def create
method edit (line 21) | def edit
method update (line 25) | def update
method set_contact_type (line 36) | def set_contact_type
method contact_type_params (line 40) | def contact_type_params
FILE: app/controllers/court_dates_controller.rb
class CourtDatesController (line 1) | class CourtDatesController < ApplicationController
method show (line 10) | def show
method new (line 25) | def new
method edit (line 30) | def edit
method create (line 34) | def create
method update (line 45) | def update
method destroy (line 54) | def destroy
method set_casa_case (line 66) | def set_casa_case
method set_court_date (line 75) | def set_court_date
method generate_report_to_string (line 79) | def generate_report_to_string(court_date, time_zone)
FILE: app/controllers/custom_org_links_controller.rb
class CustomOrgLinksController (line 1) | class CustomOrgLinksController < ApplicationController
method new (line 5) | def new
method create (line 10) | def create
method edit (line 22) | def edit
method update (line 26) | def update
method destroy (line 35) | def destroy
method set_custom_org_link (line 43) | def set_custom_org_link
method custom_org_link_params (line 47) | def custom_org_link_params
FILE: app/controllers/dashboard_controller.rb
class DashboardController (line 1) | class DashboardController < ApplicationController
method show (line 5) | def show
method volunteer_with_only_one_active_case? (line 20) | def volunteer_with_only_one_active_case?
FILE: app/controllers/emancipation_checklists_controller.rb
class EmancipationChecklistsController (line 1) | class EmancipationChecklistsController < ApplicationController
method index (line 6) | def index
FILE: app/controllers/emancipations_controller.rb
class EmancipationsController (line 1) | class EmancipationsController < ApplicationController
method show (line 11) | def show
method save (line 34) | def save
method not_authorized (line 82) | def not_authorized(exception)
FILE: app/controllers/error_controller.rb
class ErrorController (line 3) | class ErrorController < ApplicationController
method index (line 7) | def index
method create (line 10) | def create
FILE: app/controllers/followup_reports_controller.rb
class FollowupReportsController (line 3) | class FollowupReportsController < ApplicationController
method index (line 6) | def index
FILE: app/controllers/fund_requests_controller.rb
class FundRequestsController (line 1) | class FundRequestsController < ApplicationController
method new (line 5) | def new
method create (line 10) | def create
method verify_casa_case (line 24) | def verify_casa_case
method parsed_params (line 31) | def parsed_params
FILE: app/controllers/health_controller.rb
class HealthController (line 1) | class HealthController < ApplicationController
method index (line 6) | def index
method gc (line 16) | def gc
method case_contacts_creation_times_in_last_week (line 24) | def case_contacts_creation_times_in_last_week
method monthly_line_graph_data (line 32) | def monthly_line_graph_data
method monthly_unique_users_graph_data (line 55) | def monthly_unique_users_graph_data
method verify_token_for_gc_stats (line 82) | def verify_token_for_gc_stats
FILE: app/controllers/hearing_types_controller.rb
class HearingTypesController (line 1) | class HearingTypesController < ApplicationController
method new (line 5) | def new
method create (line 10) | def create
method edit (line 21) | def edit
method update (line 25) | def update
method set_hearing_type (line 36) | def set_hearing_type
method hearing_type_params (line 40) | def hearing_type_params
FILE: app/controllers/imports_controller.rb
class ImportsController (line 1) | class ImportsController < ApplicationController
method index (line 16) | def index
method create (line 25) | def create
method download_failed (line 52) | def download_failed
method failed_csv_service (line 61) | def failed_csv_service(failed_rows: "")
method header (line 69) | def header
method header_valid? (line 77) | def header_valid?(file_header, import_type)
method import_from_csv (line 81) | def import_from_csv(import_type, sms_opt_in, file, org_id)
method validate_file (line 103) | def validate_file(file, import_type)
method requires_sms_opt_in (line 131) | def requires_sms_opt_in(file, import_type, sms_opt_in)
method import_contains_phone_numbers (line 139) | def import_contains_phone_numbers(file)
FILE: app/controllers/judges_controller.rb
class JudgesController (line 1) | class JudgesController < ApplicationController
method new (line 5) | def new
method create (line 10) | def create
method edit (line 21) | def edit
method update (line 25) | def update
method set_judge (line 36) | def set_judge
method judge_params (line 40) | def judge_params
FILE: app/controllers/languages_controller.rb
class LanguagesController (line 1) | class LanguagesController < ApplicationController
method new (line 4) | def new
method edit (line 9) | def edit
method create (line 13) | def create
method update (line 26) | def update
method set_language (line 39) | def set_language
method language_params (line 43) | def language_params
FILE: app/controllers/learning_hour_topics_controller.rb
class LearningHourTopicsController (line 3) | class LearningHourTopicsController < ApplicationController
method new (line 7) | def new
method edit (line 12) | def edit
method create (line 16) | def create
method update (line 27) | def update
method set_learning_hour_topic (line 39) | def set_learning_hour_topic
method learning_hour_topic_params (line 43) | def learning_hour_topic_params
FILE: app/controllers/learning_hour_types_controller.rb
class LearningHourTypesController (line 3) | class LearningHourTypesController < ApplicationController
method new (line 7) | def new
method edit (line 12) | def edit
method create (line 16) | def create
method update (line 27) | def update
method set_learning_hour_type (line 39) | def set_learning_hour_type
method learning_hour_type_params (line 43) | def learning_hour_type_params
FILE: app/controllers/learning_hours/volunteers_controller.rb
class LearningHours::VolunteersController (line 1) | class LearningHours::VolunteersController < ApplicationController
method show (line 5) | def show
method set_volunteer (line 12) | def set_volunteer
FILE: app/controllers/learning_hours_controller.rb
class LearningHoursController (line 1) | class LearningHoursController < ApplicationController
method index (line 5) | def index
method show (line 10) | def show
method new (line 14) | def new
method create (line 19) | def create
method edit (line 32) | def edit
method update (line 36) | def update
method destroy (line 47) | def destroy
method set_learning_hour (line 56) | def set_learning_hour
method learning_hours_params (line 62) | def learning_hours_params
method update_learning_hours_params (line 67) | def update_learning_hours_params
FILE: app/controllers/learning_hours_reports_controller.rb
class LearningHoursReportsController (line 1) | class LearningHoursReportsController < ApplicationController
method index (line 4) | def index
FILE: app/controllers/mileage_rates_controller.rb
class MileageRatesController (line 1) | class MileageRatesController < ApplicationController
method index (line 5) | def index
method new (line 10) | def new
method create (line 15) | def create
method edit (line 25) | def edit
method update (line 29) | def update
method mileage_rate_params (line 41) | def mileage_rate_params
method set_mileage_rate (line 45) | def set_mileage_rate
FILE: app/controllers/mileage_reports_controller.rb
class MileageReportsController (line 5) | class MileageReportsController < ApplicationController
method index (line 8) | def index
FILE: app/controllers/missing_data_reports_controller.rb
class MissingDataReportsController (line 1) | class MissingDataReportsController < ApplicationController
method index (line 4) | def index
FILE: app/controllers/notes_controller.rb
class NotesController (line 1) | class NotesController < ApplicationController
method create (line 5) | def create
method edit (line 11) | def edit
method update (line 15) | def update
method destroy (line 22) | def destroy
method find_note (line 31) | def find_note
method find_volunteer (line 36) | def find_volunteer
method note_params (line 41) | def note_params
FILE: app/controllers/notifications_controller.rb
class NotificationsController (line 1) | class NotificationsController < ApplicationController
method index (line 5) | def index
method mark_as_read (line 13) | def mark_as_read
method set_notification (line 22) | def set_notification
FILE: app/controllers/other_duties_controller.rb
class OtherDutiesController (line 1) | class OtherDutiesController < ApplicationController
method index (line 5) | def index
method new (line 17) | def new
method create (line 22) | def create
method edit (line 33) | def edit
method update (line 37) | def update
method convert_duration_minutes (line 49) | def convert_duration_minutes
method generate_other_duty_list (line 56) | def generate_other_duty_list(volunteers)
method no_other_duties_for (line 66) | def no_other_duties_for(volunteers)
method other_duty_params (line 76) | def other_duty_params
method set_other_duty (line 80) | def set_other_duty
FILE: app/controllers/placement_reports_controller.rb
class PlacementReportsController (line 1) | class PlacementReportsController < ApplicationController
method index (line 4) | def index
FILE: app/controllers/placement_types_controller.rb
class PlacementTypesController (line 1) | class PlacementTypesController < ApplicationController
method new (line 6) | def new
method create (line 11) | def create
method edit (line 22) | def edit
method update (line 26) | def update
method set_placement_type (line 38) | def set_placement_type
method placement_type_params (line 44) | def placement_type_params
FILE: app/controllers/placements_controller.rb
class PlacementsController (line 1) | class PlacementsController < ApplicationController
method index (line 6) | def index
method show (line 10) | def show
method new (line 14) | def new
method edit (line 19) | def edit
method create (line 23) | def create
method update (line 34) | def update
method destroy (line 44) | def destroy
method set_casa_case (line 56) | def set_casa_case
method set_placement (line 60) | def set_placement
method placement_params (line 64) | def placement_params
FILE: app/controllers/preference_sets_controller.rb
class PreferenceSetsController (line 1) | class PreferenceSetsController < ApplicationController
method table_state (line 4) | def table_state
method table_state_update (line 10) | def table_state_update
method set_table_name (line 21) | def set_table_name
FILE: app/controllers/reimbursements_controller.rb
class ReimbursementsController (line 1) | class ReimbursementsController < ApplicationController
method new (line 2) | def new
method index (line 5) | def index
method datatable (line 17) | def datatable
method change_complete_status (line 28) | def change_complete_status
method apply_filters_to_query (line 43) | def apply_filters_to_query(query)
method apply_occurred_at_filters (line 49) | def apply_occurred_at_filters(query)
method apply_occurred_at_filter (line 58) | def apply_occurred_at_filter(key, query)
method fetch_reimbursements (line 69) | def fetch_reimbursements
method fetch_filtered_reimbursements (line 78) | def fetch_filtered_reimbursements(complete_only)
method get_normalised_time_for_occurred_at_filter (line 87) | def get_normalised_time_for_occurred_at_filter(key)
method reimbursement_params (line 96) | def reimbursement_params
method volunteers_for_filter (line 100) | def volunteers_for_filter(reimbursements)
FILE: app/controllers/reports_controller.rb
class ReportsController (line 1) | class ReportsController < ApplicationController
method index (line 4) | def index
method export_emails (line 8) | def export_emails
FILE: app/controllers/static_controller.rb
class StaticController (line 2) | class StaticController < ApplicationController
method index (line 9) | def index
method register (line 14) | def register
method page (line 17) | def page
FILE: app/controllers/supervisor_volunteers_controller.rb
class SupervisorVolunteersController (line 1) | class SupervisorVolunteersController < ApplicationController
method create (line 4) | def create
method unassign (line 17) | def unassign
method bulk_assignment (line 30) | def bulk_assignment
method supervisor_volunteer_params (line 46) | def supervisor_volunteer_params
method set_supervisor (line 50) | def set_supervisor
method bulk_change_supervisor (line 54) | def bulk_change_supervisor(supervisor, volunteers)
method assign_volunteer_to_supervisor (line 66) | def assign_volunteer_to_supervisor(volunteer, supervisor)
method unassign_volunteers_supervisor (line 72) | def unassign_volunteers_supervisor(volunteer)
FILE: app/controllers/supervisors_controller.rb
class SupervisorsController (line 3) | class SupervisorsController < ApplicationController
method index (line 13) | def index
method new (line 19) | def new
method create (line 24) | def create
method edit (line 42) | def edit
method update (line 50) | def update
method activate (line 62) | def activate
method deactivate (line 73) | def deactivate
method resend_invitation (line 82) | def resend_invitation
method change_to_admin (line 89) | def change_to_admin
method datatable (line 96) | def datatable
method set_supervisor (line 106) | def set_supervisor
method all_volunteers_ever_assigned (line 110) | def all_volunteers_ever_assigned
method supervisor_has_unassigned_volunteers (line 115) | def supervisor_has_unassigned_volunteers
method available_volunteers (line 119) | def available_volunteers
method supervisor_values (line 123) | def supervisor_values
method supervisor_params (line 127) | def supervisor_params
method update_supervisor_params (line 143) | def update_supervisor_params
FILE: app/controllers/users/invitations_controller.rb
class Users::InvitationsController (line 1) | class Users::InvitationsController < Devise::InvitationsController
method edit (line 3) | def edit
FILE: app/controllers/users/passwords_controller.rb
class Users::PasswordsController (line 1) | class Users::PasswordsController < Devise::PasswordsController
method create (line 6) | def create
method update (line 21) | def update
method render_error (line 36) | def render_error
method send_password (line 41) | def send_password
method send_password_reset_mail (line 48) | def send_password_reset_mail
method send_password_reset_sms (line 52) | def send_password_reset_sms
method valid_params? (line 67) | def valid_params?(email, phone_number)
method email? (line 76) | def email?
method phone_number? (line 80) | def phone_number?
method empty_fields_error (line 84) | def empty_fields_error
method invalid_phone_number_error (line 91) | def invalid_phone_number_error(error_message)
method params_not_present (line 97) | def params_not_present(email, phone_number)
method user_exists (line 101) | def user_exists
method no_user_found_error (line 105) | def no_user_found_error
method create_short_url (line 111) | def create_short_url
FILE: app/controllers/users/sessions_controller.rb
class Users::SessionsController (line 3) | class Users::SessionsController < Devise::SessionsController
FILE: app/controllers/users_controller.rb
class UsersController (line 1) | class UsersController < ApplicationController
method edit (line 10) | def edit
method update (line 14) | def update
method add_language (line 23) | def add_language
method remove_language (line 42) | def remove_language
method update_password (line 54) | def update_password
method update_email (line 72) | def update_email
method set_language (line 90) | def set_language
method set_initial_address (line 94) | def set_initial_address
method set_active_casa_admins (line 98) | def set_active_casa_admins
method authorize_user_with_policy (line 102) | def authorize_user_with_policy
method get_user (line 106) | def get_user
method password_params (line 110) | def password_params
method update_user_password (line 114) | def update_user_password
method email_params (line 118) | def email_params
method update_user_email (line 122) | def update_user_email
method user_params (line 127) | def user_params
method valid_user_password (line 135) | def valid_user_password
method set_custom_error_heading (line 143) | def set_custom_error_heading
method reset_custom_error_heading (line 147) | def reset_custom_error_heading
FILE: app/controllers/volunteers_controller.rb
class VolunteersController (line 1) | class VolunteersController < ApplicationController
method index (line 7) | def index
method show (line 12) | def show
method datatable (line 17) | def datatable
method new (line 25) | def new
method create (line 30) | def create
method edit (line 57) | def edit
method update (line 62) | def update
method activate (line 74) | def activate
method deactivate (line 89) | def deactivate
method resend_invitation (line 98) | def resend_invitation
method send_reactivation_alert (line 109) | def send_reactivation_alert
method reminder (line 121) | def reminder
method impersonate (line 137) | def impersonate
method stop_impersonating (line 143) | def stop_impersonating
method set_volunteer (line 150) | def set_volunteer
method generate_devise_password (line 154) | def generate_devise_password
method create_volunteer_params (line 158) | def create_volunteer_params
method update_volunteer_params (line 165) | def update_volunteer_params
method volunteers_phone_number (line 171) | def volunteers_phone_number
method send_sms_to (line 176) | def send_sms_to(phone_number, body)
FILE: app/datatables/application_datatable.rb
class ApplicationDatatable (line 1) | class ApplicationDatatable
method initialize (line 8) | def initialize(base_relation, params)
method as_json (line 13) | def as_json(*)
method sanitize (line 23) | def sanitize(data)
method filtered_records (line 33) | def filtered_records
method paginated_records (line 37) | def paginated_records
method additional_filters (line 44) | def additional_filters
method search_term (line 48) | def search_term
method build_order_clause (line 52) | def build_order_clause
method order_by (line 56) | def order_by
method order_column_index (line 64) | def order_column_index
method order_params (line 68) | def order_params
method order_direction (line 72) | def order_direction
method limit (line 77) | def limit
method offset (line 81) | def offset
method bool_filter (line 85) | def bool_filter(filter)
method sanitize_sql (line 97) | def sanitize_sql(sql)
FILE: app/datatables/case_contact_datatable.rb
class CaseContactDatatable (line 3) | class CaseContactDatatable < ApplicationDatatable
method initialize (line 11) | def initialize(base_relation, params, current_user)
method data (line 20) | def data
method filtered_records (line 57) | def filtered_records
method raw_records (line 61) | def raw_records
method search_filter (line 71) | def search_filter
method contact_type_search_subquery (line 88) | def contact_type_search_subquery
method order_clause (line 100) | def order_clause
FILE: app/datatables/reimbursement_datatable.rb
class ReimbursementDatatable (line 1) | class ReimbursementDatatable < ApplicationDatatable
method data (line 11) | def data
method case_contact_types (line 34) | def case_contact_types(case_contact)
method mark_as_complete_path (line 43) | def mark_as_complete_path(case_contact)
method raw_records (line 47) | def raw_records
method order_clause (line 59) | def order_clause
FILE: app/datatables/supervisor_datatable.rb
class SupervisorDatatable (line 1) | class SupervisorDatatable < ApplicationDatatable
method data (line 10) | def data
method raw_records (line 24) | def raw_records
method filtered_records (line 28) | def filtered_records
method active_filter (line 32) | def active_filter
method order_clause (line 43) | def order_clause
FILE: app/datatables/volunteer_datatable.rb
class VolunteerDatatable (line 1) | class VolunteerDatatable < ApplicationDatatable
method data (line 15) | def data
method filtered_records (line 37) | def filtered_records
method raw_records (line 47) | def raw_records
method transition_aged_youth_cases_subquery (line 85) | def transition_aged_youth_cases_subquery
method most_recent_attempts_subquery (line 96) | def most_recent_attempts_subquery
method contacts_made_in_past_days_subquery (line 108) | def contacts_made_in_past_days_subquery
method hours_spent_in_days_subquery (line 122) | def hours_spent_in_days_subquery
method order_clause (line 136) | def order_clause
method supervisor_filter (line 140) | def supervisor_filter
method active_filter (line 152) | def active_filter
method transition_aged_youth_filter (line 163) | def transition_aged_youth_filter
method extra_languages_filter (line 174) | def extra_languages_filter
method search_filter (line 187) | def search_filter
method casa_case_number_filter_subquery (line 206) | def casa_case_number_filter_subquery
FILE: app/decorators/android_app_association_decorator.rb
class AndroidAppAssociationDecorator (line 1) | class AndroidAppAssociationDecorator < ApplicationDecorator
FILE: app/decorators/application_decorator.rb
class ApplicationDecorator (line 1) | class ApplicationDecorator < Draper::Decorator; end
FILE: app/decorators/casa_case_decorator.rb
class CasaCaseDecorator (line 1) | class CasaCaseDecorator < Draper::Decorator
method case_contacts_ordered_by_occurred_at (line 6) | def case_contacts_ordered_by_occurred_at
method case_contacts_latest (line 10) | def case_contacts_latest
method case_contacts_latest_before (line 14) | def case_contacts_latest_before(date)
method case_contacts_filtered_by_active_assignment_ordered_by_occurred_at (line 18) | def case_contacts_filtered_by_active_assignment_ordered_by_occurred_at
method court_report_submission (line 25) | def court_report_submission
method court_report_submitted_date (line 29) | def court_report_submitted_date
method court_report_select_option (line 33) | def court_report_select_option
method date_in_care (line 46) | def date_in_care
method duration_in_care (line 51) | def duration_in_care
method calendar_next_court_date (line 56) | def calendar_next_court_date
method calendar_court_report_due_date (line 61) | def calendar_court_report_due_date
method calendar_format (line 66) | def calendar_format(date)
method formatted_updated_at (line 70) | def formatted_updated_at
method inactive_class (line 74) | def inactive_class
method status (line 78) | def status
method successful_contacts_this_week (line 82) | def successful_contacts_this_week
method successful_contacts_this_week_before (line 87) | def successful_contacts_this_week_before(date)
method transition_aged_youth (line 92) | def transition_aged_youth
method transition_aged_youth_icon (line 102) | def transition_aged_youth_icon
method unsuccessful_contacts_this_week (line 106) | def unsuccessful_contacts_this_week
method unsuccessful_contacts_this_week_before (line 111) | def unsuccessful_contacts_this_week_before(date)
method emancipation_checklist_count (line 116) | def emancipation_checklist_count
method show_contact_type? (line 120) | def show_contact_type?(contact_type_id)
method hash_for_multi_select (line 124) | def hash_for_multi_select
FILE: app/decorators/case_assignment_decorator.rb
class CaseAssignmentDecorator (line 1) | class CaseAssignmentDecorator < Draper::Decorator
method unassigned_in_past_week? (line 4) | def unassigned_in_past_week?
FILE: app/decorators/case_contact_decorator.rb
class CaseContactDecorator (line 1) | class CaseContactDecorator < Draper::Decorator
method duration_minutes (line 6) | def duration_minutes
method report_duration_minutes (line 18) | def report_duration_minutes
method miles_traveled (line 22) | def miles_traveled
method reimbursement (line 26) | def reimbursement
method contact_made (line 30) | def contact_made
method report_contact_made (line 34) | def report_contact_made
method subheading (line 38) | def subheading
method paragraph_notes (line 48) | def paragraph_notes
method contact_types (line 56) | def contact_types
method contact_types_comma_separated (line 64) | def contact_types_comma_separated
method report_contact_types (line 72) | def report_contact_types
method medium_icon_classes (line 76) | def medium_icon_classes
method contact_groups (line 93) | def contact_groups
method limited_notes (line 102) | def limited_notes
method full_notes (line 106) | def full_notes
method show_contact_type? (line 110) | def show_contact_type?(contact_type_id)
method additional_expenses_count (line 114) | def additional_expenses_count
method address_of_volunteer (line 118) | def address_of_volunteer
method ambiguous_volunteer_address_message (line 126) | def ambiguous_volunteer_address_message
method form_title (line 130) | def form_title
method form_page_notes (line 134) | def form_page_notes
method form_updated_message (line 142) | def form_updated_message
method formatted_hours_and_minutes (line 148) | def formatted_hours_and_minutes(minutes)
FILE: app/decorators/case_contacts/form_decorator.rb
class CaseContacts::FormDecorator (line 1) | class CaseContacts::FormDecorator < ApplicationDecorator
FILE: app/decorators/contact_type_decorator.rb
class ContactTypeDecorator (line 1) | class ContactTypeDecorator < Draper::Decorator
method hash_for_multi_select_with_cases (line 5) | def hash_for_multi_select_with_cases(casa_case_ids)
method last_time_used_with_cases (line 13) | def last_time_used_with_cases(casa_case_ids)
FILE: app/decorators/court_date_decorator.rb
class CourtDateDecorator (line 1) | class CourtDateDecorator < Draper::Decorator
method formatted_date (line 4) | def formatted_date
method court_date_info (line 8) | def court_date_info
FILE: app/decorators/learning_hour_decorator.rb
class LearningHourDecorator (line 1) | class LearningHourDecorator < ApplicationDecorator
FILE: app/decorators/learning_hour_topic_decorator.rb
class LearningHourTopicDecorator (line 1) | class LearningHourTopicDecorator < ApplicationDecorator
FILE: app/decorators/other_duty_decorator.rb
class OtherDutyDecorator (line 1) | class OtherDutyDecorator < Draper::Decorator
method duration_in_minutes (line 6) | def duration_in_minutes
method truncate_notes (line 19) | def truncate_notes
method limited_notes (line 29) | def limited_notes
method full_notes (line 33) | def full_notes
FILE: app/decorators/patch_note_decorator.rb
class PatchNoteDecorator (line 1) | class PatchNoteDecorator < ApplicationDecorator
FILE: app/decorators/placement_decorator.rb
class PlacementDecorator (line 1) | class PlacementDecorator < Draper::Decorator
method formatted_date (line 4) | def formatted_date
method placement_info (line 8) | def placement_info
method placement_started_at (line 12) | def placement_started_at
method created_at (line 16) | def created_at
FILE: app/decorators/user_decorator.rb
class UserDecorator (line 1) | class UserDecorator < Draper::Decorator
method status (line 4) | def status
method local_time_zone (line 8) | def local_time_zone
method formatted_timestamp (line 13) | def formatted_timestamp(attribute)
method formatted_created_at (line 24) | def formatted_created_at
method formatted_updated_at (line 28) | def formatted_updated_at
method formatted_current_sign_in_at (line 32) | def formatted_current_sign_in_at
method formatted_invitation_accepted_at (line 36) | def formatted_invitation_accepted_at
method formatted_reset_password_sent_at (line 40) | def formatted_reset_password_sent_at
method formatted_invitation_sent_at (line 44) | def formatted_invitation_sent_at
method formatted_birthday (line 48) | def formatted_birthday
method formatted_date_of_birth (line 54) | def formatted_date_of_birth
FILE: app/decorators/volunteer_decorator.rb
class VolunteerDecorator (line 1) | class VolunteerDecorator < UserDecorator
method cc_reminder_text (line 4) | def cc_reminder_text
FILE: app/helpers/all_casa_admins/casa_orgs_helper.rb
type AllCasaAdmins (line 1) | module AllCasaAdmins
type CasaOrgsHelper (line 2) | module CasaOrgsHelper
function selected_organization (line 3) | def selected_organization
FILE: app/helpers/api_base_helper.rb
type ApiBaseHelper (line 1) | module ApiBaseHelper
FILE: app/helpers/application_helper.rb
type ApplicationHelper (line 1) | module ApplicationHelper
function body_class (line 4) | def body_class
function logged_in? (line 9) | def logged_in?
function not_logged_in? (line 13) | def not_logged_in?
function page_header (line 17) | def page_header
function default_page_header (line 23) | def default_page_header
function session_link (line 27) | def session_link
function flash_class (line 37) | def flash_class(level)
function og_tag (line 46) | def og_tag(type, options = {})
function resource_name (line 50) | def resource_name
function resource (line 54) | def resource
function devise_mapping (line 58) | def devise_mapping
FILE: app/helpers/banner_helper.rb
type BannerHelper (line 1) | module BannerHelper
function conditionally_add_hidden_class (line 2) | def conditionally_add_hidden_class(current_banner_is_active)
function banner_expiration_time_in_words (line 8) | def banner_expiration_time_in_words(banner)
FILE: app/helpers/case_contacts_helper.rb
type CaseContactsHelper (line 2) | module CaseContactsHelper
function duration_hours (line 3) | def duration_hours(case_contact)
function duration_minutes (line 7) | def duration_minutes(case_contact)
function contact_mediums (line 11) | def contact_mediums
function render_back_link (line 17) | def render_back_link(casa_case)
function thank_you_message (line 23) | def thank_you_message
function show_volunteer_reimbursement (line 36) | def show_volunteer_reimbursement(casa_cases)
function expand_filters? (line 47) | def expand_filters?(surfaced_keys = %i[no_drafts sorted_by])
function send_home (line 56) | def send_home
function send_to_case (line 60) | def send_to_case(casa_case)
FILE: app/helpers/contact_types_helper.rb
type ContactTypesHelper (line 4) | module ContactTypesHelper
function set_group_options (line 5) | def set_group_options
FILE: app/helpers/court_dates_helper.rb
type CourtDatesHelper (line 4) | module CourtDatesHelper
function when_do_we_have_court_dates (line 5) | def when_do_we_have_court_dates(casa_case)
FILE: app/helpers/court_orders_helper.rb
type CourtOrdersHelper (line 1) | module CourtOrdersHelper
function court_order_select_options (line 2) | def court_order_select_options
FILE: app/helpers/date_helper.rb
type DateHelper (line 1) | module DateHelper
function validate_date (line 5) | def validate_date(day, month, year)
function parse_date (line 11) | def parse_date(errors, date_field_name, args)
FILE: app/helpers/emancipations_helper.rb
type EmancipationsHelper (line 1) | module EmancipationsHelper
function emancipation_category_checkbox_checked (line 2) | def emancipation_category_checkbox_checked(casa_case, emancipation_cat...
function emancipation_category_collapse_hidden (line 6) | def emancipation_category_collapse_hidden(casa_case, emancipation_cate...
function emancipation_category_collapse_icon (line 10) | def emancipation_category_collapse_icon(casa_case, emancipation_category)
function emancipation_option_checkbox_checked (line 14) | def emancipation_option_checkbox_checked(casa_case, emancipation_option)
function emancipation_category_checkbox_checked_download (line 18) | def emancipation_category_checkbox_checked_download(casa_case, emancip...
function emancipation_option_checkbox_checked_download (line 22) | def emancipation_option_checkbox_checked_download(casa_case, emancipat...
function emancipation_option_radio_checked_download (line 26) | def emancipation_option_radio_checked_download(casa_case, emancipation...
function case_contains_category? (line 32) | def case_contains_category?(casa_case, emancipation_category)
FILE: app/helpers/followup_helper.rb
type FollowupHelper (line 1) | module FollowupHelper
function followup_icon (line 2) | def followup_icon(creator)
FILE: app/helpers/learning_hours_helper.rb
type LearningHoursHelper (line 1) | module LearningHoursHelper
function format_time (line 2) | def format_time(minutes)
FILE: app/helpers/mileage_rates_helper.rb
type MileageRatesHelper (line 1) | module MileageRatesHelper
function effective_date_parser (line 2) | def effective_date_parser(date)
FILE: app/helpers/notifications_helper.rb
type NotificationsHelper (line 1) | module NotificationsHelper
function read_when_seen_notifications (line 2) | def read_when_seen_notifications
function notifications_after_and_including_deploy (line 6) | def notifications_after_and_including_deploy(notifications)
function notifications_before_deploy (line 16) | def notifications_before_deploy(notifications)
function patch_notes_as_hash_keyed_by_type_name (line 20) | def patch_notes_as_hash_keyed_by_type_name(patch_notes)
FILE: app/helpers/other_duties_helper.rb
type OtherDutiesHelper (line 2) | module OtherDutiesHelper
function duration_hours (line 3) | def duration_hours(duty)
function duration_minutes (line 7) | def duration_minutes(duty)
FILE: app/helpers/phone_number_helper.rb
type PhoneNumberHelper (line 1) | module PhoneNumberHelper
function valid_phone_number (line 6) | def valid_phone_number(number)
function strip_unnecessary_characters (line 36) | def strip_unnecessary_characters(number)
FILE: app/helpers/preference_sets_helper.rb
type PreferenceSetsHelper (line 1) | module PreferenceSetsHelper
FILE: app/helpers/report_helper.rb
type ReportHelper (line 1) | module ReportHelper
function boolean_choices (line 2) | def boolean_choices
FILE: app/helpers/request_header_helper.rb
type RequestHeaderHelper (line 1) | module RequestHeaderHelper
FILE: app/helpers/sidebar_helper.rb
type SidebarHelper (line 1) | module SidebarHelper
function cases_index_title (line 2) | def cases_index_title
function inbox_label (line 8) | def inbox_label
function menu_item (line 14) | def menu_item(label:, path:, visible: false)
function active_class (line 20) | def active_class(link_path)
function request_path_active? (line 30) | def request_path_active?(link_path)
FILE: app/helpers/sms_body_helper.rb
type SmsBodyHelper (line 1) | module SmsBodyHelper
function account_activation_msg (line 2) | def account_activation_msg(resource = "primorgens", hash_of_links = {})
function court_report_due_msg (line 21) | def court_report_due_msg(report_due_date, short_link)
function no_contact_made_msg (line 25) | def no_contact_made_msg(contact_type, short_link)
function case_contact_flagged_msg (line 29) | def case_contact_flagged_msg(display_name, short_link)
function password_reset_msg (line 33) | def password_reset_msg(display_name, short_link)
FILE: app/helpers/template_helper.rb
type TemplateHelper (line 1) | module TemplateHelper
function sanitize_opening_tags (line 2) | def sanitize_opening_tags(opening_tags)
function sanitize_closing_tags (line 16) | def sanitize_closing_tags(closing_tags)
function validate_closing_tags_exist (line 22) | def validate_closing_tags_exist(file_content)
function active_if (line 35) | def active_if(cond)
function active_if_status (line 39) | def active_if_status(status)
FILE: app/helpers/ui_helper.rb
type UiHelper (line 1) | module UiHelper
function grouped_options_for_assigning_case (line 4) | def grouped_options_for_assigning_case(volunteer)
function contact_types_list (line 23) | def contact_types_list(reimbursement)
FILE: app/helpers/volunteer_helper.rb
type VolunteerHelper (line 1) | module VolunteerHelper
function volunteer_badge (line 2) | def volunteer_badge(casa_case, current_user)
FILE: app/javascript/__tests__/password_confirmation.test.js
function isDisabled (line 34) | function isDisabled (el) {
FILE: app/javascript/__tests__/require_communication_preference.test.js
function isDisabled (line 35) | function isDisabled (el) {
FILE: app/javascript/controllers/alert_controller.js
method confirm (line 21) | confirm (e) {
FILE: app/javascript/controllers/autosave_controller.js
method connect (line 19) | connect () {
method save (line 25) | save () {
method submitForm (line 30) | submitForm () {
method autosaveAlert (line 65) | autosaveAlert () {
method goodAlert (line 73) | goodAlert () {
method removeBadAlert (line 80) | removeBadAlert () {
method badAlert (line 87) | badAlert (message) {
method hideAlert (line 95) | hideAlert () {
method revealAlert (line 102) | revealAlert (hide = true) {
FILE: app/javascript/controllers/casa_nested_form_controller.js
method connect (line 28) | connect () {
method disconnect (line 43) | disconnect () {
method getRecordId (line 47) | getRecordId (wrapper) {
method dispatchChangeEvent (line 73) | dispatchChangeEvent (action) {
method add (line 80) | add (e) {
method addAndCreate (line 86) | addAndCreate (e) {
method remove (line 142) | remove (e) {
method destroyAndRemove (line 148) | destroyAndRemove (e) {
method confirmDestroyAndRemove (line 188) | confirmDestroyAndRemove (e) {
FILE: app/javascript/controllers/case_contact_form_controller.js
method connect (line 15) | connect () {
method toggleAddAnotherTopicButton (line 27) | toggleAddAnotherTopicButton () {
method onNestedFormChange (line 36) | onNestedFormChange (e) {
method onContactTopicSelect (line 44) | onContactTopicSelect (_e) {
FILE: app/javascript/controllers/court_order_form_controller.js
method remove (line 8) | remove (e) {
method add (line 17) | add (e) {
method removeCourtOrderWithConfirmation (line 27) | removeCourtOrderWithConfirmation (e, wrapper) {
method removeCourtOrder (line 50) | removeCourtOrder (e, wrapper) {
FILE: app/javascript/controllers/disable_form_controller.js
method validate (line 11) | validate () {
FILE: app/javascript/controllers/dismiss_controller.js
method dismiss (line 9) | dismiss (event) {
FILE: app/javascript/controllers/hello_controller.js
method connect (line 4) | connect () {
FILE: app/javascript/controllers/icon_toggle_controller.js
method toggle (line 9) | toggle () {
FILE: app/javascript/controllers/multiple_select_controller.js
method connect (line 17) | connect () {
method createBasicMultiSelect (line 25) | createBasicMultiSelect () {
method createMultiSelectWithOptionGroups (line 36) | createMultiSelectWithOptionGroups () {
FILE: app/javascript/controllers/navbar_controller.js
method click (line 6) | click () {
FILE: app/javascript/controllers/select_all_controller.js
method toggleAll (line 13) | toggleAll () {
method toggleSingle (line 23) | toggleSingle () {
method toggleCheckedAll (line 28) | toggleCheckedAll () {
method toggleButton (line 42) | toggleButton () {
method setButtonLabel (line 55) | setButtonLabel (numChecked) {
method getNumberChecked (line 68) | getNumberChecked () {
method getTotalCheckboxes (line 72) | getTotalCheckboxes () {
FILE: app/javascript/controllers/sidebar_controller.js
method click (line 12) | click () {
method hoverOn (line 24) | hoverOn () {
method hoverOff (line 28) | hoverOff () {
method toggleHover (line 32) | toggleHover () {
method toggleSidebar (line 39) | toggleSidebar () {
method toggleLinks (line 43) | toggleLinks () {
method toggleOverlay (line 53) | toggleOverlay () {
method isNotMobile (line 58) | isNotMobile () {
FILE: app/javascript/controllers/sidebar_group_controller.js
method connect (line 6) | connect () {
method toggleShow (line 21) | toggleShow () {
method anchorLinkMap (line 26) | anchorLinkMap () {
method initializeMenuHighlight (line 38) | initializeMenuHighlight () {
method isAnchorGroupPage (line 60) | isAnchorGroupPage () {
FILE: app/javascript/controllers/truncated_text_controller.js
method toggle (line 7) | toggle () {
FILE: app/javascript/datatable.js
function initializeDataTable (line 3) | function initializeDataTable (selector) {
FILE: app/javascript/src/add_to_calendar_button.js
function createCalendarEvents (line 5) | function createCalendarEvents () {
FILE: app/javascript/src/casa_case.js
function copyOrdersFromCaseWithConfirmation (line 9) | function copyOrdersFromCaseWithConfirmation () {
function copyOrdersFromCaseAction (line 33) | function copyOrdersFromCaseAction (id, caseNumber) {
function showBtn (line 58) | function showBtn (el) {
function hideBtn (line 63) | function hideBtn (el) {
function disableBtn (line 68) | function disableBtn (el) {
function enableBtn (line 75) | function enableBtn (el) {
function showAlert (line 82) | function showAlert (html) {
function validateForm (line 88) | function validateForm (formEl, errorEl) {
function handleGenerateReport (line 99) | function handleGenerateReport (e) {
function clearSelectErrors (line 144) | function clearSelectErrors () {
function handleModalClose (line 152) | function handleModalClose () {
function handleDropdownSelection (line 163) | function handleDropdownSelection () {
FILE: app/javascript/src/casa_org.js
function twilioToggle (line 1) | function twilioToggle () {
function addCheckedAttr (line 20) | function addCheckedAttr (el) {
function removeCheckedAttr (line 27) | function removeCheckedAttr (el) {
FILE: app/javascript/src/case_contact.js
function convertDateToSystemTimeZone (line 5) | function convertDateToSystemTimeZone (date) {
function displayFollowupAlert (line 9) | async function displayFollowupAlert () {
function fireSwalFollowupAlert (line 24) | async function fireSwalFollowupAlert () {
FILE: app/javascript/src/case_emancipation.js
function resolveAsyncOperation (line 15) | function resolveAsyncOperation (error) {
function saveCheckState (line 34) | function saveCheckState (action, checkItemId) {
class Toggler (line 65) | class Toggler {
method constructor (line 66) | constructor (emancipationCategory) {
method manageTogglerText (line 72) | manageTogglerText () {
method openChildren (line 80) | openChildren () {
method closeChildren (line 85) | closeChildren () {
method deselectChildren (line 90) | deselectChildren (notifierCallback) {
FILE: app/javascript/src/dashboard.js
constant MAX_VISIBLE_TOPIC_PILLS (line 8) | const MAX_VISIBLE_TOPIC_PILLS = 2
function buildTopicPills (line 10) | function buildTopicPills (topics) {
function buildExpandedContent (line 23) | function buildExpandedContent (data) {
function filterOutUnassignedVolunteers (line 678) | function filterOutUnassignedVolunteers (checked) {
FILE: app/javascript/src/display_app_metric.js
function fetchDataAndCreateChart (line 40) | function fetchDataAndCreateChart (url, chartElement, successCallback) {
function handleAjaxError (line 49) | function handleAjaxError (xhr, status, error) {
function formatTimestampsAsBubbleChartData (line 56) | function formatTimestampsAsBubbleChartData (timestamps) {
function createChart (line 101) | function createChart (chartElement, dataset) {
function getYTickCallback (line 157) | function getYTickCallback (value) {
function getTooltipLabelCallback (line 161) | function getTooltipLabelCallback (context) {
function createLineChartForCaseContacts (line 167) | function createLineChartForCaseContacts (chartElement, dataset) {
function createLineChartForUniqueUsersMonthly (line 172) | function createLineChartForUniqueUsersMonthly (chartElement, dataset) {
function createLineChart (line 177) | function createLineChart (chartElement, dataset, chartTitle, datasetLabe...
function extractChartData (line 200) | function extractChartData (dataset, index) {
function createLineChartDataset (line 204) | function createLineChartDataset (label, data, borderColor, pointBackgrou...
function createChartOptions (line 218) | function createChartOptions (label) {
FILE: app/javascript/src/import.js
function dataURItoBlob (line 9) | function dataURItoBlob (dataURI) {
function storeCSVFile (line 28) | function storeCSVFile (file, key) {
function fetchCSVFile (line 39) | function fetchCSVFile (key) {
function populateFileInput (line 46) | function populateFileInput (inputId) {
FILE: app/javascript/src/new_casa_case.js
constant COURT_DATE_TOGGLE_CLASS (line 3) | const COURT_DATE_TOGGLE_CLASS = 'toggle-court-date-input'
constant COURT_DATE_INPUT_ID (line 4) | const COURT_DATE_INPUT_ID = 'casa_case_court_dates_attributes_0_date'
FILE: app/javascript/src/notifier.js
class Notification (line 12) | class Notification {
method constructor (line 13) | constructor (notificationElementAsJQuery, parentNotifier) {
method dismiss (line 44) | dismiss () {
method getText (line 51) | getText () {
method isUserDismissable (line 55) | isUserDismissable () {
method isDismissed (line 59) | isDismissed () {
method setUserDismissable (line 63) | setUserDismissable (dismissable) {
method setText (line 73) | setText (newText) {
method #throwErrorIfDismissed (line 80) | #throwErrorIfDismissed () { // Methods prefixed with a hash are private
method toggleUserDismissable (line 86) | toggleUserDismissable () {
method #userDismissableDisable (line 96) | #userDismissableDisable () {
method #userDismissableEnable (line 100) | #userDismissableEnable () {
class Notifier (line 110) | class Notifier {
method constructor (line 112) | constructor (notificationsElement) {
method notify (line 179) | notify (message, level, isDismissable = true) {
method resolveAsyncOperation (line 209) | resolveAsyncOperation (errorMsg) {
method #setMinimizeButtonVisibility (line 242) | #setMinimizeButtonVisibility (visible) {
method #toggleMinimize (line 250) | #toggleMinimize () {
method totalNotificationCount (line 275) | totalNotificationCount () {
method waitForAsyncOperation (line 282) | waitForAsyncOperation () {
FILE: app/javascript/src/password_confirmation.js
constant SUBMIT_BUTTON_CLASS (line 7) | const SUBMIT_BUTTON_CLASS = 'submit-password'
constant PASSWORD_FIELD_CLASS (line 8) | const PASSWORD_FIELD_CLASS = 'password-new'
constant CONFIRMATION_FIELD_CLASS (line 9) | const CONFIRMATION_FIELD_CLASS = 'password-confirmation'
function disableButtonWhenEmptyString (line 11) | function disableButtonWhenEmptyString (str, button) {
function checkPasswordsAndDisplayPopup (line 21) | function checkPasswordsAndDisplayPopup (button, password, confirmation, ...
FILE: app/javascript/src/require_communication_preference.js
constant EMAIL_TOGGLE_CLASS (line 7) | const EMAIL_TOGGLE_CLASS = 'toggle-email-notifications'
constant SMS_TOGGLE_CLASS (line 8) | const SMS_TOGGLE_CLASS = 'toggle-sms-notifications'
constant SAVE_BUTTON_CLASS (line 9) | const SAVE_BUTTON_CLASS = 'save-preference'
constant SMS_NOTIFICATION_EVENT_ID (line 10) | const SMS_NOTIFICATION_EVENT_ID = 'toggle-sms-notification-event'
function displayPopUpIfPreferencesIsInvalid (line 12) | function displayPopUpIfPreferencesIsInvalid () {
FILE: app/javascript/src/session_timeout_poller.js
function warningBoxAndReload (line 10) | function warningBoxAndReload () {
function myTimer (line 17) | function myTimer () {
FILE: app/javascript/src/time_zone.js
function findTimeZone (line 5) | function findTimeZone () {
FILE: app/javascript/src/type_checker.js
method checkNonEmptyJQueryObject (line 9) | checkNonEmptyJQueryObject (variable, varName) {
method checkNonEmptyString (line 24) | checkNonEmptyString (variable, varName) {
method checkObject (line 36) | checkObject (variable, varName) {
method checkPositiveInteger (line 47) | checkPositiveInteger (variable, varName) {
method checkString (line 59) | checkString (variable, varName) {
FILE: app/javascript/src/validated_form.js
constant GET_ERROR_STATE_UNDEFINED_MESSAGE (line 5) | const GET_ERROR_STATE_UNDEFINED_MESSAGE = 'getErrorState for the compone...
constant GET_WARNING_STATE_UNDEFINED_MESSAGE (line 6) | const GET_WARNING_STATE_UNDEFINED_MESSAGE = 'getWarningState for the com...
class ValidatableFormSectionComponent (line 9) | class ValidatableFormSectionComponent {
method constructor (line 10) | constructor (componentElementsAsJQuery, notifier) {
method getErrorState (line 25) | getErrorState () {
method errorHighlightUI (line 30) | errorHighlightUI (errorState) {
method showUserError (line 36) | showUserError (errorMsg) {
method removeUserError (line 41) | removeUserError () {
method getWarningState (line 49) | getWarningState () {
method warningHighlightUI (line 54) | warningHighlightUI (errorState) {
method showUserWarning (line 60) | showUserWarning (warningMsg) {
method removeUserWarning (line 65) | removeUserWarning () {
method showWarningConfirmation (line 70) | showWarningConfirmation () {
method removeWarningConfirmation (line 75) | removeWarningConfirmation () {
method validate (line 80) | validate () {
method #validateError (line 123) | #validateError () {
method #validateWarning (line 136) | #validateWarning () {
class NonDrivingContactMediumWarning (line 153) | class NonDrivingContactMediumWarning extends ValidatableFormSectionCompo...
method constructor (line 154) | constructor (allInputs, notifier) {
method getWarningState (line 172) | getWarningState () {
method warningHighlightUI (line 181) | warningHighlightUI (warningState) {
method showUserWarning (line 191) | showUserWarning (warningMsg) {
method removeUserWarning (line 201) | removeUserWarning () {
method showWarningConfirmation (line 211) | showWarningConfirmation () {
method removeWarningConfirmation (line 224) | removeWarningConfirmation () {
function safeInstantiateComponent (line 231) | function safeInstantiateComponent (componentName, instantiate) {
FILE: app/javascript/sweet-alert-confirm.js
function handleConfirm (line 43) | function handleConfirm (element) {
FILE: app/jobs/application_job.rb
class ApplicationJob (line 1) | class ApplicationJob < ActiveJob::Base; end
FILE: app/lib/importers/case_importer.rb
class CaseImporter (line 1) | class CaseImporter < FileImporter
method import_cases (line 4) | def self.import_cases(csv_filespec, org_id)
method initialize (line 8) | def initialize(csv_filespec, org_id)
method import_cases (line 12) | def import_cases
method create_casa_case (line 38) | def create_casa_case(case_params, volunteer_assignment_list, next_cour...
method update_casa_case (line 49) | def update_casa_case(casa_case, case_params, volunteer_assignment_list...
FILE: app/lib/importers/file_importer.rb
class FileImporter (line 1) | class FileImporter
method initialize (line 9) | def initialize(csv_filespec, org_id, type_label, header_names)
method import (line 18) | def import
method create_user_record (line 46) | def create_user_record(user_class, user_params)
method email_addresses_to_users (line 55) | def email_addresses_to_users(clazz, comma_separated_emails)
method export_failed_imports (line 60) | def export_failed_imports
method failed? (line 75) | def failed?
method message (line 79) | def message
method record_outdated? (line 87) | def record_outdated?(record, new_data)
method success? (line 98) | def success?
method status (line 102) | def status
FILE: app/lib/importers/supervisor_importer.rb
class SupervisorImporter (line 1) | class SupervisorImporter < FileImporter
method import_supervisors (line 4) | def self.import_supervisors(csv_filespec, org_id)
method initialize (line 8) | def initialize(csv_filespec, org_id)
method import_supervisors (line 12) | def import_supervisors
method update_supervisor (line 40) | def update_supervisor(supervisor, supervisor_params, volunteer_assignm...
method assign_volunteers (line 46) | def assign_volunteers(supervisor, volunteer_assignment_list)
FILE: app/lib/importers/volunteer_importer.rb
class VolunteerImporter (line 1) | class VolunteerImporter < FileImporter
method import_volunteers (line 4) | def self.import_volunteers(csv_filespec, org_id)
method initialize (line 8) | def initialize(csv_filespec, org_id)
method import_volunteers (line 12) | def import_volunteers
method update_volunteer (line 33) | def update_volunteer(volunteer, volunteer_params)
FILE: app/mailers/application_mailer.rb
class ApplicationMailer (line 1) | class ApplicationMailer < ActionMailer::Base
FILE: app/mailers/casa_admin_mailer.rb
class CasaAdminMailer (line 1) | class CasaAdminMailer < UserMailer
method deactivation (line 2) | def deactivation(user)
method account_setup (line 8) | def account_setup(user)
FILE: app/mailers/fund_request_mailer.rb
class FundRequestMailer (line 1) | class FundRequestMailer < ApplicationMailer
method send_request (line 4) | def send_request(_user, fund_request, bugsnag_active = true)
FILE: app/mailers/learning_hours_mailer.rb
class LearningHoursMailer (line 1) | class LearningHoursMailer < ApplicationMailer
method learning_hours_report_email (line 2) | def learning_hours_report_email(user)
FILE: app/mailers/supervisor_mailer.rb
class SupervisorMailer (line 1) | class SupervisorMailer < UserMailer
method account_setup (line 2) | def account_setup(supervisor)
method weekly_digest (line 9) | def weekly_digest(supervisor)
method reimbursement_request_email (line 24) | def reimbursement_request_email(volunteer, supervisor)
FILE: app/mailers/user_mailer.rb
class UserMailer (line 1) | class UserMailer < ApplicationMailer
method password_changed_reminder (line 2) | def password_changed_reminder(user)
FILE: app/mailers/volunteer_mailer.rb
class VolunteerMailer (line 1) | class VolunteerMailer < UserMailer
method account_setup (line 2) | def account_setup(user)
method court_report_reminder (line 9) | def court_report_reminder(user, court_report_due_date)
method case_contacts_reminder (line 16) | def case_contacts_reminder(user, cc_recipients)
FILE: app/models/additional_expense.rb
class AdditionalExpense (line 1) | class AdditionalExpense < ApplicationRecord
method describe_required? (line 14) | def describe_required?
FILE: app/models/address.rb
class Address (line 1) | class Address < ApplicationRecord
FILE: app/models/all_casa_admin.rb
class AllCasaAdmin (line 1) | class AllCasaAdmin < ApplicationRecord
method casa_admin? (line 9) | def casa_admin?
method supervisor? (line 13) | def supervisor?
method volunteer? (line 17) | def volunteer?
FILE: app/models/all_casa_admins/casa_org_metrics.rb
type AllCasaAdmins (line 1) | module AllCasaAdmins
class CasaOrgMetrics (line 2) | class CasaOrgMetrics
method initialize (line 3) | def initialize(casa_org)
method metrics (line 7) | def metrics
FILE: app/models/api_credential.rb
class ApiCredential (line 3) | class ApiCredential < ApplicationRecord
method authenticate_api_token (line 10) | def authenticate_api_token(api_token)
method authenticate_refresh_token (line 14) | def authenticate_refresh_token(refresh_token)
method return_new_api_token! (line 19) | def return_new_api_token!
method return_new_refresh_token! (line 25) | def return_new_refresh_token!(remember_me)
method is_api_token_expired? (line 37) | def is_api_token_expired?
method is_refresh_token_expired? (line 41) | def is_refresh_token_expired?
method revoke_api_token (line 45) | def revoke_api_token
method revoke_refresh_token (line 49) | def revoke_refresh_token
method generate_api_token (line 56) | def generate_api_token
method generate_refresh_token (line 62) | def generate_refresh_token
FILE: app/models/application_record.rb
class ApplicationRecord (line 1) | class ApplicationRecord < ActiveRecord::Base
FILE: app/models/banner.rb
class Banner (line 1) | class Banner < ApplicationRecord
method expired? (line 13) | def expired?
method expires_at_in_time_zone (line 21) | def expires_at_in_time_zone(timezone)
method only_one_banner_is_active_per_organization (line 27) | def only_one_banner_is_active_per_organization
method expires_at_must_be_in_future (line 37) | def expires_at_must_be_in_future
FILE: app/models/casa_admin.rb
class CasaAdmin (line 1) | class CasaAdmin < User
method activate (line 8) | def activate
method deactivate (line 12) | def deactivate
method change_to_supervisor! (line 16) | def change_to_supervisor!
FILE: app/models/casa_case.rb
class CasaCase (line 1) | class CasaCase < ApplicationRecord
method add_emancipation_category (line 110) | def add_emancipation_category(category_id)
method add_emancipation_option (line 114) | def add_emancipation_option(option_id)
method clear_court_dates (line 125) | def clear_court_dates
method court_report_status= (line 133) | def court_report_status=(value)
method in_transition_age? (line 143) | def in_transition_age?
method latest_court_report (line 147) | def latest_court_report
method next_court_date (line 151) | def next_court_date
method most_recent_past_court_date (line 155) | def most_recent_past_court_date
method formatted_latest_court_date (line 159) | def formatted_latest_court_date
method has_judge_name? (line 165) | def has_judge_name?
method remove_emancipation_category (line 169) | def remove_emancipation_category(category_id)
method remove_emancipation_option (line 176) | def remove_emancipation_option(option_id)
method update_cleaning_contact_types (line 183) | def update_cleaning_contact_types(args)
method deactivate (line 196) | def deactivate
method reactivate (line 201) | def reactivate
method unassigned_volunteers (line 205) | def unassigned_volunteers
method full_attributes_hash (line 210) | def full_attributes_hash
method contact_type_validation? (line 214) | def contact_type_validation?
method should_generate_new_friendly_id? (line 218) | def should_generate_new_friendly_id?
FILE: app/models/casa_case_contact_type.rb
class CasaCaseContactType (line 1) | class CasaCaseContactType < ApplicationRecord
FILE: app/models/casa_case_emancipation_category.rb
class CasaCaseEmancipationCategory (line 1) | class CasaCaseEmancipationCategory < ApplicationRecord
FILE: app/models/casa_case_emancipation_option.rb
class CasaCaseEmancipationOption (line 1) | class CasaCaseEmancipationOption < ApplicationRecord
FILE: app/models/casa_org.rb
class CasaOrg (line 1) | class CasaOrg < ApplicationRecord
method casa_admins (line 35) | def casa_admins
method supervisors (line 39) | def supervisors
method volunteers (line 43) | def volunteers
method case_contacts (line 47) | def case_contacts
method followups (line 57) | def followups
method case_contacts_count (line 61) | def case_contacts_count
method org_logo (line 65) | def org_logo
method open_org_court_report_template (line 73) | def open_org_court_report_template(&)
method user_count (line 81) | def user_count
method set_slug (line 85) | def set_slug
method generate_defaults (line 89) | def generate_defaults
method contact_types_by_group (line 97) | def contact_types_by_group
method contact_types (line 103) | def contact_types
method mileage_rate_for_given_date (line 114) | def mileage_rate_for_given_date(date)
method has_alternate_active_banner? (line 118) | def has_alternate_active_banner?(current_banner_id)
method sanitize_svg (line 124) | def sanitize_svg
method validate_twilio_credentials (line 137) | def validate_twilio_credentials
method normalize_phone_number (line 146) | def normalize_phone_number
FILE: app/models/case_assignment.rb
class CaseAssignment (line 1) | class CaseAssignment < ApplicationRecord
method inactive_this_week (line 14) | def self.inactive_this_week(volunteer_id)
method inactive? (line 18) | def inactive? = !active?
method assignee_must_be_volunteer (line 22) | def assignee_must_be_volunteer
method casa_case_and_volunteer_must_belong_to_same_casa_org (line 26) | def casa_case_and_volunteer_must_belong_to_same_casa_org
FILE: app/models/case_contact.rb
class CaseContact (line 1) | class CaseContact < ApplicationRecord
method active_or_details? (line 64) | def active_or_details?
method active_or_expenses? (line 68) | def active_or_expenses?
method active_or_notes? (line 72) | def active_or_notes?
method update_cleaning_contact_types (line 194) | def update_cleaning_contact_types(args)
method occurred_at_display (line 203) | def occurred_at_display
method reimbursement_amount (line 209) | def reimbursement_amount
method reimbursement_only_when_miles_driven (line 216) | def reimbursement_only_when_miles_driven
method volunteer_address_when_reimbursement_wanted (line 222) | def volunteer_address_when_reimbursement_wanted
method volunteer_address_is_valid (line 228) | def volunteer_address_is_valid
method supervisor_id (line 236) | def supervisor_id
method has_casa_case_transitioned (line 240) | def has_casa_case_transitioned
method contact_groups_with_types (line 244) | def contact_groups_with_types
method requested_followup (line 252) | def requested_followup
method should_send_reimbursement_email? (line 256) | def should_send_reimbursement_email?
method supervisor_active? (line 260) | def supervisor_active?
method address_field_disabled? (line 264) | def address_field_disabled?
method volunteer (line 268) | def volunteer
method options_for_sorted_by (line 276) | def self.options_for_sorted_by
method case_hash_from_cases (line 280) | def self.case_hash_from_cases(cases)
method casa_org_any_expenses_enabled? (line 287) | def casa_org_any_expenses_enabled?
method sorted_by_params (line 291) | def self.sorted_by_params
FILE: app/models/case_contact_contact_type.rb
class CaseContactContactType (line 1) | class CaseContactContactType < ApplicationRecord
FILE: app/models/case_contact_report.rb
class CaseContactReport (line 1) | class CaseContactReport
method initialize (line 21) | def initialize(args = {})
method to_csv (line 26) | def to_csv
method filtered_case_contacts (line 33) | def filtered_case_contacts(args)
method filtered_columns (line 47) | def filtered_columns(args)
FILE: app/models/case_court_order.rb
class CaseCourtOrder (line 1) | class CaseCourtOrder < ApplicationRecord
method court_order_options (line 36) | def self.court_order_options
method implementation_status_symbol (line 40) | def implementation_status_symbol
FILE: app/models/case_court_report.rb
class CaseCourtReport (line 5) | class CaseCourtReport
method initialize (line 8) | def initialize(path_to_template:, context:)
method generate_to_string (line 17) | def generate_to_string
FILE: app/models/case_court_report_context.rb
class CaseCourtReportContext (line 5) | class CaseCourtReportContext
method initialize (line 8) | def initialize(args = {})
method context (line 18) | def context
method case_contacts (line 39) | def case_contacts
method latest_hearing_date (line 46) | def latest_hearing_date
method case_orders (line 51) | def case_orders(orders)
method filtered_interviewees (line 60) | def filtered_interviewees
method case_details (line 67) | def case_details
method volunteer_info (line 77) | def volunteer_info
method org_address (line 87) | def org_address(path_to_template)
method court_topics (line 108) | def court_topics
method calculate_date_range (line 140) | def calculate_date_range(args)
FILE: app/models/case_group.rb
class CaseGroup (line 1) | class CaseGroup < ApplicationRecord
method strip_name (line 13) | def strip_name
FILE: app/models/case_group_membership.rb
class CaseGroupMembership (line 1) | class CaseGroupMembership < ApplicationRecord
FILE: app/models/checklist_item.rb
class ChecklistItem (line 1) | class ChecklistItem < ApplicationRecord
FILE: app/models/concerns/CasaCase/validations.rb
type CasaCase::Validations (line 3) | module CasaCase::Validations
FILE: app/models/concerns/api.rb
type Api (line 1) | module Api
function initialize_api_credentials (line 10) | def initialize_api_credentials
FILE: app/models/concerns/by_organization_scope.rb
type ByOrganizationScope (line 3) | module ByOrganizationScope
FILE: app/models/concerns/roles.rb
type Roles (line 1) | module Roles
function role (line 4) | def role
FILE: app/models/contact_topic.rb
class ContactTopic (line 1) | class ContactTopic < ApplicationRecord
method generate_for_org! (line 25) | def generate_for_org!(casa_org)
method default_contact_topics (line 35) | def default_contact_topics
FILE: app/models/contact_topic_answer.rb
class ContactTopicAnswer (line 1) | class ContactTopicAnswer < ApplicationRecord
FILE: app/models/contact_type.rb
class ContactType (line 1) | class ContactType < ApplicationRecord
FILE: app/models/contact_type_group.rb
class ContactTypeGroup (line 1) | class ContactTypeGroup < ApplicationRecord
method generate_for_org! (line 25) | def generate_for_org!(casa_org)
FILE: app/models/court_date.rb
class CourtDate (line 5) | class CourtDate < ApplicationRecord
method associated_reports (line 31) | def associated_reports
method latest_associated_report (line 40) | def latest_associated_report
method additional_info? (line 44) | def additional_info?
method display_name (line 48) | def display_name
method set_court_report_due_date (line 54) | def set_court_report_due_date
FILE: app/models/custom_org_link.rb
class CustomOrgLink (line 1) | class CustomOrgLink < ApplicationRecord
method trim_name (line 14) | def trim_name
FILE: app/models/emancipation_category.rb
class EmancipationCategory (line 1) | class EmancipationCategory < ApplicationRecord
method add_option (line 8) | def add_option(option_name)
method delete_option (line 12) | def delete_option(option_name)
FILE: app/models/emancipation_option.rb
class EmancipationOption (line 1) | class EmancipationOption < ApplicationRecord
FILE: app/models/followup.rb
class Followup (line 1) | class Followup < ApplicationRecord
method in_organization (line 10) | def self.in_organization(casa_org)
method uniqueness_of_requested (line 14) | def uniqueness_of_requested
method existing_requested_followup? (line 23) | def existing_requested_followup?
FILE: app/models/fund_request.rb
class FundRequest (line 1) | class FundRequest < ApplicationRecord
FILE: app/models/health.rb
class Health (line 1) | class Health < ApplicationRecord
method instance (line 6) | def self.instance
FILE: app/models/hearing_type.rb
class HearingType (line 1) | class HearingType < ApplicationRecord
method generate_for_org! (line 21) | def generate_for_org!(casa_org)
FILE: app/models/judge.rb
class Judge (line 1) | class Judge < ApplicationRecord
FILE: app/models/language.rb
class Language (line 1) | class Language < ApplicationRecord
method strip_name (line 11) | def strip_name
FILE: app/models/learning_hour.rb
class LearningHour (line 1) | class LearningHour < ApplicationRecord
method zero_duration_hours? (line 37) | def zero_duration_hours?
method occurred_at_not_in_future (line 41) | def occurred_at_not_in_future
method user_org_learning_topic_enable? (line 49) | def user_org_learning_topic_enable?
FILE: app/models/learning_hour_topic.rb
class LearningHourTopic (line 1) | class LearningHourTopic < ApplicationRecord
method strip_name (line 9) | def strip_name
FILE: app/models/learning_hour_type.rb
class LearningHourType (line 1) | class LearningHourType < ApplicationRecord
method strip_name (line 12) | def strip_name
FILE: app/models/learning_hours_report.rb
class LearningHoursReport (line 1) | class LearningHoursReport
method initialize (line 4) | def initialize(casa_org_id)
method to_csv (line 10) | def to_csv
FILE: app/models/login_activity.rb
class LoginActivity (line 1) | class LoginActivity < ApplicationRecord
FILE: app/models/mileage_rate.rb
class MileageRate (line 1) | class MileageRate < ApplicationRecord
FILE: app/models/mileage_report.rb
class MileageReport (line 1) | class MileageReport
method initialize (line 4) | def initialize(org_id)
method to_csv (line 11) | def to_csv
FILE: app/models/missing_data_report.rb
class MissingDataReport (line 1) | class MissingDataReport
method initialize (line 4) | def initialize(org_id)
method to_csv (line 9) | def to_csv
FILE: app/models/note.rb
class Note (line 1) | class Note < ApplicationRecord
FILE: app/models/other_duty.rb
class OtherDuty (line 1) | class OtherDuty < ApplicationRecord
FILE: app/models/patch_note.rb
class PatchNote (line 1) | class PatchNote < ApplicationRecord
FILE: app/models/patch_note_group.rb
class PatchNoteGroup (line 1) | class PatchNoteGroup < ApplicationRecord
FILE: app/models/patch_note_type.rb
class PatchNoteType (line 1) | class PatchNoteType < ApplicationRecord
FILE: app/models/placement.rb
class Placement (line 1) | class Placement < ApplicationRecord
FILE: app/models/placement_type.rb
class PlacementType (line 1) | class PlacementType < ApplicationRecord
FILE: app/models/preference_set.rb
class PreferenceSet (line 1) | class PreferenceSet < ApplicationRecord
FILE: app/models/sent_email.rb
class SentEmail (line 1) | class SentEmail < ApplicationRecord
FILE: app/models/sms_notification_event.rb
class SmsNotificationEvent (line 1) | class SmsNotificationEvent < ApplicationRecord
FILE: app/models/supervisor.rb
class Supervisor (line 1) | class Supervisor < User
method activate (line 14) | def activate
method deactivate (line 19) | def deactivate
method change_to_admin! (line 30) | def change_to_admin!
method pending_volunteers (line 34) | def pending_volunteers
method inactive_volunteers (line 40) | def inactive_volunteers
method recently_unassigned_volunteers (line 48) | def recently_unassigned_volunteers
FILE: app/models/supervisor_volunteer.rb
class SupervisorVolunteer (line 2) | class SupervisorVolunteer < ApplicationRecord
method ensure_supervisor_and_volunteer_belong_to_same_casa_org (line 12) | def ensure_supervisor_and_volunteer_belong_to_same_casa_org
FILE: app/models/user.rb
class User (line 4) | class User < ApplicationRecord
method casa_admin? (line 63) | def casa_admin?
method supervisor? (line 67) | def supervisor?
method volunteer? (line 71) | def volunteer?
method actively_assigned_and_active_cases (line 75) | def actively_assigned_and_active_cases
method active_volunteers (line 79) | def active_volunteers
method create_preference_set (line 83) | def create_preference_set
method case_contacts_for (line 88) | def case_contacts_for(casa_case_id)
method recent_contacts_made (line 98) | def recent_contacts_made(days_counter = 60)
method most_recent_contact (line 102) | def most_recent_contact
method volunteers_serving_transition_aged_youth (line 107) | def volunteers_serving_transition_aged_youth
method no_attempt_for_two_weeks (line 115) | def no_attempt_for_two_weeks
method generate_password_reset_token (line 134) | def generate_password_reset_token
method active_for_authentication? (line 147) | def active_for_authentication?
method serving_transition_aged_youth? (line 151) | def serving_transition_aged_youth?
method record_previous_email (line 155) | def record_previous_email
method filter_old_emails! (line 161) | def filter_old_emails!(previous_email)
method skip_email_confirmation_upon_creation (line 166) | def skip_email_confirmation_upon_creation
method send_email_changed_notification? (line 171) | def send_email_changed_notification?
method after_confirmation (line 175) | def after_confirmation
method normalize_phone_number (line 181) | def normalize_phone_number
FILE: app/models/user_language.rb
class UserLanguage (line 1) | class UserLanguage < ApplicationRecord
FILE: app/models/user_reminder_time.rb
class UserReminderTime (line 1) | class UserReminderTime < ApplicationRecord
FILE: app/models/user_sms_notification_event.rb
class UserSmsNotificationEvent (line 1) | class UserSmsNotificationEvent < ApplicationRecord
FILE: app/models/volunteer.rb
class Volunteer (line 3) | class Volunteer < User
method send_court_report_reminder (line 70) | def self.send_court_report_reminder
method activate (line 84) | def activate
method deactivate (line 89) | def deactivate
method case_assignments_with_cases (line 99) | def case_assignments_with_cases
method has_supervisor? (line 103) | def has_supervisor?
method supervised_by? (line 107) | def supervised_by?(supervisor)
method made_contact_with_all_cases_in_days? (line 112) | def made_contact_with_all_cases_in_days?(num_days = CONTACT_MADE_IN_DA...
method hours_spent_in_days (line 120) | def hours_spent_in_days(num_days)
method learning_hours_spent_in_one_year (line 129) | def learning_hours_spent_in_one_year
method cases_where_contact_made_in_days (line 142) | def cases_where_contact_made_in_days(num_days = CONTACT_MADE_IN_DAYS_NUM)
FILE: app/notifications/base_notifier.rb
class BaseNotifier (line 1) | class BaseNotifier < Noticed::Event
method title (line 3) | def title
method message (line 7) | def message
method url (line 11) | def url
method read? (line 16) | def read?
method created_at (line 20) | def created_at
method updated_at (line 24) | def updated_at
method created_by (line 28) | def created_by
method created_by_name (line 34) | def created_by_name
FILE: app/notifications/delivery_methods/sms.rb
class DeliveryMethods::Sms (line 1) | class DeliveryMethods::Sms < Noticed::DeliveryMethod
method deliver (line 3) | def deliver
method case_contact_url (line 13) | def case_contact_url
method sender (line 19) | def sender
method case_contact_id (line 23) | def case_contact_id
FILE: app/notifications/emancipation_checklist_reminder_notifier.rb
class EmancipationChecklistReminderNotifier (line 5) | class EmancipationChecklistReminderNotifier < BaseNotifier
method message (line 18) | def message
method title (line 25) | def title
method url (line 29) | def url
FILE: app/notifications/followup_notifier.rb
class FollowupNotifier (line 5) | class FollowupNotifier < BaseNotifier
method title (line 18) | def title
method message (line 22) | def message
method url (line 26) | def url
method sms_notifications? (line 32) | def sms_notifications?
method email_notifications? (line 36) | def email_notifications?
method build_message (line 40) | def build_message
FILE: app/notifications/followup_resolved_notifier.rb
class FollowupResolvedNotifier (line 5) | class FollowupResolvedNotifier < BaseNotifier
method title (line 18) | def title
method message (line 22) | def message
method url (line 26) | def url
FILE: app/notifications/reimbursement_complete_notifier.rb
class ReimbursementCompleteNotifier (line 5) | class ReimbursementCompleteNotifier < BaseNotifier
method title (line 15) | def title
method message (line 19) | def message
method url (line 27) | def url
FILE: app/notifications/volunteer_birthday_notifier.rb
class VolunteerBirthdayNotifier (line 5) | class VolunteerBirthdayNotifier < BaseNotifier
method message (line 18) | def message
method title (line 22) | def title
method url (line 26) | def url
FILE: app/notifications/youth_birthday_notifier.rb
class YouthBirthdayNotifier (line 5) | class YouthBirthdayNotifier < BaseNotifier
method message (line 17) | def message
method title (line 21) | def title
method url (line 25) | def url
FILE: app/policies/additional_expense_policy.rb
class AdditionalExpensePolicy (line 1) | class AdditionalExpensePolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
method create? (line 15) | def create?
method same_org? (line 30) | def same_org?
FILE: app/policies/application_policy.rb
class ApplicationPolicy (line 1) | class ApplicationPolicy
class Scope (line 2) | class Scope
method initialize (line 5) | def initialize(user, scope)
method resolve (line 10) | def resolve
method initialize (line 17) | def initialize(user, record)
method index? (line 22) | def index?
method show? (line 26) | def show?
method create? (line 30) | def create?
method new? (line 34) | def new?
method update? (line 38) | def update?
method edit? (line 42) | def edit?
method destroy? (line 46) | def destroy?
method is_admin? (line 50) | def is_admin?
method same_org? (line 54) | def same_org?
method is_admin_same_org? (line 61) | def is_admin_same_org?
method is_supervisor? (line 66) | def is_supervisor?
method is_supervisor_same_org? (line 70) | def is_supervisor_same_org?
method is_volunteer? (line 75) | def is_volunteer? # deprecated in favor of is_volunteer_same_org?
method is_volunteer_same_org? (line 79) | def is_volunteer_same_org?
method admin_or_supervisor? (line 83) | def admin_or_supervisor?
method admin_or_supervisor_same_org? (line 87) | def admin_or_supervisor_same_org?
method admin_or_supervisor_or_volunteer? (line 92) | def admin_or_supervisor_or_volunteer?
method admin_or_supervisor_or_volunteer_same_org? (line 96) | def admin_or_supervisor_or_volunteer_same_org?
method see_reports_page? (line 100) | def see_reports_page?
method see_emancipation_checklist? (line 104) | def see_emancipation_checklist?
method see_court_reports_page? (line 108) | def see_court_reports_page?
method see_mileage_rate? (line 112) | def see_mileage_rate?
method matches_casa_org? (line 116) | def matches_casa_org?
method reimbursement_enabled? (line 120) | def reimbursement_enabled?
method current_organization (line 124) | def current_organization
FILE: app/policies/bulk_court_date_policy.rb
class BulkCourtDatePolicy (line 1) | class BulkCourtDatePolicy < ApplicationPolicy
method new? (line 5) | def new?
method create? (line 9) | def create?
FILE: app/policies/casa_admin_policy.rb
class CasaAdminPolicy (line 1) | class CasaAdminPolicy < UserPolicy
method index? (line 2) | def index?
method edit? (line 15) | def edit?
method deactivate? (line 19) | def deactivate?
method see_deactivate_option? (line 23) | def see_deactivate_option?
FILE: app/policies/casa_case_policy.rb
class CasaCasePolicy (line 1) | class CasaCasePolicy < ApplicationPolicy
class Scope (line 2) | class Scope
method initialize (line 5) | def initialize(user, scope)
method resolve (line 10) | def resolve
method sibling_cases (line 21) | def sibling_cases
method update_contact_types? (line 33) | def update_contact_types?
method update_birth_month_year_youth? (line 37) | def update_birth_month_year_youth?
method update_date_in_care_youth? (line 41) | def update_date_in_care_youth?
method update_emancipation_option? (line 45) | def update_emancipation_option?
method assign_volunteers? (line 50) | def assign_volunteers?
method can_see_filters? (line 54) | def can_see_filters?
method permitted_attributes (line 66) | def permitted_attributes
method same_org_supervisor_admin_or_assigned? (line 90) | def same_org_supervisor_admin_or_assigned?
method same_org_supervisor_admin? (line 94) | def same_org_supervisor_admin?
method index? (line 98) | def index?
method is_volunteer_actively_assigned_to_case? (line 112) | def is_volunteer_actively_assigned_to_case?
method case_court_orders_attributes (line 119) | def case_court_orders_attributes
FILE: app/policies/casa_org_policy.rb
class CasaOrgPolicy (line 1) | class CasaOrgPolicy < ApplicationPolicy
method edit? (line 2) | def edit?
method update? (line 6) | def update?
method same_org? (line 10) | def same_org?
FILE: app/policies/case_assignment_policy.rb
class CaseAssignmentPolicy (line 1) | class CaseAssignmentPolicy < ApplicationPolicy
class Scope (line 2) | class Scope
method initialize (line 5) | def initialize(user, scope)
method resolve (line 10) | def resolve
method create? (line 15) | def create?
method destroy? (line 19) | def destroy?
method unassign? (line 23) | def unassign?
method reimbursement? (line 27) | def reimbursement?
method show_or_hide_contacts? (line 31) | def show_or_hide_contacts?
FILE: app/policies/case_contact_policy.rb
class CaseContactPolicy (line 1) | class CaseContactPolicy < ApplicationPolicy
method new? (line 2) | def new?
method show? (line 6) | def show?
method update? (line 10) | def update?
method destroy? (line 14) | def destroy?
method additional_expenses_allowed? (line 18) | def additional_expenses_allowed?
class Scope (line 29) | class Scope < ApplicationPolicy::Scope
method resolve (line 30) | def resolve
method creator_or_supervisor_or_admin? (line 44) | def creator_or_supervisor_or_admin?
method is_draft? (line 48) | def is_draft?
method is_creator? (line 52) | def is_creator?
method same_org? (line 56) | def same_org?
FILE: app/policies/case_court_order_policy.rb
class CaseCourtOrderPolicy (line 1) | class CaseCourtOrderPolicy < ApplicationPolicy
FILE: app/policies/case_court_report_policy.rb
class CaseCourtReportPolicy (line 1) | class CaseCourtReportPolicy < ApplicationPolicy
method index? (line 2) | def index?
FILE: app/policies/case_group_policy.rb
class CaseGroupPolicy (line 1) | class CaseGroupPolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
method index? (line 15) | def index?
method new? (line 19) | def new?
method show? (line 23) | def show?
method create? (line 27) | def create?
method edit? (line 31) | def edit?
method update? (line 35) | def update?
method destroy? (line 39) | def destroy?
method same_org? (line 43) | def same_org?
FILE: app/policies/checklist_item_policy.rb
class ChecklistItemPolicy (line 1) | class ChecklistItemPolicy < ApplicationPolicy
method new? (line 2) | def new?
method create? (line 6) | def create?
method edit? (line 10) | def edit?
method update? (line 14) | def update?
method destroy? (line 18) | def destroy?
FILE: app/policies/contact_topic_answer_policy.rb
class ContactTopicAnswerPolicy (line 1) | class ContactTopicAnswerPolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
method create? (line 15) | def create?
method same_org? (line 30) | def same_org?
FILE: app/policies/contact_topic_policy.rb
class ContactTopicPolicy (line 1) | class ContactTopicPolicy < ApplicationPolicy
FILE: app/policies/contact_type_group_policy.rb
class ContactTypeGroupPolicy (line 1) | class ContactTypeGroupPolicy < ApplicationPolicy
FILE: app/policies/contact_type_policy.rb
class ContactTypePolicy (line 1) | class ContactTypePolicy < ApplicationPolicy
FILE: app/policies/court_date_policy.rb
class CourtDatePolicy (line 1) | class CourtDatePolicy < ApplicationPolicy
method allowed_to_edit_casa_case? (line 2) | def allowed_to_edit_casa_case?
method casa_case_policy (line 15) | def casa_case_policy
FILE: app/policies/custom_org_link_policy.rb
class CustomOrgLinkPolicy (line 1) | class CustomOrgLinkPolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
FILE: app/policies/dashboard_policy.rb
class DashboardPolicy (line 1) | class DashboardPolicy < ApplicationPolicy
method all_allowed (line 2) | def all_allowed
method is_admin? (line 6) | def is_admin?
method create_case_contacts? (line 10) | def create_case_contacts?
FILE: app/policies/followup_policy.rb
class FollowupPolicy (line 1) | class FollowupPolicy < ApplicationPolicy
method create? (line 2) | def create?
FILE: app/policies/fund_request_policy.rb
class FundRequestPolicy (line 1) | class FundRequestPolicy < ApplicationPolicy
method new? (line 2) | def new?
method create? (line 6) | def create?
FILE: app/policies/hearing_type_policy.rb
class HearingTypePolicy (line 1) | class HearingTypePolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method initialize (line 5) | def initialize(user, scope)
method resolve (line 10) | def resolve
FILE: app/policies/import_policy.rb
class ImportPolicy (line 1) | class ImportPolicy < ApplicationPolicy
method index? (line 2) | def index?
FILE: app/policies/judge_policy.rb
class JudgePolicy (line 1) | class JudgePolicy < ApplicationPolicy
FILE: app/policies/language_policy.rb
class LanguagePolicy (line 1) | class LanguagePolicy < ApplicationPolicy
FILE: app/policies/learning_hour_policy.rb
class LearningHourPolicy (line 1) | class LearningHourPolicy < ApplicationPolicy
method index? (line 2) | def index?
method show? (line 6) | def show?
method new? (line 10) | def new?
class Scope (line 19) | class Scope
method initialize (line 22) | def initialize(user, scope)
method resolve (line 27) | def resolve
FILE: app/policies/learning_hour_topic_policy.rb
class LearningHourTopicPolicy (line 1) | class LearningHourTopicPolicy < ApplicationPolicy
FILE: app/policies/learning_hour_type_policy.rb
class LearningHourTypePolicy (line 1) | class LearningHourTypePolicy < ApplicationPolicy
FILE: app/policies/nil_class_policy.rb
class NilClassPolicy (line 1) | class NilClassPolicy < ApplicationPolicy
method method_missing (line 2) | def method_missing(*)
method respond_to_missing? (line 6) | def respond_to_missing?(*)
FILE: app/policies/note_policy.rb
class NotePolicy (line 1) | class NotePolicy < ApplicationPolicy
method create? (line 2) | def create?
method edit? (line 6) | def edit?
method update? (line 10) | def update?
method destroy? (line 14) | def destroy?
FILE: app/policies/notification_policy.rb
class NotificationPolicy (line 1) | class NotificationPolicy < ApplicationPolicy
method index? (line 2) | def index?
method mark_as_read? (line 6) | def mark_as_read?
FILE: app/policies/other_duty_policy.rb
class OtherDutyPolicy (line 1) | class OtherDutyPolicy < UserPolicy
class Scope (line 2) | class Scope
method initialize (line 5) | def initialize(user, scope)
method index? (line 11) | def index?
method new? (line 15) | def new?
method create? (line 19) | def create?
method edit? (line 23) | def edit?
method update? (line 27) | def update?
method casa_org_other_duties_enabled? (line 31) | def casa_org_other_duties_enabled?
FILE: app/policies/patch_note_policy.rb
class PatchNotePolicy (line 1) | class PatchNotePolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method initialize (line 3) | def initialize(user, scope)
method resolve (line 8) | def resolve
FILE: app/policies/placement_policy.rb
class PlacementPolicy (line 1) | class PlacementPolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
method allowed_to_edit_casa_case? (line 10) | def allowed_to_edit_casa_case?
method casa_case_policy (line 23) | def casa_case_policy
FILE: app/policies/placement_type_policy.rb
class PlacementTypePolicy (line 1) | class PlacementTypePolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
method edit? (line 15) | def edit?
FILE: app/policies/reimbursement_policy.rb
class ReimbursementPolicy (line 1) | class ReimbursementPolicy < ApplicationPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
method index? (line 9) | def index?
method datatable? (line 13) | def datatable?
method change_complete_status? (line 17) | def change_complete_status?
FILE: app/policies/supervisor_policy.rb
class SupervisorPolicy (line 1) | class SupervisorPolicy < UserPolicy
class Scope (line 2) | class Scope < ApplicationPolicy::Scope
method resolve (line 3) | def resolve
method index? (line 11) | def index?
method new? (line 15) | def new?
method update? (line 19) | def update?
method activate? (line 23) | def activate?
method deactivate? (line 27) | def deactivate?
method resend_invitation? (line 31) | def resend_invitation?
method edit? (line 35) | def edit?
FILE: app/policies/supervisor_volunteer_policy.rb
class SupervisorVolunteerPolicy (line 1) | class SupervisorVolunteerPolicy < ApplicationPolicy
method create? (line 2) | def create?
method unassign? (line 6) | def unassign?
method bulk_assignment? (line 10) | def bulk_assignment?
FILE: app/policies/user_policy.rb
class UserPolicy (line 1) | class UserPolicy < ApplicationPolicy
method add_language? (line 2) | def add_language?
method remove_language? (line 6) | def remove_language?
method edit? (line 10) | def edit?
method update_volunteer_email? (line 14) | def update_volunteer_email?
method unassign_case? (line 18) | def unassign_case?
method deactivate? (line 24) | def deactivate?
method update_supervisor_email? (line 28) | def update_supervisor_email?
method update_supervisor_name? (line 32) | def update_supervisor_name?
method update_user_setting? (line 36) | def update_user_setting?
method edit_name? (line 44) | def edit_name?(viewed_user)
class Scope (line 52) | class Scope
method initialize (line 55) | def initialize(user, scope)
method resolve (line 60) | def resolve
FILE: app/policies/volunteer_policy.rb
class VolunteerPolicy (line 1) | class VolunteerPolicy < UserPolicy
class Scope (line 2) | class Scope
method initialize (line 5) | def initialize(user, scope)
method resolve (line 10) | def resolve
method index? (line 20) | def index?
method edit? (line 24) | def edit?
method impersonate? (line 28) | def impersonate?
method stop_impersonating? (line 32) | def stop_impersonating?
FILE: app/presenters/base_presenter.rb
class BasePresenter (line 1) | class BasePresenter
method current_user (line 4) | def current_user
method current_organization (line 8) | def current_organization
method policy_scope (line 12) | def policy_scope(scope)
FILE: app/presenters/case_contact_presenter.rb
class CaseContactPresenter (line 1) | class CaseContactPresenter < BasePresenter
method initialize (line 5) | def initialize(case_contacts)
method display_case_number (line 10) | def display_case_number(casa_case_id)
method boolean_select_options (line 18) | def boolean_select_options
method org_cases (line 27) | def org_cases
FILE: app/services/additional_expense_params_service.rb
class AdditionalExpenseParamsService (line 1) | class AdditionalExpenseParamsService
method initialize (line 2) | def initialize(params)
method calculate (line 6) | def calculate
FILE: app/services/backfill_followupable_service.rb
class BackfillFollowupableService (line 1) | class BackfillFollowupableService
method fill_followup_id_and_type (line 2) | def fill_followup_id_and_type
FILE: app/services/casa_case_change_service.rb
class CasaCaseChangeService (line 1) | class CasaCaseChangeService
method initialize (line 2) | def initialize(original, changed)
method calculate (line 9) | def calculate
method changed_attributes_messages (line 13) | def changed_attributes_messages
method html_formatted_list (line 24) | def html_formatted_list(messages)
method change_message_text (line 31) | def change_message_text(attribute, original_attribute, updated_attribute)
FILE: app/services/case_contacts_contact_dates.rb
class CaseContactsContactDates (line 1) | class CaseContactsContactDates
method initialize (line 2) | def initialize(case_contact_contact_types)
method contact_dates_details (line 6) | def contact_dates_details
method case_contacts_for_type (line 22) | def case_contacts_for_type(contact_type_name)
method format_dates (line 28) | def format_dates(case_contacts)
method chron_sort (line 32) | def chron_sort(case_contacts)
method order_and_format (line 36) | def order_and_format(case_contacts)
FILE: app/services/case_contacts_export_csv_service.rb
class CaseContactsExportCsvService (line 5) | class CaseContactsExportCsvService
method initialize (line 8) | def initialize(case_contacts_scope, filtered_columns)
method perform (line 13) | def perform
method fixed_column_values (line 27) | def fixed_column_values(case_contact)
method fixed_column_headers (line 50) | def fixed_column_headers
method court_topic_answers (line 54) | def court_topic_answers(case_contact)
method court_topics (line 64) | def court_topics
method court_topics_filtered? (line 75) | def court_topics_filtered?
FILE: app/services/court_report_due_sms_reminder_service.rb
type CourtReportDueSmsReminderService (line 1) | module CourtReportDueSmsReminderService
function court_report_reminder (line 8) | def court_report_reminder(user, report_due_date)
FILE: app/services/court_report_format_contact_date.rb
class CourtReportFormatContactDate (line 3) | class CourtReportFormatContactDate
method initialize (line 7) | def initialize(case_contact)
method format (line 11) | def format
method format_long (line 15) | def format_long
method contact_made_suffix (line 23) | def contact_made_suffix
FILE: app/services/create_all_casa_admin_service.rb
class CreateAllCasaAdminService (line 1) | class CreateAllCasaAdminService
method initialize (line 2) | def initialize(params, current_user)
method build (line 7) | def build
method create! (line 13) | def create!
FILE: app/services/create_casa_admin_service.rb
class CreateCasaAdminService (line 1) | class CreateCasaAdminService
method initialize (line 4) | def initialize(current_organization, params, current_user)
method build (line 10) | def build
method create! (line 19) | def create!
FILE: app/services/deployment/backfill_case_contact_started_metadata_service.rb
type Deployment (line 1) | module Deployment
class BackfillCaseContactStartedMetadataService (line 2) | class BackfillCaseContactStartedMetadataService
method backfill_metadata (line 3) | def backfill_metadata
FILE: app/services/emancipation_checklist_download_html.rb
class EmancipationChecklistDownloadHtml (line 1) | class EmancipationChecklistDownloadHtml
method initialize (line 2) | def initialize(current_case, emancipation_form_data)
method call (line 7) | def call
FILE: app/services/emancipation_checklist_reminder_service.rb
class EmancipationChecklistReminderService (line 1) | class EmancipationChecklistReminderService
method initialize (line 4) | def initialize
method send_reminders (line 13) | def send_reminders
FILE: app/services/failed_import_csv_service.rb
class FailedImportCsvService (line 3) | class FailedImportCsvService
method initialize (line 10) | def initialize(import_type:, user:, failed_rows: "", filepath: nil)
method store (line 17) | def store
method read (line 27) | def read
method cleanup (line 38) | def cleanup
method log_info (line 47) | def log_info(msg)
method exists_warning (line 51) | def exists_warning
method expired_warning (line 55) | def expired_warning
method max_size_warning (line 59) | def max_size_warning
method generate_filepath (line 63) | def generate_filepath
method csv_exists? (line 67) | def csv_exists?
method expired? (line 71) | def expired?
method remove_csv (line 75) | def remove_csv
method filename (line 79) | def filename
method humanised_import_type (line 84) | def humanised_import_type
FILE: app/services/fdf_inputs_service.rb
class FdfInputsService (line 3) | class FdfInputsService
method clean (line 6) | def self.clean(str)
method initialize (line 14) | def initialize(inputs:, pdf_template_path:, basename:)
method write_to_file (line 20) | def write_to_file(flatten: true)
method with_fdf_tempfile (line 33) | def with_fdf_tempfile
method fdf_template (line 41) | def fdf_template
FILE: app/services/followup_export_csv_service.rb
class FollowupExportCsvService (line 3) | class FollowupExportCsvService
method initialize (line 4) | def initialize(casa_org)
method perform (line 8) | def perform
method full_data (line 27) | def full_data(followup = nil)
FILE: app/services/followup_service.rb
class FollowupService (line 1) | class FollowupService
method create_followup (line 2) | def self.create_followup(case_contact, creator, note)
method send_notification (line 19) | def self.send_notification(followup, creator)
FILE: app/services/inactive_messages_service.rb
class InactiveMessagesService (line 1) | class InactiveMessagesService
method initialize (line 4) | def initialize(supervisor)
method calculate_inactive_messages (line 10) | def calculate_inactive_messages(supervisor)
FILE: app/services/learning_hours_export_csv_service.rb
class LearningHoursExportCsvService (line 3) | class LearningHoursExportCsvService
method initialize (line 6) | def initialize(learning_hours)
method perform (line 10) | def perform
method get_duration (line 21) | def get_duration(learning_hour = nil)
method filtered_learning_hours (line 26) | def filtered_learning_hours(learning_hour = nil)
FILE: app/services/mileage_export_csv_service.rb
class MileageExportCsvService (line 3) | class MileageExportCsvService
method initialize (line 4) | def initialize(case_contacts)
method perform (line 8) | def perform
method full_data (line 21) | def full_data(case_contact = nil)
FILE: app/services/missing_data_export_csv_service.rb
class MissingDataExportCsvService (line 3) | class MissingDataExportCsvService
method initialize (line 6) | def initialize(casa_cases)
method perform (line 10) | def perform
method has_missing_values? (line 25) | def has_missing_values?(casa_case)
method get_status (line 31) | def get_status(missing)
method full_data (line 35) | def full_data(casa_case = nil)
FILE: app/services/no_contact_made_sms_reminder_service.rb
type NoContactMadeSmsReminderService (line 1) | module NoContactMadeSmsReminderService
function no_contact_made_reminder (line 8) | def no_contact_made_reminder(user, contact_type)
FILE: app/services/placement_export_csv_service.rb
class PlacementExportCsvService (line 3) | class PlacementExportCsvService
method initialize (line 6) | def initialize(casa_org:)
method perform (line 10) | def perform
method full_data (line 23) | def full_data(placement = nil)
method fetch_placements (line 34) | def fetch_placements
FILE: app/services/preference_set_table_state_service.rb
class PreferenceSetTableStateService (line 1) | class PreferenceSetTableStateService
class TableStateUpdateFailed (line 2) | class TableStateUpdateFailed < StandardError; end
method initialize (line 4) | def initialize(user_id:)
method table_state (line 8) | def table_state(table_name:)
method update! (line 12) | def update!(table_name:, table_state:)
method preference_set (line 22) | def preference_set
FILE: app/services/short_url_service.rb
class ShortUrlService (line 3) | class ShortUrlService
method initialize (line 13) | def initialize
method create_short_url (line 23) | def create_short_url(original_url = nil)
method validate_credentials (line 32) | def validate_credentials
FILE: app/services/sms_reminder_service.rb
type SmsReminderService (line 1) | module SmsReminderService
function send_reminder (line 5) | def send_reminder(user, message)
function create_short_link (line 18) | def create_short_link(path)
FILE: app/services/svg_sanitizer_service.rb
class SvgSanitizerService (line 1) | class SvgSanitizerService
method sanitize (line 3) | def sanitize(file)
method scrubber (line 17) | def scrubber
FILE: app/services/twilio_service.rb
class TwilioService (line 4) | class TwilioService
method initialize (line 7) | def initialize(casa_org)
method client (line 14) | def client # lazy create client only if twilio enabled
method enabled? (line 18) | def enabled?
method send_sms (line 25) | def send_sms(params)
FILE: app/services/volunteer_birthday_reminder_service.rb
class VolunteerBirthdayReminderService (line 1) | class VolunteerBirthdayReminderService
method send_reminders (line 2) | def send_reminders
FILE: app/services/volunteers_emails_export_csv_service.rb
class VolunteersEmailsExportCsvService (line 3) | class VolunteersEmailsExportCsvService
method initialize (line 6) | def initialize(casa_org)
method call (line 10) | def call
method full_data (line 21) | def full_data(volunteer = nil)
FILE: app/validators/casa_org_validator.rb
class CasaOrgValidator (line 1) | class CasaOrgValidator < ActiveModel::Validator
method validate (line 4) | def validate(record)
method valid_twilio_phone_number (line 10) | def valid_twilio_phone_number(number, record)
FILE: app/validators/court_report_validator.rb
class CourtReportValidator (line 2) | class CourtReportValidator < ActiveModel::Validator
method validate (line 3) | def validate(record)
FILE: app/validators/url_validator.rb
class UrlValidator (line 1) | class UrlValidator < ActiveModel::EachValidator
method validate_each (line 7) | def validate_each(record, attribute, value)
method validate_scheme (line 19) | def validate_scheme(uri)
method validate_host (line 26) | def validate_host(uri)
FILE: app/validators/user_validator.rb
class UserValidator (line 1) | class UserValidator < ActiveModel::Validator
method validate (line 4) | def validate(record)
method valid_phone_number_contents (line 16) | def valid_phone_number_contents(number, record)
method validate_presence (line 24) | def validate_presence(attribute, record)
method at_least_one_communication_preference_selected (line 33) | def at_least_one_communication_preference_selected(record)
method valid_phone_number_if_receive_sms_notifications (line 37) | def valid_phone_number_if_receive_sms_notifications(record)
method validate_date_of_birth_in_past (line 43) | def validate_date_of_birth_in_past(date_of_birth, record)
method validate_date_of_birth_not_before_1920 (line 49) | def validate_date_of_birth_not_before_1920(date_of_birth, record)
method validate_uniqueness (line 55) | def validate_uniqueness(attribute, record, message)
FILE: app/values/all_casa_admin_parameters.rb
class AllCasaAdminParameters (line 1) | class AllCasaAdminParameters < SimpleDelegator
method initialize (line 2) | def initialize(params)
method with_password (line 9) | def with_password(password)
method params (line 16) | def params
FILE: app/values/banner_parameters.rb
class BannerParameters (line 2) | class BannerParameters < SimpleDelegator
method initialize (line 3) | def initialize(params, user, timezone)
method convert_expires_at_with_user_time_zone (line 18) | def convert_expires_at_with_user_time_zone(params, timezone)
method params (line 22) | def params
FILE: app/values/casa_admin_parameters.rb
class CasaAdminParameters (line 1) | class CasaAdminParameters < UserParameters
method initialize (line 2) | def initialize(params)
FILE: app/values/case_contact_parameters.rb
class CaseContactParameters (line 2) | class CaseContactParameters < SimpleDelegator
method initialize (line 3) | def initialize(params)
method normalize_params (line 28) | def normalize_params(params)
method convert_metadata (line 44) | def convert_metadata(metadata)
method convert_duration_minutes (line 51) | def convert_duration_minutes(params)
method convert_miles_driven (line 58) | def convert_miles_driven(params)
method params (line 65) | def params
FILE: app/values/supervisor_parameters.rb
class SupervisorParameters (line 1) | class SupervisorParameters < UserParameters
method initialize (line 2) | def initialize(params)
FILE: app/values/user_parameters.rb
class UserParameters (line 1) | class UserParameters < SimpleDelegator
method initialize (line 2) | def initialize(params, key = :user)
method with_organization (line 21) | def with_organization(organization)
method with_password (line 26) | def with_password(password)
method with_type (line 31) | def with_type(type)
method without_type (line 36) | def without_type
method without_active (line 41) | def without_active
method with_only (line 46) | def with_only(*)
method without (line 51) | def without(*keys)
method params (line 57) | def params
FILE: app/values/volunteer_parameters.rb
class VolunteerParameters (line 1) | class VolunteerParameters < UserParameters
method initialize (line 4) | def initialize(params)
FILE: bin/asset_bundling_scripts/build_js.js
method setup (line 11) | setup (build) {
function main (line 29) | async function main () {
FILE: config/application.rb
type Casa (line 9) | module Casa
class Application (line 10) | class Application < Rails::Application
FILE: config/initializers/all_casa_admin_access.rb
class CanAccessFlipperUI (line 1) | class CanAccessFlipperUI
method matches? (line 2) | def self.matches?(request)
FILE: config/initializers/generators.rb
type PolicyGenerator (line 5) | module PolicyGenerator
type ControllerGenerator (line 6) | module ControllerGenerator
type ScaffoldControllerGenerator (line 17) | module ScaffoldControllerGenerator
type ActiveModel (line 30) | module ActiveModel
class Railtie (line 31) | class Railtie < Rails::Railtie
FILE: config/initializers/rack_attack.rb
class Rack::Attack (line 1) | class Rack::Attack
FILE: db/migrate/20200329050100_create_casa_cases.rb
class CreateCasaCases (line 1) | class CreateCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329062155_devise_create_users.rb
class DeviseCreateUsers (line 3) | class DeviseCreateUsers < ActiveRecord::Migration[6.0]
method change (line 4) | def change
FILE: db/migrate/20200329064203_add_role_to_user.rb
class AddRoleToUser (line 1) | class AddRoleToUser < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329071025_change_casa_case_teen_to_required.rb
class ChangeCasaCaseTeenToRequired (line 1) | class ChangeCasaCaseTeenToRequired < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329071327_change_casa_case_number_to_required.rb
class ChangeCasaCaseNumberToRequired (line 1) | class ChangeCasaCaseNumberToRequired < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329071626_add_unique_index_on_case_case_number.rb
class AddUniqueIndexOnCaseCaseNumber (line 1) | class AddUniqueIndexOnCaseCaseNumber < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329074655_create_supervisor_volunteers.rb
class CreateSupervisorVolunteers (line 1) | class CreateSupervisorVolunteers < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329081206_create_case_assignments.rb
class CreateCaseAssignments (line 1) | class CreateCaseAssignments < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329085225_create_versions.rb
class CreateVersions (line 3) | class CreateVersions < ActiveRecord::Migration[6.0]
method change (line 10) | def change
FILE: db/migrate/20200329095031_create_casa_orgs.rb
class CreateCasaOrgs (line 1) | class CreateCasaOrgs < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329095154_add_casa_org_to_user.rb
class AddCasaOrgToUser (line 1) | class AddCasaOrgToUser < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200329102102_devise_create_all_casa_admins.rb
class DeviseCreateAllCasaAdmins (line 3) | class DeviseCreateAllCasaAdmins < ActiveRecord::Migration[6.0]
method change (line 4) | def change
FILE: db/migrate/20200329175337_create_case_contacts.rb
class CreateCaseContacts (line 1) | class CreateCaseContacts < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200330231711_add_volunteer_reference_to_casa_cases.rb
class AddVolunteerReferenceToCasaCases (line 1) | class AddVolunteerReferenceToCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200405112910_remove_volunteer_id_from_casa_case.rb
class RemoveVolunteerIdFromCasaCase (line 1) | class RemoveVolunteerIdFromCasaCase < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200420004403_add_medium_type_and_contact_made_to_case_contacts.rb
class AddMediumTypeAndContactMadeToCaseContacts (line 1) | class AddMediumTypeAndContactMadeToCaseContacts < ActiveRecord::Migratio...
method change (line 2) | def change
FILE: db/migrate/20200422180727_replace_contact_type_with_contact_types_on_case_contact.rb
class ReplaceContactTypeWithContactTypesOnCaseContact (line 1) | class ReplaceContactTypeWithContactTypesOnCaseContact < ActiveRecord::Mi...
method change (line 2) | def change
FILE: db/migrate/20200423154018_change_teen_program_to_transition_aged_youth.rb
class ChangeTeenProgramToTransitionAgedYouth (line 1) | class ChangeTeenProgramToTransitionAgedYouth < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200423204147_add_name_to_user.rb
class AddNameToUser (line 1) | class AddNameToUser < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200525220759_add_driving_fields_to_case_contact.rb
class AddDrivingFieldsToCaseContact (line 1) | class AddDrivingFieldsToCaseContact < ActiveRecord::Migration[6.0]
method up (line 2) | def up
method down (line 12) | def down
FILE: db/migrate/20200726185103_devise_invitable_add_to_users.rb
class DeviseInvitableAddToUsers (line 1) | class DeviseInvitableAddToUsers < ActiveRecord::Migration[6.0]
method up (line 2) | def up
method down (line 17) | def down
FILE: db/migrate/20200729002247_add_casa_org_to_casa_case.rb
class AddCasaOrgToCasaCase (line 1) | class AddCasaOrgToCasaCase < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200801170524_add_type_to_user.rb
class User (line 1) | class User < ApplicationRecord
class AddTypeToUser (line 5) | class AddTypeToUser < ActiveRecord::Migration[6.0]
method up (line 6) | def up
method down (line 21) | def down
FILE: db/migrate/20200801192923_remove_role_from_user.rb
class RemoveRoleFromUser (line 1) | class RemoveRoleFromUser < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200818220659_add_is_active_to_supervisor_volunteers.rb
class AddIsActiveToSupervisorVolunteers (line 1) | class AddIsActiveToSupervisorVolunteers < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200830011647_add_notes_to_case_contacts.rb
class AddNotesToCaseContacts (line 1) | class AddNotesToCaseContacts < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200905192934_remove_other_type_text_from_case_contacts.rb
class RemoveOtherTypeTextFromCaseContacts (line 1) | class RemoveOtherTypeTextFromCaseContacts < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200906145045_add_display_name_to_casa_orgs.rb
class AddDisplayNameToCasaOrgs (line 1) | class AddDisplayNameToCasaOrgs < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200906145725_add_address_to_casa_orgs.rb
class AddAddressToCasaOrgs (line 1) | class AddAddressToCasaOrgs < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200906145830_add_footer_links_to_casa_orgs.rb
class AddFooterLinksToCasaOrgs (line 1) | class AddFooterLinksToCasaOrgs < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200906150641_create_casa_org_logos.rb
class CreateCasaOrgLogos (line 1) | class CreateCasaOrgLogos < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200906184455_add_banner_color_to_casa_org_logos.rb
class AddBannerColorToCasaOrgLogos (line 1) | class AddBannerColorToCasaOrgLogos < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200907142411_create_task_records.rb
class CreateTaskRecords (line 1) | class CreateTaskRecords < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200917175655_add_default_value_to_case_contact_miles_driven.rb
class AddDefaultValueToCaseContactMilesDriven (line 1) | class AddDefaultValueToCaseContactMilesDriven < ActiveRecord::Migration[...
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20200918115741_set_miles_driven_as_not_nullable.rb
class SetMilesDrivenAsNotNullable (line 1) | class SetMilesDrivenAsNotNullable < ActiveRecord::Migration[6.0]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20200922144730_add_birth_month_year_youth_to_casa_cases.rb
class AddBirthMonthYearYouthToCasaCases (line 1) | class AddBirthMonthYearYouthToCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200922150754_create_contact_type.rb
class CreateContactType (line 1) | class CreateContactType < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200922170308_link_case_contacts_to_contact_types.rb
class LinkCaseContactsToContactTypes (line 1) | class LinkCaseContactsToContactTypes < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200924192310_create_casa_case_contact_type.rb
class CreateCasaCaseContactType (line 1) | class CreateCasaCaseContactType < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200925180941_add_active_to_contact_type_groups.rb
class AddActiveToContactTypeGroups (line 1) | class AddActiveToContactTypeGroups < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200925181042_add_active_to_contact_types.rb
class AddActiveToContactTypes (line 1) | class AddActiveToContactTypes < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20200928233606_add_court_report_submitted_to_casa_cases.rb
class AddCourtReportSubmittedToCasaCases (line 1) | class AddCourtReportSubmittedToCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201002192636_add_court_date_to_casa_cases.rb
class AddCourtDateToCasaCases (line 1) | class AddCourtDateToCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201004165322_add_court_report_due_date_to_casa_cases.rb
class AddCourtReportDueDateToCasaCases (line 1) | class AddCourtReportDueDateToCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201005191326_create_hearing_types.rb
class CreateHearingTypes (line 1) | class CreateHearingTypes < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201013171632_remove_contact_types_from_case_contacts.rb
class RemoveContactTypesFromCaseContacts (line 1) | class RemoveContactTypesFromCaseContacts < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201019120548_create_active_storage_tables.active_storage.rb
class CreateActiveStorageTables (line 2) | class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
method change (line 3) | def change
FILE: db/migrate/20201020095451_add_hearing_type_to_court_cases.rb
class AddHearingTypeToCourtCases (line 1) | class AddHearingTypeToCourtCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201020220412_create_emancipation_categories.rb
class CreateEmancipationCategories (line 1) | class CreateEmancipationCategories < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201021024459_create_emancipation_options.rb
class CreateEmancipationOptions (line 1) | class CreateEmancipationOptions < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201021034012_create_join_table_casa_cases_emancipaton_options.rb
class CreateJoinTableCasaCasesEmancipatonOptions (line 1) | class CreateJoinTableCasaCasesEmancipatonOptions < ActiveRecord::Migrati...
method change (line 2) | def change
FILE: db/migrate/20201021143642_add_active_column_to_casa_cases_table.rb
class AddActiveColumnToCasaCasesTable (line 1) | class AddActiveColumnToCasaCasesTable < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201022034445_add_foreign_key_constraints_to_case_emancipation_join_table.rb
class AddForeignKeyConstraintsToCaseEmancipationJoinTable (line 1) | class AddForeignKeyConstraintsToCaseEmancipationJoinTable < ActiveRecord...
method change (line 2) | def change
FILE: db/migrate/20201023233638_create_judges.rb
class CreateJudges (line 1) | class CreateJudges < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201023234325_add_active_to_judge.rb
class AddActiveToJudge (line 1) | class AddActiveToJudge < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201024003821_add_name_to_judge.rb
class AddNameToJudge (line 1) | class AddNameToJudge < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201024113046_create_past_court_dates.rb
class CreatePastCourtDates (line 1) | class CreatePastCourtDates < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201025162142_add_judge_to_court_cases.rb
class AddJudgeToCourtCases (line 1) | class AddJudgeToCourtCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201108142333_add_court_report_status_to_casa_cases.rb
class AddCourtReportStatusToCasaCases (line 1) | class AddCourtReportStatusToCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201120103041_remove_remember_created_at_from_users.rb
class RemoveRememberCreatedAtFromUsers (line 1) | class RemoveRememberCreatedAtFromUsers < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201120103146_remove_remember_created_at_from_all_casa_admins.rb
class RemoveRememberCreatedAtFromAllCasaAdmins (line 1) | class RemoveRememberCreatedAtFromAllCasaAdmins < ActiveRecord::Migration...
method change (line 2) | def change
FILE: db/migrate/20201120215756_remove_court_report_submitted_from_casa_cases.rb
class RemoveCourtReportSubmittedFromCasaCases (line 1) | class RemoveCourtReportSubmittedFromCasaCases < ActiveRecord::Migration[...
method change (line 2) | def change
FILE: db/migrate/20201123100716_remove_case_number_index_from_casa_cases.rb
class RemoveCaseNumberIndexFromCasaCases (line 1) | class RemoveCaseNumberIndexFromCasaCases < ActiveRecord::Migration[6.0]
method change (line 2) | def change
FILE: db/migrate/20201123112651_add_case_number_index_scoped_by_casa_org_to_casa_cases.rb
class AddCaseNumberIndexScopedByCasaOrgToCasaCases (line 1) | class AddCaseNumberIndexScopedByCasaOrgToCasaCases < ActiveRecord::Migra...
method change (line 2) | def change
FILE: db/migrate/20201222125441_add_service_name_to_active_storage_blobs.active_storage.rb
class AddServiceNameToActiveStorageBlobs (line 2) | class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]
method up (line 3) | def up
method down (line 15) | def down
FILE: db/migrate/20201222125442_create_active_storage_variant_records.active_storage.rb
class CreateActiveStorageVariantRecords (line 2) | class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
method change (line 3) | def change
FILE: db/migrate/20201226024029_create_casa_case_emancipation_categories.rb
class CreateCasaCaseEmancipationCategories (line 1) | class CreateCasaCaseEmancipationCategories < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210105155534_create_followups.rb
class CreateFollowups (line 1) | class CreateFollowups < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210107181908_add_id_and_timestamps_to_case_emancipation_options_table.rb
class AddIdAndTimestampsToCaseEmancipationOptionsTable (line 1) | class AddIdAndTimestampsToCaseEmancipationOptionsTable < ActiveRecord::M...
method change (line 2) | def change
FILE: db/migrate/20210109231411_drop_casa_org_logos_table.rb
class DropCasaOrgLogosTable (line 1) | class DropCasaOrgLogosTable < ActiveRecord::Migration[6.1]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20210117185614_create_notifications.rb
class CreateNotifications (line 1) | class CreateNotifications < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210223133248_create_case_court_mandates.rb
class CreateCaseCourtMandates (line 1) | class CreateCaseCourtMandates < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210308195135_change_is_active_name.rb
class ChangeIsActiveName (line 1) | class ChangeIsActiveName < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210330182538_add_devise_trackable_columns_to_users.rb
class AddDeviseTrackableColumnsToUsers (line 1) | class AddDeviseTrackableColumnsToUsers < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210401161710_add_deleted_at_to_case_contacts.rb
class AddDeletedAtToCaseContacts (line 1) | class AddDeletedAtToCaseContacts < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210401182359_add_implementation_status_to_edit_case_court_mandates.rb
class AddImplementationStatusToEditCaseCourtMandates (line 1) | class AddImplementationStatusToEditCaseCourtMandates < ActiveRecord::Mig...
method change (line 2) | def change
FILE: db/migrate/20210502172706_add_devise_invitable_to_all_casa_admins.rb
class AddDeviseInvitableToAllCasaAdmins (line 1) | class AddDeviseInvitableToAllCasaAdmins < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210521151549_add_casa_case_details_to_past_court_dates.rb
class AddCasaCaseDetailsToPastCourtDates (line 1) | class AddCasaCaseDetailsToPastCourtDates < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210521194321_add_past_court_date_to_case_court_mandates.rb
class AddPastCourtDateToCaseCourtMandates (line 1) | class AddPastCourtDateToCaseCourtMandates < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210526233058_create_sent_emails.rb
class CreateSentEmails (line 1) | class CreateSentEmails < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210624125750_add_note_to_followups.rb
class AddNoteToFollowups (line 1) | class AddNoteToFollowups < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20210913142024_set_display_name_as_not_nullable.rb
class SetDisplayNameAsNotNullable (line 1) | class SetDisplayNameAsNotNullable < ActiveRecord::Migration[6.1]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20210925140028_add_slug_to_casa_orgs_and_casa_cases.rb
class AddSlugToCasaOrgsAndCasaCases (line 1) | class AddSlugToCasaOrgsAndCasaCases < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211001204053_rename_court_mandates_to_court_orders.rb
class RenameCourtMandatesToCourtOrders (line 1) | class RenameCourtMandatesToCourtOrders < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211007144114_add_show_driving_reimbursement_to_casa_orgs.rb
class AddShowDrivingReimbursementToCasaOrgs (line 1) | class AddShowDrivingReimbursementToCasaOrgs < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211008170357_add_text_to_case_court_orders.rb
class AddTextToCaseCourtOrders (line 1) | class AddTextToCaseCourtOrders < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211008170724_migrate_case_court_orders_mandate_text_to_text.rb
class MigrateCaseCourtOrdersMandateTextToText (line 1) | class MigrateCaseCourtOrdersMandateTextToText < ActiveRecord::Migration[...
method up (line 2) | def up
FILE: db/migrate/20211008174527_remove_mandate_text_from_case_court_orders.rb
class RemoveMandateTextFromCaseCourtOrders (line 1) | class RemoveMandateTextFromCaseCourtOrders < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211011195857_rename_past_court_date_to_court_date.rb
class RenamePastCourtDateToCourtDate (line 1) | class RenamePastCourtDateToCourtDate < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211012180102_change_casa_cases_court_date_to_reference.rb
class ChangeCasaCasesCourtDateToReference (line 1) | class ChangeCasaCasesCourtDateToReference < ActiveRecord::Migration[6.1]
method up (line 2) | def up
FILE: db/migrate/20211023165907_add_reimbursement_complete_to_case_contacts.rb
class AddReimbursementCompleteToCaseContacts (line 1) | class AddReimbursementCompleteToCaseContacts < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211024011923_create_mileage_rates.rb
class CreateMileageRates (line 1) | class CreateMileageRates < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211024060815_create_preference_sets.rb
class CreatePreferenceSets (line 1) | class CreatePreferenceSets < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211025143709_create_healths.rb
class CreateHealths (line 1) | class CreateHealths < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211029032305_add_casa_org_to_mileage_rate.rb
class AddCasaOrgToMileageRate (line 1) | class AddCasaOrgToMileageRate < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211029033530_remove_user_required_from_mileage_rate.rb
class RemoveUserRequiredFromMileageRate (line 1) | class RemoveUserRequiredFromMileageRate < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211203181342_create_additional_expenses.rb
class CreateAdditionalExpenses (line 1) | class CreateAdditionalExpenses < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20211230033457_create_delayed_jobs.rb
class CreateDelayedJobs (line 1) | class CreateDelayedJobs < ActiveRecord::Migration[6.1]
method up (line 2) | def self.up
method down (line 19) | def self.down
FILE: db/migrate/20220105030922_create_feature_flags.rb
class CreateFeatureFlags (line 1) | class CreateFeatureFlags < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20220127055733_create_notes.rb
class CreateNotes (line 1) | class CreateNotes < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20220223035901_remove_null_check_deprecated_field.rb
class RemoveNullCheckDeprecatedField (line 1) | class RemoveNullCheckDeprecatedField < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20220226040507_create_fund_request.rb
class CreateFundRequest (line 1) | class CreateFundRequest < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20220303183053_create_other_duty.rb
class CreateOtherDuty (line 1) | class CreateOtherDuty < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20220323145733_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
class RemoveNotNullOnActiveStorageBlobsChecksum (line 2) | class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migratio...
method change (line 3) | def change
FILE: db/migrate/20220324141758_create_learning_hours.rb
class CreateLearningHours (line 1) | class CreateLearningHours < ActiveRecord::Migration[6.1]
method change (line 2) | def change
FILE: db/migrate/20220402201247_add_phone_number_to_users.rb
class AddPhoneNumberToUsers (line 1) | class AddPhoneNumberToUsers < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220406011016_add_sms_notification_preferences_to_users.rb
class AddSmsNotificationPreferencesToUsers (line 1) | class AddSmsNotificationPreferencesToUsers < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220406011144_add_email_notification_preferences_to_users.rb
class AddEmailNotificationPreferencesToUsers (line 1) | class AddEmailNotificationPreferencesToUsers < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220409184741_add_fund_request.rb
class AddFundRequest (line 1) | class AddFundRequest < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220411180242_add_uniqueness_constraint_to_feature_flag_name.rb
class AddUniquenessConstraintToFeatureFlagName (line 1) | class AddUniquenessConstraintToFeatureFlagName < ActiveRecord::Migration...
method change (line 4) | def change
FILE: db/migrate/20220509224425_add_columns_to_casa_orgs.rb
class AddColumnsToCasaOrgs (line 1) | class AddColumnsToCasaOrgs < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220513084954_add_date_in_care_to_casa_cases.rb
class AddDateInCareToCasaCases (line 1) | class AddDateInCareToCasaCases < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220513111133_delete_versions.rb
class DeleteVersions (line 1) | class DeleteVersions < ActiveRecord::Migration[7.0]
method up (line 2) | def up
method down (line 9) | def down
FILE: db/migrate/20220519210423_create_sms_notification_events.rb
class CreateSmsNotificationEvents (line 1) | class CreateSmsNotificationEvents < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220519233803_create_user_sms_notification_events.rb
class CreateUserSmsNotificationEvents (line 1) | class CreateUserSmsNotificationEvents < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220526011848_create_user_reminder_times.rb
class CreateUserReminderTimes (line 1) | class CreateUserReminderTimes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220602215632_create_addresses.rb
class CreateAddresses (line 1) | class CreateAddresses < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220607184910_add_hide_old_contacts_to_case_assignment.rb
class AddHideOldContactsToCaseAssignment (line 1) | class AddHideOldContactsToCaseAssignment < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220610221701_create_checklist_items.rb
class CreateChecklistItems (line 1) | class CreateChecklistItems < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220615015056_create_patch_note_types.rb
class CreatePatchNoteTypes (line 1) | class CreatePatchNoteTypes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220616021404_add_checklist_updated_date_to_hearing_types.rb
class AddChecklistUpdatedDateToHearingTypes (line 1) | class AddChecklistUpdatedDateToHearingTypes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220618042137_create_patch_note_groups.rb
class CreatePatchNoteGroups (line 1) | class CreatePatchNoteGroups < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220622022147_create_patch_notes.rb
class CreatePatchNotes (line 1) | class CreatePatchNotes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220820231119_create_languages.rb
class CreateLanguages (line 1) | class CreateLanguages < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220826130829_create_languages_users_join_table.rb
class CreateLanguagesUsersJoinTable (line 1) | class CreateLanguagesUsersJoinTable < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20220924181447_remove_all_empty_languages.rb
class RemoveAllEmptyLanguages (line 1) | class RemoveAllEmptyLanguages < ActiveRecord::Migration[7.0]
method up (line 2) | def up
FILE: db/migrate/20221002103627_add_user_foreign_key_to_other_duties.rb
class AddUserForeignKeyToOtherDuties (line 1) | class AddUserForeignKeyToOtherDuties < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20221002103754_validate_add_user_foreign_key_to_other_duties.rb
class ValidateAddUserForeignKeyToOtherDuties (line 1) | class ValidateAddUserForeignKeyToOtherDuties < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20221003202112_add_court_report_due_date_to_court_dates.rb
class AddCourtReportDueDateToCourtDates (line 1) | class AddCourtReportDueDateToCourtDates < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20221011044911_add_user_languages.rb
class AddUserLanguages (line 1) | class AddUserLanguages < ActiveRecord::Migration[7.0]
method change (line 4) | def change
FILE: db/migrate/20221012203806_populate_user_languages_from_languages_users.rb
class PopulateUserLanguagesFromLanguagesUsers (line 1) | class PopulateUserLanguagesFromLanguagesUsers < ActiveRecord::Migration[...
method change (line 2) | def change
FILE: db/migrate/20230121174227_remove_court_data_from_casa_cases.rb
class RemoveCourtDataFromCasaCases (line 1) | class RemoveCourtDataFromCasaCases < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230220210146_add_phone_number_to_all_casa_admin_resource.rb
class AddPhoneNumberToAllCasaAdminResource (line 1) | class AddPhoneNumberToAllCasaAdminResource < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230316152808_remove_phone_number_from_all_casa_admin_resource.rb
class RemovePhoneNumberFromAllCasaAdminResource (line 1) | class RemovePhoneNumberFromAllCasaAdminResource < ActiveRecord::Migratio...
method change (line 2) | def change
FILE: db/migrate/20230326225216_create_placement_types.rb
class CreatePlacementTypes (line 1) | class CreatePlacementTypes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230326225230_create_placements.rb
class CreatePlacements (line 1) | class CreatePlacements < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230327154626_add_confirmable_to_users.rb
class AddConfirmableToUsers (line 1) | class AddConfirmableToUsers < ActiveRecord::Migration[7.0]
method up (line 4) | def up
method down (line 17) | def down
FILE: db/migrate/20230327155053_add_email_confirmation_and_old_emails_to_users.rb
class AddEmailConfirmationAndOldEmailsToUsers (line 1) | class AddEmailConfirmationAndOldEmailsToUsers < ActiveRecord::Migration[...
method change (line 2) | def change
FILE: db/migrate/20230405202939_remove_email_confirmation_from_users.rb
class RemoveEmailConfirmationFromUsers (line 1) | class RemoveEmailConfirmationFromUsers < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230412103356_add_casa_case_to_placements.rb
class AddCasaCaseToPlacements (line 1) | class AddCasaCaseToPlacements < ActiveRecord::Migration[7.0]
method change (line 4) | def change
FILE: db/migrate/20230420212437_add_table_columns_display_to_preference_set.rb
class AddTableColumnsDisplayToPreferenceSet (line 1) | class AddTableColumnsDisplayToPreferenceSet < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230610153139_add_receive_reimbursement_email_to_users.rb
class AddReceiveReimbursementEmailToUsers (line 1) | class AddReceiveReimbursementEmailToUsers < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230615155223_add_twilio_enabled_to_casa_orgs.rb
class AddTwilioEnabledToCasaOrgs (line 1) | class AddTwilioEnabledToCasaOrgs < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230621161252_add_additional_expenses_to_casa_orgs.rb
class AddAdditionalExpensesToCasaOrgs (line 1) | class AddAdditionalExpensesToCasaOrgs < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230627210040_add_allow_reimbursement_to_case_assignments.rb
class AddAllowReimbursementToCaseAssignments (line 1) | class AddAllowReimbursementToCaseAssignments < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230704123327_add_foreign_key_constraints_to_mileage_rates.rb
class AddForeignKeyConstraintsToMileageRates (line 1) | class AddForeignKeyConstraintsToMileageRates < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230710025852_add_token_to_users.rb
class AddTokenToUsers (line 1) | class AddTokenToUsers < ActiveRecord::Migration[7.0]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20230712080040_add_foreign_key_creator_id_to_note.rb
class AddForeignKeyCreatorIdToNote (line 1) | class AddForeignKeyCreatorIdToNote < ActiveRecord::Migration[7.0]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20230728135743_create_action_text_tables.action_text.rb
class CreateActionTextTables (line 2) | class CreateActionTextTables < ActiveRecord::Migration[6.0]
method change (line 3) | def change
method primary_and_foreign_key_types (line 20) | def primary_and_foreign_key_types
FILE: db/migrate/20230728140249_create_banners.rb
class CreateBanners (line 1) | class CreateBanners < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230729143126_create_learning_hour_types.rb
class CreateLearningHourTypes (line 1) | class CreateLearningHourTypes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230729145310_add_reference_learning_hour_types.rb
class AddReferenceLearningHourTypes (line 1) | class AddReferenceLearningHourTypes < ActiveRecord::Migration[7.0]
method change (line 4) | def change
FILE: db/migrate/20230729145351_add_foreign_key_learning_hour_types.rb
class AddForeignKeyLearningHourTypes (line 1) | class AddForeignKeyLearningHourTypes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230729145419_validate_foreign_key_learning_hour_types.rb
class ValidateForeignKeyLearningHourTypes (line 1) | class ValidateForeignKeyLearningHourTypes < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230729154529_create_case_groups.rb
class CreateCaseGroups (line 1) | class CreateCaseGroups < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230729154545_create_case_group_memberships.rb
class CreateCaseGroupMemberships (line 1) | class CreateCaseGroupMemberships < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230729213608_remove_hearing_type_id_and_judge_id_from_casa_cases.rb
class RemoveHearingTypeIdAndJudgeIdFromCasaCases (line 1) | class RemoveHearingTypeIdAndJudgeIdFromCasaCases < ActiveRecord::Migrati...
method change (line 2) | def change
FILE: db/migrate/20230730103110_remove_learning_type.rb
class RemoveLearningType (line 1) | class RemoveLearningType < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230809002819_drop_languages_users.rb
class DropLanguagesUsers (line 1) | class DropLanguagesUsers < ActiveRecord::Migration[7.0]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20230817144910_create_learning_hour_topics.rb
class CreateLearningHourTopics (line 1) | class CreateLearningHourTopics < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230819124840_add_learning_hour_topic_id_to_learning_hour.rb
class AddLearningHourTopicIdToLearningHour (line 1) | class AddLearningHourTopicIdToLearningHour < ActiveRecord::Migration[7.0]
method change (line 4) | def change
FILE: db/migrate/20230819132316_add_learning_topic_active_to_casa_org.rb
class AddLearningTopicActiveToCasaOrg (line 1) | class AddLearningTopicActiveToCasaOrg < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230822152341_drop_jwt_denylist_table.rb
class DropJwtDenylistTable (line 1) | class DropJwtDenylistTable < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230902021531_add_monthly_learning_hours_report_to_user.rb
class AddMonthlyLearningHoursReportToUser (line 1) | class AddMonthlyLearningHoursReportToUser < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20230903182657_add_foreign_key_casa_case_to_placement.rb
class AddForeignKeyCasaCaseToPlacement (line 1) | class AddForeignKeyCasaCaseToPlacement < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20231102181027_add_birthdays_to_users.rb
class AddBirthdaysToUsers (line 1) | class AddBirthdaysToUsers < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20231125150721_status_for_case_contacts.rb
class StatusForCaseContacts (line 1) | class StatusForCaseContacts < ActiveRecord::Migration[7.0]
method change (line 2) | def change
FILE: db/migrate/20240216013254_add_contact_topics.rb
class AddContactTopics (line 1) | class AddContactTopics < ActiveRecord::Migration[7.1]
method change (line 2) | def change
FILE: db/migrate/20240415160842_add_followupable_to_followups.rb
class AddFollowupableToFollowups (line 1) | class AddFollowupableToFollowups < ActiveRecord::Migration[7.1]
method change (line 11) | def change
FILE: db/migrate/20240507022441_create_login_activities.rb
class CreateLoginActivities (line 1) | class CreateLoginActivities < ActiveRecord::Migration[7.1]
method change (line 2) | def change
FILE: db/migrate/20240509104733_create_noticed_tables.noticed.rb
class CreateNoticedTables (line 2) | class CreateNoticedTables < ActiveRecord::Migration[6.1]
method change (line 3) | def change
method primary_and_foreign_key_types (line 30) | def primary_and_foreign_key_types
FILE: db/migrate/20240509104734_add_notifications_count_to_noticed_event.noticed.rb
class AddNotificationsCountToNoticedEvent (line 2) | class AddNotificationsCountToNoticedEvent < ActiveRecord::Migration[6.1]
method change (line 3) | def change
FILE: db/migrate/20240531172823_add_expires_at_to_banner.rb
class AddExpiresAtToBanner (line 1) | class AddExpiresAtToBanner < ActiveRecord::Migration[7.1]
method change (line 2) | def change
FILE: db/migrate/20240610071054_add_other_duties_enabled_to_casa_org.rb
class AddOtherDutiesEnabledToCasaOrg (line 1) | class AddOtherDutiesEnabledToCasaOrg < ActiveRecord::Migration[7.1]
method change (line 2) | def change
FILE: db/migrate/20240621165358_create_flipper_tables.rb
class CreateFlipperTables (line 1) | class CreateFlipperTables < ActiveRecord::Migration[7.1]
method up (line 2) | def up
method down (line 18) | def down
FILE: db/migrate/20240622020203_drop_feature_flags.rb
class DropFeatureFlags (line 1) | class DropFeatureFlags < ActiveRecord::Migration[7.1]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20240716194609_add_metadata_to_case_contacts.rb
class AddMetadataToCaseContacts (line 1) | class AddMetadataToCaseContacts < ActiveRecord::Migration[7.1]
method change (line 2) | def change
FILE: db/migrate/20241017050129_remove_contact_topic_answer_contact_topic_id_null_constraint.rb
class RemoveContactTopicAnswerContactTopicIdNullConstraint (line 1) | class RemoveContactTopicAnswerContactTopicIdNullConstraint < ActiveRecor...
method change (line 2) | def change
FILE: db/migrate/20250207080433_remove_token_from_users.rb
class RemoveTokenFromUsers (line 1) | class RemoveTokenFromUsers < ActiveRecord::Migration[7.2]
method change (line 2) | def change
FILE: db/migrate/20250207080511_create_api_credentials.rb
class CreateApiCredentials (line 1) | class CreateApiCredentials < ActiveRecord::Migration[7.2]
method change (line 2) | def change
FILE: db/migrate/20250208160513_remove_plain_text_tokens_from_api_credentials.rb
class RemovePlainTextTokensFromApiCredentials (line 1) | class RemovePlainTextTokensFromApiCredentials < ActiveRecord::Migration[...
method change (line 2) | def change
FILE: db/migrate/20250331032424_validate_constraint_mileage_rates.rb
class ValidateConstraintMileageRates (line 1) | class ValidateConstraintMileageRates < ActiveRecord::Migration[7.2]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20250331033339_validate_constraint_notes.rb
class ValidateConstraintNotes (line 1) | class ValidateConstraintNotes < ActiveRecord::Migration[7.2]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20250331033350_validate_constraint_placements.rb
class ValidateConstraintPlacements (line 1) | class ValidateConstraintPlacements < ActiveRecord::Migration[7.2]
method up (line 2) | def up
method down (line 6) | def down
FILE: db/migrate/20250331033418_remove_duplicate_indexindex_emancipation_options_on_emancipation_category_id.rb
class RemoveDuplicateIndexindexEmancipationOptionsOnEmancipationCategoryId (line 1) | class RemoveDuplicateIndexindexEmancipationOptionsOnEmancipationCategory...
method change (line 2) | def change
FILE: db/migrate/20250331033441_remove_duplicate_indexindex_user_languages_on_language_id.rb
class RemoveDuplicateIndexindexUserLanguagesOnLanguageId (line 1) | class RemoveDuplicateIndexindexUserLanguagesOnLanguageId < ActiveRecord:...
method change (line 2) | def change
FILE: db/migrate/20250404200715_create_custom_org_links.rb
class CreateCustomOrgLinks (line 1) | class CreateCustomOrgLinks < ActiveRecord::Migration[7.2]
method change (line 2) | def change
FILE: db/migrate/20250507011754_remove_unused_indexes.rb
class RemoveUnusedIndexes (line 1) | class RemoveUnusedIndexes < ActiveRecord::Migration[7.2]
method change (line 2) | def change
FILE: db/migrate/20250528092341_trim_whitespace_from_custom_org_links.rb
class TrimWhitespaceFromCustomOrgLinks (line 1) | class TrimWhitespaceFromCustomOrgLinks < ActiveRecord::Migration[7.2]
method up (line 2) | def up
method down (line 11) | def down
FILE: db/migrate/20250702142004_add_exclude_from_court_report_to_contact_topics.rb
class AddExcludeFromCourtReportToContactTopics (line 1) | class AddExcludeFromCourtReportToContactTopics < ActiveRecord::Migration...
method change (line 2) | def change
FILE: db/migrate/20260210233737_rename_casa_cases_emancipaton_options_to_casa_case_emancipaton_options.rb
class RenameCasaCasesEmancipatonOptionsToCasaCaseEmancipatonOptions (line 1) | class RenameCasaCasesEmancipatonOptionsToCasaCaseEmancipatonOptions < Ac...
method change (line 2) | def change
FILE: db/migrate/20260211001655_rename_casa_cases_emancipaton_options_to_casa_case_emancipaton_options_follow_up.rb
class RenameCasaCasesEmancipatonOptionsToCasaCaseEmancipatonOptionsFollowUp (line 1) | class RenameCasaCasesEmancipatonOptionsToCasaCaseEmancipatonOptionsFollo...
method up (line 2) | def up
method down (line 9) | def down
FILE: db/migrate/20260414132818_add_deleted_at_to_contact_topic_answers.rb
class AddDeletedAtToContactTopicAnswers (line 1) | class AddDeletedAtToContactTopicAnswers < ActiveRecord::Migration[7.2]
method change (line 2) | def change
FILE: db/seeds.rb
class SeederMain (line 16) | class SeederMain
method initialize (line 19) | def initialize
method seed (line 27) | def seed
method active_record_classes (line 58) | def active_record_classes
method post_process_data (line 89) | def post_process_data
method get_seed_specification (line 95) | def get_seed_specification
method report_object_counts (line 111) | def report_object_counts
method log (line 119) | def log(message)
method create_org_related_data (line 125) | def create_org_related_data(db_populator, casa_org, options)
FILE: db/seeds/casa_org_populator_presets.rb
type CasaOrgPopulatorPresets (line 3) | module CasaOrgPopulatorPresets
function minimal_dataset_options (line 6) | def minimal_dataset_options
function small_dataset_options (line 15) | def small_dataset_options
function medium_dataset_options (line 24) | def medium_dataset_options
function large_dataset_options (line 33) | def large_dataset_options
function for_environment (line 42) | def for_environment
FILE: db/seeds/db_populator.rb
class DbPopulator (line 6) | class DbPopulator
method initialize (line 17) | def initialize(random_instance, case_fourteen_years_old: false)
method create_all_casa_admin (line 24) | def create_all_casa_admin(email)
method create_org (line 29) | def create_org(options)
method create_judges (line 47) | def create_judges(casa_org)
method create_users (line 53) | def create_users(casa_org, options)
method create_other_duties (line 96) | def create_other_duties
method create_case_contacts (line 110) | def create_case_contacts(casa_case)
method create_case_contact (line 121) | def create_case_contact(casa_case, status: "active")
method create_cases (line 135) | def create_cases(casa_org, options)
method create_hearing_types (line 230) | def create_hearing_types(casa_org)
method create_checklist_items (line 258) | def create_checklist_items
method create_languages (line 282) | def create_languages(casa_org)
method create_language (line 291) | def create_language(name, casa_org)
method create_mileage_rates (line 295) | def create_mileage_rates(casa_org)
method create_learning_hour_types (line 315) | def create_learning_hour_types(casa_org)
method create_learning_hour_topics (line 325) | def create_learning_hour_topics(casa_org)
method create_learning_hours (line 333) | def create_learning_hours(casa_org)
method most_recent_past_court_date (line 358) | def most_recent_past_court_date(casa_case_id)
method case_contact_before_last_court_date? (line 366) | def case_contact_before_last_court_date?(casa_case_id, date)
method case_contact_after_last_court_date? (line 374) | def case_contact_after_last_court_date?(case_case_id, date)
method order_choices (line 382) | def order_choices
method transition_aged_youth? (line 398) | def transition_aged_youth?(birth_month_year_youth)
method base_case_contact_params (line 402) | def base_case_contact_params(casa_case, status)
method random_case_contact_count (line 419) | def random_case_contact_count
method random_past_court_date_count (line 424) | def random_past_court_date_count
method random_zero_one_count (line 429) | def random_zero_one_count
method random_court_order_count (line 434) | def random_court_order_count
method likely_contact_durations (line 439) | def likely_contact_durations
method note_generator (line 443) | def note_generator
method generate_case_number (line 450) | def generate_case_number
method generate_court_date (line 458) | def generate_court_date
method random_true_false (line 462) | def random_true_false
FILE: db/seeds/emancipation_options_prune.rb
function get_category_by_name (line 1) | def get_category_by_name(category_name)
FILE: lib/ext/pdf_forms.rb
type Ext (line 1) | module Ext
type PdfForms (line 2) | module PdfForms
function fill_form_with_fdf (line 6) | def fill_form_with_fdf(template, destination, fdf_path, fill_options...
function pdftk_arguments (line 18) | def pdftk_arguments(template, destination, fdf_path, flatten:)
FILE: lib/generators/rails/policy/policy_generator.rb
class Rails::PolicyGenerator (line 2) | class Rails::PolicyGenerator < Rails::Generators::NamedBase
method create_policy (line 13) | def create_policy
method create_policy_spec (line 17) | def create_policy_spec
FILE: lib/mailers/debug_preview_mailer.rb
class DebugPreviewMailer (line 1) | class DebugPreviewMailer < ActionMailer::Base
method invalid_user (line 2) | def invalid_user(role)
FILE: lib/mailers/previews/casa_admin_mailer_preview.rb
class CasaAdminMailerPreview (line 2) | class CasaAdminMailerPreview < ActionMailer::Preview
method account_setup (line 3) | def account_setup
method deactivation (line 12) | def deactivation
FILE: lib/mailers/previews/concerns/mailer_preview.rb
type MailerPreview (line 1) | module MailerPreview
function preview_linkable (line 4) | def preview_linkable(record)
FILE: lib/mailers/previews/devise_mailer_preview.rb
class DeviseMailerPreview (line 4) | class DeviseMailerPreview < ActionMailer::Preview
method reset_password_instructions (line 5) | def reset_password_instructions
method invitation_instructions_as_all_casa_admin (line 14) | def invitation_instructions_as_all_casa_admin
method invitation_instructions_as_casa_admin (line 20) | def invitation_instructions_as_casa_admin
method invitation_instructions_as_supervisor (line 26) | def invitation_instructions_as_supervisor
method invitation_instructions_as_volunteer (line 32) | def invitation_instructions_as_volunteer
method update_invitation_sent_at (line 42) | def update_invitation_sent_at(model)
method preview (line 47) | def preview(model)
method email_changed (line 51) | def email_changed
method password_change (line 56) | def password_change
FILE: lib/mailers/previews/fund_request_mailer_preview.rb
class FundRequestMailerPreview (line 5) | class FundRequestMailerPreview < ActionMailer::Preview
method send_request (line 6) | def send_request
FILE: lib/mailers/previews/learning_hours_mailer_preview.rb
class LearningHoursMailerPreview (line 3) | class LearningHoursMailerPreview < ActionMailer::Preview
method learning_hours_report_email (line 4) | def learning_hours_report_email
FILE: lib/mailers/previews/supervisor_mailer_preview.rb
class SupervisorMailerPreview (line 5) | class SupervisorMailerPreview < ActionMailer::Preview
method account_setup (line 6) | def account_setup
method weekly_digest_no_volunteers (line 15) | def weekly_digest_no_volunteers
method weekly_digest_more_data (line 24) | def weekly_digest_more_data
method weekly_digest (line 33) | def weekly_digest
method reimbursement_request_email (line 42) | def reimbursement_request_email
FILE: lib/mailers/previews/volunteer_mailer_preview.rb
class VolunteerMailerPreview (line 4) | class VolunteerMailerPreview < ActionMailer::Preview
method account_setup (line 5) | def account_setup
method court_report_reminder (line 14) | def court_report_reminder
method case_contacts_reminder (line 23) | def case_contacts_reminder
FILE: lib/tasks/case_contact_types_reminder.rb
class CaseContactTypesReminder (line 1) | class CaseContactTypesReminder
method send! (line 6) | def send!
method uncontacted_case_contact_types (line 33) | def uncontacted_case_contact_types(volunteer)
method send_sms_messages (line 38) | def send_sms_messages(volunteer, uncontacted_case_contact_type_names)
method valid_casa_twilio_creds (line 65) | def valid_casa_twilio_creds(casa_org)
method last_reminder_within_quarter (line 69) | def last_reminder_within_quarter(volunteer)
method new_case_contact_page_short_link (line 79) | def new_case_contact_page_short_link
FILE: lib/tasks/data_post_processors/case_contact_populator.rb
type CaseContactPopulator (line 1) | module CaseContactPopulator
function populate (line 2) | def self.populate
FILE: lib/tasks/data_post_processors/contact_topic_populator.rb
type ContactTopicPopulator (line 1) | module ContactTopicPopulator
function populate (line 2) | def self.populate
FILE: lib/tasks/data_post_processors/contact_type_populator.rb
type ContactTypePopulator (line 1) | module ContactTypePopulator
function populate (line 2) | def self.populate
FILE: lib/tasks/data_post_processors/sms_notification_event_populator.rb
type SmsNotificationEventPopulator (line 1) | module SmsNotificationEventPopulator
function populate (line 8) | def self.populate
FILE: lib/tasks/deployment/20220902180609_populate_languages.rake
function create_languages (line 16) | def create_languages(casa_org)
function create_language (line 25) | def create_language(name, casa_org)
FILE: lib/tasks/deployment/20240604121427_migrate_notifications.rake
class Notification (line 2) | class Notification < ActiveRecord::Base
FILE: lib/tasks/example_recurring_task.rb
class ExampleRecurringTask (line 1) | class ExampleRecurringTask
method perform (line 7) | def perform
FILE: lib/tasks/no_contact_made_reminder.rb
class NoContactMadeReminder (line 1) | class NoContactMadeReminder
method send! (line 2) | def send!
method send_reminders (line 18) | def send_reminders(volunteer)
method get_contact_types_in_past_2_weeks (line 36) | def get_contact_types_in_past_2_weeks(volunteer, contact_made)
method valid_past_reminders (line 40) | def valid_past_reminders(volunteer)
FILE: lib/tasks/supervisor_weekly_digest.rb
class SupervisorWeeklyDigest (line 1) | class SupervisorWeeklyDigest
method send! (line 2) | def send!
FILE: lib/tasks/test_checker.rake
function deny_filespec (line 6) | def deny_filespec
function dashed_line (line 10) | def dashed_line
function amazing_printize (line 18) | def amazing_printize(object)
function top_level_dir (line 23) | def top_level_dir(name)
function ruby_files (line 28) | def ruby_files(dir)
function app_dir (line 34) | def app_dir
function spec_dir (line 39) | def spec_dir
function app_files (line 44) | def app_files
function spec_files (line 49) | def spec_files
function ignore_files (line 60) | def ignore_files
function missing_spec_files (line 67) | def missing_spec_files
function missing_and_not_denied_spec_files (line 71) | def missing_and_not_denied_spec_files
function missing_but_denied_files (line 75) | def missing_but_denied_files
function output_missing_but_denied (line 79) | def output_missing_but_denied
function output_missing_and_not_denied (line 91) | def output_missing_and_not_denied
FILE: scripts/import_casa_case_date_of_birth.rb
function update_casa_case_birth_month_year_youth (line 12) | def update_casa_case_birth_month_year_youth(casa_case, new_date)
function dates_match (line 16) | def dates_match(casa_case, new_date)
function update_casa_case_dates_of_birth (line 20) | def update_casa_case_dates_of_birth(data, case_not_found, already_has_no...
function process_casa_case_date (line 36) | def process_casa_case_date(cc, import_date, case_number, already_has_non...
FILE: spec/components/previews/truncated_text_component_preview.rb
class TruncatedTextComponentPreview (line 1) | class TruncatedTextComponentPreview < ViewComponent::Preview
method default (line 2) | def default
FILE: spec/config/initializers/rack_attack_spec.rb
function app (line 26) | def app
FILE: spec/controllers/application_controller_spec.rb
function index (line 8) | def index
function handle_short_url (line 14) | def handle_short_url(url_list)
function store_referring_location (line 18) | def store_referring_location
function not_authorized_error (line 22) | def not_authorized_error
function unknown_organization (line 26) | def unknown_organization
FILE: spec/controllers/concerns/accessible_spec.rb
class MockController (line 3) | class MockController < ApplicationController
method action (line 6) | def action
method no_session_action (line 10) | def no_session_action
FILE: spec/controllers/concerns/court_date_params_spec.rb
function initialize (line 10) | def initialize(params)
FILE: spec/controllers/concerns/organizational_spec.rb
class MockController (line 3) | class MockController < ApplicationController
FILE: spec/controllers/concerns/users/time_zone_spec.rb
class MockController (line 3) | class MockController < ApplicationController
FILE: spec/controllers/emancipations_controller_spec.rb
function post_save (line 61) | def post_save(action, check_item_id, case_id: casa_case.friendly_id)
function json_response (line 237) | def json_response
FILE: spec/documents/templates/prince_george_report_template_spec.rb
function extract_document_xml (line 11) | def extract_document_xml(docx_path)
function find_contacts_table (line 18) | def find_contacts_table(doc)
FILE: spec/models/case_court_report_context_spec.rb
function build_context (line 369) | def build_context(start_date:, end_date:, court_date:, time_zone:)
function zone_days_ago (line 381) | def zone_days_ago(days)
function days_ago (line 385) | def days_ago(days)
FILE: spec/models/case_court_report_spec.rb
function generate_doc (line 482) | def generate_doc(context, path_to_template)
FILE: spec/requests/api/v1/base_spec.rb
function index (line 6) | def index
FILE: spec/requests/case_contact_reports_spec.rb
function case_contact_report_params (line 137) | def case_contact_report_params
FILE: spec/requests/case_contacts/case_contacts_new_design_spec.rb
function post_datatable (line 273) | def post_datatable
function row_for (line 277) | def row_for(contact_id)
FILE: spec/requests/health_spec.rb
function setup (line 50) | def setup
function setup (line 102) | def setup
FILE: spec/seeds/seeds_spec.rb
function empty_ar_classes (line 4) | def empty_ar_classes
FILE: spec/services/case_contacts_export_csv_service_spec.rb
function filtered_columns (line 124) | def filtered_columns
function expected_headers (line 128) | def expected_headers
FILE: spec/services/failed_import_csv_service_spec.rb
function create_file (line 17) | def create_file(content: csv_string, mtime: Time.current)
FILE: spec/support/api_helper.rb
type ApiHelper (line 1) | module ApiHelper
function app (line 4) | def app
FILE: spec/support/case_court_report_helpers.rb
type CaseCourtReportHelpers (line 4) | module CaseCourtReportHelpers
function open_court_report_modal (line 7) | def open_court_report_modal
function open_case_select2_dropdown (line 14) | def open_case_select2_dropdown
FILE: spec/support/datatable_helper.rb
type DatatableHelper (line 1) | module DatatableHelper
function datatable_params (line 2) | def datatable_params(order_by:, additional_filters: {}, order_directio...
function described_class (line 19) | def described_class
function escaped (line 26) | def escaped(value)
FILE: spec/support/download_helpers.rb
type DownloadHelpers (line 1) | module DownloadHelpers
function downloads (line 5) | def downloads
function download (line 9) | def download
function download_content (line 13) | def download_content
function download_docx (line 18) | def download_docx
function header_text (line 23) | def header_text(download_docx)
function table_text (line 34) | def table_text(download_docx)
function download_file_name (line 38) | def download_file_name
function wait_for_download (line 42) | def wait_for_download
function downloaded? (line 48) | def downloaded?
function downloading? (line 52) | def downloading?
function clear_downloads (line 56) | def clear_downloads
FILE: spec/support/factory_bot.rb
function described_class_factory (line 3) | def described_class_factory
FILE: spec/support/fill_in_case_contact_fields.rb
type FillInCaseContactFields (line 1) | module FillInCaseContactFields
function fill_in_contact_details (line 10) | def fill_in_contact_details(case_numbers: [], contact_types: [], conta...
function fill_in_notes (line 55) | def fill_in_notes(notes: nil, contact_topic_answers_attrs: [])
function fill_in_mileage (line 72) | def fill_in_mileage(miles: 0, want_reimbursement: false, address: nil)
function choose_medium (line 83) | def choose_medium(medium)
function check_reimbursement (line 87) | def check_reimbursement(want_reimbursement = true)
function fill_expense_fields (line 95) | def fill_expense_fields(amount, describe, index: nil)
function answer_topic (line 104) | def answer_topic(question, answer, index: nil)
function answer_topic_unscoped (line 113) | def answer_topic_unscoped(question, answer, index: nil)
FILE: spec/support/pretender_context.rb
type PretenderContext (line 1) | module PretenderContext
function true_user (line 2) | def true_user
FILE: spec/support/prosopite.rb
function create (line 38) | def create(*args, **kwargs, &block)
function use_prosopite? (line 64) | def use_prosopite?(example)
FILE: spec/support/pundit_helper.rb
type PunditHelper (line 1) | module PunditHelper
function enable_pundit (line 2) | def enable_pundit(view, user)
FILE: spec/support/request_helpers.rb
type Support (line 1) | module Support
type RequestHelpers (line 2) | module RequestHelpers
function response_json (line 3) | def response_json
FILE: spec/support/session_helper.rb
type SessionHelper (line 1) | module SessionHelper
function sign_in_as_admin (line 2) | def sign_in_as_admin
function sign_in_as_volunteer (line 6) | def sign_in_as_volunteer
function sign_in_as_supervisor (line 11) | def sign_in_as_supervisor
function sign_in_as_all_casa_admin (line 16) | def sign_in_as_all_casa_admin
FILE: spec/support/stubbed_requests/short_io_api.rb
type ShortIOAPI (line 1) | module ShortIOAPI
function short_io_stub (line 2) | def short_io_stub(base_url = "https://www.google.com")
function short_io_stub_sms (line 17) | def short_io_stub_sms
function short_io_error_stub (line 31) | def short_io_error_stub
function short_io_stub_localhost (line 39) | def short_io_stub_localhost(base_url = "http://localhost:3000/case_con...
function short_io_court_report_due_date_stub (line 54) | def short_io_court_report_due_date_stub(base_url = "http://localhost:3...
FILE: spec/support/stubbed_requests/twilio_api.rb
type TwilioAPI (line 1) | module TwilioAPI
function twilio_success_stub_messages_60_days (line 2) | def twilio_success_stub_messages_60_days
function twilio_success_stub (line 15) | def twilio_success_stub
function twilio_activation_success_stub (line 27) | def twilio_activation_success_stub(resource = "")
function twilio_activation_error_stub (line 38) | def twilio_activation_error_stub(resource = "")
function twilio_court_report_due_date_stub (line 49) | def twilio_court_report_due_date_stub(resource = "")
function twilio_no_contact_made_stub (line 62) | def twilio_no_contact_made_stub(resource = "")
function twilio_password_reset_stub (line 74) | def twilio_password_reset_stub(resource)
FILE: spec/support/stubbed_requests/webmock_helper.rb
class WebMockHelper (line 4) | class WebMockHelper
FILE: spec/support/twilio_helper.rb
type TwilioHelper (line 1) | module TwilioHelper
function stub_twilio (line 2) | def stub_twilio
FILE: spec/support/user_input_helpers.rb
class UserInputHelpers (line 1) | class UserInputHelpers
FILE: spec/system/all_casa_admins/edit_spec.rb
function expect_password_section_hidden (line 25) | def expect_password_section_hidden
function expect_password_section_visible (line 29) | def expect_password_section_visible
FILE: spec/system/casa_cases/edit_spec.rb
function sign_in_and_assign_volunteer (line 310) | def sign_in_and_assign_volunteer
FILE: spec/system/case_contacts/contact_topic_answers_spec.rb
function notes_section (line 26) | def notes_section
FILE: spec/system/devise/passwords/new_spec.rb
function reset_password_link (line 100) | def reset_password_link(email_address)
FILE: spec/system/judges/new_spec.rb
function submit_judge_form (line 81) | def submit_judge_form(name:, active: true)
FILE: spec/system/reports/index_spec.rb
function select_report_filter_option (line 209) | def select_report_filter_option(select_id, option)
function set_report_date_range (line 214) | def set_report_date_range(start_date:, end_date:)
function choose_report_radio_option (line 219) | def choose_report_radio_option(field_name, value)
Condensed preview — 1723 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,488K chars).
[
{
"path": ".allow_skipping_tests",
"chars": 0,
"preview": ""
},
{
"path": ".better-html.yml",
"chars": 11,
"preview": "# defaults\n"
},
{
"path": ".browserslistrc",
"chars": 9,
"preview": "defaults\n"
},
{
"path": ".devcontainer/Dockerfile",
"chars": 162,
"preview": "FROM mcr.microsoft.com/devcontainers/ruby:dev-3.3-bookworm\nRUN apt-get update && apt-get install -y vim curl gpg postgre"
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 891,
"preview": "// For format details, see https://aka.ms/devcontainer.json. For config options, see the\n// README at: https://github.co"
},
{
"path": ".devcontainer/docker-compose.yml",
"chars": 748,
"preview": "version: \"3.8\"\n\nservices:\n app:\n build:\n context: ..\n dockerfile: .devcontainer/Dockerfile\n\n volumes:\n "
},
{
"path": ".devcontainer/post-create.sh",
"chars": 435,
"preview": "RUBY_VERSION=\"$(cat .ruby-version | tr -d '\\n')\"\n\n# copy the file only if it doesn't already exist\ncp -n .devcontainer/."
},
{
"path": ".dockerignore",
"chars": 206,
"preview": "/.bundle\n\n/log/*\n/tmp/*\n!/log/.keep\n!/tmp/.keep\n\n/storage/*\n!/storage/.keep\n\n/public/assets\n.byebug_history\n\n/config/mas"
},
{
"path": ".erb_lint.yml",
"chars": 271,
"preview": "EnableDefaultLinters: true\nexclude:\n - '**/vendor/**/*'\nlinters:\n ErbSafety:\n enabled: true\n better_html_config:"
},
{
"path": ".github/CODEOWNERS",
"chars": 237,
"preview": "# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/ab"
},
{
"path": ".github/FUNDING.yml",
"chars": 642,
"preview": "# These are supported funding model platforms\n\ngithub: [rubyforgood]\npatreon: # Replace with a single Patreon username\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 1459,
"preview": "---\nname: 🪲Bug report\nabout: 🔨What needs fixing? ✨\ntitle: \"Bug: \"\nlabels: [\"Type: Bug\", \"Help Wanted\"]\n---\n\n## Impacted "
},
{
"path": ".github/ISSUE_TEMPLATE/chore.md",
"chars": 435,
"preview": "**Description**\n\n**Existing gem(s), file(s) needing updating, changing or deleting**\n\n**New file(s) needing creating**\n\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 587,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: 📄Documentation addition/change\n about: 🔨What needs documenting? "
},
{
"path": ".github/ISSUE_TEMPLATE/documentation.md",
"chars": 405,
"preview": "**Description**\n\n**Existing file(s) needing changing**\n\n**New file(s) needing creating**\n\n### Questions? Join Slack!\n\nWe"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 1076,
"preview": "---\nname: 💡Feature request\nabout: 🔨What needs building? ✨ \nlabels: [\"✨ New Feature\", \"Help Wanted\"]\n---\n\n## What type(s)"
},
{
"path": ".github/ISSUE_TEMPLATE/flaky_test.md",
"chars": 715,
"preview": "---\nname: Flaky Test\nabout: one of the tests is inconsistent and likely producing false positives\ntitle: \"Bug: Flaky Tes"
},
{
"path": ".github/ISSUE_TEMPLATE/problem_validation.md",
"chars": 716,
"preview": "Please use this template to document problems mentioned by CASA stakeholders so we make the best decisions for the solut"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 924,
"preview": "### What github issue is this PR for, if any?\nResolves #XXXX\n\n### What changed, and _why_?\n\n\n### How is this **tested**?"
},
{
"path": ".github/autoapproval.yml",
"chars": 35,
"preview": "from_owner:\n - dependabot-preview\n"
},
{
"path": ".github/dependabot.yml",
"chars": 913,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/instructions/copilot-review.instructions.md",
"chars": 5842,
"preview": "---\napplyTo: \"**\"\n---\n\n# CASA Code Review Instructions\n\nYou are reviewing pull requests for CASA (Court Appointed Specia"
},
{
"path": ".github/instructions/ruby.instructions.md",
"chars": 5829,
"preview": "---\napplyTo: \"**/*.rb\"\n---\n\n# Ruby / Rails Review Instructions\n\n## Authorization (Pundit)\n\nEvery controller action that "
},
{
"path": ".github/labeler.yml",
"chars": 1065,
"preview": "# Configuration for the Labeler action\n# The action is set up in ./workflows/label.yml\n# See https://github.com/actions/"
},
{
"path": ".github/workflows/add-labels-based-on-column.yml",
"chars": 1440,
"preview": "on:\n schedule:\n # * is a special character in YAML so you have to quote this string\n - cron: '0 * * * *'\n workfl"
},
{
"path": ".github/workflows/after-deploy.yml",
"chars": 489,
"preview": "on:\n schedule:\n - cron: '0 7 * * *' # Run every day at 7AM UTC\n workflow_dispatch: # Enable Manual Runs\n\njobs:\n "
},
{
"path": ".github/workflows/codeql-analysis.yml",
"chars": 2531,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/combine_and_report.yml",
"chars": 1665,
"preview": "on:\n workflow_call:\njobs:\n combine_and_report:\n runs-on: ubuntu-latest\n env:\n AZURE_STORAGE_KEY: ${{ secret"
},
{
"path": ".github/workflows/docker.yml",
"chars": 1310,
"preview": "name: docker\n\non:\n push:\n branches:\n - main\n paths-ignore:\n - \"doc/**\"\n - \"**/*.md\"\n pull_request"
},
{
"path": ".github/workflows/erb_lint.yml",
"chars": 487,
"preview": "name: ERB lint\n\non:\n push:\n branches:\n - main\n paths:\n - '**/*.erb'\n - '**/*.html'\n pull_request:"
},
{
"path": ".github/workflows/factory_bot_lint.yml",
"chars": 1372,
"preview": "name: factory bot lint\n\non:\n push:\n branches:\n - main\n paths-ignore:\n - 'doc/**'\n - '**/*.md'\n "
},
{
"path": ".github/workflows/issue-auto-close-done.yml",
"chars": 302,
"preview": "name: 'Close issue when Done'\n\non:\n project_card:\n types: [moved]\n\njobs:\n set-state:\n runs-on: ubuntu-latest\n "
},
{
"path": ".github/workflows/issue-auto-unassign.yml",
"chars": 1385,
"preview": "on:\n schedule:\n # * is a special character in YAML so you have to quote this string\n - cron: '0 0 * * *'\n workfl"
},
{
"path": ".github/workflows/label.yml",
"chars": 444,
"preview": "# This workflow will triage pull requests and apply a label based on the\n# paths that are modified in the pull request.\n"
},
{
"path": ".github/workflows/npm_lint_and_test.yml",
"chars": 635,
"preview": "name: npm lint\n\non:\n push:\n branches:\n - main\n paths:\n - '**/*.js'\n - '**/*.json'\n - '**/*.js"
},
{
"path": ".github/workflows/rake-after_party.yml",
"chars": 1405,
"preview": "name: Run rake after_party\n\non:\n push:\n branches:\n - main\n paths-ignore:\n - \"doc/**\"\n - \"**/*.md\"\n"
},
{
"path": ".github/workflows/remove-helped-wanted.yml",
"chars": 251,
"preview": "name: Remove Help Wanted Label on Issue Assignment\n\non:\n issues:\n types: [assigned]\n\njobs:\n automate-issues-labels:"
},
{
"path": ".github/workflows/remove-label-based-on-column.yml",
"chars": 1411,
"preview": "on:\n schedule:\n # * is a special character in YAML so you have to quote this string\n - cron: '0 * * * *'\n workfl"
},
{
"path": ".github/workflows/rspec.yml",
"chars": 2314,
"preview": "name: rspec\n\non:\n push:\n branches:\n - main\n paths-ignore:\n - \"doc/**\"\n - \"**/*.md\"\n pull_request:"
},
{
"path": ".github/workflows/ruby_lint.yml",
"chars": 522,
"preview": "name: standardrb lint\n\non:\n push:\n branches:\n - main\n paths-ignore:\n - 'doc/**'\n - '**/*.md'\n "
},
{
"path": ".github/workflows/security.yml",
"chars": 516,
"preview": "name: brakeman\n\non:\n push:\n branches:\n - main\n paths-ignore:\n - 'doc/**'\n - '**/*.md'\n - 'bin"
},
{
"path": ".github/workflows/spec_checker.yml",
"chars": 538,
"preview": "name: spec checker\n\non:\n push:\n branches:\n - main\n paths-ignore:\n - 'doc/**'\n - '**/*.md'\n - "
},
{
"path": ".github/workflows/stale.yml",
"chars": 610,
"preview": "name: Mark stale issues and pull requests\n\non:\n schedule:\n - cron: \"30 1 * * *\"\n\njobs:\n stale:\n\n runs-on: ubuntu-l"
},
{
"path": ".github/workflows/toc.yml",
"chars": 228,
"preview": "on:\n push:\n branches:\n - main\nname: TOC Generator\njobs:\n generateTOC:\n name: TOC Generator\n runs-on: ubu"
},
{
"path": ".github/workflows/yaml_lint.yml",
"chars": 431,
"preview": "name: Yaml Lint\non:\n push:\n branches:\n - main\n paths-ignore:\n - 'doc/**'\n - '**/*.md'\n pull_reque"
},
{
"path": ".gitignore",
"chars": 1122,
"preview": "# See https://help.github.com/articles/ignoring-files for more about ignoring files.\n#\n# If you find yourself ignoring t"
},
{
"path": ".npmrc",
"chars": 18,
"preview": "engine-strict=true"
},
{
"path": ".nvmrc",
"chars": 12,
"preview": "lts/krypton\n"
},
{
"path": ".prettierrc.yml",
"chars": 16,
"preview": "printWidth: 100\n"
},
{
"path": ".rspec",
"chars": 22,
"preview": "--require spec_helper\n"
},
{
"path": ".rspec_parallel",
"chars": 314,
"preview": "--format RspecJunitFormatter --out tmp/reports/rspec_<%= ENV[\"GROUPS_UNDERSCORE\"] %>_<%= ENV[\"TEST_ENV_NUMBER\"] %>.xml\n-"
},
{
"path": ".rubocop.yml",
"chars": 168,
"preview": "require:\n - standard\n\nplugins:\n - rubocop-capybara\n - rubocop-factory_bot\n - rubocop-rspec\n - rubocop-rspec_rails\n\n"
},
{
"path": ".ruby-gemset",
"chars": 4,
"preview": "casa"
},
{
"path": ".ruby-version",
"chars": 6,
"preview": "4.0.2\n"
},
{
"path": ".slugignore",
"chars": 16,
"preview": "*.md\n/docs\n/spec"
},
{
"path": ".standard.yml",
"chars": 381,
"preview": "extend_config:\n - .rubocop.yml\n\nplugins:\n - standard-rails\n\nignore:\n - 'storage/**/*'\n - 'db/migrate/2020*.rb'\n - '"
},
{
"path": ".standard_todo.yml",
"chars": 8118,
"preview": "# Auto generated files with errors to ignore.\n# Remove from this list as you refactor files.\n---\nignore:\n- app/controlle"
},
{
"path": ".tool-versions",
"chars": 26,
"preview": "ruby 4.0.2\nnodejs 24.13.0\n"
},
{
"path": ".yamllint.yml",
"chars": 484,
"preview": "extends: default\n\nignore:\n - .standard_todo.yml # generated by standard\n - .git\n - node_modules\n\nrules:\n document-s"
},
{
"path": "CONTRIBUTING.md",
"chars": 70,
"preview": "[Please press here if you want to contribute!](./doc/CONTRIBUTING.md)\n"
},
{
"path": "DEPLOY_CHECKLIST.md",
"chars": 62,
"preview": "See https://github.com/rubyforgood/casa/wiki/deploy-checklist\n"
},
{
"path": "Dockerfile",
"chars": 1123,
"preview": "ARG ROOT=/usr/src/app/\n\n# available alpine packages: https://pkgs.alpinelinux.org/packages\n\nFROM node:24-alpine AS node-"
},
{
"path": "Gemfile",
"chars": 5569,
"preview": "# frozen_string_literal: true\n\nsource \"https://rubygems.org\"\n\nruby \"4.0.2\"\ngem \"rails\", \"~> 7.2\"\n\ngem \"after_party\" # Po"
},
{
"path": "LICENSE.md",
"chars": 1080,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2020 Ruby for Good\n\nPermission is hereby granted, free of charge, to any person obt"
},
{
"path": "PROSOPITE_TODO.md",
"chars": 5423,
"preview": "# Prosopite N+1 Query Issues\n\nIssues detected by Prosopite during test suite run. Fix by adding eager loading (`includes"
},
{
"path": "Procfile",
"chars": 124,
"preview": "release: bundle exec rake db:migrate && bundle exec rake after_party:run\nweb: bundle exec puma\ncustom_web: bundle exec p"
},
{
"path": "Procfile.dev",
"chars": 106,
"preview": "web: bin/rails server -p 3000 -b 0.0.0.0\njs: npm run build:dev --watch\ncss: npm run build:css:dev --watch\n"
},
{
"path": "README.md",
"chars": 15412,
"preview": "# CASA Project and Organization Overview\n\n[](http"
},
{
"path": "Rakefile",
"chars": 316,
"preview": "# Add your own tasks in files placed in lib/tasks ending in .rake,\n# for example lib/tasks/capistrano.rake, and they wil"
},
{
"path": "SECURITY.md",
"chars": 42,
"preview": "See [doc/SECURITY.md](./doc/SECURITY.md) 💖"
},
{
"path": "app/assets/builds/.keep",
"chars": 0,
"preview": ""
},
{
"path": "app/assets/config/manifest.js",
"chars": 143,
"preview": "//= link_directory ../builds .css\n//= link_directory ../builds .js\n//= link_tree ../images\n//= link_tree ../fonts\n//= li"
},
{
"path": "app/assets/stylesheets/actiontext.css",
"chars": 1134,
"preview": "/*\n * Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and\n * the trix-editor con"
},
{
"path": "app/assets/stylesheets/android_app_associations.css",
"chars": 128,
"preview": "/*\n Place all the styles related to the matching controller here.\n They will automatically be included in application."
},
{
"path": "app/assets/stylesheets/application.scss",
"chars": 1320,
"preview": "// links to stylesheets inside node_modules\n@use \"bootstrap/scss/bootstrap.scss\" with (\n $primary: #00447c\n);\n@use \"boo"
},
{
"path": "app/assets/stylesheets/base/breakpoints.scss",
"chars": 196,
"preview": "$small: 640px;\n$medium: 1024px;\n$large: 1200px;\n\n// If you adjust this breakpoint, you also need to adjust the breakpoin"
},
{
"path": "app/assets/stylesheets/base/variables.scss",
"chars": 502,
"preview": "$primary: #00447c;\n$red: #dc3545;\n\n// ======== Sidebar colors\n$sidebar-inactive: #9AA4CA;\n$sidebar-active: #365CF5;\n$sid"
},
{
"path": "app/assets/stylesheets/pages/all_casa_admin_dashboard.scss",
"chars": 580,
"preview": ".dashboard, .all_casa_admins-dashboard {\n .container {\n @media (max-width: 1200px) {\n max-width: 95%;\n }\n }"
},
{
"path": "app/assets/stylesheets/pages/casa_cases.scss",
"chars": 3488,
"preview": "@use \"../base/breakpoints.scss\" as screen-sizes;\n\nbody.casa_cases {\n .form-header {\n h1 {\n display: inline-bloc"
},
{
"path": "app/assets/stylesheets/pages/casa_org.scss",
"chars": 56,
"preview": "#casa_org_logo{\n height: 2.7rem;\n overflow: hidden;\n}\n"
},
{
"path": "app/assets/stylesheets/pages/case_contacts.scss",
"chars": 2777,
"preview": ".slide-container {\n padding: 0rem 1rem;\n}\n\n.slider {\n display: inline;\n}\n\n.slider-row {\n margin: 0px;\n}\n\n.dataT"
},
{
"path": "app/assets/stylesheets/pages/case_contacts_form.scss",
"chars": 2682,
"preview": "@use \"../base/breakpoints.scss\" as screen-sizes;\n\n#case-contact-form {\n color: var(--gunmetal);\n\n & section {\n back"
},
{
"path": "app/assets/stylesheets/pages/case_court_reports.scss",
"chars": 0,
"preview": ""
},
{
"path": "app/assets/stylesheets/pages/court_dates.scss",
"chars": 292,
"preview": "body.court_dates {\n .court-orders {\n textarea {\n display: block;\n margin-bottom: 5px;\n }\n\n textarea,"
},
{
"path": "app/assets/stylesheets/pages/emancipation.scss",
"chars": 1448,
"preview": ".category-options {\n margin-left: 2em;\n\n input[type=\"checkbox\"], input[type=\"radio\"] {\n pointer-events: none\n }\n}\n"
},
{
"path": "app/assets/stylesheets/pages/feature_flags.scss",
"chars": 117,
"preview": "#feature-flags {\n padding-top: 1em;\n h1 {\n padding-bottom: 1em;\n }\n .flag-name {\n padding-right: 2em;\n }\n}"
},
{
"path": "app/assets/stylesheets/pages/login.scss",
"chars": 342,
"preview": "body.devise-sessions-new, body.users-sessions-new, body.devise-passwords-new {\n .container {\n max-width: none;\n }\n\n"
},
{
"path": "app/assets/stylesheets/pages/password.scss",
"chars": 923,
"preview": "@use \"../base/variables.scss\" as globals;\n\n.password-box {\n width: 80%;\n margin: 10% auto;\n text-align: center;\n bor"
},
{
"path": "app/assets/stylesheets/pages/patch_notes.scss",
"chars": 741,
"preview": "#patch-notes {\n display: flex;\n\n #patch-note-list {\n width: 50%;\n\n h1 {\n text-align: left;\n }\n\n .patc"
},
{
"path": "app/assets/stylesheets/pages/reimbursements.scss",
"chars": 158,
"preview": ".reimbursements-index {\n .select2-container {\n .select2-selection {\n max-height: 60px;\n overflow-y: auto;\n"
},
{
"path": "app/assets/stylesheets/pages/supervisors.scss",
"chars": 1571,
"preview": "$indictator_negative_color: #f44336;\n$indicator_positive_color: #4caf50;\n\n.supervisor_case_contact_stats {\n display: fl"
},
{
"path": "app/assets/stylesheets/pages/volunteers.scss",
"chars": 757,
"preview": "@use \"../base/breakpoints.scss\" as screen-sizes;\n\nbody.volunteers {\n @media only screen and (max-width: screen-sizes.$m"
},
{
"path": "app/assets/stylesheets/shared/dashboard.scss",
"chars": 518,
"preview": ".dashboard-table-header {\n h1,h2,h3,h4,h5,h6 {\n display: inline-block;\n margin-right: 15px;\n vertical-align: m"
},
{
"path": "app/assets/stylesheets/shared/data_tables_overide.scss",
"chars": 352,
"preview": "/**\n Needed to display the prev, next, number, and ellipsis buttons on the same line. This causes issues on mobile with"
},
{
"path": "app/assets/stylesheets/shared/flashes.scss",
"chars": 157,
"preview": ".notice {\n text-align: center;\n padding: 8px;\n margin: 12px 0;\n list-style-position: inside;\n}\n\n.alert-dismissible ."
},
{
"path": "app/assets/stylesheets/shared/footer.scss",
"chars": 1628,
"preview": "//@use \"../base/variables\" as globals;\n//@use \"../base/breakpoints.scss\" as screen-sizes;\n//\n//footer {\n// padding: 2re"
},
{
"path": "app/assets/stylesheets/shared/form.scss",
"chars": 443,
"preview": "@use \"../base/variables.scss\" as globals;\n\nform {\n .field_with_errors {\n label {\n @extend .text-danger !optiona"
},
{
"path": "app/assets/stylesheets/shared/header.scss",
"chars": 359,
"preview": "@use \"../base/breakpoints.scss\" as screen-sizes;\n\n.header {\n .header-left {\n .menu-toggle-btn {\n display: none;"
},
{
"path": "app/assets/stylesheets/shared/layout.scss",
"chars": 1803,
"preview": "@use \"../base/variables.scss\" as globals;\n@use \"../base/breakpoints.scss\" as screen-sizes;\n\nbody {\n background-color: #"
},
{
"path": "app/assets/stylesheets/shared/navbar.scss",
"chars": 500,
"preview": "@use \"../base/breakpoints.scss\" as screen-sizes;\n\n.navbar {\n color: #fff;\n background: #00447c;\n box-shadow: 0 0 4px "
},
{
"path": "app/assets/stylesheets/shared/noscript.css",
"chars": 120,
"preview": ".noscript {\n position: fixed;\n left: 50%;\n top: 25%;\n transform: translateX(-50%);\n padding: 5vw;\n z-index: 99;\n}\n"
},
{
"path": "app/assets/stylesheets/shared/notifier.scss",
"chars": 1546,
"preview": "@keyframes spin {\n 0% {\n transform: rotate(0deg)\n }\n 100% {\n transform: rotate(360deg)\n }\n}\n\n#notifications {\n"
},
{
"path": "app/assets/stylesheets/shared/select2_additional_styles.scss",
"chars": 49,
"preview": ".select2 {\n input {\n min-width: 250px;\n }\n}\n"
},
{
"path": "app/assets/stylesheets/shared/sidebar.scss",
"chars": 3970,
"preview": "@use \"../base/variables.scss\" as globals;\n@use \"../base/breakpoints.scss\" as screen-sizes;\n\n#wrapper {\n overflow-x: h"
},
{
"path": "app/assets/stylesheets/shared/tomselect_additional_styles.scss",
"chars": 72,
"preview": ".ts-dropdown [data-selectable] .highlight {\n display: inline-block;\n}"
},
{
"path": "app/assets/stylesheets/shared/truncated_text_component.scss",
"chars": 113,
"preview": ".truncation-container {\n display: flex;\n\n a {\n min-width: fit-content;\n margin-inline-start: auto;\n }\n}\n"
},
{
"path": "app/assets/stylesheets/shared/typography.scss",
"chars": 622,
"preview": "// TODO check in css so tests can run without internet\n@use \"../base/variables.scss\" as globals;\n@import url(https://fon"
},
{
"path": "app/assets/stylesheets/shared/utilities.scss",
"chars": 643,
"preview": "@use \"../base/variables.scss\" as globals;\n\n.pull-left {\n float: left;\n}\n\n.pull-right {\n float: right;\n}\n\n.vertically-c"
},
{
"path": "app/assets/stylesheets/shared/validated_form_component.scss",
"chars": 189,
"preview": ".warning-required-checkbox {\n background-color: #ffc107;\n padding: 0.5em;\n\n input[type=\"checkbox\"] {\n wi"
},
{
"path": "app/blueprints/api/v1/session_blueprint.rb",
"chars": 682,
"preview": "class Api::V1::SessionBlueprint < Blueprinter::Base\n field :user do |user|\n {\n id: user.id,\n display_name:"
},
{
"path": "app/callbacks/case_contact_metadata_callback.rb",
"chars": 748,
"preview": "class CaseContactMetadataCallback\n def after_commit(case_contact)\n changes = case_contact.saved_changes\n\n set_sta"
},
{
"path": "app/channels/application_cable/channel.rb",
"chars": 78,
"preview": "module ApplicationCable\n class Channel < ActionCable::Channel::Base; end\nend\n"
},
{
"path": "app/channels/application_cable/connection.rb",
"chars": 84,
"preview": "module ApplicationCable\n class Connection < ActionCable::Connection::Base; end\nend\n"
},
{
"path": "app/components/badge_component.html.erb",
"chars": 81,
"preview": "<span class='badge <%= style %> text-uppercase display-1'>\n <%= text %>\n</span>\n"
},
{
"path": "app/components/badge_component.rb",
"chars": 473,
"preview": "class BadgeComponent < ViewComponent::Base\n DARK_TEXT_TYPES = [:warning, :light]\n\n attr_reader :text\n\n def initialize"
},
{
"path": "app/components/dropdown_menu_component.html.erb",
"chars": 1632,
"preview": "<div class=\"dropdown <%= @class %>\">\n <button class=\"btn btn-secondary dropdown-toggle\" type=\"button\" data-bs-toggle=\"d"
},
{
"path": "app/components/dropdown_menu_component.rb",
"chars": 711,
"preview": "# frozen_string_literal: true\n\nclass DropdownMenuComponent < ViewComponent::Base\n renders_one :icon\n\n def initialize(m"
},
{
"path": "app/components/form/hour_minute_duration_component.html.erb",
"chars": 565,
"preview": "<div class=\"row input-style-1\">\n <div class=\"col-12 col-md\">\n <%= @form.label :duration_hours, \"Hour(s)\" %>\n <%= "
},
{
"path": "app/components/form/hour_minute_duration_component.rb",
"chars": 1290,
"preview": "# frozen_string_literal: true\n\nclass Form::HourMinuteDurationComponent < ViewComponent::Base\n def initialize(form:, hou"
},
{
"path": "app/components/form/multiple_select/item_component.html.erb",
"chars": 86,
"preview": "<div class=\"badge rounded-pill bg-primary active px-3\">\n ${escape(data.text)}\n</div>\n"
},
{
"path": "app/components/form/multiple_select/item_component.rb",
"chars": 127,
"preview": "# frozen_string_literal: true\n\nclass Form::MultipleSelect::ItemComponent < ViewComponent::Base\n strip_trailing_whitespa"
},
{
"path": "app/components/form/multiple_select_component.html.erb",
"chars": 1458,
"preview": "<div class=\"select-style-1 mr-8\"\n data-controller=\"multiple-select\"\n data-multiple-select-options-value=\"<%= @op"
},
{
"path": "app/components/form/multiple_select_component.rb",
"chars": 467,
"preview": "# frozen_string_literal: true\n\nclass Form::MultipleSelectComponent < ViewComponent::Base\n def initialize(form:, name:, "
},
{
"path": "app/components/local_time_component.html.erb",
"chars": 60,
"preview": "<span title=\"<%= specific_time %>\"><%= local_time %></span>\n"
},
{
"path": "app/components/local_time_component.rb",
"chars": 506,
"preview": "# frozen_string_literal: true\n\nclass LocalTimeComponent < ViewComponent::Base\n attr_reader :format, :unix_timestamp, :t"
},
{
"path": "app/components/modal/body_component.html.erb",
"chars": 68,
"preview": "<div class=\"modal-body <%= @class %>\">\n <%= body_content %>\n</div>\n"
},
{
"path": "app/components/modal/body_component.rb",
"chars": 450,
"preview": "# frozen_string_literal: true\n\nclass Modal::BodyComponent < ViewComponent::Base\n def initialize(text: nil, klass: nil, "
},
{
"path": "app/components/modal/footer_component.html.erb",
"chars": 161,
"preview": "<div class=\"modal-footer <%= @class %>\">\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" data-bs-dismiss=\"modal"
},
{
"path": "app/components/modal/footer_component.rb",
"chars": 252,
"preview": "# frozen_string_literal: true\n\nclass Modal::FooterComponent < ViewComponent::Base\n def initialize(klass: nil, render_ch"
},
{
"path": "app/components/modal/group_component.html.erb",
"chars": 291,
"preview": "<div class=\"modal fade <%= @class %>\" id=\"<%= @id %>\" tabindex=\"-1\" aria-labelledby=\"<%= @id %>-label\" aria-hidden=\"true"
},
{
"path": "app/components/modal/group_component.rb",
"chars": 422,
"preview": "# frozen_string_literal: true\n\nclass Modal::GroupComponent < ViewComponent::Base\n renders_one :header, Modal::HeaderCom"
},
{
"path": "app/components/modal/header_component.html.erb",
"chars": 167,
"preview": "<div class=\"modal-header <%= @class %>\">\n <%= header_content %>\n <button type=\"button\" class=\"btn-close\" data-bs-dismi"
},
{
"path": "app/components/modal/header_component.rb",
"chars": 598,
"preview": "# frozen_string_literal: true\n\nclass Modal::HeaderComponent < ViewComponent::Base\n def initialize(id:, text: nil, icon:"
},
{
"path": "app/components/modal/open_button_component.html.erb",
"chars": 213,
"preview": "<button type=\"button\" class=\"<%= @class %>\" data-bs-toggle=\"modal\" data-bs-target=\"<%= \"##{@target}\" %>\">\n <% if @icon "
},
{
"path": "app/components/modal/open_button_component.rb",
"chars": 437,
"preview": "# frozen_string_literal: true\n\nclass Modal::OpenButtonComponent < ViewComponent::Base\n def initialize(target:, text: ni"
},
{
"path": "app/components/modal/open_link_component.html.erb",
"chars": 214,
"preview": "<a href=\"#\" role=\"button\" class=\"btn <%= @class %>\" data-bs-toggle=\"modal\" data-bs-target=\"<%= \"##{@target}\" %>\">\n <% i"
},
{
"path": "app/components/modal/open_link_component.rb",
"chars": 433,
"preview": "# frozen_string_literal: true\n\nclass Modal::OpenLinkComponent < ViewComponent::Base\n def initialize(target:, text: nil,"
},
{
"path": "app/components/notification_component.html.erb",
"chars": 710,
"preview": "<a\n href=\"<%= mark_as_read_notification_path(notification) %>\"\n class=\"<%= muted_display %> list-group-item list-group"
},
{
"path": "app/components/notification_component.rb",
"chars": 260,
"preview": "# frozen_string_literal: true\n\nclass NotificationComponent < ViewComponent::Base\n attr_reader :notification\n\n def init"
},
{
"path": "app/components/sidebar/group_component.html.erb",
"chars": 750,
"preview": "<li class=\"nav-item nav-item-has-children group-item\" data-sidebar-target=\"groupList\" data-controller=\"sidebar-group\">\n "
},
{
"path": "app/components/sidebar/group_component.rb",
"chars": 783,
"preview": "# frozen_string_literal: true\n\nclass Sidebar::GroupComponent < ViewComponent::Base\n renders_many :links, Sidebar::LinkC"
},
{
"path": "app/components/sidebar/link_component.html.erb",
"chars": 270,
"preview": "<li class=\"<%= @class %>\" data-sidebar-group-target=\"link\">\n <%= link_to @path do %>\n <% if @icon %>\n <i class="
},
{
"path": "app/components/sidebar/link_component.rb",
"chars": 890,
"preview": "# frozen_string_literal: true\n\nclass Sidebar::LinkComponent < ViewComponent::Base\n include SidebarHelper\n\n # @param ti"
},
{
"path": "app/components/truncated_text_component.html.erb",
"chars": 558,
"preview": "<div class=\"truncation-container\" data-controller=\"truncated-text\">\n <div class=\"line-clamp-1\" data-truncated-text-targ"
},
{
"path": "app/components/truncated_text_component.rb",
"chars": 197,
"preview": "# frozen_string_literal: true\n\nclass TruncatedTextComponent < ViewComponent::Base\n attr_reader :text, :label\n def init"
},
{
"path": "app/controllers/additional_expenses_controller.rb",
"chars": 772,
"preview": "class AdditionalExpensesController < ApplicationController\n before_action :force_json_format\n\n def create\n @additio"
},
{
"path": "app/controllers/all_casa_admins/casa_admins_controller.rb",
"chars": 1808,
"preview": "class AllCasaAdmins::CasaAdminsController < AllCasaAdminsController\n before_action :set_casa_org\n\n def new\n @casa_a"
},
{
"path": "app/controllers/all_casa_admins/casa_orgs_controller.rb",
"chars": 997,
"preview": "class AllCasaAdmins::CasaOrgsController < AllCasaAdminsController\n def show\n @casa_org = CasaOrg.find(params[:id])\n "
},
{
"path": "app/controllers/all_casa_admins/dashboard_controller.rb",
"chars": 121,
"preview": "class AllCasaAdmins::DashboardController < AllCasaAdminsController\n def show\n @organizations = CasaOrg.all\n end\nend"
},
{
"path": "app/controllers/all_casa_admins/patch_notes_controller.rb",
"chars": 1526,
"preview": "class AllCasaAdmins::PatchNotesController < AllCasaAdminsController\n # GET /patch_notes or /patch_notes.json\n def inde"
},
{
"path": "app/controllers/all_casa_admins/sessions_controller.rb",
"chars": 174,
"preview": "# frozen_string_literal: true\n\nclass AllCasaAdmins::SessionsController < Devise::SessionsController\n include Accessible"
},
{
"path": "app/controllers/all_casa_admins_controller.rb",
"chars": 2748,
"preview": "class AllCasaAdminsController < ApplicationController\n skip_before_action :authenticate_user!\n before_action :authenti"
},
{
"path": "app/controllers/android_app_associations_controller.rb",
"chars": 486,
"preview": "class AndroidAppAssociationsController < ApplicationController\n skip_before_action :authenticate_user!\n\n def index\n "
},
{
"path": "app/controllers/api/v1/base_controller.rb",
"chars": 696,
"preview": "class Api::V1::BaseController < ActionController::API\n rescue_from ActiveRecord::RecordNotFound, with: :not_found\n bef"
},
{
"path": "app/controllers/api/v1/users/sessions_controller.rb",
"chars": 1197,
"preview": "class Api::V1::Users::SessionsController < Api::V1::BaseController\n def create\n load_resource\n if @user\n ren"
},
{
"path": "app/controllers/application_controller.rb",
"chars": 5419,
"preview": "class ApplicationController < ActionController::Base\n include Pundit::Authorization\n include Pagy::Backend\n include O"
},
{
"path": "app/controllers/banners_controller.rb",
"chars": 1723,
"preview": "class BannersController < ApplicationController\n after_action :verify_authorized, except: %i[dismiss]\n before_action :"
},
{
"path": "app/controllers/bulk_court_dates_controller.rb",
"chars": 1623,
"preview": "class BulkCourtDatesController < ApplicationController\n include CourtDateParams\n\n before_action :require_organization!"
},
{
"path": "app/controllers/casa_admins_controller.rb",
"chars": 4526,
"preview": "class CasaAdminsController < ApplicationController\n include SmsBodyHelper\n\n before_action :set_admin, except: [:index,"
},
{
"path": "app/controllers/casa_cases_controller.rb",
"chars": 6554,
"preview": "class CasaCasesController < ApplicationController\n before_action :set_casa_case, only: %i[show edit update deactivate r"
},
{
"path": "app/controllers/casa_org_controller.rb",
"chars": 3012,
"preview": "class CasaOrgController < ApplicationController\n before_action :set_casa_org, only: %i[edit update]\n before_action :se"
},
{
"path": "app/controllers/case_assignments_controller.rb",
"chars": 4398,
"preview": "class CaseAssignmentsController < ApplicationController\n before_action :load_case_assignment, only: %i[destroy unassign"
},
{
"path": "app/controllers/case_contact_reports_controller.rb",
"chars": 1419,
"preview": "require \"csv\"\n\nclass CaseContactReportsController < ApplicationController\n after_action :verify_authorized\n\n def index"
},
{
"path": "app/controllers/case_contacts/case_contacts_new_design_controller.rb",
"chars": 593,
"preview": "class CaseContacts::CaseContactsNewDesignController < ApplicationController\n include LoadsCaseContacts\n\n before_action"
},
{
"path": "app/controllers/case_contacts/followups_controller.rb",
"chars": 1036,
"preview": "class CaseContacts::FollowupsController < ApplicationController\n after_action :verify_authorized\n\n def create\n auth"
},
{
"path": "app/controllers/case_contacts/form_controller.rb",
"chars": 5372,
"preview": "class CaseContacts::FormController < ApplicationController\n include Wicked::Wizard\n\n before_action :require_organizati"
},
{
"path": "app/controllers/case_contacts_controller.rb",
"chars": 3135,
"preview": "# frozen_string_literal: true\n\nclass CaseContactsController < ApplicationController\n include LoadsCaseContacts\n\n befor"
},
{
"path": "app/controllers/case_court_orders_controller.rb",
"chars": 433,
"preview": "class CaseCourtOrdersController < ApplicationController\n before_action :set_case_court_order, only: %i[destroy]\n befor"
},
{
"path": "app/controllers/case_court_reports_controller.rb",
"chars": 3618,
"preview": "# frozen_string_literal: true\n\nclass CaseCourtReportsController < ApplicationController\n before_action :set_casa_case, "
},
{
"path": "app/controllers/case_groups_controller.rb",
"chars": 1302,
"preview": "class CaseGroupsController < ApplicationController\n before_action :require_organization!\n before_action :set_case_grou"
},
{
"path": "app/controllers/checklist_items_controller.rb",
"chars": 1805,
"preview": "class ChecklistItemsController < ApplicationController\n before_action :authorize_checklist_item\n before_action :set_he"
},
{
"path": "app/controllers/concerns/accessible.rb",
"chars": 609,
"preview": "module Accessible\n extend ActiveSupport::Concern\n\n included do\n before_action :check_user\n end\n\n protected\n\n def"
},
{
"path": "app/controllers/concerns/court_date_params.rb",
"chars": 753,
"preview": "module CourtDateParams\n private\n\n def sanitized_court_date_params(casa_case)\n params.require(:court_date).tap do |p"
},
{
"path": "app/controllers/concerns/loads_case_contacts.rb",
"chars": 1305,
"preview": "module LoadsCaseContacts\n extend ActiveSupport::Concern\n\n private\n\n def load_case_contacts\n authorize CaseContact\n"
},
{
"path": "app/controllers/concerns/organizational.rb",
"chars": 556,
"preview": "module Organizational\n extend ActiveSupport::Concern\n\n class UnknownOrganization < StandardError\n end\n\n def require_"
},
{
"path": "app/controllers/concerns/users/time_zone.rb",
"chars": 904,
"preview": "module Users\n module TimeZone\n extend ActiveSupport::Concern\n\n included do\n helper_method :browser_time_zone"
},
{
"path": "app/controllers/contact_topic_answers_controller.rb",
"chars": 791,
"preview": "class ContactTopicAnswersController < ApplicationController\n before_action :force_json_format\n\n def create\n @contac"
},
{
"path": "app/controllers/contact_topics_controller.rb",
"chars": 1780,
"preview": "class ContactTopicsController < ApplicationController\n before_action :set_contact_topic, only: %i[edit update soft_dele"
},
{
"path": "app/controllers/contact_type_groups_controller.rb",
"chars": 1194,
"preview": "class ContactTypeGroupsController < ApplicationController\n before_action :set_contact_type_group, except: [:new, :creat"
},
{
"path": "app/controllers/contact_types_controller.rb",
"chars": 1060,
"preview": "class ContactTypesController < ApplicationController\n before_action :set_contact_type, except: [:new, :create]\n after_"
},
{
"path": "app/controllers/court_dates_controller.rb",
"chars": 3016,
"preview": "class CourtDatesController < ApplicationController\n include CourtDateParams\n\n before_action :set_casa_case\n before_ac"
},
{
"path": "app/controllers/custom_org_links_controller.rb",
"chars": 1309,
"preview": "class CustomOrgLinksController < ApplicationController\n before_action :set_custom_org_link, only: %i[edit update destro"
},
{
"path": "app/controllers/dashboard_controller.rb",
"chars": 603,
"preview": "class DashboardController < ApplicationController\n before_action :require_organization!\n after_action :verify_authoriz"
},
{
"path": "app/controllers/emancipation_checklists_controller.rb",
"chars": 552,
"preview": "class EmancipationChecklistsController < ApplicationController\n include DateHelper\n before_action :require_organizatio"
},
{
"path": "app/controllers/emancipations_controller.rb",
"chars": 3647,
"preview": "class EmancipationsController < ApplicationController\n before_action :require_organization!\n after_action :verify_auth"
},
{
"path": "app/controllers/error_controller.rb",
"chars": 268,
"preview": "# frozen_string_literal: true\n\nclass ErrorController < ApplicationController\n skip_before_action :authenticate_user!\n "
},
{
"path": "app/controllers/followup_reports_controller.rb",
"chars": 452,
"preview": "# frozen_string_literal: true\n\nclass FollowupReportsController < ApplicationController\n after_action :verify_authorized"
},
{
"path": "app/controllers/fund_requests_controller.rb",
"chars": 1088,
"preview": "class FundRequestsController < ApplicationController\n before_action :verify_casa_case\n after_action :verify_authorized"
},
{
"path": "app/controllers/health_controller.rb",
"chars": 4036,
"preview": "class HealthController < ApplicationController\n skip_before_action :authenticate_user!\n skip_after_action :verify_auth"
},
{
"path": "app/controllers/hearing_types_controller.rb",
"chars": 1086,
"preview": "class HearingTypesController < ApplicationController\n before_action :set_hearing_type, except: [:new, :create]\n after_"
},
{
"path": "app/controllers/imports_controller.rb",
"chars": 4703,
"preview": "class ImportsController < ApplicationController\n require \"csv\"\n\n include ActionView::Helpers::UrlHelper\n before_actio"
},
{
"path": "app/controllers/judges_controller.rb",
"chars": 945,
"preview": "class JudgesController < ApplicationController\n before_action :set_judge, except: [:new, :create]\n after_action :verif"
},
{
"path": "app/controllers/languages_controller.rb",
"chars": 1142,
"preview": "class LanguagesController < ApplicationController\n before_action :set_language, only: %i[edit update]\n\n def new\n au"
},
{
"path": "app/controllers/learning_hour_topics_controller.rb",
"chars": 1238,
"preview": "# frozen_string_literal: true\n\nclass LearningHourTopicsController < ApplicationController\n before_action :set_learning_"
},
{
"path": "app/controllers/learning_hour_types_controller.rb",
"chars": 1226,
"preview": "# frozen_string_literal: true\n\nclass LearningHourTypesController < ApplicationController\n before_action :set_learning_h"
},
{
"path": "app/controllers/learning_hours/volunteers_controller.rb",
"chars": 354,
"preview": "class LearningHours::VolunteersController < ApplicationController\n before_action :set_volunteer, only: :show\n after_ac"
},
{
"path": "app/controllers/learning_hours_controller.rb",
"chars": 1936,
"preview": "class LearningHoursController < ApplicationController\n before_action :set_learning_hour, only: %i[show edit update dest"
},
{
"path": "app/controllers/learning_hours_reports_controller.rb",
"chars": 441,
"preview": "class LearningHoursReportsController < ApplicationController\n after_action :verify_authorized\n\n def index\n authoriz"
},
{
"path": "app/controllers/mileage_rates_controller.rb",
"chars": 1128,
"preview": "class MileageRatesController < ApplicationController\n after_action :verify_authorized\n before_action :set_mileage_rate"
},
{
"path": "app/controllers/mileage_reports_controller.rb",
"chars": 454,
"preview": "# frozen_string_literal: true\n\nrequire \"csv\"\n\nclass MileageReportsController < ApplicationController\n after_action :ver"
}
]
// ... and 1523 more files (download for full content)
About this extraction
This page contains the full source code of the rubyforgood/casa GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1723 files (62.6 MB), approximately 894.4k tokens, and a symbol index with 2395 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.