Skip to content

fix(mail): db:generate_feedback_chips has no production guard and modifies existing outcomes - #113

Open
gnahk66 wants to merge 1561 commits into
thoth-tech:developmentfrom
ontrack-features-t2-2026:fix/bgw-17
Open

fix(mail): db:generate_feedback_chips has no production guard and modifies existing outcomes#113
gnahk66 wants to merge 1561 commits into
thoth-tech:developmentfrom
ontrack-features-t2-2026:fix/bgw-17

Conversation

@gnahk66

@gnahk66 gnahk66 commented Sep 7, 2026

Copy link
Copy Markdown

Description

Fixes db:generate_feedback_chips generating fake feedback chips for existing learning outcomes without invoking the production guard.
This change:

Adds [:skip_prod, :environment] to use the existing production confirmation guard.
Collects learning outcome IDs from both create_list loops.
Restricts chip generation to those newly created outcomes.
Adds Minitest coverage for outcome isolation and production refusal.

The existing guard remains unchanged: entering Yes permits production execution, and staging does not trigger confirmation.
Fixes # (issue)
Dependencies: no new package dependencies.

Target branch: 11.0.x.

Type of change

Please delete options that are not relevant.

  • [x ] Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

Test file: test/sidekiq/generate_feedback_data_test.rb

Outcome isolation: verifies existing outcomes receive no additional chips and newly created outcomes receive the expected chips.
Production refusal: simulates production and answers No, verifying an exception occurs without creating outcomes or chips.

Run from doubtfire-deploy/development:

docker compose exec -e RAILS_ENV=test doubtfire-api bin/rails test test/sidekiq/generate_feedback_data_test.rb

The tests use the test database. Production is simulated through stubbing; no production database is used.
Manual check beyond the tests: reviewed skip_prod.rake and confirmed that production permits explicit Yes confirmation, while staging is not guarded.

Test setup note: test:setup failed because it references the missing db:setup_jplag_submissions task. The test database was populated using RAILS_ENV=test bin/rails db:populate; no setup-task source changes were made.

Checklist:

  • [ x] My code follows the style guidelines of this project
  • [x ] I have performed a self-review of my own code
  • [x ] I have commented my code, particularly in hard-to-understand areas
  • [x ] I have made corresponding changes to the documentation if appropriate
  • [x ] My changes generate no new warnings
  • [ x] I have added tests that prove my fix is effective or that my feature works
  • I have created or extended unit tests to address my new additions
  • [x ] New and existing unit tests pass locally with my changes
  • [x ] Any dependent changes have been merged and published in downstream modules

If you have any questions, please contact @macite or @jakerenzella.

…n/11.0.x-all-features-20260824

# Conflicts:
#	db/schema.rb
#	test/sidekiq/scheduled_job_test.rb
…ll-features-20260824

# Conflicts:
#	test/api/tasks_api_test.rb
maplefoxgit and others added 30 commits September 1, 2026 09:09
…l-concurrency

ci(codeql): cancel superseded CodeQL runs on the same ref
fix(api): mailer text leak, image bloat, dependabot path and an api-root auth guard
chore(ci): lint workflow YAML with actionlint
check_jplag_similarity ran only from rake tasks and the nightly container cron,
and that cron does not treat a threshold change as a reason to rescan, so a
convenor who lowered plagiarism_warn_pct had to email an administrator and wait.

Add CheckUnitSimilarityJob, POST /units/:id/similarity/scan gated on a new
:run_similarity_scan permission for convenors and admins, and a config/schedule.yml
entry so the nightly run is visible in Sidekiq. The job locks per unit id, so a
nightly child and an on-demand request for the same unit reject rather than race
on the shared jplag directory, and the nightly run moves out of the crontab so it
does not run in both places. A 30-minute cooldown rate limits the endpoint.
The task update endpoint added a Discussed in class comment whenever discussed
was not nil, so discussed:false marked the task discussed, and that comment type
cannot be removed from the UI. discussed:false now removes the most recent
discussed comment. The removal is refused when it would leave a discussion
required task complete without evidence, and is otherwise deferred until the
trigger and grade have applied so a refused request does not destroy the comment.
remove_comment_read_entry passed a conditions hash to
ActiveRecord::Relation#delete_all, which takes no arguments on Rails 8, so
every mark-as-unread raised ArgumentError and the Grape rescue turned it into
a 500. Scope the receipts with where(...) first, then delete_all.

Adds api tests for the mark-as-unread endpoint: the happy path (receipt
removed, comment unread) and an unauthorised caller rejected. The endpoint
had no coverage before.
…e-preference

feat(users): persist and timestamp the theme preference
feat(units): on-demand plagiarism rescan for convenors
fix(tasks): make discussed:false unmark a task instead of marking it
…achment-error-status

fix(discussions): return 4xx for invalid audio attachments
fix(domain): "Mark comment as unread" always returns 500 - delete_all
…1-feedback-state

CPD-FB01: expose privacy-safe dashboard feedback state
fix(uploads): an oversized or empty chat attachment is answered with
docs(docs): the student import lead time is read from a misspelled variable
fix(uploads): the portfolio upload endpoint enforces no size limit at all
fix(push): add notification icon and badge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants