diff --git a/backend/Gemfile b/backend/Gemfile index 7b44641..ba2bbb1 100644 --- a/backend/Gemfile +++ b/backend/Gemfile @@ -71,3 +71,5 @@ gem "rspec-rails", "~> 8.0", :groups => [:development, :test] gem 'aws-sdk-s3', require: false gem 'rails-i18n', '~> 8.0.0' + +gem "json", "~> 2.19.9" diff --git a/backend/Gemfile.lock b/backend/Gemfile.lock index 555f867..c130664 100644 --- a/backend/Gemfile.lock +++ b/backend/Gemfile.lock @@ -1,29 +1,29 @@ GEM remote: https://rubygems.org/ specs: - actioncable (8.0.2) - actionpack (= 8.0.2) - activesupport (= 8.0.2) + actioncable (8.0.5.1) + actionpack (= 8.0.5.1) + activesupport (= 8.0.5.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.0.2) - actionpack (= 8.0.2) - activejob (= 8.0.2) - activerecord (= 8.0.2) - activestorage (= 8.0.2) - activesupport (= 8.0.2) + actionmailbox (8.0.5.1) + actionpack (= 8.0.5.1) + activejob (= 8.0.5.1) + activerecord (= 8.0.5.1) + activestorage (= 8.0.5.1) + activesupport (= 8.0.5.1) mail (>= 2.8.0) - actionmailer (8.0.2) - actionpack (= 8.0.2) - actionview (= 8.0.2) - activejob (= 8.0.2) - activesupport (= 8.0.2) + actionmailer (8.0.5.1) + actionpack (= 8.0.5.1) + actionview (= 8.0.5.1) + activejob (= 8.0.5.1) + activesupport (= 8.0.5.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.0.2) - actionview (= 8.0.2) - activesupport (= 8.0.2) + actionpack (8.0.5.1) + actionview (= 8.0.5.1) + activesupport (= 8.0.5.1) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -31,35 +31,35 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.0.2) - actionpack (= 8.0.2) - activerecord (= 8.0.2) - activestorage (= 8.0.2) - activesupport (= 8.0.2) + actiontext (8.0.5.1) + actionpack (= 8.0.5.1) + activerecord (= 8.0.5.1) + activestorage (= 8.0.5.1) + activesupport (= 8.0.5.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.0.2) - activesupport (= 8.0.2) + actionview (8.0.5.1) + activesupport (= 8.0.5.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.0.2) - activesupport (= 8.0.2) + activejob (8.0.5.1) + activesupport (= 8.0.5.1) globalid (>= 0.3.6) - activemodel (8.0.2) - activesupport (= 8.0.2) - activerecord (8.0.2) - activemodel (= 8.0.2) - activesupport (= 8.0.2) + activemodel (8.0.5.1) + activesupport (= 8.0.5.1) + activerecord (8.0.5.1) + activemodel (= 8.0.5.1) + activesupport (= 8.0.5.1) timeout (>= 0.4.0) - activestorage (8.0.2) - actionpack (= 8.0.2) - activejob (= 8.0.2) - activerecord (= 8.0.2) - activesupport (= 8.0.2) + activestorage (8.0.5.1) + actionpack (= 8.0.5.1) + activejob (= 8.0.5.1) + activerecord (= 8.0.5.1) + activesupport (= 8.0.5.1) marcel (~> 1.0) - activesupport (8.0.2) + activesupport (8.0.5.1) base64 benchmark (>= 0.3) bigdecimal @@ -92,22 +92,22 @@ GEM aws-sigv4 (~> 1.5) aws-sigv4 (1.12.1) aws-eventstream (~> 1, >= 1.0.2) - base64 (0.2.0) + base64 (0.3.0) bcrypt_pbkdf (1.1.1) bcrypt_pbkdf (1.1.1-arm64-darwin) bcrypt_pbkdf (1.1.1-x86_64-darwin) - benchmark (0.4.0) - bigdecimal (3.1.9) + benchmark (0.5.0) + bigdecimal (4.1.3) bootsnap (1.18.6) msgpack (~> 1.2) brakeman (7.0.2) racc builder (3.3.0) chronic (0.10.2) - concurrent-ruby (1.3.5) - connection_pool (2.5.3) - crass (1.0.6) - date (3.4.1) + concurrent-ruby (1.3.8) + connection_pool (3.0.2) + crass (1.0.7) + date (3.6.0) diff-lcs (1.6.2) discard (1.4.0) activerecord (>= 4.2, < 9.0) @@ -115,8 +115,9 @@ GEM dotenv-rails (3.1.8) dotenv (= 3.1.8) railties (>= 6.1) - drb (2.2.1) + drb (2.2.3) ed25519 (1.4.0) + erb (6.0.7) erubi (1.13.1) factory_bot (6.5.6) activesupport (>= 6.1.0) @@ -134,7 +135,7 @@ GEM gemojione (4.3.3) json github-markup (4.0.2) - globalid (1.2.1) + globalid (1.4.0) activesupport (>= 6.1) gollum (6.1.0) gemojione (~> 4.1) @@ -166,19 +167,20 @@ GEM gollum-rugged_adapter (3.0) mime-types (~> 3.4) rugged (~> 1.5) - i18n (1.14.7) + i18n (1.15.2) concurrent-ruby (~> 1.0) image_processing (1.14.0) mini_magick (>= 4.9.5, < 6) ruby-vips (>= 2.0.17, < 3) - io-console (0.8.0) - irb (1.15.2) + io-console (0.9.4) + irb (1.18.0) pp (>= 0.6.0) + prism (>= 1.3.0) rdoc (>= 4.0.0) reline (>= 0.4.2) jmespath (1.6.2) - json (2.12.0) - jwt (2.10.1) + json (2.19.9) + jwt (3.3.0) base64 kamal (2.6.1) activesupport (>= 7.0) @@ -198,15 +200,16 @@ GEM language_server-protocol (3.17.0.5) lint_roller (1.1.0) logger (1.7.0) - loofah (2.24.1) + loofah (2.25.2) crass (~> 1.0.2) nokogiri (>= 1.12.0) - mail (2.8.1) + mail (2.9.1) + logger mini_mime (>= 0.1.1) net-imap net-pop net-smtp - marcel (1.0.4) + marcel (1.2.1) mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) @@ -215,45 +218,46 @@ GEM benchmark logger mini_mime (1.1.5) - minitest (5.25.5) - msgpack (1.8.0) - multi_json (1.15.0) + minitest (6.0.6) + drb (~> 2.0) + prism (~> 1.5) + msgpack (1.8.5) + multi_json (1.21.2) mustache (1.1.1) mustache-sinatra (2.0.0) mustache (~> 1.0) - mustermann (3.0.3) - ruby2_keywords (~> 0.0.1) + mustermann (3.1.1) mysql2 (0.5.6) - net-imap (0.5.8) + net-imap (0.6.8) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.2) + net-protocol (0.4.0) timeout 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.1) + net-smtp (0.5.2) net-protocol net-ssh (7.3.0) - nio4r (2.7.4) - nokogiri (1.18.8-aarch64-linux-gnu) + nio4r (2.7.5) + nokogiri (1.19.4-aarch64-linux-gnu) racc (~> 1.4) - nokogiri (1.18.8-aarch64-linux-musl) + nokogiri (1.19.4-aarch64-linux-musl) racc (~> 1.4) - nokogiri (1.18.8-arm-linux-gnu) + nokogiri (1.19.4-arm-linux-gnu) racc (~> 1.4) - nokogiri (1.18.8-arm-linux-musl) + nokogiri (1.19.4-arm-linux-musl) racc (~> 1.4) - nokogiri (1.18.8-arm64-darwin) + nokogiri (1.19.4-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.8-x86_64-darwin) + nokogiri (1.19.4-x86_64-darwin) racc (~> 1.4) - nokogiri (1.18.8-x86_64-linux-gnu) + nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) - nokogiri (1.18.8-x86_64-linux-musl) + nokogiri (1.19.4-x86_64-linux-musl) racc (~> 1.4) octicons (19.15.2) ostruct (0.6.1) @@ -261,70 +265,73 @@ GEM parser (3.3.8.0) ast (~> 2.4.1) racc - pp (0.6.2) + pp (0.6.4) prettyprint - prettyprint (0.2.0) - prism (1.4.0) - psych (5.2.6) + prettyprint (0.2.1) + prism (1.9.0) + psych (5.5.0) date stringio puma (6.6.0) nio4r (~> 2.0) racc (1.8.1) - rack (3.1.14) + rack (3.2.7) rack-cors (2.0.2) rack (>= 2.0.0) - rack-protection (4.1.1) + rack-protection (4.2.1) base64 (>= 0.1.0) logger (>= 1.6.0) rack (>= 3.0.0, < 4) - rack-session (2.1.1) + rack-session (2.1.2) base64 (>= 0.1.0) rack (>= 3.0.0) - rack-test (2.2.0) + rack-test (2.3.0) rack (>= 1.3) - rackup (2.2.1) + rackup (2.3.1) rack (>= 3) - rails (8.0.2) - actioncable (= 8.0.2) - actionmailbox (= 8.0.2) - actionmailer (= 8.0.2) - actionpack (= 8.0.2) - actiontext (= 8.0.2) - actionview (= 8.0.2) - activejob (= 8.0.2) - activemodel (= 8.0.2) - activerecord (= 8.0.2) - activestorage (= 8.0.2) - activesupport (= 8.0.2) + rails (8.0.5.1) + actioncable (= 8.0.5.1) + actionmailbox (= 8.0.5.1) + actionmailer (= 8.0.5.1) + actionpack (= 8.0.5.1) + actiontext (= 8.0.5.1) + actionview (= 8.0.5.1) + activejob (= 8.0.5.1) + activemodel (= 8.0.5.1) + activerecord (= 8.0.5.1) + activestorage (= 8.0.5.1) + activesupport (= 8.0.5.1) bundler (>= 1.15.0) - railties (= 8.0.2) - rails-dom-testing (2.2.0) + railties (= 8.0.5.1) + rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.2) - loofah (~> 2.21) + rails-html-sanitizer (1.7.1) + loofah (~> 2.25, >= 2.25.2) 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) rails-i18n (8.0.2) i18n (>= 0.7, < 2) railties (>= 8.0.0, < 9) - railties (8.0.2) - actionpack (= 8.0.2) - activesupport (= 8.0.2) + railties (8.0.5.1) + actionpack (= 8.0.5.1) + activesupport (= 8.0.5.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.2.1) - rdoc (6.13.1) + rake (13.4.2) + rdoc (6.17.0) + erb psych (>= 4.0.0) - regexp_parser (2.10.0) - reline (0.6.1) + tsort + regexp_parser (2.13.1) + reline (0.7.0) io-console (~> 0.5) - rexml (3.4.1) + rexml (3.4.4) rouge (3.30.0) rspec-core (3.13.6) rspec-support (~> 3.13.0) @@ -345,20 +352,20 @@ GEM rspec-support (3.13.6) rss (0.3.1) rexml - rubocop (1.75.6) - json (~> 2.3) + rubocop (1.92.0) + json (>= 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) - parallel (~> 1.10) + parallel (>= 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.44.0, < 2.0) + regexp_parser (>= 2.11.3, < 3.0) + rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.44.1) + rubocop-ast (1.50.0) parser (>= 3.3.7.2) - prism (~> 1.4) + prism (~> 1.7) rubocop-performance (1.25.0) lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) @@ -377,24 +384,23 @@ GEM ruby-vips (2.2.3) ffi (~> 1.12) logger - ruby2_keywords (0.0.5) rugged (1.9.0) securerandom (0.4.1) - sinatra (4.1.1) + sinatra (4.2.1) logger (>= 1.6.0) mustermann (~> 3.0) rack (>= 3.0.0, < 4) - rack-protection (= 4.1.1) + rack-protection (= 4.2.1) rack-session (>= 2.0.0, < 3) tilt (~> 2.0) - sinatra-contrib (4.1.1) + sinatra-contrib (4.2.1) multi_json (>= 0.0.2) mustermann (~> 3.0) - rack-protection (= 4.1.1) - sinatra (= 4.1.1) + rack-protection (= 4.2.1) + sinatra (= 4.2.1) tilt (~> 2.0) - sprockets (4.2.2) - concurrent-ruby (~> 1.0) + sprockets (4.4.1) + concurrent-ruby (~> 1.1) logger rack (>= 2.2.4, < 4) sprockets-helpers (1.4.0) @@ -403,14 +409,14 @@ GEM actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) - sqlite3 (2.6.0-aarch64-linux-gnu) - sqlite3 (2.6.0-aarch64-linux-musl) - sqlite3 (2.6.0-arm-linux-gnu) - sqlite3 (2.6.0-arm-linux-musl) - sqlite3 (2.6.0-arm64-darwin) - sqlite3 (2.6.0-x86_64-darwin) - sqlite3 (2.6.0-x86_64-linux-gnu) - sqlite3 (2.6.0-x86_64-linux-musl) + sqlite3 (2.10.1-aarch64-linux-gnu) + sqlite3 (2.10.1-aarch64-linux-musl) + sqlite3 (2.10.1-arm-linux-gnu) + sqlite3 (2.10.1-arm-linux-musl) + sqlite3 (2.10.1-arm64-darwin) + sqlite3 (2.10.1-x86_64-darwin) + sqlite3 (2.10.1-x86_64-linux-gnu) + sqlite3 (2.10.1-x86_64-linux-musl) sshkit (1.24.0) base64 logger @@ -418,18 +424,19 @@ GEM net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) ostruct - stringio (3.1.7) + stringio (3.2.0) therubyrhino (2.1.2) therubyrhino_jar (>= 1.7.4, < 1.7.9) therubyrhino_jar (1.7.8) - thor (1.3.2) + thor (1.5.0) thruster (0.1.13) thruster (0.1.13-aarch64-linux) thruster (0.1.13-arm64-darwin) thruster (0.1.13-x86_64-darwin) thruster (0.1.13-x86_64-linux) - tilt (2.6.0) - timeout (0.4.3) + tilt (2.9.0) + timeout (0.6.1) + tsort (0.2.0) twitter-text (1.14.7) unf (~> 0.1.0) tzinfo (2.0.6) @@ -440,16 +447,16 @@ GEM unicode-display_width (3.1.4) unicode-emoji (~> 4.0, >= 4.0.4) unicode-emoji (4.0.4) - uri (1.0.3) + uri (1.1.2) useragent (0.16.11) webrick (1.9.1) - websocket-driver (0.7.7) + websocket-driver (0.8.2) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) whenever (1.0.0) chronic (>= 0.6.3) - zeitwerk (2.7.2) + zeitwerk (2.8.3) PLATFORMS aarch64-linux @@ -473,6 +480,7 @@ DEPENDENCIES factory_bot_rails gollum image_processing (~> 1.14) + json (~> 2.19.9) jwt kamal mysql2 (~> 0.5.6) diff --git a/backend/app/controllers/post_versions_controller.rb b/backend/app/controllers/post_versions_controller.rb index 9c86c93..92b35c7 100644 --- a/backend/app/controllers/post_versions_controller.rb +++ b/backend/app/controllers/post_versions_controller.rb @@ -15,6 +15,7 @@ class PostVersionsController < ApplicationController offset = (page - 1) * limit q = HistoryAccess.visible(PostVersion.all) + q = q.with_previous_version if tag_id || external_tag_id q = q.where('post_versions.post_id = ?', post_id) if post_id q = q.with_previous_version if tag_id || external_tag_id if external_tag_id || (tag_id && !(Tag.exists?(id: tag_id))) diff --git a/backend/app/controllers/posts_controller.rb b/backend/app/controllers/posts_controller.rb index 38c74ca..4d96673 100644 --- a/backend/app/controllers/posts_controller.rb +++ b/backend/app/controllers/posts_controller.rb @@ -37,15 +37,7 @@ class PostsController < ApplicationController offset = (page - 1) * limit - pt_max_sql = - HistoryAccess.visible(PostVersion.all) - .where('post_versions.post_id = posts.id') - .select('MAX(post_versions.created_at)') - .to_sql - - updated_at_all_sql = - 'GREATEST(posts.updated_at,' + - "COALESCE((#{ pt_max_sql }), posts.updated_at))" + updated_at_all_sql = 'posts.updated_at' q = filtered_posts(locale) @@ -93,8 +85,7 @@ class PostsController < ApplicationController render json: { posts: posts.map { |post| PostRepr.base(post, language_code: locale.language_code) - .merge(updated_at: [post.updated_at, latest_version_times[post.id]].compact.max) - .tap do |json| + .merge(updated_at: post.updated_at).tap do |json| json['thumbnail'] = if post.thumbnail.attached? rails_storage_proxy_url(post.thumbnail, only_path: false) diff --git a/backend/app/models/history_access.rb b/backend/app/models/history_access.rb index ced5f98..5745e73 100644 --- a/backend/app/models/history_access.rb +++ b/backend/app/models/history_access.rb @@ -114,7 +114,7 @@ class HistoryAccess < ActiveSupport::CurrentAttributes private_names = 'SELECT DISTINCT private_name.name, ' + 'CAST(private_name.name AS BINARY) AS name_bytes FROM tag_versions private_tag ' + "JOIN (#{ discarded_keys('tag_versions', 'tag_id') }) blocked " + - "ON blocked.tag_id = private_tag.tag_id " + + 'ON blocked.tag_id = private_tag.tag_id ' + "JOIN JSON_TABLE(#{ names }, '$[*]' COLUMNS (name TEXT PATH '$')) private_name " + "WHERE private_name.name <> ''" ["NOT EXISTS (SELECT 1 FROM (#{ private_names }) private_name WHERE " +