watchCourseTable method

Stream<CourseTableData> watchCourseTable({
  1. required int semesterId,
})

Watches the course schedule for a semester with automatic background refresh.

Emits cached data immediately, then triggers a background network fetch if data is empty or stale. The stream re-emits automatically when the DB is updated.

Use getCourseOffering for related data (teachers, classrooms, schedules).

Implementation

Stream<CourseTableData> watchCourseTable({required int semesterId}) async* {
  const ttl = Duration(days: 3);

  final query = _database.select(_database.courseTableSlots)
    ..where((s) => s.semester.equals(semesterId));

  await for (final rows in query.watch()) {
    final data = _buildCourseTableData(rows);

    if (data.isEmpty) {
      try {
        await refreshCourseTable(semesterId: semesterId);
      } catch (_) {
        // Absorb: yield empty below so UI exits loading state
      }
    }

    yield data;

    final semesterRow = await (_database.select(
      _database.semesters,
    )..where((s) => s.id.equals(semesterId))).getSingle();
    final age = switch (semesterRow.courseTableFetchedAt) {
      final t? => DateTime.now().difference(t),
      null => ttl,
    };

    if (age >= ttl) {
      try {
        await refreshCourseTable(semesterId: semesterId);
      } catch (_) {
        // Absorb: stale data is shown via stream
      }
    }
  }
}