activity_notification 2.4.1 → 2.5.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 +4 -4
- data/README.md +4 -2
- data/app/jobs/activity_notification/cascading_notification_job.rb +123 -0
- data/docs/Functions.md +197 -1
- data/lib/activity_notification/apis/cascading_notification_api.rb +208 -0
- data/lib/activity_notification/apis/notification_api.rb +3 -0
- data/lib/activity_notification/config.rb +10 -0
- data/lib/activity_notification/mailers/helpers.rb +27 -1
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/templates/activity_notification.rb +8 -0
- metadata +5 -441
- data/.codeclimate.yml +0 -33
- data/.coveralls.yml +0 -1
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -22
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
- data/.github/pull_request_template.md +0 -13
- data/.github/workflows/build.yml +0 -100
- data/.gitignore +0 -74
- data/.rspec +0 -3
- data/.rubocop.yml +0 -1157
- data/.yardopts +0 -6
- data/CHANGELOG.md +0 -452
- data/Gemfile +0 -31
- data/Procfile +0 -2
- data/Rakefile +0 -28
- data/activity_notification.gemspec +0 -44
- data/ai-curated-specs/issues/172/design.md +0 -220
- data/ai-curated-specs/issues/172/tasks.md +0 -326
- data/ai-curated-specs/issues/188/design.md +0 -227
- data/ai-curated-specs/issues/188/requirements.md +0 -78
- data/ai-curated-specs/issues/188/tasks.md +0 -203
- data/ai-curated-specs/issues/188/upstream-contributions.md +0 -592
- data/ai-curated-specs/issues/50/design.md +0 -235
- data/ai-curated-specs/issues/50/requirements.md +0 -49
- data/ai-curated-specs/issues/50/tasks.md +0 -232
- data/bin/_dynamodblocal +0 -4
- data/bin/bundle_update.sh +0 -7
- data/bin/deploy_on_heroku.sh +0 -16
- data/bin/install_dynamodblocal.sh +0 -5
- data/bin/start_dynamodblocal.sh +0 -47
- data/bin/stop_dynamodblocal.sh +0 -34
- data/gemfiles/Gemfile.rails-5.0 +0 -25
- data/gemfiles/Gemfile.rails-5.1 +0 -25
- data/gemfiles/Gemfile.rails-5.2 +0 -24
- data/gemfiles/Gemfile.rails-6.0 +0 -23
- data/gemfiles/Gemfile.rails-6.1 +0 -22
- data/gemfiles/Gemfile.rails-7.0 +0 -25
- data/gemfiles/Gemfile.rails-7.1 +0 -23
- data/gemfiles/Gemfile.rails-7.2 +0 -23
- data/gemfiles/Gemfile.rails-8.0 +0 -24
- data/package.json +0 -8
- data/spec/channels/notification_api_channel_shared_examples.rb +0 -59
- data/spec/channels/notification_api_channel_spec.rb +0 -49
- data/spec/channels/notification_api_with_devise_channel_spec.rb +0 -76
- data/spec/channels/notification_channel_shared_examples.rb +0 -59
- data/spec/channels/notification_channel_spec.rb +0 -48
- data/spec/channels/notification_with_devise_channel_spec.rb +0 -97
- data/spec/concerns/apis/notification_api_spec.rb +0 -1627
- data/spec/concerns/apis/subscription_api_spec.rb +0 -474
- data/spec/concerns/common_spec.rb +0 -213
- data/spec/concerns/models/group_spec.rb +0 -61
- data/spec/concerns/models/notifiable_spec.rb +0 -782
- data/spec/concerns/models/notifier_spec.rb +0 -71
- data/spec/concerns/models/subscriber_spec.rb +0 -800
- data/spec/concerns/models/target_spec.rb +0 -1285
- data/spec/concerns/renderable_spec.rb +0 -129
- data/spec/config_spec.rb +0 -85
- data/spec/controllers/common_controller_spec.rb +0 -25
- data/spec/controllers/controller_spec_utility.rb +0 -100
- data/spec/controllers/dummy_common_controller.rb +0 -5
- data/spec/controllers/notifications_api_controller_shared_examples.rb +0 -619
- data/spec/controllers/notifications_api_controller_spec.rb +0 -19
- data/spec/controllers/notifications_api_with_devise_controller_spec.rb +0 -60
- data/spec/controllers/notifications_controller_shared_examples.rb +0 -743
- data/spec/controllers/notifications_controller_spec.rb +0 -11
- data/spec/controllers/notifications_with_devise_controller_spec.rb +0 -97
- data/spec/controllers/subscriptions_api_controller_shared_examples.rb +0 -750
- data/spec/controllers/subscriptions_api_controller_spec.rb +0 -19
- data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +0 -60
- data/spec/controllers/subscriptions_controller_shared_examples.rb +0 -946
- data/spec/controllers/subscriptions_controller_spec.rb +0 -11
- data/spec/controllers/subscriptions_with_devise_controller_spec.rb +0 -97
- data/spec/factories/admins.rb +0 -5
- data/spec/factories/articles.rb +0 -5
- data/spec/factories/comments.rb +0 -6
- data/spec/factories/dummy/dummy_group.rb +0 -4
- data/spec/factories/dummy/dummy_notifiable.rb +0 -4
- data/spec/factories/dummy/dummy_notifier.rb +0 -4
- data/spec/factories/dummy/dummy_subscriber.rb +0 -4
- data/spec/factories/dummy/dummy_target.rb +0 -4
- data/spec/factories/notifications.rb +0 -7
- data/spec/factories/subscriptions.rb +0 -8
- data/spec/factories/users.rb +0 -11
- data/spec/generators/controllers_generator_spec.rb +0 -85
- data/spec/generators/install_generator_spec.rb +0 -43
- data/spec/generators/migration/migration_generator_spec.rb +0 -80
- data/spec/generators/models_generator_spec.rb +0 -96
- data/spec/generators/views_generator_spec.rb +0 -195
- data/spec/helpers/polymorphic_helpers_spec.rb +0 -89
- data/spec/helpers/view_helpers_spec.rb +0 -547
- data/spec/jobs/notification_resilience_job_spec.rb +0 -167
- data/spec/jobs/notify_all_job_spec.rb +0 -23
- data/spec/jobs/notify_job_spec.rb +0 -23
- data/spec/jobs/notify_to_job_spec.rb +0 -23
- data/spec/mailers/mailer_spec.rb +0 -214
- data/spec/mailers/notification_resilience_spec.rb +0 -263
- data/spec/models/dummy/dummy_group_spec.rb +0 -10
- data/spec/models/dummy/dummy_notifiable_spec.rb +0 -10
- data/spec/models/dummy/dummy_notifier_spec.rb +0 -10
- data/spec/models/dummy/dummy_subscriber_spec.rb +0 -8
- data/spec/models/dummy/dummy_target_spec.rb +0 -10
- data/spec/models/notification_spec.rb +0 -472
- data/spec/models/subscription_spec.rb +0 -215
- data/spec/optional_targets/action_cable_api_channel_spec.rb +0 -34
- data/spec/optional_targets/action_cable_channel_spec.rb +0 -41
- data/spec/optional_targets/amazon_sns_spec.rb +0 -47
- data/spec/optional_targets/base_spec.rb +0 -45
- data/spec/optional_targets/slack_spec.rb +0 -44
- data/spec/orm/dynamoid_spec.rb +0 -115
- data/spec/rails_app/Rakefile +0 -15
- data/spec/rails_app/app/assets/config/manifest.js +0 -3
- data/spec/rails_app/app/assets/images/.keep +0 -0
- data/spec/rails_app/app/assets/javascripts/application.js +0 -3
- data/spec/rails_app/app/assets/javascripts/cable.js +0 -12
- data/spec/rails_app/app/assets/stylesheets/application.css +0 -15
- data/spec/rails_app/app/assets/stylesheets/reset.css +0 -85
- data/spec/rails_app/app/assets/stylesheets/style.css +0 -244
- data/spec/rails_app/app/controllers/admins_controller.rb +0 -21
- data/spec/rails_app/app/controllers/application_controller.rb +0 -5
- data/spec/rails_app/app/controllers/articles_controller.rb +0 -67
- data/spec/rails_app/app/controllers/comments_controller.rb +0 -36
- data/spec/rails_app/app/controllers/concerns/.keep +0 -0
- data/spec/rails_app/app/controllers/spa_controller.rb +0 -7
- data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users_controller.rb +0 -26
- data/spec/rails_app/app/helpers/application_helper.rb +0 -2
- data/spec/rails_app/app/helpers/devise_helper.rb +0 -2
- data/spec/rails_app/app/javascript/App.vue +0 -40
- data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +0 -82
- data/spec/rails_app/app/javascript/components/Top.vue +0 -98
- data/spec/rails_app/app/javascript/components/notifications/Index.vue +0 -200
- data/spec/rails_app/app/javascript/components/notifications/Notification.vue +0 -133
- data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +0 -122
- data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +0 -279
- data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +0 -112
- data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +0 -141
- data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +0 -226
- data/spec/rails_app/app/javascript/config/development.js +0 -5
- data/spec/rails_app/app/javascript/config/environment.js +0 -7
- data/spec/rails_app/app/javascript/config/production.js +0 -5
- data/spec/rails_app/app/javascript/config/test.js +0 -5
- data/spec/rails_app/app/javascript/packs/application.js +0 -18
- data/spec/rails_app/app/javascript/packs/spa.js +0 -14
- data/spec/rails_app/app/javascript/router/index.js +0 -73
- data/spec/rails_app/app/javascript/store/index.js +0 -37
- data/spec/rails_app/app/mailers/.keep +0 -0
- data/spec/rails_app/app/mailers/custom_notification_mailer.rb +0 -5
- data/spec/rails_app/app/models/admin.rb +0 -35
- data/spec/rails_app/app/models/article.rb +0 -54
- data/spec/rails_app/app/models/comment.rb +0 -81
- data/spec/rails_app/app/models/dummy/dummy_base.rb +0 -11
- data/spec/rails_app/app/models/dummy/dummy_group.rb +0 -23
- data/spec/rails_app/app/models/dummy/dummy_notifiable.rb +0 -15
- data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +0 -27
- data/spec/rails_app/app/models/dummy/dummy_notifier.rb +0 -15
- data/spec/rails_app/app/models/dummy/dummy_subscriber.rb +0 -14
- data/spec/rails_app/app/models/dummy/dummy_target.rb +0 -16
- data/spec/rails_app/app/models/user.rb +0 -73
- data/spec/rails_app/app/views/activity_notification/mailer/dummy_subscribers/test_key.text.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +0 -146
- data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_path_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/users/_custom_index.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/users/custom/_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +0 -10
- data/spec/rails_app/app/views/articles/_form.html.erb +0 -24
- data/spec/rails_app/app/views/articles/edit.html.erb +0 -8
- data/spec/rails_app/app/views/articles/index.html.erb +0 -113
- data/spec/rails_app/app/views/articles/new.html.erb +0 -7
- data/spec/rails_app/app/views/articles/show.html.erb +0 -49
- data/spec/rails_app/app/views/layouts/_header.html.erb +0 -46
- data/spec/rails_app/app/views/layouts/application.html.erb +0 -15
- data/spec/rails_app/app/views/spa/index.html.erb +0 -2
- data/spec/rails_app/babel.config.js +0 -72
- data/spec/rails_app/bin/bundle +0 -3
- data/spec/rails_app/bin/rails +0 -4
- data/spec/rails_app/bin/rake +0 -4
- data/spec/rails_app/bin/setup +0 -29
- data/spec/rails_app/bin/webpack +0 -18
- data/spec/rails_app/bin/webpack-dev-server +0 -18
- data/spec/rails_app/config/application.rb +0 -54
- data/spec/rails_app/config/boot.rb +0 -5
- data/spec/rails_app/config/cable.yml +0 -8
- data/spec/rails_app/config/database.yml +0 -36
- data/spec/rails_app/config/dynamoid.rb +0 -13
- data/spec/rails_app/config/environment.rb +0 -26
- data/spec/rails_app/config/environments/development.rb +0 -60
- data/spec/rails_app/config/environments/production.rb +0 -85
- data/spec/rails_app/config/environments/test.rb +0 -53
- data/spec/rails_app/config/initializers/activity_notification.rb +0 -104
- data/spec/rails_app/config/initializers/assets.rb +0 -11
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/rails_app/config/initializers/cookies_serializer.rb +0 -3
- data/spec/rails_app/config/initializers/copy_it.aws.rb.template +0 -6
- data/spec/rails_app/config/initializers/devise.rb +0 -278
- data/spec/rails_app/config/initializers/devise_token_auth.rb +0 -55
- data/spec/rails_app/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/rails_app/config/initializers/inflections.rb +0 -16
- data/spec/rails_app/config/initializers/mime_types.rb +0 -4
- data/spec/rails_app/config/initializers/mysql.rb +0 -9
- data/spec/rails_app/config/initializers/session_store.rb +0 -3
- data/spec/rails_app/config/initializers/wrap_parameters.rb +0 -14
- data/spec/rails_app/config/initializers/zeitwerk.rb +0 -10
- data/spec/rails_app/config/locales/activity_notification.en.yml +0 -26
- data/spec/rails_app/config/locales/devise.en.yml +0 -62
- data/spec/rails_app/config/mongoid.yml +0 -13
- data/spec/rails_app/config/routes.rb +0 -50
- data/spec/rails_app/config/secrets.yml +0 -22
- data/spec/rails_app/config/webpack/development.js +0 -5
- data/spec/rails_app/config/webpack/environment.js +0 -7
- data/spec/rails_app/config/webpack/loaders/vue.js +0 -6
- data/spec/rails_app/config/webpack/production.js +0 -5
- data/spec/rails_app/config/webpack/test.js +0 -5
- data/spec/rails_app/config/webpacker.yml +0 -97
- data/spec/rails_app/config.ru +0 -4
- data/spec/rails_app/db/migrate/20160716000000_create_test_tables.rb +0 -42
- data/spec/rails_app/db/migrate/20181209000000_create_activity_notification_tables.rb +0 -33
- data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +0 -10
- data/spec/rails_app/db/schema.rb +0 -98
- data/spec/rails_app/db/seeds.rb +0 -95
- data/spec/rails_app/lib/custom_optional_targets/console_output.rb +0 -16
- data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +0 -14
- data/spec/rails_app/lib/custom_optional_targets/wrong_target.rb +0 -13
- data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +0 -29
- data/spec/rails_app/package.json +0 -23
- data/spec/rails_app/postcss.config.js +0 -12
- data/spec/rails_app/public/404.html +0 -67
- data/spec/rails_app/public/422.html +0 -67
- data/spec/rails_app/public/500.html +0 -66
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/roles/acts_as_group_spec.rb +0 -30
- data/spec/roles/acts_as_notifiable_spec.rb +0 -432
- data/spec/roles/acts_as_notifier_spec.rb +0 -30
- data/spec/roles/acts_as_target_spec.rb +0 -36
- data/spec/spec_helper.rb +0 -56
- data/spec/version_spec.rb +0 -31
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
# Design Document: Bulk destroy notifications API
|
|
2
|
-
|
|
3
|
-
## Issue Summary
|
|
4
|
-
GitHub Issue [#172](https://github.com/simukappu/activity_notification/issues/172) requests the ability to delete more than one notification for a target. Currently, only single notification deletion is available through the `destroy` API. The user wants a `bulk_destroy` API or provision to create custom APIs for bulk destroying notifications.
|
|
5
|
-
|
|
6
|
-
## Current State Analysis
|
|
7
|
-
|
|
8
|
-
### Existing Destroy Functionality
|
|
9
|
-
- **Single Destroy**: `DELETE /:target_type/:target_id/notifications/:id`
|
|
10
|
-
- Implemented in `NotificationsController#destroy`
|
|
11
|
-
- API version in `NotificationsApiController#destroy`
|
|
12
|
-
- Simply calls `@notification.destroy` on individual notification
|
|
13
|
-
|
|
14
|
-
### Existing Bulk Operations Pattern
|
|
15
|
-
- **Bulk Open**: `POST /:target_type/:target_id/notifications/open_all`
|
|
16
|
-
- Implemented in `NotificationsController#open_all`
|
|
17
|
-
- Uses `@target.open_all_notifications(params)`
|
|
18
|
-
- Backend implementation in `NotificationApi#open_all_of`
|
|
19
|
-
- Uses `update_all(opened_at: opened_at)` for efficient bulk updates
|
|
20
|
-
|
|
21
|
-
## Proposed Implementation
|
|
22
|
-
|
|
23
|
-
### 1. Backend API Method (NotificationApi)
|
|
24
|
-
**File**: `lib/activity_notification/apis/notification_api.rb`
|
|
25
|
-
|
|
26
|
-
Add a new class method `destroy_all_of` following the pattern of `open_all_of`:
|
|
27
|
-
|
|
28
|
-
```ruby
|
|
29
|
-
# Destroys all notifications of the target matching the filter criteria.
|
|
30
|
-
#
|
|
31
|
-
# @param [Object] target Target of the notifications to destroy
|
|
32
|
-
# @param [Hash] options Options for filtering notifications to destroy
|
|
33
|
-
# @option options [String] :filtered_by_type (nil) Notifiable type for filter
|
|
34
|
-
# @option options [Object] :filtered_by_group (nil) Group instance for filter
|
|
35
|
-
# @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
|
|
36
|
-
# @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
|
|
37
|
-
# @option options [String] :filtered_by_key (nil) Key of the notification for filter
|
|
38
|
-
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
39
|
-
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
40
|
-
# @option options [Array] :ids (nil) Array of specific notification IDs to destroy
|
|
41
|
-
# @return [Array<Notification>] Destroyed notification records
|
|
42
|
-
def destroy_all_of(target, options = {})
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### 2. Target Model Method
|
|
46
|
-
**File**: `lib/activity_notification/models/concerns/target.rb`
|
|
47
|
-
|
|
48
|
-
Add instance method `destroy_all_notifications` following the pattern of `open_all_notifications`:
|
|
49
|
-
|
|
50
|
-
```ruby
|
|
51
|
-
# Destroys all notifications of the target matching the filter criteria.
|
|
52
|
-
#
|
|
53
|
-
# @param [Hash] options Options for filtering notifications to destroy
|
|
54
|
-
# @option options [String] :filtered_by_type (nil) Notifiable type for filter
|
|
55
|
-
# @option options [Object] :filtered_by_group (nil) Group instance for filter
|
|
56
|
-
# @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
|
|
57
|
-
# @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
|
|
58
|
-
# @option options [String] :filtered_by_key (nil) Key of the notification for filter
|
|
59
|
-
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
60
|
-
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
61
|
-
# @option options [Array] :ids (nil) Array of specific notification IDs to destroy
|
|
62
|
-
# @return [Array<Notification>] Destroyed notification records
|
|
63
|
-
def destroy_all_notifications(options = {})
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 3. Controller Actions
|
|
67
|
-
|
|
68
|
-
#### Web Controller
|
|
69
|
-
**File**: `app/controllers/activity_notification/notifications_controller.rb`
|
|
70
|
-
|
|
71
|
-
Add new action `destroy_all`:
|
|
72
|
-
|
|
73
|
-
```ruby
|
|
74
|
-
# Destroys all notifications of the target matching filter criteria.
|
|
75
|
-
#
|
|
76
|
-
# POST /:target_type/:target_id/notifications/destroy_all
|
|
77
|
-
# @overload destroy_all(params)
|
|
78
|
-
# @param [Hash] params Request parameters
|
|
79
|
-
# @option params [String] :filter (nil) Filter option to load notification index by their status (Nothing as auto, 'opened' or 'unopened')
|
|
80
|
-
# @option params [String] :limit (nil) Maximum number of notifications to return
|
|
81
|
-
# @option params [String] :without_grouping ('false') Whether notification index will include group members
|
|
82
|
-
# @option params [String] :with_group_members ('false') Whether notification index will include group members
|
|
83
|
-
# @option params [String] :filtered_by_type (nil) Notifiable type to filter notifications
|
|
84
|
-
# @option params [String] :filtered_by_group_type (nil) Group type to filter notifications, valid with :filtered_by_group_id
|
|
85
|
-
# @option params [String] :filtered_by_group_id (nil) Group instance ID to filter notifications, valid with :filtered_by_group_type
|
|
86
|
-
# @option params [String] :filtered_by_key (nil) Key of notifications to filter
|
|
87
|
-
# @option params [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
88
|
-
# @option params [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
89
|
-
# @option params [Array] :ids (nil) Array of specific notification IDs to destroy
|
|
90
|
-
# @option params [String] :reload ('true') Whether notification index will be reloaded
|
|
91
|
-
# @return [Response] JavaScript view for ajax request or redirects to back as default
|
|
92
|
-
def destroy_all
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
#### API Controller
|
|
96
|
-
**File**: `app/controllers/activity_notification/notifications_api_controller.rb`
|
|
97
|
-
|
|
98
|
-
Add new action `destroy_all`:
|
|
99
|
-
|
|
100
|
-
```ruby
|
|
101
|
-
# Destroys all notifications of the target matching filter criteria.
|
|
102
|
-
#
|
|
103
|
-
# POST /:target_type/:target_id/notifications/destroy_all
|
|
104
|
-
# @overload destroy_all(params)
|
|
105
|
-
# @param [Hash] params Request parameters
|
|
106
|
-
# @option params [String] :filtered_by_type (nil) Notifiable type to filter notifications
|
|
107
|
-
# @option params [String] :filtered_by_group_type (nil) Group type to filter notifications, valid with :filtered_by_group_id
|
|
108
|
-
# @option params [String] :filtered_by_group_id (nil) Group instance ID to filter notifications, valid with :filtered_by_group_type
|
|
109
|
-
# @option params [String] :filtered_by_key (nil) Key of notifications to filter
|
|
110
|
-
# @option params [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
111
|
-
# @option params [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
112
|
-
# @option params [Array] :ids (nil) Array of specific notification IDs to destroy
|
|
113
|
-
# @return [JSON] count: number of destroyed notification records, notifications: destroyed notifications
|
|
114
|
-
def destroy_all
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### 4. Routes Configuration
|
|
118
|
-
**File**: Routes will be automatically generated by the existing `notify_to` helper
|
|
119
|
-
|
|
120
|
-
The route will be: `POST /:target_type/:target_id/notifications/destroy_all`
|
|
121
|
-
|
|
122
|
-
### 5. View Templates
|
|
123
|
-
**Files**:
|
|
124
|
-
- `app/views/activity_notification/notifications/default/destroy_all.js.erb`
|
|
125
|
-
- Template generators will need to be updated to include the new view
|
|
126
|
-
|
|
127
|
-
### 6. Swagger API Documentation
|
|
128
|
-
**File**: Update Swagger documentation to include the new bulk destroy endpoint
|
|
129
|
-
|
|
130
|
-
### 7. Generator Templates
|
|
131
|
-
**Files**: Update controller generator templates to include the new `destroy_all` action:
|
|
132
|
-
- `lib/generators/templates/controllers/notifications_api_controller.rb`
|
|
133
|
-
- `lib/generators/templates/controllers/notifications_controller.rb`
|
|
134
|
-
- `lib/generators/templates/controllers/notifications_with_devise_controller.rb`
|
|
135
|
-
|
|
136
|
-
## Implementation Details
|
|
137
|
-
|
|
138
|
-
### Filter Options Support
|
|
139
|
-
The bulk destroy API will support the same filtering options as the existing `open_all` functionality:
|
|
140
|
-
- `filtered_by_type`: Filter by notifiable type
|
|
141
|
-
- `filtered_by_group_type` + `filtered_by_group_id`: Filter by group
|
|
142
|
-
- `filtered_by_key`: Filter by notification key
|
|
143
|
-
- `later_than` / `earlier_than`: Filter by time range
|
|
144
|
-
- `ids`: Array of specific notification IDs (new option for precise control)
|
|
145
|
-
|
|
146
|
-
### Safety Considerations
|
|
147
|
-
1. **Validation**: Ensure all notifications belong to the specified target
|
|
148
|
-
2. **Permissions**: Leverage existing authentication/authorization patterns
|
|
149
|
-
3. **Soft Delete**: Consider if soft delete should be supported (follow existing destroy pattern)
|
|
150
|
-
4. **Callbacks**: Ensure any existing destroy callbacks are properly triggered
|
|
151
|
-
|
|
152
|
-
### Performance Considerations
|
|
153
|
-
1. **Batch Operations**: Use `destroy_all` for efficient database operations
|
|
154
|
-
2. **Memory Usage**: For large datasets, consider pagination or streaming
|
|
155
|
-
3. **Callbacks**: Balance between performance and callback execution
|
|
156
|
-
|
|
157
|
-
### Error Handling
|
|
158
|
-
1. **Partial Failures**: Handle cases where some notifications can't be destroyed
|
|
159
|
-
2. **Validation Errors**: Provide meaningful error messages
|
|
160
|
-
3. **Authorization Errors**: Consistent with existing error handling patterns
|
|
161
|
-
|
|
162
|
-
## Testing Requirements
|
|
163
|
-
|
|
164
|
-
### Unit Tests
|
|
165
|
-
- Test `NotificationApi#destroy_all_of` method
|
|
166
|
-
- Test `Target#destroy_all_notifications` method
|
|
167
|
-
- Test controller actions for both web and API versions
|
|
168
|
-
|
|
169
|
-
### Integration Tests
|
|
170
|
-
- Test complete request/response cycle
|
|
171
|
-
- Test with various filter combinations
|
|
172
|
-
- Test error scenarios
|
|
173
|
-
|
|
174
|
-
### Performance Tests
|
|
175
|
-
- Test with large datasets
|
|
176
|
-
- Verify efficient database queries
|
|
177
|
-
|
|
178
|
-
## Migration Considerations
|
|
179
|
-
- No database schema changes required
|
|
180
|
-
- Backward compatible addition
|
|
181
|
-
- Follows existing patterns and conventions
|
|
182
|
-
|
|
183
|
-
## Documentation Updates
|
|
184
|
-
- Update README.md with new bulk destroy functionality
|
|
185
|
-
- Update API documentation
|
|
186
|
-
- Update controller documentation
|
|
187
|
-
- Add examples to documentation
|
|
188
|
-
|
|
189
|
-
## Alternative Implementation Options
|
|
190
|
-
|
|
191
|
-
### Option 1: Single Endpoint with Multiple IDs
|
|
192
|
-
Instead of filter-based bulk destroy, accept an array of notification IDs:
|
|
193
|
-
```
|
|
194
|
-
POST /:target_type/:target_id/notifications/destroy_all
|
|
195
|
-
Body: { "ids": [1, 2, 3, 4, 5] }
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Option 2: RESTful Bulk Operations
|
|
199
|
-
Follow RESTful conventions with a bulk operations endpoint:
|
|
200
|
-
```
|
|
201
|
-
POST /:target_type/:target_id/notifications/bulk
|
|
202
|
-
Body: { "action": "destroy", "filters": {...} }
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Option 3: Query Parameter Approach
|
|
206
|
-
Use existing destroy endpoint with query parameters:
|
|
207
|
-
```
|
|
208
|
-
DELETE /:target_type/:target_id/notifications?ids[]=1&ids[]=2&ids[]=3
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## Recommended Approach
|
|
212
|
-
The proposed implementation follows the existing pattern established by `open_all` functionality, making it consistent with the current codebase architecture. This approach provides:
|
|
213
|
-
|
|
214
|
-
1. **Consistency**: Matches existing bulk operation patterns
|
|
215
|
-
2. **Flexibility**: Supports various filtering options
|
|
216
|
-
3. **Safety**: Leverages existing validation and authorization
|
|
217
|
-
4. **Performance**: Uses efficient bulk database operations
|
|
218
|
-
5. **Maintainability**: Follows established code organization
|
|
219
|
-
|
|
220
|
-
The implementation should prioritize the filter-based approach (similar to `open_all`) while also supporting the `ids` parameter for precise control when needed.
|
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
# Implementation Plan
|
|
2
|
-
|
|
3
|
-
## Problem 1: Mongoid ORM Compatibility Issue with ID Array Filtering
|
|
4
|
-
|
|
5
|
-
### Issue Description
|
|
6
|
-
The bulk destroy functionality works correctly with ActiveRecord ORM but fails with Mongoid ORM. Specifically, the test case `context 'with ids options'` in `spec/concerns/apis/notification_api_spec.rb` is failing.
|
|
7
|
-
|
|
8
|
-
**Location**: `lib/activity_notification/apis/notification_api.rb` line 440
|
|
9
|
-
**Problematic Code**:
|
|
10
|
-
```ruby
|
|
11
|
-
target_notifications = target_notifications.where(id: options[:ids])
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
### Root Cause Analysis
|
|
15
|
-
The issue stems from different query syntax requirements between ActiveRecord and Mongoid when filtering by an array of IDs:
|
|
16
|
-
|
|
17
|
-
1. **ActiveRecord**: Uses `where(id: [1, 2, 3])` which automatically translates to SQL `WHERE id IN (1, 2, 3)`
|
|
18
|
-
2. **Mongoid**: Requires explicit `$in` operator syntax for array matching: `where(id: { '$in' => [1, 2, 3] })`
|
|
19
|
-
|
|
20
|
-
### Current Implementation Problem
|
|
21
|
-
The current implementation uses ActiveRecord syntax:
|
|
22
|
-
```ruby
|
|
23
|
-
target_notifications = target_notifications.where(id: options[:ids])
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
This works for ActiveRecord but fails for Mongoid because Mongoid doesn't automatically interpret an array as an `$in` operation.
|
|
27
|
-
|
|
28
|
-
### Expected Behavior
|
|
29
|
-
- When `options[:ids]` contains `[notification1.id, notification2.id]`, only notifications with those specific IDs should be destroyed
|
|
30
|
-
- The filtering should work consistently across both ActiveRecord and Mongoid ORMs
|
|
31
|
-
- Other filter options should still be applied in combination with ID filtering
|
|
32
|
-
|
|
33
|
-
### Test Case Analysis
|
|
34
|
-
The failing test:
|
|
35
|
-
```ruby
|
|
36
|
-
it "destroys notifications with specified IDs only" do
|
|
37
|
-
notification_to_destroy = @user_1.notifications.first
|
|
38
|
-
described_class.destroy_all_of(@user_1, { ids: [notification_to_destroy.id] })
|
|
39
|
-
expect(@user_1.notifications.count).to eq(1)
|
|
40
|
-
expect(@user_1.notifications.first).not_to eq(notification_to_destroy)
|
|
41
|
-
end
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
This test expects that when an array of IDs is provided, only those specific notifications are destroyed.
|
|
45
|
-
|
|
46
|
-
### Solution Strategy
|
|
47
|
-
Implement ORM-specific ID filtering logic that:
|
|
48
|
-
|
|
49
|
-
1. **Detection**: Check the current ORM configuration using `ActivityNotification.config.orm`
|
|
50
|
-
2. **ActiveRecord Path**: Use existing `where(id: options[:ids])` syntax
|
|
51
|
-
3. **Mongoid Path**: Use `where(id: { '$in' => options[:ids] })` syntax
|
|
52
|
-
4. **Dynamoid Path**: Use `where(‘id.in‘: options[:ids])` syntax
|
|
53
|
-
|
|
54
|
-
### Implementation Plan
|
|
55
|
-
1. **Conditional Logic**: Add ORM detection in the `destroy_all_of` method
|
|
56
|
-
2. **Mongoid Syntax**: Use `{ '$in' => options[:ids] }` for Mongoid
|
|
57
|
-
3. **Backward Compatibility**: Ensure ActiveRecord continues to work as before
|
|
58
|
-
4. **Testing**: Verify both ORMs work correctly with the new implementation
|
|
59
|
-
|
|
60
|
-
### Code Changes Required
|
|
61
|
-
**File**: `lib/activity_notification/apis/notification_api.rb`
|
|
62
|
-
**Method**: `destroy_all_of` (around line 440)
|
|
63
|
-
|
|
64
|
-
Replace:
|
|
65
|
-
```ruby
|
|
66
|
-
if options[:ids].present?
|
|
67
|
-
target_notifications = target_notifications.where(id: options[:ids])
|
|
68
|
-
end
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
With ORM-specific logic:
|
|
72
|
-
```ruby
|
|
73
|
-
if options[:ids].present?
|
|
74
|
-
case ActivityNotification.config.orm
|
|
75
|
-
when :mongoid
|
|
76
|
-
target_notifications = target_notifications.where(id: { '$in' => options[:ids] })
|
|
77
|
-
when :dynamoid
|
|
78
|
-
target_notifications = target_notifications.where('id.in': options[:ids])
|
|
79
|
-
else # :active_record
|
|
80
|
-
target_notifications = target_notifications.where(id: options[:ids])
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Testing Requirements
|
|
86
|
-
1. **Unit Tests**: Ensure the method works with both ActiveRecord and Mongoid
|
|
87
|
-
2. **Integration Tests**: Verify the complete destroy_all functionality
|
|
88
|
-
3. **Regression Tests**: Ensure existing functionality remains intact
|
|
89
|
-
|
|
90
|
-
### Risk Assessment
|
|
91
|
-
- **Low Risk**: The change is isolated to the ID filtering logic
|
|
92
|
-
- **Backward Compatible**: ActiveRecord behavior remains unchanged
|
|
93
|
-
- **Well-Tested**: Existing test suite will catch any regressions
|
|
94
|
-
|
|
95
|
-
### Future Considerations
|
|
96
|
-
- Consider extracting ORM-specific query logic into a helper method if more similar cases arise
|
|
97
|
-
- Document the ORM differences for future developers
|
|
98
|
-
- Consider adding similar logic to other methods that might have the same issue
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Problem 2: Add IDs Parameter to open_all API
|
|
103
|
-
|
|
104
|
-
### Issue Description
|
|
105
|
-
Enhance the `open_all_of` method to support the `ids` parameter functionality, similar to the implementation in `destroy_all_of`. This will allow users to open specific notifications by providing an array of notification IDs.
|
|
106
|
-
|
|
107
|
-
### Current State Analysis
|
|
108
|
-
|
|
109
|
-
#### Existing open_all_of Method
|
|
110
|
-
**Location**: `lib/activity_notification/apis/notification_api.rb` (around line 415)
|
|
111
|
-
|
|
112
|
-
**Current Implementation**:
|
|
113
|
-
```ruby
|
|
114
|
-
def open_all_of(target, options = {})
|
|
115
|
-
opened_at = options[:opened_at] || Time.current
|
|
116
|
-
target_unopened_notifications = target.notifications.unopened_only.filtered_by_options(options)
|
|
117
|
-
opened_notifications = target_unopened_notifications.to_a.map { |n| n.opened_at = opened_at; n }
|
|
118
|
-
target_unopened_notifications.update_all(opened_at: opened_at)
|
|
119
|
-
opened_notifications
|
|
120
|
-
end
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
**Current Parameters**:
|
|
124
|
-
- `opened_at`: Time to set to opened_at of the notification record
|
|
125
|
-
- `filtered_by_type`: Notifiable type for filter
|
|
126
|
-
- `filtered_by_group`: Group instance for filter
|
|
127
|
-
- `filtered_by_group_type`: Group type for filter, valid with :filtered_by_group_id
|
|
128
|
-
- `filtered_by_group_id`: Group instance id for filter, valid with :filtered_by_group_type
|
|
129
|
-
- `filtered_by_key`: Key of the notification for filter
|
|
130
|
-
- `later_than`: ISO 8601 format time to filter notification index later than specified time
|
|
131
|
-
- `earlier_than`: ISO 8601 format time to filter notification index earlier than specified time
|
|
132
|
-
|
|
133
|
-
### Proposed Enhancement
|
|
134
|
-
|
|
135
|
-
#### Add IDs Parameter Support
|
|
136
|
-
Add support for the `ids` parameter to allow opening specific notifications by their IDs, following the same pattern as `destroy_all_of`.
|
|
137
|
-
|
|
138
|
-
#### Updated Method Signature
|
|
139
|
-
```ruby
|
|
140
|
-
# @option options [Array] :ids (nil) Array of specific notification IDs to open
|
|
141
|
-
def open_all_of(target, options = {})
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Implementation Strategy
|
|
145
|
-
1. **Reuse existing pattern**: Follow the same ORM-specific ID filtering logic implemented in `destroy_all_of`
|
|
146
|
-
2. **Maintain backward compatibility**: Ensure existing functionality remains unchanged
|
|
147
|
-
3. **Consistent behavior**: Apply ID filtering after other filters, similar to destroy_all_of
|
|
148
|
-
|
|
149
|
-
### Code Changes Required
|
|
150
|
-
|
|
151
|
-
#### 1. Update Method Documentation
|
|
152
|
-
**File**: `lib/activity_notification/apis/notification_api.rb`
|
|
153
|
-
|
|
154
|
-
Add the `ids` parameter to the method documentation:
|
|
155
|
-
```ruby
|
|
156
|
-
# @option options [Array] :ids (nil) Array of specific notification IDs to open
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
#### 2. Add ID Filtering Logic
|
|
160
|
-
Insert the same ORM-specific ID filtering logic used in `destroy_all_of`:
|
|
161
|
-
|
|
162
|
-
```ruby
|
|
163
|
-
def open_all_of(target, options = {})
|
|
164
|
-
opened_at = options[:opened_at] || Time.current
|
|
165
|
-
target_unopened_notifications = target.notifications.unopened_only.filtered_by_options(options)
|
|
166
|
-
|
|
167
|
-
# Add ID filtering logic (same as destroy_all_of)
|
|
168
|
-
if options[:ids].present?
|
|
169
|
-
# :nocov:
|
|
170
|
-
case ActivityNotification.config.orm
|
|
171
|
-
when :mongoid
|
|
172
|
-
target_unopened_notifications = target_unopened_notifications.where(id: { '$in' => options[:ids] })
|
|
173
|
-
when :dynamoid
|
|
174
|
-
target_unopened_notifications = target_unopened_notifications.where('id.in': options[:ids])
|
|
175
|
-
else # :active_record
|
|
176
|
-
target_unopened_notifications = target_unopened_notifications.where(id: options[:ids])
|
|
177
|
-
end
|
|
178
|
-
# :nocov:
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
opened_notifications = target_unopened_notifications.to_a.map { |n| n.opened_at = opened_at; n }
|
|
182
|
-
target_unopened_notifications.update_all(opened_at: opened_at)
|
|
183
|
-
opened_notifications
|
|
184
|
-
end
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
#### 3. Update Controller Actions
|
|
188
|
-
The controller actions that use `open_all_of` should be updated to accept and pass through the `ids` parameter:
|
|
189
|
-
|
|
190
|
-
**Files to Update**:
|
|
191
|
-
- `app/controllers/activity_notification/notifications_controller.rb`
|
|
192
|
-
- `app/controllers/activity_notification/notifications_api_controller.rb`
|
|
193
|
-
|
|
194
|
-
**Parameter Addition**:
|
|
195
|
-
```ruby
|
|
196
|
-
# Add :ids to permitted parameters
|
|
197
|
-
params.permit(:ids => [])
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
#### 4. Update API Documentation
|
|
201
|
-
**File**: `lib/activity_notification/controllers/concerns/swagger/notifications_api.rb`
|
|
202
|
-
|
|
203
|
-
Add `ids` parameter to the Swagger documentation for the open_all endpoint:
|
|
204
|
-
```ruby
|
|
205
|
-
parameter do
|
|
206
|
-
key :name, :ids
|
|
207
|
-
key :in, :query
|
|
208
|
-
key :description, 'Array of specific notification IDs to open'
|
|
209
|
-
key :required, false
|
|
210
|
-
key :type, :array
|
|
211
|
-
items do
|
|
212
|
-
key :type, :string
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Testing Requirements
|
|
218
|
-
|
|
219
|
-
#### 1. Add Test Cases
|
|
220
|
-
**File**: `spec/concerns/apis/notification_api_spec.rb`
|
|
221
|
-
|
|
222
|
-
Add test cases similar to the `destroy_all_of` tests:
|
|
223
|
-
|
|
224
|
-
```ruby
|
|
225
|
-
context 'with ids options' do
|
|
226
|
-
it "opens notifications with specified IDs only" do
|
|
227
|
-
notification_to_open = @user_1.notifications.first
|
|
228
|
-
described_class.open_all_of(@user_1, { ids: [notification_to_open.id] })
|
|
229
|
-
expect(@user_1.notifications.unopened_only.count).to eq(1)
|
|
230
|
-
expect(@user_1.notifications.opened_only!.count).to eq(1)
|
|
231
|
-
expect(@user_1.notifications.opened_only!.first).to eq(notification_to_open)
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
it "applies other filter options when ids are specified" do
|
|
235
|
-
notification_to_open = @user_1.notifications.first
|
|
236
|
-
described_class.open_all_of(@user_1, {
|
|
237
|
-
ids: [notification_to_open.id],
|
|
238
|
-
filtered_by_key: 'non_existent_key'
|
|
239
|
-
})
|
|
240
|
-
expect(@user_1.notifications.unopened_only.count).to eq(2)
|
|
241
|
-
expect(@user_1.notifications.opened_only!.count).to eq(0)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
it "only opens unopened notifications even when opened notification IDs are provided" do
|
|
245
|
-
# First open one notification
|
|
246
|
-
notification_to_open = @user_1.notifications.first
|
|
247
|
-
notification_to_open.open!
|
|
248
|
-
|
|
249
|
-
# Try to open it again using ids parameter
|
|
250
|
-
described_class.open_all_of(@user_1, { ids: [notification_to_open.id] })
|
|
251
|
-
|
|
252
|
-
# Should not affect the count since it was already opened
|
|
253
|
-
expect(@user_1.notifications.unopened_only.count).to eq(1)
|
|
254
|
-
expect(@user_1.notifications.opened_only!.count).to eq(1)
|
|
255
|
-
end
|
|
256
|
-
end
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
#### 2. Update Controller Tests
|
|
260
|
-
**File**: `spec/controllers/notifications_api_controller_shared_examples.rb`
|
|
261
|
-
|
|
262
|
-
Add test cases for the API controller to ensure the `ids` parameter is properly handled:
|
|
263
|
-
|
|
264
|
-
```ruby
|
|
265
|
-
context 'with ids parameter' do
|
|
266
|
-
it "opens only specified notifications" do
|
|
267
|
-
notification_to_open = @user.notifications.first
|
|
268
|
-
post open_all_notification_path(@user), params: { ids: [notification_to_open.id] }
|
|
269
|
-
expect(response).to have_http_status(200)
|
|
270
|
-
expect(@user.notifications.unopened_only.count).to eq(1)
|
|
271
|
-
expect(@user.notifications.opened_only!.count).to eq(1)
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Benefits
|
|
277
|
-
|
|
278
|
-
#### 1. Consistency
|
|
279
|
-
- Provides consistent API between `open_all_of` and `destroy_all_of` methods
|
|
280
|
-
- Both methods now support the same filtering options including `ids`
|
|
281
|
-
|
|
282
|
-
#### 2. Flexibility
|
|
283
|
-
- Allows precise control over which notifications to open
|
|
284
|
-
- Enables batch operations on specific notifications
|
|
285
|
-
- Supports complex filtering combinations
|
|
286
|
-
|
|
287
|
-
#### 3. Performance
|
|
288
|
-
- Efficient database operations using bulk updates
|
|
289
|
-
- Reduces the need for multiple individual open operations
|
|
290
|
-
|
|
291
|
-
#### 4. User Experience
|
|
292
|
-
- Provides the functionality requested in the original issue
|
|
293
|
-
- Enables building more sophisticated notification management UIs
|
|
294
|
-
|
|
295
|
-
### Implementation Considerations
|
|
296
|
-
|
|
297
|
-
#### 1. Backward Compatibility
|
|
298
|
-
- All existing functionality remains unchanged
|
|
299
|
-
- New `ids` parameter is optional
|
|
300
|
-
- Existing tests should continue to pass
|
|
301
|
-
|
|
302
|
-
#### 2. ORM Compatibility
|
|
303
|
-
- Uses the same ORM-specific logic as `destroy_all_of`
|
|
304
|
-
- Tested across ActiveRecord, Mongoid, and Dynamoid
|
|
305
|
-
|
|
306
|
-
#### 3. Security
|
|
307
|
-
- ID filtering is applied after target validation
|
|
308
|
-
- Only notifications belonging to the specified target can be opened
|
|
309
|
-
- Follows existing security patterns
|
|
310
|
-
|
|
311
|
-
#### 4. Error Handling
|
|
312
|
-
- Invalid IDs are silently ignored (consistent with existing behavior)
|
|
313
|
-
- Non-existent notifications don't cause errors
|
|
314
|
-
- Maintains existing error handling patterns
|
|
315
|
-
|
|
316
|
-
### Risk Assessment
|
|
317
|
-
- **Low Risk**: Follows established patterns from `destroy_all_of`
|
|
318
|
-
- **Backward Compatible**: ActiveRecord behavior remains unchanged
|
|
319
|
-
- **Well-Tested**: Existing test suite will catch any regressions
|
|
320
|
-
|
|
321
|
-
### Implementation Timeline
|
|
322
|
-
1. **Phase 1**: Update `open_all_of` method with ID filtering logic
|
|
323
|
-
2. **Phase 2**: Add comprehensive test cases
|
|
324
|
-
3. **Phase 3**: Update controller actions and API documentation
|
|
325
|
-
4. **Phase 4**: Update controller tests and integration tests
|
|
326
|
-
5. **Phase 5**: Documentation updates and final testing
|