Skip to content

introduces a comprehensive bulk activation workflow for contest instances, improves entry editing logic to better support administrative corrections, and adds several supporting utilities and policy updates. - #282

Merged
rsmoke merged 10 commits into
mainfrom
staging
Sep 23, 2026

Conversation

@rsmoke

@rsmoke rsmoke commented Sep 23, 2026

Copy link
Copy Markdown
Member

This pull request introduces a comprehensive bulk activation workflow for contest instances, improves entry editing logic to better support administrative corrections, and adds several supporting utilities and policy updates. The main themes are the addition of bulk contest instance activation, enhanced entry update handling, and supporting service and model changes.

Bulk Contest Instance Activation

  • Added a new controller BulkContestInstanceActivationsController to handle the bulk activation flow, including form handling, validation, and reporting.
  • Introduced BulkContestInstanceActivationForm for validating activation requests, including date parsing and confirmation logic.
  • Implemented BulkContestInstanceActivator service to activate contest instances in bulk, with detailed reporting of activated, deactivated, skipped, failed, and unchanged instances.
  • Added supporting scopes to ContestInstance for querying inactive, not archived, and date-specific instances.
  • The bulk activation report is now shown on the container page after activation, using session and cache for temporary storage. [1] [2]

Bulk Creation and Activation Flow Improvements

  • After bulk creation of contest instances, the user is redirected to the new bulk activation screen for the created season, streamlining the workflow. [1] [2] [3] [4]

Entry Editing and Profile Handling

  • Entry updates now always target the entry owner's profile (not the editor's), ensuring that administrative users (like Axis Mundi) do not accidentally update their own profile when editing another user's entry. [1] [2] [3] [4]
  • Entry update parameters are now restricted to prevent changing the contest instance after creation, maintaining contest integrity.
  • The entry update policy has been clarified: owners can edit while the contest is open, and admins can always edit for corrections.

Supporting Service and Model Improvements

  • Judging round date updates are now applied per-round in a single update to avoid validation errors from partial updates.

These changes collectively provide a robust and user-friendly workflow for managing contest instance activations and ensure data integrity and proper permission handling throughout the entry lifecycle.

cursoragent and others added 8 commits September 23, 2026 10:25
Restore EntryPolicy#update? so owners can edit open submissions, sync the
in-memory profile class level used during answer validation, and cover
upsert, class-level switching, and non-applicable answer preservation.

Co-authored-by: rsmoke <rsmoke@umich.edu>
Let admins activate a shared date_open season after bulk create (or later), promoting each contest’s newest instance while closing the predecessor and completing its judging rounds.

Co-authored-by: Cursor <cursoragent@cursor.com>
…rgeting.

Keep contest_instance_id immutable on update, and always read/write the entry owner's profile so Axis Mundi edits cannot reassign contests or mutate an admin profile.
…rgeting.

Keep contest_instance_id immutable on update, and always read/write the entry owner's profile so Axis Mundi edits cannot reassign contests or mutate an admin profile.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add entry update permission and answer persistence regression coverage
Scope activation to the selected season date, serialize per-description updates with row locks, cache the report instead of the cookie session, and validate malformed open dates before querying.

Co-authored-by: Cursor <cursoragent@cursor.com>
…test close.

Apply start and end date changes in one update so validations see the intended state instead of rejecting against a stale start_date.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI lite review requested due to automatic review settings September 23, 2026 16:41
@cursor
cursor Bot requested review from britaumich and dschmura September 23, 2026 16:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Five moderate findings remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds bulk contest-instance activation, improved administrative entry editing, and safer judging-round date updates.

Changes:

  • Adds activation form, service, controller, routes, views, and reporting.
  • Redirects bulk creation into the activation workflow.
  • Targets entry owners’ profiles and restricts contest reassignment.
  • Updates entry policies and batches judging-round changes.

Open findings: Five moderate issues remain around no-op messaging, report scoping, deleted-entry authorization, and multiple active siblings.

File Reviewed change
spec/​services/​judging_round_date_updater_spec.rb Date updater coverage
spec/​services/​bulk_contest_instance_activator_spec.rb Bulk activation coverage
spec/​policies/​entry_policy_update_spec.rb Entry policy coverage
spec/​forms/​bulk_contest_instance_activation_form_spec.rb Activation validation coverage
spec/​features/​bulk_contest_instance_activation_spec.rb Activation workflow coverage
spec/​controllers/​entries_controller_spec.rb Entry update coverage
spec/​controllers/​bulk_contest_instance_activations_controller_spec.rb Activation controller coverage
config/​routes.rb Activation routes
app/​views/​entries/​_form.html.erb Owner profile selection
app/​views/​containers/​show.html.erb Report display
app/​views/​containers/​_container_detail.html.erb Activation navigation
app/​views/​containers/​_bulk_activation_report.html.erb Activation report rendering
app/​views/​bulk_contest_instance_activations/​new.html.erb Activation form UI
app/​services/​judging_round_date_updater.rb Batched round updates
app/​services/​bulk_contest_instance_activator.rb Bulk activation logic
app/​policies/​entry_policy.rb Entry update authorization
app/​models/​contest_instance.rb Activation scopes
app/​forms/​bulk_contest_instance_activation_form.rb Activation request validation
app/​controllers/​entries_controller.rb Owner-profile entry updates
app/​controllers/​containers_controller.rb Activation report loading
app/​controllers/​bulk_contest_instances_controller.rb Post-creation redirect
app/​controllers/​bulk_contest_instance_activations_controller.rb Activation workflow and reporting

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/controllers/bulk_contest_instance_activations_controller.rb
Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings September 23, 2026 16:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Two unresolved moderate issues affect activation feedback and report isolation.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Activation reports are not scoped to their container

app/​controllers/​containers_controller.rb:208

This loader consumes the session's single report key for whichever container is shown, without recording or checking the container that produced the report. If a user activates one collection and then opens another collection (for example in a second tab), the second page can display the first collection's activation report and the intended page loses it. Include the container id in the cached/session payload and only consume the report when it matches @container (or otherwise scope the key to the container).

…hat collection.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings September 23, 2026 17:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved activation race-condition, entry-policy, and timestamp-consistency issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)

Comment on lines +74 to +80
unless description.active?
result.skipped << skip_entry(description, 'Contest description is inactive')
return
end

ActiveRecord::Base.transaction do
description.lock!
@rsmoke
rsmoke merged commit 3de546e into main Sep 23, 2026
11 checks passed

This branch was successfully deployed

1 active deployment
staging — 1271960d Deployed Sep 23, 2026 by hatchbox-io[bot]
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.

3 participants