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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +17 -0
- data/LICENSE +21 -0
- data/README.md +267 -0
- data/exe/metro +3 -0
- data/lib/rails/metro/cli.rb +162 -0
- data/lib/rails/metro/config.rb +40 -0
- data/lib/rails/metro/feature_pack.rb +59 -0
- data/lib/rails/metro/feature_registry.rb +147 -0
- data/lib/rails/metro/packs/aasm_pack.rb +29 -0
- data/lib/rails/metro/packs/ab_testing_pack.rb +39 -0
- data/lib/rails/metro/packs/action_text_pack.rb +29 -0
- data/lib/rails/metro/packs/activeadmin_pack.rb +32 -0
- data/lib/rails/metro/packs/activity_feed_pack.rb +31 -0
- data/lib/rails/metro/packs/acts_as_list_pack.rb +28 -0
- data/lib/rails/metro/packs/acts_as_votable_pack.rb +32 -0
- data/lib/rails/metro/packs/administrate_pack.rb +31 -0
- data/lib/rails/metro/packs/after_party_pack.rb +31 -0
- data/lib/rails/metro/packs/ahoy_pack.rb +31 -0
- data/lib/rails/metro/packs/amplitude_pack.rb +45 -0
- data/lib/rails/metro/packs/annotate_pack.rb +30 -0
- data/lib/rails/metro/packs/api_cors_pack.rb +41 -0
- data/lib/rails/metro/packs/api_docs_pack.rb +34 -0
- data/lib/rails/metro/packs/api_guard_pack.rb +31 -0
- data/lib/rails/metro/packs/api_serialization_pack.rb +38 -0
- data/lib/rails/metro/packs/app_linting_pack.rb +35 -0
- data/lib/rails/metro/packs/audit_trail_pack.rb +31 -0
- data/lib/rails/metro/packs/authentication_pack.rb +31 -0
- data/lib/rails/metro/packs/authorization_pack.rb +31 -0
- data/lib/rails/metro/packs/avo_pack.rb +32 -0
- data/lib/rails/metro/packs/aws_ses_pack.rb +45 -0
- data/lib/rails/metro/packs/background_jobs_pack.rb +34 -0
- data/lib/rails/metro/packs/blazer_pack.rb +62 -0
- data/lib/rails/metro/packs/breadcrumbs_pack.rb +31 -0
- data/lib/rails/metro/packs/caching_pack.rb +30 -0
- data/lib/rails/metro/packs/charting_pack.rb +67 -0
- data/lib/rails/metro/packs/circuit_breaker_pack.rb +34 -0
- data/lib/rails/metro/packs/clicky_pack.rb +37 -0
- data/lib/rails/metro/packs/cloudinary_pack.rb +42 -0
- data/lib/rails/metro/packs/components_pack.rb +30 -0
- data/lib/rails/metro/packs/counter_culture_pack.rb +29 -0
- data/lib/rails/metro/packs/data_migrate_pack.rb +29 -0
- data/lib/rails/metro/packs/datadog_pack.rb +41 -0
- data/lib/rails/metro/packs/deployment_pack.rb +30 -0
- data/lib/rails/metro/packs/devise_pack.rb +33 -0
- data/lib/rails/metro/packs/doorkeeper_pack.rb +32 -0
- data/lib/rails/metro/packs/dotenv_pack.rb +36 -0
- data/lib/rails/metro/packs/elasticsearch_pack.rb +31 -0
- data/lib/rails/metro/packs/encryption_pack.rb +37 -0
- data/lib/rails/metro/packs/error_tracking_pack.rb +40 -0
- data/lib/rails/metro/packs/event_sourcing_pack.rb +31 -0
- data/lib/rails/metro/packs/faraday_pack.rb +42 -0
- data/lib/rails/metro/packs/fathom_pack.rb +36 -0
- data/lib/rails/metro/packs/feature_flags_pack.rb +34 -0
- data/lib/rails/metro/packs/friendly_id_pack.rb +31 -0
- data/lib/rails/metro/packs/geocoder_pack.rb +38 -0
- data/lib/rails/metro/packs/good_job_pack.rb +34 -0
- data/lib/rails/metro/packs/google_analytics_pack.rb +42 -0
- data/lib/rails/metro/packs/google_tag_manager_pack.rb +51 -0
- data/lib/rails/metro/packs/graphql_pack.rb +31 -0
- data/lib/rails/metro/packs/health_check_pack.rb +34 -0
- data/lib/rails/metro/packs/heap_pack.rb +39 -0
- data/lib/rails/metro/packs/honeybadger_pack.rb +37 -0
- data/lib/rails/metro/packs/hotwire_livereload_pack.rb +28 -0
- data/lib/rails/metro/packs/icons_pack.rb +28 -0
- data/lib/rails/metro/packs/invisible_captcha_pack.rb +35 -0
- data/lib/rails/metro/packs/kredis_pack.rb +31 -0
- data/lib/rails/metro/packs/lemon_squeezy_pack.rb +36 -0
- data/lib/rails/metro/packs/letter_opener_pack.rb +31 -0
- data/lib/rails/metro/packs/letter_opener_web_pack.rb +32 -0
- data/lib/rails/metro/packs/logging_pack.rb +36 -0
- data/lib/rails/metro/packs/madmin_pack.rb +32 -0
- data/lib/rails/metro/packs/mailgun_pack.rb +44 -0
- data/lib/rails/metro/packs/maintenance_mode_pack.rb +30 -0
- data/lib/rails/metro/packs/maintenance_tasks_pack.rb +32 -0
- data/lib/rails/metro/packs/markdown_pack.rb +48 -0
- data/lib/rails/metro/packs/matomo_pack.rb +48 -0
- data/lib/rails/metro/packs/meilisearch_pack.rb +37 -0
- data/lib/rails/metro/packs/mixpanel_pack.rb +47 -0
- data/lib/rails/metro/packs/mobility_pack.rb +32 -0
- data/lib/rails/metro/packs/mollie_pack.rb +36 -0
- data/lib/rails/metro/packs/multitenancy_pack.rb +35 -0
- data/lib/rails/metro/packs/newrelic_pack.rb +52 -0
- data/lib/rails/metro/packs/notifications_pack.rb +31 -0
- data/lib/rails/metro/packs/omniauth_pack.rb +49 -0
- data/lib/rails/metro/packs/paddle_pack.rb +37 -0
- data/lib/rails/metro/packs/pagination_pack.rb +44 -0
- data/lib/rails/metro/packs/passwordless_pack.rb +32 -0
- data/lib/rails/metro/packs/payments_pack.rb +35 -0
- data/lib/rails/metro/packs/paypal_pack.rb +35 -0
- data/lib/rails/metro/packs/pdf_pack.rb +45 -0
- data/lib/rails/metro/packs/performance_pack.rb +37 -0
- data/lib/rails/metro/packs/pghero_pack.rb +31 -0
- data/lib/rails/metro/packs/plausible_pack.rb +36 -0
- data/lib/rails/metro/packs/posthog_pack.rb +40 -0
- data/lib/rails/metro/packs/postmark_pack.rb +39 -0
- data/lib/rails/metro/packs/pretender_pack.rb +33 -0
- data/lib/rails/metro/packs/profiling_pack.rb +30 -0
- data/lib/rails/metro/packs/pundit_pack.rb +50 -0
- data/lib/rails/metro/packs/qr_code_pack.rb +37 -0
- data/lib/rails/metro/packs/r2_storage_pack.rb +48 -0
- data/lib/rails/metro/packs/rack_timeout_pack.rb +34 -0
- data/lib/rails/metro/packs/rails_i18n_pack.rb +31 -0
- data/lib/rails/metro/packs/ransack_pack.rb +29 -0
- data/lib/rails/metro/packs/rate_limiting_pack.rb +39 -0
- data/lib/rails/metro/packs/recaptcha_pack.rb +38 -0
- data/lib/rails/metro/packs/resend_pack.rb +37 -0
- data/lib/rails/metro/packs/revenuecat_pack.rb +36 -0
- data/lib/rails/metro/packs/rolify_pack.rb +32 -0
- data/lib/rails/metro/packs/rollbar_pack.rb +38 -0
- data/lib/rails/metro/packs/s3_storage_pack.rb +45 -0
- data/lib/rails/metro/packs/scenic_pack.rb +28 -0
- data/lib/rails/metro/packs/scheduling_pack.rb +46 -0
- data/lib/rails/metro/packs/search_pack.rb +32 -0
- data/lib/rails/metro/packs/security_pack.rb +30 -0
- data/lib/rails/metro/packs/sendgrid_pack.rb +44 -0
- data/lib/rails/metro/packs/sent_dm_pack.rb +36 -0
- data/lib/rails/metro/packs/seo_pack.rb +40 -0
- data/lib/rails/metro/packs/shoulda_matchers_pack.rb +37 -0
- data/lib/rails/metro/packs/sidekiq_pack.rb +42 -0
- data/lib/rails/metro/packs/simple_calendar_pack.rb +29 -0
- data/lib/rails/metro/packs/simple_form_pack.rb +30 -0
- data/lib/rails/metro/packs/simplecov_pack.rb +38 -0
- data/lib/rails/metro/packs/slack_notifier_pack.rb +36 -0
- data/lib/rails/metro/packs/soft_deletes_pack.rb +30 -0
- data/lib/rails/metro/packs/solidus_pack.rb +31 -0
- data/lib/rails/metro/packs/spreadsheets_pack.rb +29 -0
- data/lib/rails/metro/packs/statcounter_pack.rb +41 -0
- data/lib/rails/metro/packs/stimulus_components_pack.rb +33 -0
- data/lib/rails/metro/packs/storage_validations_pack.rb +28 -0
- data/lib/rails/metro/packs/strong_migrations_pack.rb +30 -0
- data/lib/rails/metro/packs/tagging_pack.rb +31 -0
- data/lib/rails/metro/packs/test_mocking_pack.rb +41 -0
- data/lib/rails/metro/packs/testing_pack.rb +39 -0
- data/lib/rails/metro/packs/twilio_pack.rb +38 -0
- data/lib/rails/metro/packs/vite_rails_pack.rb +31 -0
- data/lib/rails/metro/packs/web_push_pack.rb +39 -0
- data/lib/rails/metro/packs/webhooks_pack.rb +45 -0
- data/lib/rails/metro/packs/websockets_pack.rb +29 -0
- data/lib/rails/metro/template_compiler.rb +85 -0
- data/lib/rails/metro/tui/app.rb +119 -0
- data/lib/rails/metro/tui/steps/app_name_step.rb +57 -0
- data/lib/rails/metro/tui/steps/database_step.rb +53 -0
- data/lib/rails/metro/tui/steps/pack_step.rb +248 -0
- data/lib/rails/metro/tui/steps/review_step.rb +94 -0
- data/lib/rails/metro/tui/styles.rb +47 -0
- data/lib/rails/metro/tui.rb +37 -0
- data/lib/rails/metro/version.rb +5 -0
- data/lib/rails/metro.rb +9 -0
- metadata +206 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class DatadogPack < FeaturePack
|
|
5
|
+
pack_name "datadog"
|
|
6
|
+
description "Datadog APM for tracing, metrics, and log management"
|
|
7
|
+
category "ops"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "datadog"}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'create_file "config/initializers/datadog.rb", <<~RUBY',
|
|
18
|
+
" Datadog.configure do |c|",
|
|
19
|
+
" c.service = Rails.application.class.module_parent_name.underscore",
|
|
20
|
+
" c.env = Rails.env",
|
|
21
|
+
"",
|
|
22
|
+
" c.tracing.instrument :rails",
|
|
23
|
+
" c.tracing.instrument :http",
|
|
24
|
+
" c.tracing.instrument :active_record",
|
|
25
|
+
" c.tracing.instrument :redis if defined?(Redis)",
|
|
26
|
+
" c.tracing.instrument :sidekiq if defined?(Sidekiq)",
|
|
27
|
+
" end",
|
|
28
|
+
"RUBY"
|
|
29
|
+
]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def post_install_notes
|
|
33
|
+
[
|
|
34
|
+
"Datadog: Install the Datadog Agent on your server (not a Ruby gem)",
|
|
35
|
+
"Datadog: Set DD_API_KEY and DD_ENV environment variables in production"
|
|
36
|
+
]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class DeploymentPack < FeaturePack
|
|
5
|
+
pack_name "deployment"
|
|
6
|
+
description "Kamal for zero-downtime deploys to any Linux box"
|
|
7
|
+
category "ops"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "kamal", version: "~> 2.0"}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'rails_command "generate kamal"'
|
|
18
|
+
]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def post_install_notes
|
|
22
|
+
[
|
|
23
|
+
"Deployment: Edit config/deploy.yml with your server details",
|
|
24
|
+
"Deployment: Run `kamal setup` to provision, then `kamal deploy`"
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class DevisePack < FeaturePack
|
|
5
|
+
pack_name "devise"
|
|
6
|
+
description "Devise for full-featured authentication (OmniAuth, LDAP, etc.)"
|
|
7
|
+
category "core"
|
|
8
|
+
conflicts_with "authentication", "passwordless"
|
|
9
|
+
|
|
10
|
+
def gems
|
|
11
|
+
[
|
|
12
|
+
{name: "devise"}
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def template_lines
|
|
17
|
+
[
|
|
18
|
+
'rails_command "generate devise:install"',
|
|
19
|
+
'rails_command "generate devise User"'
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def post_install_notes
|
|
24
|
+
[
|
|
25
|
+
"Devise: Run `bin/rails db:migrate` to create users table",
|
|
26
|
+
"Devise: Generate views with `bin/rails g devise:views`",
|
|
27
|
+
"Devise: Configure mailer sender in config/initializers/devise.rb"
|
|
28
|
+
]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class DoorkeeperPack < FeaturePack
|
|
5
|
+
pack_name "doorkeeper"
|
|
6
|
+
description "Doorkeeper for OAuth2 provider (issue tokens, authorize apps)"
|
|
7
|
+
category "api"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "doorkeeper"}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'rails_command "generate doorkeeper:install"',
|
|
18
|
+
'rails_command "generate doorkeeper:migration"'
|
|
19
|
+
]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def post_install_notes
|
|
23
|
+
[
|
|
24
|
+
"Doorkeeper: Run `bin/rails db:migrate` to create OAuth tables",
|
|
25
|
+
"Doorkeeper: Configure resource owner in config/initializers/doorkeeper.rb",
|
|
26
|
+
"Doorkeeper: Manage OAuth apps at /oauth/applications"
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class DotenvPack < FeaturePack
|
|
5
|
+
pack_name "dotenv"
|
|
6
|
+
description "Dotenv for loading .env files in development"
|
|
7
|
+
category "ops"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "dotenv-rails", group: :development}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'create_file ".env.example", <<~ENV',
|
|
18
|
+
" # Copy to .env and fill in values",
|
|
19
|
+
" # DATABASE_URL=postgres://localhost/myapp_development",
|
|
20
|
+
" # RAILS_MASTER_KEY=your_master_key",
|
|
21
|
+
"ENV",
|
|
22
|
+
"",
|
|
23
|
+
'append_to_file ".gitignore", "\\n.env\\n.env.local\\n"'
|
|
24
|
+
]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def post_install_notes
|
|
28
|
+
[
|
|
29
|
+
"Dotenv: Copy .env.example to .env and fill in your values",
|
|
30
|
+
"Dotenv: .env files are gitignored -- never commit secrets"
|
|
31
|
+
]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class ElasticsearchPack < FeaturePack
|
|
5
|
+
pack_name "elasticsearch"
|
|
6
|
+
description "Searchkick for Elasticsearch-powered search"
|
|
7
|
+
category "data"
|
|
8
|
+
conflicts_with "search", "meilisearch"
|
|
9
|
+
|
|
10
|
+
def gems
|
|
11
|
+
[
|
|
12
|
+
{name: "searchkick"}
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def template_lines
|
|
17
|
+
[]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def post_install_notes
|
|
21
|
+
[
|
|
22
|
+
"Searchkick: Install and run Elasticsearch (or OpenSearch)",
|
|
23
|
+
"Searchkick: Add `searchkick` to models you want to search",
|
|
24
|
+
"Searchkick: Reindex with `Model.reindex`",
|
|
25
|
+
"Searchkick: Search with `Model.search(\"query\")`"
|
|
26
|
+
]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class EncryptionPack < FeaturePack
|
|
5
|
+
pack_name "encryption"
|
|
6
|
+
description "Lockbox for application-level field encryption"
|
|
7
|
+
category "data"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "lockbox"},
|
|
12
|
+
{name: "blind_index"}
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def template_lines
|
|
17
|
+
[
|
|
18
|
+
'create_file "config/initializers/lockbox.rb", <<~RUBY',
|
|
19
|
+
" Lockbox.master_key = Rails.application.credentials.dig(:lockbox, :master_key) || ENV[\"LOCKBOX_MASTER_KEY\"]",
|
|
20
|
+
"RUBY"
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def post_install_notes
|
|
25
|
+
[
|
|
26
|
+
"Lockbox: Generate a master key with `Lockbox.generate_key`",
|
|
27
|
+
"Lockbox: Add to credentials with `bin/rails credentials:edit`:",
|
|
28
|
+
" lockbox:",
|
|
29
|
+
" master_key: your_generated_key",
|
|
30
|
+
"Lockbox: Use `encrypts :email` in models to encrypt fields",
|
|
31
|
+
"Lockbox: Use `blind_index :email` for searchable encrypted fields"
|
|
32
|
+
]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class ErrorTrackingPack < FeaturePack
|
|
5
|
+
pack_name "error_tracking"
|
|
6
|
+
description "Sentry for error tracking and performance monitoring"
|
|
7
|
+
category "ops"
|
|
8
|
+
conflicts_with "honeybadger", "rollbar"
|
|
9
|
+
|
|
10
|
+
def gems
|
|
11
|
+
[
|
|
12
|
+
{name: "sentry-ruby"},
|
|
13
|
+
{name: "sentry-rails"}
|
|
14
|
+
]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def template_lines
|
|
18
|
+
[
|
|
19
|
+
'create_file "config/initializers/sentry.rb", <<~RUBY',
|
|
20
|
+
" Sentry.init do |config|",
|
|
21
|
+
' config.dsn = Rails.application.credentials.dig(:sentry, :dsn) || ENV["SENTRY_DSN"]',
|
|
22
|
+
" config.breadcrumbs_logger = [:active_support_logger, :http_logger]",
|
|
23
|
+
" config.traces_sample_rate = 0.1",
|
|
24
|
+
" config.profiles_sample_rate = 0.1",
|
|
25
|
+
" end",
|
|
26
|
+
"RUBY"
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def post_install_notes
|
|
31
|
+
[
|
|
32
|
+
"Sentry: Add your DSN with `bin/rails credentials:edit`:",
|
|
33
|
+
" sentry:",
|
|
34
|
+
" dsn: https://your-dsn@sentry.io/project-id"
|
|
35
|
+
]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class EventSourcingPack < FeaturePack
|
|
5
|
+
pack_name "event_sourcing"
|
|
6
|
+
description "Rails Event Store for event sourcing and CQRS"
|
|
7
|
+
category "data"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "rails_event_store"}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'rails_command "generate rails_event_store_active_record:install"'
|
|
18
|
+
]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def post_install_notes
|
|
22
|
+
[
|
|
23
|
+
"Event Store: Run `bin/rails db:migrate` to create events table",
|
|
24
|
+
"Event Store: Publish events with `Rails.configuration.event_store.publish(event)`",
|
|
25
|
+
"Event Store: Browse events at /res if you mount the browser engine"
|
|
26
|
+
]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class FaradayPack < FeaturePack
|
|
5
|
+
pack_name "faraday"
|
|
6
|
+
description "Faraday for composable HTTP client requests"
|
|
7
|
+
category "core"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "faraday", version: "~> 2.0"},
|
|
12
|
+
{name: "faraday-retry"}
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def template_lines
|
|
17
|
+
[
|
|
18
|
+
'create_file "app/clients/application_client.rb", <<~RUBY',
|
|
19
|
+
" class ApplicationClient",
|
|
20
|
+
" def connection",
|
|
21
|
+
" @connection ||= Faraday.new do |f|",
|
|
22
|
+
" f.request :json",
|
|
23
|
+
" f.response :json",
|
|
24
|
+
" f.request :retry, max: 2, interval: 0.5",
|
|
25
|
+
" f.adapter Faraday.default_adapter",
|
|
26
|
+
" end",
|
|
27
|
+
" end",
|
|
28
|
+
" end",
|
|
29
|
+
"RUBY"
|
|
30
|
+
]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def post_install_notes
|
|
34
|
+
[
|
|
35
|
+
"Faraday: Base client class at app/clients/application_client.rb",
|
|
36
|
+
"Faraday: Create service-specific clients inheriting from ApplicationClient"
|
|
37
|
+
]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class FathomPack < FeaturePack
|
|
5
|
+
pack_name "fathom"
|
|
6
|
+
description "Fathom -- simple, privacy-focused website analytics"
|
|
7
|
+
category "analytics"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def template_lines
|
|
14
|
+
[
|
|
15
|
+
'create_file "app/views/layouts/_fathom.html.erb", <<~ERB',
|
|
16
|
+
' <script src="https://cdn.usefathom.com/script.js" data-site="<%%= Rails.application.credentials.dig(:fathom, :site_id) || ENV["FATHOM_SITE_ID"] %>" defer></script>',
|
|
17
|
+
"ERB",
|
|
18
|
+
"",
|
|
19
|
+
'inject_into_file "app/views/layouts/application.html.erb", after: "<head>\\n" do',
|
|
20
|
+
' " <%= render \\"layouts/fathom\\" %>\\n"',
|
|
21
|
+
"end"
|
|
22
|
+
]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def post_install_notes
|
|
26
|
+
[
|
|
27
|
+
"Fathom: Add your site ID with `bin/rails credentials:edit`:",
|
|
28
|
+
" fathom:",
|
|
29
|
+
" site_id: ABCDEFGH",
|
|
30
|
+
"Fathom: No cookie banner needed -- privacy-first, GDPR compliant"
|
|
31
|
+
]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class FeatureFlagsPack < FeaturePack
|
|
5
|
+
pack_name "feature_flags"
|
|
6
|
+
description "Flipper for feature flags with web UI"
|
|
7
|
+
category "ops"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "flipper"},
|
|
12
|
+
{name: "flipper-active_record"},
|
|
13
|
+
{name: "flipper-ui"}
|
|
14
|
+
]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def template_lines
|
|
18
|
+
[
|
|
19
|
+
'rails_command "generate flipper:setup"',
|
|
20
|
+
'route "mount Flipper::UI.app(Flipper) => \\"/flipper\\""'
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def post_install_notes
|
|
25
|
+
[
|
|
26
|
+
"Feature Flags: Run `bin/rails db:migrate` to create Flipper tables",
|
|
27
|
+
"Feature Flags: Manage flags at /flipper",
|
|
28
|
+
"Feature Flags: Use `Flipper.enabled?(:my_feature)` in code"
|
|
29
|
+
]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class FriendlyIdPack < FeaturePack
|
|
5
|
+
pack_name "friendly_id"
|
|
6
|
+
description "FriendlyId for human-readable URL slugs"
|
|
7
|
+
category "ui"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "friendly_id", version: "~> 5.5"}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'rails_command "generate friendly_id"'
|
|
18
|
+
]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def post_install_notes
|
|
22
|
+
[
|
|
23
|
+
"FriendlyId: Run `bin/rails db:migrate` to create slugs table",
|
|
24
|
+
"FriendlyId: Add `extend FriendlyId` and `friendly_id :name, use: :slugged` to models",
|
|
25
|
+
"FriendlyId: Use `User.friendly.find(\"john-doe\")` instead of `User.find(id)`"
|
|
26
|
+
]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class GeocoderPack < FeaturePack
|
|
5
|
+
pack_name "geocoder"
|
|
6
|
+
description "Geocoder for address lookup, geocoding, and distance queries"
|
|
7
|
+
category "data"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "geocoder"}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'create_file "config/initializers/geocoder.rb", <<~RUBY',
|
|
18
|
+
" Geocoder.configure(",
|
|
19
|
+
" timeout: 5,",
|
|
20
|
+
" lookup: :nominatim,",
|
|
21
|
+
" units: :mi,",
|
|
22
|
+
" cache: Rails.cache",
|
|
23
|
+
" )",
|
|
24
|
+
"RUBY"
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def post_install_notes
|
|
29
|
+
[
|
|
30
|
+
"Geocoder: Add `geocoded_by :address` to models with latitude/longitude columns",
|
|
31
|
+
"Geocoder: Use `Model.near(\"New York\", 50)` for proximity search",
|
|
32
|
+
"Geocoder: Default uses free Nominatim API -- switch to Google/Mapbox for production"
|
|
33
|
+
]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class GoodJobPack < FeaturePack
|
|
5
|
+
pack_name "good_job"
|
|
6
|
+
description "GoodJob for Postgres-backed background jobs (no Redis needed)"
|
|
7
|
+
category "core"
|
|
8
|
+
conflicts_with "background_jobs", "sidekiq"
|
|
9
|
+
|
|
10
|
+
def gems
|
|
11
|
+
[
|
|
12
|
+
{name: "good_job", version: "~> 4.0"}
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def template_lines
|
|
17
|
+
[
|
|
18
|
+
'environment "config.active_job.queue_adapter = :good_job"',
|
|
19
|
+
'rails_command "generate good_job:install"',
|
|
20
|
+
'route "mount GoodJob::Engine => \\"/good_job\\""'
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def post_install_notes
|
|
25
|
+
[
|
|
26
|
+
"GoodJob: Run `bin/rails db:migrate` to create job tables",
|
|
27
|
+
"GoodJob: Monitor jobs at /good_job",
|
|
28
|
+
"GoodJob: Supports cron-like recurring jobs via config/good_job.yml"
|
|
29
|
+
]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class GoogleAnalyticsPack < FeaturePack
|
|
5
|
+
pack_name "google_analytics"
|
|
6
|
+
description "Google Analytics 4 (GA4) for web analytics"
|
|
7
|
+
category "analytics"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def template_lines
|
|
14
|
+
[
|
|
15
|
+
'create_file "app/views/layouts/_google_analytics.html.erb", <<~ERB',
|
|
16
|
+
" <!-- Google Analytics 4 -->",
|
|
17
|
+
' <script async src="https://www.googletagmanager.com/gtag/js?id=<%%= Rails.application.credentials.dig(:google_analytics, :measurement_id) || ENV["GA_MEASUREMENT_ID"] %>"></script>',
|
|
18
|
+
" <script>",
|
|
19
|
+
" window.dataLayer = window.dataLayer || [];",
|
|
20
|
+
" function gtag(){dataLayer.push(arguments);}",
|
|
21
|
+
' gtag("js", new Date());',
|
|
22
|
+
' gtag("config", "<%%= Rails.application.credentials.dig(:google_analytics, :measurement_id) || ENV["GA_MEASUREMENT_ID"] %>");',
|
|
23
|
+
" </script>",
|
|
24
|
+
"ERB",
|
|
25
|
+
"",
|
|
26
|
+
'inject_into_file "app/views/layouts/application.html.erb", after: "<head>\\n" do',
|
|
27
|
+
' " <%= render \\"layouts/google_analytics\\" %>\\n"',
|
|
28
|
+
"end"
|
|
29
|
+
]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def post_install_notes
|
|
33
|
+
[
|
|
34
|
+
"Google Analytics: Add your measurement ID with `bin/rails credentials:edit`:",
|
|
35
|
+
" google_analytics:",
|
|
36
|
+
" measurement_id: G-XXXXXXXXXX"
|
|
37
|
+
]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class GoogleTagManagerPack < FeaturePack
|
|
5
|
+
pack_name "google_tag_manager"
|
|
6
|
+
description "Google Tag Manager for managing analytics and marketing tags"
|
|
7
|
+
category "analytics"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def template_lines
|
|
14
|
+
[
|
|
15
|
+
'create_file "app/views/layouts/_gtm_head.html.erb", <<~ERB',
|
|
16
|
+
" <!-- Google Tag Manager -->",
|
|
17
|
+
" <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({\"gtm.start\":",
|
|
18
|
+
' new Date().getTime(),event:"gtm.js"});var f=d.getElementsByTagName(s)[0],',
|
|
19
|
+
' j=d.createElement(s),dl=l!="dataLayer"?"&l="+l:"";j.async=true;j.src=',
|
|
20
|
+
' "https://www.googletagmanager.com/gtm.js?id="+i+dl;f.parentNode.insertBefore(j,f);',
|
|
21
|
+
' })(window,document,"script","dataLayer","<%%= Rails.application.credentials.dig(:gtm, :container_id) || ENV["GTM_CONTAINER_ID"] %>");</script>',
|
|
22
|
+
"ERB",
|
|
23
|
+
"",
|
|
24
|
+
'create_file "app/views/layouts/_gtm_body.html.erb", <<~ERB',
|
|
25
|
+
" <!-- Google Tag Manager (noscript) -->",
|
|
26
|
+
' <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<%%= Rails.application.credentials.dig(:gtm, :container_id) || ENV["GTM_CONTAINER_ID"] %>"',
|
|
27
|
+
' height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>',
|
|
28
|
+
"ERB",
|
|
29
|
+
"",
|
|
30
|
+
'inject_into_file "app/views/layouts/application.html.erb", after: "<head>\\n" do',
|
|
31
|
+
' " <%= render \\"layouts/gtm_head\\" %>\\n"',
|
|
32
|
+
"end",
|
|
33
|
+
"",
|
|
34
|
+
'inject_into_file "app/views/layouts/application.html.erb", after: "<body>\\n" do',
|
|
35
|
+
' " <%= render \\"layouts/gtm_body\\" %>\\n"',
|
|
36
|
+
"end"
|
|
37
|
+
]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def post_install_notes
|
|
41
|
+
[
|
|
42
|
+
"GTM: Add your container ID with `bin/rails credentials:edit`:",
|
|
43
|
+
" gtm:",
|
|
44
|
+
" container_id: GTM-XXXXXXX",
|
|
45
|
+
"GTM: Manage all your analytics/marketing tags from the GTM dashboard"
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Metro
|
|
3
|
+
module Packs
|
|
4
|
+
class GraphqlPack < FeaturePack
|
|
5
|
+
pack_name "graphql"
|
|
6
|
+
description "GraphQL API with graphql-ruby"
|
|
7
|
+
category "api"
|
|
8
|
+
|
|
9
|
+
def gems
|
|
10
|
+
[
|
|
11
|
+
{name: "graphql", version: "~> 2.0"}
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def template_lines
|
|
16
|
+
[
|
|
17
|
+
'rails_command "generate graphql:install"'
|
|
18
|
+
]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def post_install_notes
|
|
22
|
+
[
|
|
23
|
+
"GraphQL: Endpoint available at /graphql",
|
|
24
|
+
"GraphQL: Generate types with `bin/rails g graphql:object User`",
|
|
25
|
+
"GraphQL: GraphiQL IDE available in development at /graphiql"
|
|
26
|
+
]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|