rails-metro 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +17 -0
  3. data/LICENSE +21 -0
  4. data/README.md +267 -0
  5. data/exe/metro +3 -0
  6. data/lib/rails/metro/cli.rb +162 -0
  7. data/lib/rails/metro/config.rb +40 -0
  8. data/lib/rails/metro/feature_pack.rb +59 -0
  9. data/lib/rails/metro/feature_registry.rb +147 -0
  10. data/lib/rails/metro/packs/aasm_pack.rb +29 -0
  11. data/lib/rails/metro/packs/ab_testing_pack.rb +39 -0
  12. data/lib/rails/metro/packs/action_text_pack.rb +29 -0
  13. data/lib/rails/metro/packs/activeadmin_pack.rb +32 -0
  14. data/lib/rails/metro/packs/activity_feed_pack.rb +31 -0
  15. data/lib/rails/metro/packs/acts_as_list_pack.rb +28 -0
  16. data/lib/rails/metro/packs/acts_as_votable_pack.rb +32 -0
  17. data/lib/rails/metro/packs/administrate_pack.rb +31 -0
  18. data/lib/rails/metro/packs/after_party_pack.rb +31 -0
  19. data/lib/rails/metro/packs/ahoy_pack.rb +31 -0
  20. data/lib/rails/metro/packs/amplitude_pack.rb +45 -0
  21. data/lib/rails/metro/packs/annotate_pack.rb +30 -0
  22. data/lib/rails/metro/packs/api_cors_pack.rb +41 -0
  23. data/lib/rails/metro/packs/api_docs_pack.rb +34 -0
  24. data/lib/rails/metro/packs/api_guard_pack.rb +31 -0
  25. data/lib/rails/metro/packs/api_serialization_pack.rb +38 -0
  26. data/lib/rails/metro/packs/app_linting_pack.rb +35 -0
  27. data/lib/rails/metro/packs/audit_trail_pack.rb +31 -0
  28. data/lib/rails/metro/packs/authentication_pack.rb +31 -0
  29. data/lib/rails/metro/packs/authorization_pack.rb +31 -0
  30. data/lib/rails/metro/packs/avo_pack.rb +32 -0
  31. data/lib/rails/metro/packs/aws_ses_pack.rb +45 -0
  32. data/lib/rails/metro/packs/background_jobs_pack.rb +34 -0
  33. data/lib/rails/metro/packs/blazer_pack.rb +62 -0
  34. data/lib/rails/metro/packs/breadcrumbs_pack.rb +31 -0
  35. data/lib/rails/metro/packs/caching_pack.rb +30 -0
  36. data/lib/rails/metro/packs/charting_pack.rb +67 -0
  37. data/lib/rails/metro/packs/circuit_breaker_pack.rb +34 -0
  38. data/lib/rails/metro/packs/clicky_pack.rb +37 -0
  39. data/lib/rails/metro/packs/cloudinary_pack.rb +42 -0
  40. data/lib/rails/metro/packs/components_pack.rb +30 -0
  41. data/lib/rails/metro/packs/counter_culture_pack.rb +29 -0
  42. data/lib/rails/metro/packs/data_migrate_pack.rb +29 -0
  43. data/lib/rails/metro/packs/datadog_pack.rb +41 -0
  44. data/lib/rails/metro/packs/deployment_pack.rb +30 -0
  45. data/lib/rails/metro/packs/devise_pack.rb +33 -0
  46. data/lib/rails/metro/packs/doorkeeper_pack.rb +32 -0
  47. data/lib/rails/metro/packs/dotenv_pack.rb +36 -0
  48. data/lib/rails/metro/packs/elasticsearch_pack.rb +31 -0
  49. data/lib/rails/metro/packs/encryption_pack.rb +37 -0
  50. data/lib/rails/metro/packs/error_tracking_pack.rb +40 -0
  51. data/lib/rails/metro/packs/event_sourcing_pack.rb +31 -0
  52. data/lib/rails/metro/packs/faraday_pack.rb +42 -0
  53. data/lib/rails/metro/packs/fathom_pack.rb +36 -0
  54. data/lib/rails/metro/packs/feature_flags_pack.rb +34 -0
  55. data/lib/rails/metro/packs/friendly_id_pack.rb +31 -0
  56. data/lib/rails/metro/packs/geocoder_pack.rb +38 -0
  57. data/lib/rails/metro/packs/good_job_pack.rb +34 -0
  58. data/lib/rails/metro/packs/google_analytics_pack.rb +42 -0
  59. data/lib/rails/metro/packs/google_tag_manager_pack.rb +51 -0
  60. data/lib/rails/metro/packs/graphql_pack.rb +31 -0
  61. data/lib/rails/metro/packs/health_check_pack.rb +34 -0
  62. data/lib/rails/metro/packs/heap_pack.rb +39 -0
  63. data/lib/rails/metro/packs/honeybadger_pack.rb +37 -0
  64. data/lib/rails/metro/packs/hotwire_livereload_pack.rb +28 -0
  65. data/lib/rails/metro/packs/icons_pack.rb +28 -0
  66. data/lib/rails/metro/packs/invisible_captcha_pack.rb +35 -0
  67. data/lib/rails/metro/packs/kredis_pack.rb +31 -0
  68. data/lib/rails/metro/packs/lemon_squeezy_pack.rb +36 -0
  69. data/lib/rails/metro/packs/letter_opener_pack.rb +31 -0
  70. data/lib/rails/metro/packs/letter_opener_web_pack.rb +32 -0
  71. data/lib/rails/metro/packs/logging_pack.rb +36 -0
  72. data/lib/rails/metro/packs/madmin_pack.rb +32 -0
  73. data/lib/rails/metro/packs/mailgun_pack.rb +44 -0
  74. data/lib/rails/metro/packs/maintenance_mode_pack.rb +30 -0
  75. data/lib/rails/metro/packs/maintenance_tasks_pack.rb +32 -0
  76. data/lib/rails/metro/packs/markdown_pack.rb +48 -0
  77. data/lib/rails/metro/packs/matomo_pack.rb +48 -0
  78. data/lib/rails/metro/packs/meilisearch_pack.rb +37 -0
  79. data/lib/rails/metro/packs/mixpanel_pack.rb +47 -0
  80. data/lib/rails/metro/packs/mobility_pack.rb +32 -0
  81. data/lib/rails/metro/packs/mollie_pack.rb +36 -0
  82. data/lib/rails/metro/packs/multitenancy_pack.rb +35 -0
  83. data/lib/rails/metro/packs/newrelic_pack.rb +52 -0
  84. data/lib/rails/metro/packs/notifications_pack.rb +31 -0
  85. data/lib/rails/metro/packs/omniauth_pack.rb +49 -0
  86. data/lib/rails/metro/packs/paddle_pack.rb +37 -0
  87. data/lib/rails/metro/packs/pagination_pack.rb +44 -0
  88. data/lib/rails/metro/packs/passwordless_pack.rb +32 -0
  89. data/lib/rails/metro/packs/payments_pack.rb +35 -0
  90. data/lib/rails/metro/packs/paypal_pack.rb +35 -0
  91. data/lib/rails/metro/packs/pdf_pack.rb +45 -0
  92. data/lib/rails/metro/packs/performance_pack.rb +37 -0
  93. data/lib/rails/metro/packs/pghero_pack.rb +31 -0
  94. data/lib/rails/metro/packs/plausible_pack.rb +36 -0
  95. data/lib/rails/metro/packs/posthog_pack.rb +40 -0
  96. data/lib/rails/metro/packs/postmark_pack.rb +39 -0
  97. data/lib/rails/metro/packs/pretender_pack.rb +33 -0
  98. data/lib/rails/metro/packs/profiling_pack.rb +30 -0
  99. data/lib/rails/metro/packs/pundit_pack.rb +50 -0
  100. data/lib/rails/metro/packs/qr_code_pack.rb +37 -0
  101. data/lib/rails/metro/packs/r2_storage_pack.rb +48 -0
  102. data/lib/rails/metro/packs/rack_timeout_pack.rb +34 -0
  103. data/lib/rails/metro/packs/rails_i18n_pack.rb +31 -0
  104. data/lib/rails/metro/packs/ransack_pack.rb +29 -0
  105. data/lib/rails/metro/packs/rate_limiting_pack.rb +39 -0
  106. data/lib/rails/metro/packs/recaptcha_pack.rb +38 -0
  107. data/lib/rails/metro/packs/resend_pack.rb +37 -0
  108. data/lib/rails/metro/packs/revenuecat_pack.rb +36 -0
  109. data/lib/rails/metro/packs/rolify_pack.rb +32 -0
  110. data/lib/rails/metro/packs/rollbar_pack.rb +38 -0
  111. data/lib/rails/metro/packs/s3_storage_pack.rb +45 -0
  112. data/lib/rails/metro/packs/scenic_pack.rb +28 -0
  113. data/lib/rails/metro/packs/scheduling_pack.rb +46 -0
  114. data/lib/rails/metro/packs/search_pack.rb +32 -0
  115. data/lib/rails/metro/packs/security_pack.rb +30 -0
  116. data/lib/rails/metro/packs/sendgrid_pack.rb +44 -0
  117. data/lib/rails/metro/packs/sent_dm_pack.rb +36 -0
  118. data/lib/rails/metro/packs/seo_pack.rb +40 -0
  119. data/lib/rails/metro/packs/shoulda_matchers_pack.rb +37 -0
  120. data/lib/rails/metro/packs/sidekiq_pack.rb +42 -0
  121. data/lib/rails/metro/packs/simple_calendar_pack.rb +29 -0
  122. data/lib/rails/metro/packs/simple_form_pack.rb +30 -0
  123. data/lib/rails/metro/packs/simplecov_pack.rb +38 -0
  124. data/lib/rails/metro/packs/slack_notifier_pack.rb +36 -0
  125. data/lib/rails/metro/packs/soft_deletes_pack.rb +30 -0
  126. data/lib/rails/metro/packs/solidus_pack.rb +31 -0
  127. data/lib/rails/metro/packs/spreadsheets_pack.rb +29 -0
  128. data/lib/rails/metro/packs/statcounter_pack.rb +41 -0
  129. data/lib/rails/metro/packs/stimulus_components_pack.rb +33 -0
  130. data/lib/rails/metro/packs/storage_validations_pack.rb +28 -0
  131. data/lib/rails/metro/packs/strong_migrations_pack.rb +30 -0
  132. data/lib/rails/metro/packs/tagging_pack.rb +31 -0
  133. data/lib/rails/metro/packs/test_mocking_pack.rb +41 -0
  134. data/lib/rails/metro/packs/testing_pack.rb +39 -0
  135. data/lib/rails/metro/packs/twilio_pack.rb +38 -0
  136. data/lib/rails/metro/packs/vite_rails_pack.rb +31 -0
  137. data/lib/rails/metro/packs/web_push_pack.rb +39 -0
  138. data/lib/rails/metro/packs/webhooks_pack.rb +45 -0
  139. data/lib/rails/metro/packs/websockets_pack.rb +29 -0
  140. data/lib/rails/metro/template_compiler.rb +85 -0
  141. data/lib/rails/metro/tui/app.rb +119 -0
  142. data/lib/rails/metro/tui/steps/app_name_step.rb +57 -0
  143. data/lib/rails/metro/tui/steps/database_step.rb +53 -0
  144. data/lib/rails/metro/tui/steps/pack_step.rb +248 -0
  145. data/lib/rails/metro/tui/steps/review_step.rb +94 -0
  146. data/lib/rails/metro/tui/styles.rb +47 -0
  147. data/lib/rails/metro/tui.rb +37 -0
  148. data/lib/rails/metro/version.rb +5 -0
  149. data/lib/rails/metro.rb +9 -0
  150. metadata +206 -0
@@ -0,0 +1,32 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SearchPack < FeaturePack
5
+ pack_name "search"
6
+ description "pg_search for PostgreSQL full-text search"
7
+ category "data"
8
+ conflicts_with "meilisearch", "elasticsearch"
9
+
10
+ def gems
11
+ [
12
+ {name: "pg_search", version: "~> 2.3"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'rails_command "generate pg_search:migration:multisearch"'
19
+ ]
20
+ end
21
+
22
+ def post_install_notes
23
+ [
24
+ "Search: Run `bin/rails db:migrate` to create pg_search tables",
25
+ "Search: Add `include PgSearch::Model` to models you want to search",
26
+ "Search: Requires PostgreSQL database"
27
+ ]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SecurityPack < FeaturePack
5
+ pack_name "security"
6
+ description "Brakeman + bundler-audit for security scanning"
7
+ category "ops"
8
+
9
+ def gems
10
+ [
11
+ {name: "brakeman", group: :development},
12
+ {name: "bundler-audit", group: :development}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ []
18
+ end
19
+
20
+ def post_install_notes
21
+ [
22
+ "Security: Run `bundle exec brakeman` to scan for vulnerabilities",
23
+ "Security: Run `bundle exec bundler-audit check --update` to check gem CVEs",
24
+ "Security: Add both to CI for continuous security checks"
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,44 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SendgridPack < FeaturePack
5
+ pack_name "sendgrid"
6
+ description "SendGrid for transactional and marketing email delivery"
7
+ category "notifications"
8
+
9
+ def gems
10
+ [
11
+ {name: "sendgrid-ruby"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'create_file "config/initializers/sendgrid.rb", <<~RUBY',
18
+ " ActionMailer::Base.smtp_settings = {",
19
+ ' user_name: "apikey",',
20
+ ' password: Rails.application.credentials.dig(:sendgrid, :api_key) || ENV["SENDGRID_API_KEY"],',
21
+ ' domain: Rails.application.credentials.dig(:sendgrid, :domain) || "example.com",',
22
+ ' address: "smtp.sendgrid.net",',
23
+ " port: 587,",
24
+ " authentication: :plain,",
25
+ " enable_starttls_auto: true",
26
+ " }",
27
+ "RUBY",
28
+ "",
29
+ 'environment "config.action_mailer.delivery_method = :smtp", env: "production"'
30
+ ]
31
+ end
32
+
33
+ def post_install_notes
34
+ [
35
+ "SendGrid: Add your API key with `bin/rails credentials:edit`:",
36
+ " sendgrid:",
37
+ " api_key: SG.your_api_key_here",
38
+ " domain: yourdomain.com"
39
+ ]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SentDmPack < FeaturePack
5
+ pack_name "sent_dm"
6
+ description "Sent.dm for multi-channel message delivery (email, SMS, push)"
7
+ category "notifications"
8
+
9
+ def gems
10
+ [
11
+ {name: "sent_dm"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'create_file "config/initializers/sent_dm.rb", <<~RUBY',
18
+ " SentDm.configure do |config|",
19
+ ' config.api_key = Rails.application.credentials.dig(:sent_dm, :api_key) || ENV["SENT_DM_API_KEY"]',
20
+ " end",
21
+ "RUBY"
22
+ ]
23
+ end
24
+
25
+ def post_install_notes
26
+ [
27
+ "Sent.dm: Add your API key with `bin/rails credentials:edit`:",
28
+ " sent_dm:",
29
+ " api_key: your_api_key_here",
30
+ "Sent.dm: Supports email, SMS, and push notifications from a single API"
31
+ ]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SeoPack < FeaturePack
5
+ pack_name "seo"
6
+ description "meta-tags + sitemap_generator for SEO"
7
+ category "seo"
8
+
9
+ def gems
10
+ [
11
+ {name: "meta-tags", version: "~> 2.22"},
12
+ {name: "sitemap_generator", version: "~> 6.3"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'create_file "config/sitemap.rb", <<~RUBY',
19
+ ' SitemapGenerator::Sitemap.default_host = "https://example.com"',
20
+ "",
21
+ " SitemapGenerator::Sitemap.create do",
22
+ ' add "/about", changefreq: "monthly"',
23
+ " end",
24
+ "RUBY",
25
+ 'inject_into_file "app/views/layouts/application.html.erb", after: "<head>\\n" do',
26
+ ' " <%= display_meta_tags site: \\"My App\\" %>\\n"',
27
+ "end"
28
+ ]
29
+ end
30
+
31
+ def post_install_notes
32
+ [
33
+ "SEO: Use `set_meta_tags title: \"Page\"` in controllers",
34
+ "SEO: Generate sitemap with `bin/rails sitemap:refresh`"
35
+ ]
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class ShouldaMatchersPack < FeaturePack
5
+ pack_name "shoulda_matchers"
6
+ description "Shoulda Matchers for one-liner model and controller test assertions"
7
+ category "testing"
8
+
9
+ def gems
10
+ [
11
+ {name: "shoulda-matchers", group: :test}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'create_file "test/support/shoulda_matchers.rb", <<~RUBY',
18
+ " Shoulda::Matchers.configure do |config|",
19
+ " config.integrate do |with|",
20
+ " with.test_framework :minitest",
21
+ " with.library :rails",
22
+ " end",
23
+ " end",
24
+ "RUBY"
25
+ ]
26
+ end
27
+
28
+ def post_install_notes
29
+ [
30
+ "Shoulda: Use `should validate_presence_of(:name)` in model tests",
31
+ "Shoulda: Use `should belong_to(:user)` for association tests"
32
+ ]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SidekiqPack < FeaturePack
5
+ pack_name "sidekiq"
6
+ description "Sidekiq for Redis-backed background jobs (high throughput)"
7
+ category "core"
8
+ conflicts_with "background_jobs", "good_job"
9
+
10
+ def gems
11
+ [
12
+ {name: "sidekiq", version: "~> 7.0"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ [
18
+ 'environment "config.active_job.queue_adapter = :sidekiq"',
19
+ "",
20
+ 'create_file "config/sidekiq.yml", <<~YML',
21
+ " :concurrency: 5",
22
+ " :queues:",
23
+ " - default",
24
+ " - mailers",
25
+ "YML",
26
+ "",
27
+ 'route "require \\"sidekiq/web\\"',
28
+ " mount Sidekiq::Web => \\\"/sidekiq\\\"\""
29
+ ]
30
+ end
31
+
32
+ def post_install_notes
33
+ [
34
+ "Sidekiq: Requires Redis -- install and run `redis-server`",
35
+ "Sidekiq: Start worker with `bundle exec sidekiq`",
36
+ "Sidekiq: Monitor jobs at /sidekiq"
37
+ ]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,29 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SimpleCalendarPack < FeaturePack
5
+ pack_name "simple_calendar"
6
+ description "Simple Calendar for month/week/day calendar views"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "simple_calendar", version: "~> 3.0"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ []
17
+ end
18
+
19
+ def post_install_notes
20
+ [
21
+ "Simple Calendar: Use `<%= month_calendar events: @events do |date, events| %>` in views",
22
+ "Simple Calendar: Models need a `start_time` attribute (or configure with `attribute: :my_date`)",
23
+ "Simple Calendar: Supports month_calendar, week_calendar, and custom ranges"
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SimpleFormPack < FeaturePack
5
+ pack_name "simple_form"
6
+ description "Simple Form for easy, flexible form building"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "simple_form"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "generate simple_form:install"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "Simple Form: Use `<%= simple_form_for @user do |f| %>` in views",
24
+ "Simple Form: Customize wrappers in config/initializers/simple_form.rb"
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SimplecovPack < FeaturePack
5
+ pack_name "simplecov"
6
+ description "SimpleCov for code coverage reporting"
7
+ category "testing"
8
+
9
+ def gems
10
+ [
11
+ {name: "simplecov", group: :test}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'prepend_to_file "test/test_helper.rb", <<~RUBY',
18
+ ' require "simplecov"',
19
+ " SimpleCov.start \"rails\" do",
20
+ ' add_filter "/test/"',
21
+ ' add_filter "/config/"',
22
+ " enable_coverage :branch",
23
+ " end",
24
+ "",
25
+ "RUBY"
26
+ ]
27
+ end
28
+
29
+ def post_install_notes
30
+ [
31
+ "SimpleCov: Coverage report generated at coverage/index.html after running tests",
32
+ "SimpleCov: Branch coverage enabled by default"
33
+ ]
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,36 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SlackNotifierPack < FeaturePack
5
+ pack_name "slack_notifier"
6
+ description "Slack Notifier for sending webhook notifications to Slack"
7
+ category "notifications"
8
+
9
+ def gems
10
+ [
11
+ {name: "slack-notifier"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'create_file "config/initializers/slack.rb", <<~RUBY',
18
+ " SLACK_NOTIFIER = Slack::Notifier.new(",
19
+ ' Rails.application.credentials.dig(:slack, :webhook_url) || ENV["SLACK_WEBHOOK_URL"]',
20
+ " )",
21
+ "RUBY"
22
+ ]
23
+ end
24
+
25
+ def post_install_notes
26
+ [
27
+ "Slack: Add your webhook URL with `bin/rails credentials:edit`:",
28
+ " slack:",
29
+ " webhook_url: https://hooks.slack.com/services/...",
30
+ "Slack: Send with `SLACK_NOTIFIER.ping(\"Hello from Rails!\")`"
31
+ ]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SoftDeletesPack < FeaturePack
5
+ pack_name "soft_deletes"
6
+ description "Discard for soft deletes (archive instead of destroy)"
7
+ category "data"
8
+
9
+ def gems
10
+ [
11
+ {name: "discard", version: "~> 1.3"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ []
17
+ end
18
+
19
+ def post_install_notes
20
+ [
21
+ "Discard: Add `include Discard::Model` to models",
22
+ "Discard: Add `discarded_at:datetime` column via migration",
23
+ "Discard: Use `record.discard` instead of `record.destroy`",
24
+ "Discard: Query with `User.kept` and `User.discarded`"
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SolidusPack < FeaturePack
5
+ pack_name "solidus"
6
+ description "Solidus for full-featured e-commerce (products, orders, payments)"
7
+ category "payments"
8
+
9
+ def gems
10
+ [
11
+ {name: "solidus"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "generate solidus:install --auto-accept"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "Solidus: Run `bin/rails db:migrate` and `bin/rails db:seed` to set up",
24
+ "Solidus: Admin panel at /admin (default: admin@example.com / test123)",
25
+ "Solidus: See https://solidus.io/docs for customization guides"
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class SpreadsheetsPack < FeaturePack
5
+ pack_name "spreadsheets"
6
+ description "Caxlsx for Excel spreadsheet generation"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "caxlsx"},
12
+ {name: "caxlsx_rails"}
13
+ ]
14
+ end
15
+
16
+ def template_lines
17
+ []
18
+ end
19
+
20
+ def post_install_notes
21
+ [
22
+ "Spreadsheets: Create .xlsx templates in app/views with `.xlsx.axlsx` extension",
23
+ "Spreadsheets: Use `format.xlsx` in controllers to serve Excel downloads"
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class StatcounterPack < FeaturePack
5
+ pack_name "statcounter"
6
+ description "StatCounter for visitor stats and web analytics"
7
+ category "analytics"
8
+
9
+ def gems
10
+ []
11
+ end
12
+
13
+ def template_lines
14
+ [
15
+ 'create_file "app/views/layouts/_statcounter.html.erb", <<~ERB',
16
+ " <script type=\"text/javascript\">",
17
+ " var sc_project=<%%= Rails.application.credentials.dig(:statcounter, :project_id) || ENV[\"STATCOUNTER_PROJECT_ID\"] %>;",
18
+ " var sc_invisible=1;",
19
+ " var sc_security=\"<%%= Rails.application.credentials.dig(:statcounter, :security_code) || ENV[\"STATCOUNTER_SECURITY\"] %>\";",
20
+ " </script>",
21
+ ' <script type="text/javascript" src="https://www.statcounter.com/counter/counter.js" async></script>',
22
+ "ERB",
23
+ "",
24
+ 'inject_into_file "app/views/layouts/application.html.erb", before: "</body>" do',
25
+ ' " <%= render \\"layouts/statcounter\\" %>\\n"',
26
+ "end"
27
+ ]
28
+ end
29
+
30
+ def post_install_notes
31
+ [
32
+ "StatCounter: Add your project credentials with `bin/rails credentials:edit`:",
33
+ " statcounter:",
34
+ " project_id: 12345678",
35
+ " security_code: your_security_code"
36
+ ]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class StimulusComponentsPack < FeaturePack
5
+ pack_name "stimulus_components"
6
+ description "Stimulus Components -- pre-built Stimulus controllers (dropdowns, modals, etc.)"
7
+ category "ui"
8
+
9
+ def gems
10
+ [
11
+ {name: "stimulus-rails"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'append_to_file "config/importmap.rb", <<~RUBY',
18
+ ' pin "stimulus-use", to: "https://ga.jspm.io/npm:stimulus-use/dist/index.js"',
19
+ ' pin "stimulus-components", to: "https://ga.jspm.io/npm:stimulus-components/dist/index.js"',
20
+ "RUBY"
21
+ ]
22
+ end
23
+
24
+ def post_install_notes
25
+ [
26
+ "Stimulus Components: Pre-built controllers for dropdowns, modals, tabs, clipboard, etc.",
27
+ "Stimulus Components: See https://www.stimulus-components.com for full list"
28
+ ]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class StorageValidationsPack < FeaturePack
5
+ pack_name "storage_validations"
6
+ description "Active Storage Validations for file type, size, and dimension checks"
7
+ category "data"
8
+
9
+ def gems
10
+ [
11
+ {name: "active_storage_validations"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ []
17
+ end
18
+
19
+ def post_install_notes
20
+ [
21
+ "Storage Validations: Use `validates :avatar, attached: true, content_type: :image` in models",
22
+ "Storage Validations: Supports size, dimension, aspect ratio, and content type validations"
23
+ ]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class StrongMigrationsPack < FeaturePack
5
+ pack_name "strong_migrations"
6
+ description "Strong Migrations -- catch unsafe migrations before they run"
7
+ category "data"
8
+
9
+ def gems
10
+ [
11
+ {name: "strong_migrations"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "generate strong_migrations:install"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "Strong Migrations: Dangerous migrations will raise errors with safe alternatives",
24
+ "Strong Migrations: Use `safety_assured { }` to override when you know it's safe"
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module Rails
2
+ module Metro
3
+ module Packs
4
+ class TaggingPack < FeaturePack
5
+ pack_name "tagging"
6
+ description "Acts As Taggable On for tagging models"
7
+ category "data"
8
+
9
+ def gems
10
+ [
11
+ {name: "acts-as-taggable-on", version: "~> 11.0"}
12
+ ]
13
+ end
14
+
15
+ def template_lines
16
+ [
17
+ 'rails_command "acts_as_taggable_on_engine:install:migrations"'
18
+ ]
19
+ end
20
+
21
+ def post_install_notes
22
+ [
23
+ "Tagging: Run `bin/rails db:migrate` to create tag tables",
24
+ "Tagging: Add `acts_as_taggable_on :tags` to models",
25
+ "Tagging: Use `@post.tag_list.add(\"ruby\", \"rails\")`"
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end