fix(metrics): always emit baseline metrics on initial course insertion

This commit is contained in:
2026-01-30 23:32:04 -06:00
parent 7d2255a988
commit 16039e02a9
2 changed files with 24 additions and 13 deletions
+3 -3
View File
@@ -276,14 +276,14 @@ fn compute_diffs(rows: &[UpsertDiffRow]) -> (Vec<AuditEntry>, Vec<MetricEntry>)
diff_field!(json audits, row, "meeting_times", old_meeting_times, new_meeting_times);
diff_field!(json audits, row, "attributes", old_attributes, new_attributes);
// Emit a metric entry when enrollment/wait_count/max_enrollment changed
// Skip fresh inserts (no old data to compare against)
// Emit a metric entry on fresh insert (baseline) or when enrollment data changed
let is_new = row.old_id.is_none();
let enrollment_changed = row.old_id.is_some()
&& (row.old_enrollment != Some(row.new_enrollment)
|| row.old_wait_count != Some(row.new_wait_count)
|| row.old_max_enrollment != Some(row.new_max_enrollment));
if enrollment_changed {
if is_new || enrollment_changed {
metrics.push(MetricEntry {
course_id: row.id,
enrollment: row.new_enrollment,
+21 -10
View File
@@ -214,7 +214,7 @@ async fn test_batch_upsert_unique_constraint_crn_term(pool: PgPool) {
#[sqlx::test]
async fn test_batch_upsert_creates_audit_and_metric_entries(pool: PgPool) {
// Insert initial data — should NOT create audits/metrics (it's a fresh insert)
// Insert initial data — should create a baseline metric but no audits
let initial = vec![helpers::make_course(
"50001",
"202510",
@@ -242,10 +242,21 @@ async fn test_batch_upsert_creates_audit_and_metric_entries(pool: PgPool) {
.await
.unwrap();
assert_eq!(
metric_count, 0,
"initial insert should not create metric entries"
metric_count, 1,
"initial insert should create a baseline metric"
);
// Verify baseline metric values
let (enrollment, wait_count, seats): (i32, i32, i32) = sqlx::query_as(
"SELECT enrollment, wait_count, seats_available FROM course_metrics ORDER BY timestamp LIMIT 1",
)
.fetch_one(&pool)
.await
.unwrap();
assert_eq!(enrollment, 10);
assert_eq!(wait_count, 0);
assert_eq!(seats, 25); // 35 - 10
// Update enrollment and wait_count
let updated = vec![helpers::make_course(
"50001",
@@ -270,16 +281,16 @@ async fn test_batch_upsert_creates_audit_and_metric_entries(pool: PgPool) {
"should have audit entries for enrollment and wait_count changes, got {audit_count}"
);
// Should have exactly 1 metric entry
// Should have 2 metric entries: baseline + change
let (metric_count,): (i64,) = sqlx::query_as("SELECT COUNT(*) FROM course_metrics")
.fetch_one(&pool)
.await
.unwrap();
assert_eq!(metric_count, 1, "should have 1 metric snapshot");
assert_eq!(metric_count, 2, "should have baseline + 1 change metric");
// Verify metric values
// Verify the latest metric values
let (enrollment, wait_count, seats): (i32, i32, i32) = sqlx::query_as(
"SELECT enrollment, wait_count, seats_available FROM course_metrics LIMIT 1",
"SELECT enrollment, wait_count, seats_available FROM course_metrics ORDER BY timestamp DESC LIMIT 1",
)
.fetch_one(&pool)
.await
@@ -291,7 +302,7 @@ async fn test_batch_upsert_creates_audit_and_metric_entries(pool: PgPool) {
#[sqlx::test]
async fn test_batch_upsert_no_change_no_audit(pool: PgPool) {
// Insert then re-insert identical data — should produce zero audits/metrics
// Insert then re-insert identical data — should produce baseline metric but no audits or extra metrics
let course = vec![helpers::make_course(
"60001",
"202510",
@@ -320,7 +331,7 @@ async fn test_batch_upsert_no_change_no_audit(pool: PgPool) {
.await
.unwrap();
assert_eq!(
metric_count, 0,
"identical re-upsert should not create metric entries"
metric_count, 1,
"identical re-upsert should only have the baseline metric"
);
}