Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ gem 'rake', '>=10.3.2'
gem 'populator', '>=1.0.0'

# To communicate with MySQL database
gem 'mysql2', '~>0.5'
gem 'mysql2', '=0.5.4'
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed?


# Development server
gem 'thin'
Expand Down
5 changes: 3 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ GEM
momentjs-rails (2.15.1)
railties (>= 3.1)
multi_xml (0.6.0)
mysql2 (0.5.5)
mysql2 (0.5.4)
net-http (0.4.0)
uri
net-imap (0.4.9)
Expand Down Expand Up @@ -470,6 +470,7 @@ PLATFORMS
arm64-darwin-21
arm64-darwin-22
arm64-darwin-23
arm64-darwin-24
x86_64-darwin-19
x86_64-darwin-20
x86_64-darwin-21
Expand Down Expand Up @@ -509,7 +510,7 @@ DEPENDENCIES
mini_racer (~> 0.6.3)
moment_timezone-rails
momentjs-rails (>= 2.9.0)
mysql2 (~> 0.5)
mysql2 (= 0.5.4)
net-http
net-ldap
newrelic_rpm
Expand Down
32 changes: 14 additions & 18 deletions app/assets/javascripts/gradesheet.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,9 @@ jQuery(function() {
// main score table
var oTable = jQuery("#grades").dataTable({
'data' : table_data,
'sDom' : '<"tools"f>t', // '<"tools"fC>t', for individual problem column hide/show
'sDom' : 't', // '<"tools"fC>t', for individual problem column hide/show
'bInfo': false,
'bPaginate': true,
'oLanguage': { "sSearch": "" },
'iTabIndex': -1,
'iDisplayLength': rows_on_display,
'iDisplayStart': 0,
Expand All @@ -148,6 +147,19 @@ jQuery(function() {
"aaSorting": [[ email_col, 'asc' ],[lec_sec_col, 'asc']]
}).fnSetFilteringDelay();

$('#filter').on('keyup', function() {
oTable.fnFilter(this.value);
});

$('#filter').on('keydown', function(event) {
if (event.keyCode === 13) { // return
asap(function() { jQuery(focusser).focus(); });
} else if (event.keyCode === 27) { // esc
event.preventDefault();
jQuery(this).val("");
}
});

// add sorting icons to table headings
function add_icons(selector) {
let icons = $icon_template.clone();
Expand Down Expand Up @@ -187,10 +199,6 @@ jQuery(function() {
}
})

// placeholder text in Search field
jQuery("#grades_filter input").attr("placeholder", "Search");


// get enclosing editor from inside of it
function get_enclosing_editor(el) {
return jQuery(el).closest('td.edit');
Expand Down Expand Up @@ -501,18 +509,6 @@ jQuery(function() {
$(event.target).data('changed', !$(event.target).data('changed'));
});


jQuery("#grades_filter input").keydown(function(event){
if (event.keyCode === 13) { // return
asap(function() { jQuery(focusser).focus(); });
} else if (event.keyCode === 27) { // esc
event.preventDefault();
jQuery(this).val("");
}
});

jQuery('#grades_filter input').focus()

jQuery(document).click(function(event) {
close_current_editor_on_blur(event);
close_current_popover_on_blur(event);
Expand Down
11 changes: 11 additions & 0 deletions app/assets/stylesheets/gradesheet.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ td.focus {
margin-bottom: 20px;
}

div.filter_container.search-student-bar {
display: flex;
flex-direction: row;
align-items: center;
}

div.filter_container.search-student-bar input {
padding-left: 8px;
height: 3rem;
}

#grades_wrapper .tools div {
display: inline;
margin-right: 7px;
Expand Down
7 changes: 7 additions & 0 deletions app/views/assessments/viewGradesheet.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,13 @@ Interaction between gradesheet and annotations
</script>
<% end %>

<div class="filter_container search-student-bar">
<i class="material-icons prefix">search</i>
<div style="width: 30%;">
<label for="filter"></label><input id="filter" placeholder="Search..." type="text" autocomplete="off">
</div>
</div>

<div id="table_container">
<table id="grades" style="width:100%"></table>
</div>
Expand Down
64 changes: 48 additions & 16 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2024_04_06_174050) do
ActiveRecord::Schema.define(version: 2025_04_26_203028) do
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify schema version timestamp

The schema version is set to 2025_04_26_203028, which contains a future year (2025). While this might be intentional for development purposes, it's unusual to have a timestamp in the future.


🏁 Script executed:

#!/bin/bash
# Check other migration files to see if this timestamp pattern is consistent

echo "Checking migration file timestamps:"
fd -e rb -p "db/migrate/.*\.rb" | sort | tail -5

Length of output: 425


🏁 Script executed:

#!/bin/bash
# Search for migrations with 2025 prefix
echo "Migrations with 2025 prefix:"
fd -e rb db/migrate | grep 'db/migrate/2025_' || echo 'None found'

Length of output: 489


🏁 Script executed:

#!/bin/bash
echo "Searching for migration file matching schema version 2025_04_26_203028..."
find db/migrate -maxdepth 1 -type f -name "2025_04_26_203028*.rb" || echo "No matching migration file found."

Length of output: 224


Migration Timestamp Mismatch in db/schema.rb

The schema version in db/schema.rb is set to 2025_04_26_203028, but there is no corresponding migration file (db/migrate/2025_04_26_203028*.rb) in the repo. This suggests the migration wasn’t committed or the timestamp is incorrect.

• File: db/schema.rb (line 13)

ActiveRecord::Schema.define(version: 2025_04_26_203028) do

• Verification:

$ find db/migrate -maxdepth 1 -name "2025_04_26_203028*.rb"
# => no matching migration found

Please ensure one of the following:

  1. Commit the missing migration file with timestamp 2025_04_26_203028
  2. Run your migrations locally and regenerate schema.rb so the version matches the latest migration
  3. Manually correct the schema version to match the most recent migration in db/migrate/
🤖 Prompt for AI Agents (early access)
In db/schema.rb at line 13, the schema version is set to 2025_04_26_203028, but no migration file with this timestamp exists in db/migrate/. To fix this, either commit the missing migration file with that timestamp if it exists, or run your migrations locally and regenerate schema.rb so the version matches the latest migration. Alternatively, manually update the schema version in schema.rb to match the most recent migration timestamp found in db/migrate/.


create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
t.bigint "record_id", null: false
t.bigint "blob_id", null: false
t.integer "record_id", null: false
t.integer "blob_id", null: false
Comment on lines +18 to +19
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider implications of changing from bigint to integer for ID columns

Several columns in Active Storage tables have been changed from bigint to integer:

  • record_id and blob_id in active_storage_attachments
  • byte_size in active_storage_blobs
  • blob_id in active_storage_variant_records

This reduces the maximum value that can be stored (from ~9.2 quintillion to ~2.1 billion). Ensure this won't cause issues with large files or in systems with many records.

Also applies to: 30-30, 38-38


🏁 Script executed:

#!/bin/bash
# Check if there are any migrations that explicitly change these column types
echo "Checking for migrations that modify Active Storage column types:"
rg -A 3 -B 3 "change_column.*active_storage" --glob="db/migrate/*.rb"

Length of output: 992


Let’s verify the original Active Storage migrations to see what column types were defined there:


🏁 Script executed:

#!/bin/bash
echo "Inspecting the Active Storage attachments migration:"
rg -A5 -B5 "create_table :active_storage_attachments" --glob="db/migrate/*.rb"

echo -e "\nInspecting the Active Storage blobs migration:"
rg -A5 -B5 "create_table :active_storage_blobs" --glob="db/migrate/*.rb"

echo -e "\nInspecting the Active Storage variant records migration:"
rg -A5 -B5 "create_table :active_storage_variant_records" --glob="db/migrate/*.rb"

Length of output: 4277


Action Required: Address Active Storage column type mismatch

The schema dump now shows these columns as integer, but the original migrations defined them as bigint and there are no migrations to change their types. Please confirm whether you intend to down-cast these columns or revert them to bigint. If the change is intentional, add migrations to alter the column types; otherwise, restore the original types in db/schema.rb.

Locations needing attention:

  • db/schema.rb:18-19
    • active_storage_attachments: record_id, blob_id
  • db/schema.rb:30
    • active_storage_blobs: byte_size
  • db/schema.rb:38
    • active_storage_variant_records: blob_id
🤖 Prompt for AI Agents (early access)
In db/schema.rb around lines 18-19, 30, and 38, the columns record_id and blob_id in active_storage_attachments, byte_size in active_storage_blobs, and blob_id in active_storage_variant_records are defined as integer but were originally bigint in the migrations. To fix this, verify if the change to integer is intentional; if not, revert these column types back to bigint in db/schema.rb. If the change is intended, create new migrations to explicitly alter these columns from bigint to integer to keep schema and database consistent.

t.datetime "created_at", null: false
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
Expand All @@ -27,15 +27,15 @@
t.string "filename", null: false
t.string "content_type"
t.text "metadata"
t.bigint "byte_size", null: false
t.integer "byte_size", null: false
t.string "checksum", null: false
t.datetime "created_at", null: false
t.string "service_name", null: false
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
end

create_table "active_storage_variant_records", force: :cascade do |t|
t.bigint "blob_id", null: false
t.integer "blob_id", null: false
t.string "variation_digest", null: false
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
end
Expand All @@ -54,6 +54,8 @@
t.string "coordinate"
t.boolean "shared_comment", default: false
t.boolean "global_comment", default: false
t.integer "rubric_item_id"
t.index ["rubric_item_id"], name: "index_annotations_on_rubric_item_id"
end

create_table "announcements", force: :cascade do |t|
Expand Down Expand Up @@ -130,7 +132,7 @@
t.integer "course_id"
t.integer "assessment_id"
t.string "category_name", default: "General"
t.datetime "release_at", default: -> { "CURRENT_TIMESTAMP" }
t.datetime "release_at"
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify removal of default value for release_at

The release_at field in attachments table appears to have had its default value removed. Ensure this change won't affect existing functionality that might rely on a default value.


🏁 Script executed:

#!/bin/bash
# Check the migration that modified this column
echo "Checking for migrations that modify the release_at column:"
rg -A 3 -B 3 "release_at" --glob="db/migrate/*.rb"

Length of output: 1455


Action Required: Confirm and Formalize Removal of release_at Default

The schema now shows:

t.datetime "release_at"

but the original migration
db/migrate/20230924161219_add_release_at_to_attachments.rb
added this column with

default: -> { 'CURRENT_TIMESTAMP' }

I did not find any subsequent migration using change_column_default (or similar) to drop that default. Please:

  • Verify whether you intended to remove the CURRENT_TIMESTAMP default.
  • If so, add and run a new migration (e.g. change_column_default :attachments, :release_at, from: -> { 'CURRENT_TIMESTAMP' }, to: nil) so the schema and DB stay in sync.
  • If not, revert the schema change to include the original default.
  • After you decide, ensure no existing code or tests assume release_at is non‐NULL (update creation logic or test fixtures as needed).
🤖 Prompt for AI Agents (early access)
In db/schema.rb at line 135, the release_at column in the attachments table no longer has the default CURRENT_TIMESTAMP, but the original migration set this default. Verify if you intended to remove this default; if yes, create and run a new migration explicitly changing the default from CURRENT_TIMESTAMP to nil to keep the schema and database consistent. If not, revert the schema change to restore the default. Also, review and update any code or tests that assume release_at is non-NULL to prevent issues.

t.string "slug"
t.index ["assessment_id"], name: "index_attachments_on_assessment_id"
t.index ["slug"], name: "index_attachments_on_slug", unique: true
Expand Down Expand Up @@ -194,14 +196,14 @@
t.boolean "infinite", default: false, null: false
end

create_table "friendly_id_slugs", charset: "utf8mb3", force: :cascade do |t|
create_table "friendly_id_slugs", force: :cascade do |t|
t.string "slug", null: false
t.integer "sluggable_id", null: false
t.string "sluggable_type", limit: 50
t.string "scope"
t.datetime "created_at"
t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true, length: { slug: 70, scope: 70 }
t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type", length: { slug: 140 }
t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true
t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type"
t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id"
end

Expand All @@ -225,8 +227,8 @@
t.string "context_id"
t.integer "course_id"
t.datetime "last_synced"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "membership_url"
t.string "platform"
t.boolean "auto_sync", default: false
Expand Down Expand Up @@ -319,14 +321,36 @@
t.integer "course_id"
end

create_table "rubric_item_assignments", force: :cascade do |t|
t.integer "rubric_item_id", null: false
t.integer "submission_id", null: false
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be from the rubric PR, these should be removed

t.boolean "assigned", default: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["rubric_item_id", "submission_id"], name: "index_ria_on_rubric_item_id_and_submission_id", unique: true
t.index ["rubric_item_id"], name: "index_rubric_item_assignments_on_rubric_item_id"
t.index ["submission_id"], name: "index_rubric_item_assignments_on_submission_id"
end

create_table "rubric_items", force: :cascade do |t|
t.integer "problem_id", null: false
t.string "description", null: false
t.float "points", null: false
t.integer "order", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["problem_id", "order"], name: "index_rubric_items_on_problem_id_and_order", unique: true
t.index ["problem_id"], name: "index_rubric_items_on_problem_id"
end

create_table "scheduler", force: :cascade do |t|
t.string "action"
t.datetime "next"
t.integer "interval"
t.integer "course_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "until", default: -> { "CURRENT_TIMESTAMP" }
t.datetime "until"
t.boolean "disabled", default: false
end

Expand All @@ -338,15 +362,15 @@

create_table "scoreboards", force: :cascade do |t|
t.integer "assessment_id"
t.text "banner"
t.text "colspec"
t.text "banner", limit: 65535
t.text "colspec", limit: 65535
Comment on lines +365 to +366
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify text field limit changes

Several text fields have had their limits specified or modified:

  • banner and colspec in scoreboards (limit: 65535)
  • feedback in scores (limit: 16777215)
  • dave in submissions (limit: 255)

Ensure that existing data fits within these limits and that the application logic accounts for these constraints.

Also applies to: 373-373, 399-399


🏁 Script executed:

#!/bin/bash
# Check the migrations that modified these text field limits
echo "Checking for migrations that modify text field limits:"
rg -A 3 -B 3 "limit:" --glob="db/migrate/*.rb" | grep -E "banner|colspec|feedback|dave"

Length of output: 1338


Ensure text field limits are enforced and existing data fits

Although the migrations setting these limits are already in place (see 20150127210917, 20150406221712, 20150119232050), you should:

• Run queries against your production data to verify no rows exceed the new limits (e.g.
SELECT MAX(CHAR_LENGTH(feedback)) FROM scores;,
SELECT MAX(CHAR_LENGTH(banner)), MAX(CHAR_LENGTH(colspec)) FROM scoreboards;,
SELECT MAX(CHAR_LENGTH(dave)) FROM submissions;)

• Add or update ActiveRecord validations to mirror the DB constraints:
– In Score model: validates :feedback, length: { maximum: 16_777_215 }
– In Scoreboard model: validates :banner, :colspec, length: { maximum: 65_535 }
– In Submission model: validates :dave, length: { maximum: 255 }

• Augment or add model-level tests to assert these validations fire when limits are exceeded.

This will prevent runtime errors and data truncation when new records are created or updated.

🤖 Prompt for AI Agents (early access)
In db/schema.rb around lines 365 to 366, the text fields banner and colspec have limits set to 65535. To fix the issue, first run SQL queries on production data to ensure no existing entries exceed these limits. Then, add or update ActiveRecord validations in the corresponding models: add length validations for banner and colspec in the Scoreboard model, feedback in the Score model, and dave in the Submission model to match their database limits. Finally, create or update model tests to verify these validations trigger correctly when limits are exceeded.

t.boolean "include_instructors", default: false
end

create_table "scores", force: :cascade do |t|
t.integer "submission_id"
t.float "score"
t.text "feedback", size: :medium
t.text "feedback", limit: 16777215
t.integer "problem_id"
t.datetime "created_at"
t.datetime "updated_at"
Expand All @@ -372,7 +396,7 @@
t.string "submitter_ip", limit: 40
t.integer "tweak_id"
t.boolean "ignored", default: false, null: false
t.string "dave"
t.string "dave", limit: 255
t.text "embedded_quiz_form_answer"
t.integer "submitted_by_app_id"
t.string "group_key", default: ""
Expand Down Expand Up @@ -437,4 +461,12 @@

add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "annotations", "rubric_items"
add_foreign_key "github_integrations", "users"
add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id"
add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
add_foreign_key "oauth_device_flow_requests", "oauth_applications", column: "application_id"
add_foreign_key "rubric_item_assignments", "rubric_items"
add_foreign_key "rubric_item_assignments", "submissions"
add_foreign_key "rubric_items", "problems"
end
Binary file added libsqlite3.dylib
Binary file not shown.