Repository navigation
Conversation
lupari
force-pushed
the
CSCEXAM-1658
branch
4 times, most recently
from
September 28, 2026 21:23
d861e4d to
15c761e
Compare
- One retention module in app/features/retention runs all passes daily: auto-lock of unassessed attempts, removal of expired attempt content, grading records, bookings, host-side visitor reservations, host copies of visiting attempts and inactive pure-student accounts - Periods per data type under exam.retention.* in application.conf, institution-chosen ranges enforced at startup - New exam.locked_at (evolution 148) set when an assessment is locked, backfilled from exam records or grading time - Visiting reservations are deleted at XM before local rows go - Ships with exam.retention.dryRun = true. While dry run is on, the old ExamExpirationService and ExternalExamExpirationService keep running - Unit, database and fake-XM tests in test/retention Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- /app/config returns the effective retention policy (periods after range checks, dry-run mode, batch size) instead of expirationPeriod - Admin settings page lists the retention periods and whether the job is still in dry run - Removed the unused ConfigReader.getExamExpirationPeriod and the i18n_exam_expiration_period translation Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- RetentionSafetySpec snapshots every table and fails if a run removes or changes any row not created for the expired student - DB-level tests for maturity, course end and exam period windows, aborted, already DELETED, never started and host reservations - Fixed attempt content removal failing for question copies with an attachment: the file path was read after the row was deleted - Retention passes have readable labels, logged one line per pass - Shared spec helpers moved to RetentionSpecBase Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Runs nightly at 02:00 in the default time zone instead of an hour after startup - Candidate queries read pages of 500 rows and stop once a batch is found; dry run still counts everything, page by page - Replaced per-candidate queries with EXISTS subqueries - Evolution 149 indexes the date columns the passes filter by - Batch size default raised to 2000; the log shows "due N+" when more remain, and the run duration Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- No-shows, assessment transfers and collaborative assessments leave the send queue when XM answers 404, the request cannot be built, or they still fail 30 days after they became ready (IopDelivery) - Giving up is logged once; retries log XM's status and answer - Given-up attempts are kept and marked delivery_abandoned_at (evolution 150, left out of exchanged JSON); the retention job removes them with their booking Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The retention job deletes a visiting booking locally when the XM delete still fails 30 days after the booking became due, so a missing host no longer keeps a student's data for good - XM removes its own copy with its nightly expiry - Booking candidates carry their due time for this Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Exam attempts that still fail 30 days after they became ready are retried once a week instead of given up, until the retention job removes them; a receiver failing only until fixed (e.g. a version mismatch) then gets them without anyone acting - Only a 404 takes an attempt out of the pipeline for good - No-shows keep giving up after 30 days - Evolution 150 adds delivery_attempted_at for the weekly cadence Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Fixed limits common to all deployments live in RetentionLimits: the institution-chosen attempt ranges, the nightly run hour and the XM give-up and weekly retry intervals - Per-deployment periods stay in application.conf - Removed an unused give-up constant from NoShowHandlerImpl Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Retention deletes a user with a plain Ebean delete instead of raw SQL; the ManyToMany cascade removes only the role and permission links, not the shared rows - The safety test gives both students a shared permission, so a cascade reaching it would fail the test Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The no-show send matches every delivery decision, removing the exhaustivity warning; a no-show never gets the weekly retry, so it is treated like any other retry Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Candidate queries page by id (keyset) instead of OFFSET, so a page costs the same at any depth; on 1M attempts a deep page went from 1.5 s to 3 ms and a full dry run counts every pass in 26 s - A dry run still counts every due item, but its report lists only the next real run's batch per pass, capping memory and the CSV at a real run's size (16 MB instead of ~290 MB on the same data) - Batch size default raised to 20000: a real run handles 80k items in about 2 minutes, clearing a mature installation's backlog in about a month instead of a year Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Evolution 151 sets last_login = now() where it is null, so accounts that never logged in start their inactivity period at release - Enrolments with no reservation, event or enrolled_on get the start of the student's own attempt, or now(); otherwise they never expire and keep the account too - The spec runs the evolution's SQL against test data, as Play applies evolutions before any spec starts Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The no-show check loaded every enrolment not marked as a no-show, with its exam, and filtered in Scala; on 1M attempts that was 1.02M rows and the server was killed for memory - The exam state and time limits now go in the query, matching what NoShowHandler keeps, so only possible no-shows are loaded - Belongs on its own ticket; fixed here to unblock retention testing Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- scripts/internal/seed_bulk.py fills a dedicated database with users, rooms, courses, exams and deep-copied student attempts in every lifecycle state, spread evenly over a configurable history - Loads with COPY and its own ids, then advances the sequences; refuses other databases and runs while the app is connected - Defaults: 20k users and 1M attempts over 10 years, about 26 min and 13 GB Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- checkout, setup-node and upload-artifact v4 -> v7, setup-java v4 -> v6, moving off the deprecated Node 20 runtime - None of their breaking changes apply here: hosted runners, the temurin distribution, no registry-url, standard artifact inputs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The settings endpoint reports the retention batch size, whose default is now 20000 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The seeder's help now shows how to back up the seeded database and restore it instead of seeding again, including the analyze step pg_restore leaves out Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Seeded users get addresses under example.invalid (RFC 2606), so reminders, reports and no-show notices cannot reach anyone when the seeder is used on a server whose mailer is not mocked - The eppn stays under funet.fi, which dev login needs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Reviews and enrolments are looked up separately for the exams a teacher owns and those they inspect; an OR across the two joins kept either index from being used, so each call scanned the whole exam table - The parent exam and course are fetched with the reviews instead of lazily per participation - On 1M attempts the review queries per teacher went from 655 and 262 ms to about 17 ms each Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The notifier loads only exams whose release type it handles; IMMEDIATE and NEVER were never sent by it but were reloaded every 15 minutes for as long as they stayed GRADED Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Each participation and external exam is checked on its own, so one that fails no longer keeps the ones after it from ending - A reservation without a machine falls back to the default time zone instead of throwing, a failed teacher email skips only that teacher, and the review deadline is read once per run - ScheduledJobsSpec covers this (checked to fail on the old code) and the weekly report's owner and inspector lookups Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
lupari
force-pushed
the
CSCEXAM-1658
branch
from
September 30, 2026 09:47
ec14f4b to
3c062fd
Compare
Retention keeps the bare student copy, marked DELETED, until pass D removes it with the booking. The reservation and examination event listings hid every DELETED exam from teachers, so such bookings vanished from their view early. - Teachers see DELETED student copies (with a parent); bookings on an exam the teacher deleted stay hidden - DELETED is a selectable state and sorts after ARCHIVED - A DELETED copy counts as attended, so a stale noShow doesn't show - DELETED rows don't link to the assessment page Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.