diff --git a/.cursor/rules/rails.mdc b/.cursor/rules/rails.mdc index 9189357..bc1df44 100644 --- a/.cursor/rules/rails.mdc +++ b/.cursor/rules/rails.mdc @@ -22,6 +22,8 @@ e.g use `rails generate model` instead of creating a model from scratch - Monitor development.log for errors and performance issues - Use `tail -f log/development.log` for real-time monitoring - Review logs before considering any change complete +- Use modern Ruby 3.4 and Rails 8.1 syntax +- Avoid using deprecated patterns, like OpenStruct 1. **Modern Infrastructure** - Use Thruster for asset compression and caching diff --git a/.ruby-version b/.ruby-version index 86fb650..f989260 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.7 +3.4.4 diff --git a/Gemfile b/Gemfile index 6dba2b5..f627a44 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ gem "rails", github: "rails/rails", branch: "main" gem "propshaft" # Use sqlite3 as the database for Active Record gem "sqlite3", ">= 2.1" -gem 'sqlite-ulid' +gem "sqlite-ulid" # Use the Puma web server [https://github.com/puma/puma] gem "puma", ">= 5.0" # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] @@ -16,16 +16,13 @@ gem "turbo-rails" # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] gem "stimulus-rails" # Use Tailwind CSS [https://github.com/rails/tailwindcss-rails] -gem "tailwindcss-rails" +gem "tailwindcss-rails", "~> 4.0" # Build JSON APIs with ease [https://github.com/rails/jbuilder] gem "jbuilder" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] # gem "bcrypt", "~> 3.1.7" -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] - # Use the database-backed adapters for Rails.cache, Active Job, and Action Cable gem "solid_cache" gem "solid_queue" @@ -53,7 +50,7 @@ group :development, :test do # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] gem "rubocop-rails-omakase", require: false - gem 'dotenv' + gem "dotenv" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 57a88cf..3157de4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/rails/rails.git - revision: 410ad1c8a18ebf7f544d77d2cb82de2a0e87d23a + revision: 5a7a59ab4a9ac34b8cadf9d8ce7b554da50c5e43 branch: main specs: actioncable (8.1.0.alpha) @@ -34,6 +34,7 @@ GIT rails-html-sanitizer (~> 1.6) useragent (~> 0.16) actiontext (8.1.0.alpha) + action_text-trix (~> 2.1.15) actionpack (= 8.1.0.alpha) activerecord (= 8.1.0.alpha) activestorage (= 8.1.0.alpha) @@ -100,18 +101,21 @@ GIT GEM remote: https://rubygems.org/ specs: + action_text-trix (2.1.15) + railties active_link_to (1.0.5) actionpack addressable addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) - ast (2.4.2) - avo (3.15.1) + ast (2.4.3) + avo (3.21.1) actionview (>= 6.1) active_link_to activerecord (>= 6.1) activesupport (>= 6.1) addressable + avo-heroicons (>= 0.1.1) docile inline_svg meta-tags @@ -121,15 +125,17 @@ GEM turbo_power (>= 0.6.0) view_component (>= 3.7.0) zeitwerk (>= 2.6.12) - base64 (0.2.0) + avo-heroicons (0.1.1) + base64 (0.3.0) bcrypt (3.1.20) bcrypt_pbkdf (1.1.1) - benchmark (0.4.0) - bigdecimal (3.1.8) + bcrypt_pbkdf (1.1.1-arm64-darwin) + benchmark (0.4.1) + bigdecimal (3.2.2) bindex (0.8.1) - bootsnap (1.18.4) + bootsnap (1.18.6) msgpack (~> 1.2) - brakeman (6.2.2) + brakeman (7.0.2) racc builder (3.3.0) capybara (3.40.0) @@ -141,11 +147,11 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - concurrent-ruby (1.3.4) - connection_pool (2.4.1) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) crass (1.0.6) date (3.4.1) - debug (1.9.2) + debug (1.10.0) irb (~> 1.10) reline (>= 0.3.8) devise (4.9.4) @@ -155,10 +161,11 @@ GEM responders warden (~> 1.2.3) docile (1.4.1) - dotenv (3.1.4) - drb (2.2.1) - ed25519 (1.3.0) - erubi (1.13.0) + dotenv (3.1.8) + drb (2.2.3) + ed25519 (1.4.0) + erb (5.0.1) + erubi (1.13.1) et-orbi (1.2.11) tzinfo fugit (1.11.1) @@ -166,9 +173,9 @@ GEM raabro (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) - i18n (1.14.6) + i18n (1.14.7) concurrent-ruby (~> 1.0) - importmap-rails (2.0.3) + importmap-rails (2.1.0) actionpack (>= 6.0.0) activesupport (>= 6.0.0) railties (>= 6.0.0) @@ -176,27 +183,29 @@ GEM activesupport (>= 3.0) nokogiri (>= 1.6) io-console (0.8.0) - irb (1.14.1) + irb (1.15.2) + pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) jbuilder (2.13.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) - json (2.9.0) - kamal (2.3.0) + json (2.12.2) + kamal (2.6.1) activesupport (>= 7.0) base64 (~> 0.2) bcrypt_pbkdf (~> 1.0) concurrent-ruby (~> 1.2) dotenv (~> 3.1) - ed25519 (~> 1.2) + ed25519 (~> 1.4) net-ssh (~> 7.3) sshkit (>= 1.23.0, < 2.0) thor (~> 1.3) zeitwerk (>= 2.6.18, < 3.0) - language_server-protocol (3.17.0.3) - logger (1.6.2) - loofah (2.23.1) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + loofah (2.24.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -210,34 +219,38 @@ GEM actionpack (>= 6.0.0, < 8.1) method_source (1.1.0) mini_mime (1.1.5) - mini_portile2 (2.8.8) - minitest (5.25.4) - msgpack (1.7.5) - net-imap (0.5.1) + minitest (5.25.5) + msgpack (1.8.0) + net-imap (0.5.8) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-scp (4.0.0) + net-scp (4.1.0) net-ssh (>= 2.6.5, < 8.0.0) net-sftp (4.0.0) net-ssh (>= 5.0.0, < 8.0.0) - net-smtp (0.5.0) + net-smtp (0.5.1) net-protocol net-ssh (7.3.0) nio4r (2.7.4) - nokogiri (1.16.8) - mini_portile2 (~> 2.8.2) + nokogiri (1.18.8-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.8-x86_64-linux-gnu) racc (~> 1.4) orm_adapter (0.5.0) ostruct (0.6.1) - pagy (9.3.2) - parallel (1.26.3) - parser (3.3.6.0) + pagy (9.3.4) + parallel (1.27.0) + parser (3.3.8.0) ast (~> 2.4.1) racc + pp (0.6.2) + prettyprint + prettyprint (0.2.0) + prism (1.4.0) prop_initializer (0.2.0) zeitwerk (>= 2.6.18) propshaft (1.1.0) @@ -245,86 +258,88 @@ GEM activesupport (>= 7.0.0) rack railties (>= 7.0.0) - psych (5.2.1) + psych (5.2.6) date stringio - public_suffix (6.0.1) - puma (6.5.0) + public_suffix (6.0.2) + puma (6.6.0) nio4r (~> 2.0) raabro (1.4.0) racc (1.8.1) - rack (3.1.8) - rack-session (2.0.0) + rack (3.1.16) + rack-session (2.1.1) + base64 (>= 0.1.0) rack (>= 3.0.0) - rack-test (2.1.0) + rack-test (2.2.0) rack (>= 1.3) rackup (2.2.1) rack (>= 3) - rails-dom-testing (2.2.0) + rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.1) + rails-html-sanitizer (1.6.2) loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) rainbow (3.1.1) - rake (13.2.1) - rdoc (6.8.1) + rake (13.3.0) + rdoc (6.14.0) + erb psych (>= 4.0.0) - regexp_parser (2.9.3) - reline (0.5.12) + regexp_parser (2.10.0) + reline (0.6.1) io-console (~> 0.5) responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.3.9) - rubocop (1.69.1) + rexml (3.4.1) + rubocop (1.76.1) json (~> 2.3) - language_server-protocol (>= 3.17.0) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.36.2, < 2.0) + rubocop-ast (>= 1.45.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.36.2) - parser (>= 3.3.1.0) - rubocop-minitest (0.36.0) - rubocop (>= 1.61, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-performance (1.23.0) - rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.27.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-performance (1.25.0) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-rails (2.32.0) activesupport (>= 4.2.0) + lint_roller (~> 1.1) rack (>= 1.1) - rubocop (>= 1.52.0, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails-omakase (1.0.0) - rubocop - rubocop-minitest - rubocop-performance - rubocop-rails + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rails-omakase (1.1.0) + rubocop (>= 1.72) + rubocop-performance (>= 1.24) + rubocop-rails (>= 2.30) ruby-progressbar (1.13.0) - rubyzip (2.3.2) - securerandom (0.4.0) - selenium-webdriver (4.27.0) + rubyzip (2.4.1) + securerandom (0.4.1) + selenium-webdriver (4.33.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - solid_cable (3.0.4) + solid_cable (3.0.8) actioncable (>= 7.2) activejob (>= 7.2) activerecord (>= 7.2) railties (>= 7.2) - solid_cache (1.0.6) + solid_cache (1.0.7) activejob (>= 7.2) activerecord (>= 7.2) railties (>= 7.2) - solid_queue (1.1.0) + solid_queue (1.1.5) activejob (>= 7.1) activerecord (>= 7.1) concurrent-ruby (>= 1.3.1) @@ -332,39 +347,43 @@ GEM railties (>= 7.1) thor (~> 1.3.1) sqlite-ulid (0.2.1-arm64-darwin) - sqlite3 (2.4.0) - mini_portile2 (~> 2.8.0) - sshkit (1.23.2) + sqlite-ulid (0.2.1-x86_64-linux) + sqlite3 (2.7.0-arm64-darwin) + sqlite3 (2.7.0-x86_64-linux-gnu) + sshkit (1.24.0) base64 + logger net-scp (>= 1.1.2) net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) ostruct stimulus-rails (1.3.4) railties (>= 6.0.0) - stringio (3.1.2) - tailwindcss-rails (3.0.0) + stringio (3.1.7) + tailwindcss-rails (4.2.3) railties (>= 7.0.0) - tailwindcss-ruby - tailwindcss-ruby (3.4.16-arm64-darwin) + tailwindcss-ruby (~> 4.0) + tailwindcss-ruby (4.1.10-arm64-darwin) + tailwindcss-ruby (4.1.10-x86_64-linux-gnu) thor (1.3.2) - thruster (0.1.9-arm64-darwin) - timeout (0.4.2) - turbo-rails (2.0.11) - actionpack (>= 6.0.0) - railties (>= 6.0.0) - turbo_power (0.6.2) + thruster (0.1.13-arm64-darwin) + thruster (0.1.13-x86_64-linux) + timeout (0.4.3) + turbo-rails (2.0.16) + actionpack (>= 7.1.0) + railties (>= 7.1.0) + turbo_power (0.7.0) turbo-rails (>= 1.3.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (3.1.2) + unicode-display_width (3.1.4) unicode-emoji (~> 4.0, >= 4.0.4) unicode-emoji (4.0.4) - uri (1.0.2) + uri (1.0.3) useragent (0.16.11) - view_component (3.20.0) + view_component (3.23.2) activesupport (>= 5.2.0, < 8.1) - concurrent-ruby (~> 1.0) + concurrent-ruby (~> 1) method_source (~> 1.0) warden (1.2.9) rack (>= 2.0.9) @@ -374,15 +393,17 @@ GEM bindex (>= 0.4.0) railties (>= 6.0.0) websocket (1.2.11) - websocket-driver (0.7.6) + websocket-driver (0.8.0) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.7.1) + zeitwerk (2.7.3) PLATFORMS arm64-darwin-24 + x86_64-linux DEPENDENCIES avo (>= 3.2) @@ -406,11 +427,10 @@ DEPENDENCIES sqlite-ulid sqlite3 (>= 2.1) stimulus-rails - tailwindcss-rails + tailwindcss-rails (~> 4.0) thruster turbo-rails - tzinfo-data web-console BUNDLED WITH - 2.5.22 + 2.6.9 diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css deleted file mode 100644 index 8666d2f..0000000 --- a/app/assets/stylesheets/application.tailwind.css +++ /dev/null @@ -1,13 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -/* - -@layer components { - .btn-primary { - @apply py-2 px-4 bg-blue-200; - } -} - -*/ diff --git a/app/assets/tailwind/application.css b/app/assets/tailwind/application.css new file mode 100644 index 0000000..7b9b841 --- /dev/null +++ b/app/assets/tailwind/application.css @@ -0,0 +1,13 @@ +@import "tailwindcss"; +@plugin "@tailwindcss/forms"; +@plugin "@tailwindcss/typography"; + +/* + +@layer components { + .btn-primary { + @apply py-2 px-4 bg-blue-200; + } +} + +*/ diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 6bd4482..43d943c 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -18,7 +18,7 @@ <%# Includes all stylesheet files in app/assets/stylesheets %> - <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %> + <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> diff --git a/config/initializers/avo.rb b/config/initializers/avo.rb index 665b2f7..c0c74c4 100644 --- a/config/initializers/avo.rb +++ b/config/initializers/avo.rb @@ -2,7 +2,7 @@ # The values disaplayed here are the default ones. Uncomment and change them to fit your needs. Avo.configure do |config| ## == Routing == - config.root_path = '/avo' + config.root_path = "/avo" # used only when you have custom `map` configuration in your config.ru # config.prefix_path = "/internal" diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 424187a..43a862f 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -24,7 +24,7 @@ # Configure the e-mail address which will be shown in Devise::Mailer, # note that it will be overwritten if you use your own mailer class # with default "from" parameter. - config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' + config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" # Configure the class responsible to send e-mails. # config.mailer = 'Devise::Mailer' @@ -36,7 +36,7 @@ # Load and configure the ORM. Supports :active_record (default) and # :mongoid (bson_ext recommended) by default. Other ORMs may be # available as additional gems. - require 'devise/orm/active_record' + require "devise/orm/active_record" # ==> Configuration for any authentication mechanism # Configure which keys are used when authenticating a user. The default is @@ -58,12 +58,12 @@ # Configure which authentication keys should be case-insensitive. # These keys will be downcased upon creating or modifying a user and when used # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [:email] + config.case_insensitive_keys = [ :email ] # Configure which authentication keys should have whitespace stripped. # These keys will have whitespace before and after removed upon creating or # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [:email] + config.strip_whitespace_keys = [ :email ] # Tell if authentication through request.params is enabled. True by default. # It can be set to an array that will enable params authentication only for the @@ -97,7 +97,7 @@ # Notice that if you are skipping storage for all authentication paths, you # may want to disable generating routes to Devise's sessions controller by # passing skip: :sessions to `devise_for` in your config/routes.rb - config.skip_session_storage = [:http_auth] + config.skip_session_storage = [ :http_auth ] # By default, Devise cleans up the CSRF token on authentication to # avoid CSRF token fixation attacks. This means that, when using AJAX @@ -263,7 +263,7 @@ # should add them to the navigational formats lists. # # The "*/*" below is required to match Internet Explorer requests. - config.navigational_formats = ['*/*', :html, :turbo_stream] + config.navigational_formats = [ "*/*", :html, :turbo_stream ] # The default HTTP method used to sign out a resource. Default is :delete. config.sign_out_via = :delete diff --git a/config/initializers/sqlite.rb b/config/initializers/sqlite.rb index 04e6f3d..30b5e76 100644 --- a/config/initializers/sqlite.rb +++ b/config/initializers/sqlite.rb @@ -8,8 +8,8 @@ def initialize_extensions(extensions) # Convert extension names to actual paths extensions&.map! do |ext| case ext - when 'ulid' - require 'sqlite_ulid' + when "ulid" + require "sqlite_ulid" SqliteUlid.ulid_loadable_path else ext diff --git a/config/tailwind.config.js b/config/tailwind.config.js index d6ad82c..a7c19a7 100644 --- a/config/tailwind.config.js +++ b/config/tailwind.config.js @@ -1,5 +1,3 @@ -const defaultTheme = require('tailwindcss/defaultTheme') - module.exports = { content: [ './public/*.html', @@ -10,13 +8,9 @@ module.exports = { theme: { extend: { fontFamily: { - sans: ['Inter var', ...defaultTheme.fontFamily.sans], + sans: ['Inter var', 'system-ui', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'sans-serif'], }, }, }, - plugins: [ - require('@tailwindcss/forms'), - require('@tailwindcss/typography'), - require('@tailwindcss/container-queries'), - ] + plugins: [] }