Skip to content

FAC-146 fix: order semesters by academic start_date #384

Description

@y4nder

Summary

Semester.createdAt reflects DB insertion time, not academic chronology. The moment a past semester is backfilled (e.g. S12526) after the current one (S22526), every query that used ORDER BY created_at to find "latest" or "previous" semester silently returns the wrong row.

The worst offender is mv_faculty_trends.ordinal, whose regr_slope(score, ordinal) drives the improving/declining classification on the trends page — with inverted ordering, an improving faculty reads as declining and vice versa.

Scope

Schema

  • Add startDate (NOT NULL, indexed) + endDate (nullable) to Semester.
  • Backfill existing rows by parsing code (S22526 → Jan 20 – Jun 1 2026) with the same calendar as admin.faculytics getSemesterDates():
    • Sem 1: Aug 1 – Dec 18 of startYear
    • Sem 2: Jan 20 – Jun 1 of endYear
    • Sem 3 (intersession): Jun 15 – Jul 31 of endYear
  • Rebuild mv_faculty_trends with ORDER BY s.start_date for the per-faculty ordinal window.

Sync

  • parseSemesterCode() returns startDate/endDate; processSemesters() upserts them so re-syncs correct backfilled values.

Query sites swapped from Semester.created_at to Semester.start_date

  • analytics.service.tsGetDepartmentOverview previous-semester lookup
  • analytics.service.tsGetFacultyTrends latest-semester fallback
  • semesters.service.tsGET /semesters list ordering (so the frontend switcher defaults to the correct "latest" term)
  • mv_faculty_trends.ordinal window

DTO

  • SemesterItemResponseDto now exposes startDate/endDate so the frontend can eventually display academic dates on the switcher.

Out of scope (follow-ups)

  • TieredPipelineSchedulerJob still reads QuestionnaireSubmission.createdAt for "new submissions" detection. Separate ticket for env kill-switch and/or submittedAt refactor.
  • GET /enrollments/me has no semester filter — students will see enrollments from all semesters after S12526 backfill. Separate ticket for semesterId query param + "current academic semester" default.

PR

#383

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions