Work · 2023 · Live since 2023

سكيدز

Scheds

Every valid timetable for a Nile University student, under their own constraints.

This case study wears Scheds's own colours
Scheds landing: "Your time, your way." beside floating section cards and a generated week
Landing, once the intro settlesDesktop · 1440

المشكلةThe problem

Nile University students pick sections under constraints: how many days on campus, the longest gap they will tolerate, the earliest start, the labs and tutorials that have to come along. The registration portal offers none of that.

البناءThe build

An ASP.NET Core application with EF Core and SQL Server that pulls live course data from the university system, lets a student build a cart, and enumerates every valid timetable that satisfies their preferences. A study-room finder reads the same data backwards to find empty rooms. It started as a Java project in 2023, became .NET 8 in 2024, and grew a React and TypeScript frontend with Google sign-in in 2026.

التشغيلHow it runs

Live since 2023 through several registration weeks, which is when everyone shows up at once.

System · النظام

How Scheds is put together

229 files in 53 folders, without dependencies or vendored code. C# 48% · TypeScript 30% · JSON 3%.

A student's browserregistration weekA student's browser · registration weekCloudflare Pagesserves the React frontendCloudflare Pages · serves the React frontendReact frontendTypeScript · Tailwind · 2026React frontend · TypeScript · Tailwind · 2026Google sign-inoptionalGoogle sign-in · optionalASP.NET Core API.NET 8 · on runasp.netASP.NET Core API · .NET 8 · on runasp.netSchedule generatorenumerates every valid weekSchedule generator · enumerates every valid weekStudy-room finderthe data, read backwardsStudy-room finder · the data, read backwardsSQL ServerEF Core · course cacheSQL Server · EF Core · course cacheNU self-servicelive course dataNU self-service · live course data
  • the product's own code
  • services it runs
  • data
  • outside providers

One request · رحلة طلب

Registration week

Step by step through the system above. The tags name the parts each step touches.

  1. Search

    A student types a course code or name. Results come from the cached catalogue, or from a live fetch against the university system when they ask for it.

    • React frontend
    • ASP.NET Core API
    • SQL Server
    • NU self-service
  2. Cart

    Courses go into a cart that survives a refresh without an account. Sign-in is optional and only matters for personal features.

    • React frontend
    • Google sign-in
  3. Constrain

    Days on campus, the longest acceptable gap, earliest start and latest end, and whether labs and tutorials have to come along for engineering students.

    • React frontend
  4. Generate

    The generator enumerates every combination of sections that satisfies the constraints and returns them all, ranked by the preferences, never just one.

    • ASP.NET Core API
    • Schedule generator
    • SQL Server
  5. Choose

    Options render as weekly timetables side by side. The student compares and picks; the system does not decide for them.

    • React frontend
  6. Find a room

    The same data, read backwards, answers a different question: which rooms are empty at this hour on this day.

    • Study-room finder
    • SQL Server

Decisions · قرارات

Why Scheds is built this way

  • Enumerate every valid timetable rather than optimise for one

    Students weigh trade-offs that no scoring function captures. The constraints prune the space and the student chooses within it.

  • Live data with a cached fallback

    The university system is slow and sometimes unavailable exactly when everyone needs it. A cached catalogue keeps the generator usable; a live refresh is one click away.

  • No account required

    Registration lasts a few days a term. Forcing a sign-up would lose the moment; the cart lives in a cookie, and Google sign-in arrived only when features needed an identity.

  • A study-room finder from the same data

    The schedule data already says where every class is. Inverting it yields empty rooms at no extra cost.

  • Java, then .NET 8, then a React frontend

    Each rewrite kept the generator and replaced the layer that had become the limit: first the runtime, then the server-rendered views that could not carry the interaction a comparison view needs.

Design system · نظام التصميم

How Scheds looks

A dark navy week with one orange, and a categorical colour per course so a timetable reads at a glance.

Palette

  • Dark#0D101CGround
  • Lighter dark#171B26Surface
  • Orange#FF7300Action
  • Light blue#004060Accent
  • Light text#FCFCFCInk
  • Card blue#1E4FA3A course
  • Card green#1C6B3FA course
  • Card yellow#F5B301A course
  • Card purple#5B3A8AA course
  • Card rose#B83280A course

Type

System sans · display and interfaceScheds Aa Bb 0123

Principles · inferred from the product

  • Constraints first: days on campus, gaps, earliest start and required labs are inputs, not afterthoughts.
  • Every valid timetable, not the first one. The generator enumerates; the student chooses.
  • Live data over cached data whenever the university system answers.

Code · الملفات

Inside the repository

Public on GitHub. 229 files in 53 folders, without dependencies, build output or vendored code.

  • C#48%
  • TypeScript30%
  • JSON3%
  • C# projects2%
  • Razor2%
  • YAML2%
Scheds/128
.github/2
workflows/2
deploy-staging.ymlyml
deploy.ymlyml
Scheds/27
.config/1
dotnet-tools.jsonjson
Controllers/15
AdminApiController.cscs
AdminController.cscs
AuthController.cscs
CardController.cscs
CourseBaseController.cscs
CourseScheduleController.cscs
CustomizationsController.cscs
FindStudyRoomsController.cscs
GenerateController.cscs
GenerateSchedulesController.cscs
HomeController.cscs
InstructorController.cscs
RoomController.cscs
SeatAlertsController.cscs
SelfServiceSearchController.cscs
Filters/1
AdminAuthorizeAttribute.cscs
Properties/1
launchSettings.jsonjson
Views/6
Shared/4
_Layout.cshtmlcshtml
_Layout.cshtml.csscss
_ValidationScriptsPartial.cshtmlcshtml
Error.cshtmlcshtml
_ViewImports.cshtmlcshtml
_ViewStart.cshtmlcshtml
Program.cscs
Scheds.MVC.csprojcsproj
Scheds.slnsln
Scheds.Application/17
Interfaces/16
Repositories/8
Common/1
IBaseRepository.cscs
ICardItemRepository.cscs
ICourseBaseRepository.cscs
ICourseScheduleRepository.cscs
IInstructorRepository.cscs
IScheduleGenerationRepository.cscs
ISeatAlertRepository.cscs
IUserRepository.cscs
Services/8
ICardItemService.cscs
ICourseBaseService.cscs
IEmailService.cscs
IEmptyRoomsService.cscs
IParsingService.cscs
ISeatAlertService.cscs
ISelfServiceLiveFetchService.cscs
IUnsubscribeTokenService.cscs
Scheds.Application.csprojcsproj
Scheds.Domain/42
Configuration/4
AdminSettings.cscs
FrontendSettings.cscs
RateLimitPolicies.cscs
SeatAlertSettings.cscs
DTOs/22
Admin/4
CourseWithCountDTO.cscs
CustomizationWithCountDTO.cscs
GenerationDetailDTO.cscs
GenerationListItemDTO.cscs
Common/1
PaginatedEntityDTO.cscs
SeatAlerts/4
CheckSeatsRequest.cscs
SeatAlertLimits.cscs
SeatAlertResponses.cscs
WatchSectionRequest.cscs
SelfService/2
SearchRequest.cscs
SectionSearchParameters.cscs
BusyTimeDTO.cscs
CardItemSummaryDTO.cscs
CartItemDTO.cscs
CourseSectionsRequestDTO.cscs
CustomCourseBaseDTO.cscs
GenerateRequestDTO.cscs
ReturnedCardItemDTO.cscs
RoomAvailabilityDTO.cscs
ScheduleGenerationResult.cscs
SubscribeRequestDTO.cscs
UpdateCartRequestDTO.cscs
Entities/12
Common/1
BaseEntity.cscs
CardItem.cscs
CourseBase.cscs
CourseSchedule.cscs
Instructor.cscs
ScheduleGeneration.cscs
SeatAlert.cscs
SeatAlertSubscription.cscs
SectionExistence.cscs
SelectedCourse.cscs
SelectedCustomCourse.cscs
User.cscs
ValueObjects/1
CourseSection.cscs
ViewModels/2
AnalyticsViewModel.cscs
ErrorViewModel.cscs
Scheds.Domain.csprojcsproj
Scheds.Infrastructure/37
Configurations/1
CourseScheduleConfiguration.cscs
Contexts/1
SchedsDbContext.cscs
Migrations/11
20260205005057_init.cscs
20260205005057_init.Designer.cscs
20260725173152_DropSeatModerationCart.cscs
20260725173152_DropSeatModerationCart.Designer.cscs
20260728093651_PerUserSeatAlertState.cscs
20260728093651_PerUserSeatAlertState.Designer.cscs
20260728100923_IndexCardItemCourseCode.cscs
20260728100923_IndexCardItemCourseCode.Designer.cscs
20260728113830_RenameSeatModerationToSeatAlert.cscs
20260728113830_RenameSeatModerationToSeatAlert.Designer.cscs
SchedsDbContextModelSnapshot.cscs
Repositories/8
Common/1
BaseRepository.cscs
CardItemRepository.cscs
CourseBaseRepository.cscs
CourseScheduleRepository.cscs
InstructorRepository.cscs
ScheduleGenerationRepository.cscs
SeatAlertRepository.cscs
UserRepository.cscs
Services/9
CardItemService.cscs
CourseBaseService.cscs
EmailService.cscs
EmptyRoomsService.cscs
ParsingService.cscs
SeatAlertService.cscs
SeatMonitoringBackgroundService.cscs
SelfServiceLiveFetchService.cscs
UnsubscribeTokenService.cscs
Util/5
GenerationUtil.cscs
GlobalTimeUtil.cscs
IdGenerationUtil.cscs
ScheduleScoring.cscs
TopScheduleCollector.cscs
InfrastructureServiceDI.cscs
Scheds.Infrastructure.csprojcsproj
.gitattributes
.gitignore
README.mdmd
scheds.frontend/101
.github/2
workflows/2
prod-cloudflare.ymlyml
staging-cloudflare.ymlyml
public/19
images/17
abdo.pngpng
Calendar-pana.pngpng
hero-bg.jpgjpg
ideas.pngpng
image-removebg-preview (1).pngpng
image-removebg-preview (2).pngpng
image-removebg-preview.pngpng
logo-new.pngpng
new-bg-final.pngpng
new-bg.pngpng
questions.pngpng
register.pngpng
Schedule-amico.pngpng
schedules.pngpng
study.pngpng
studyRooms.pngpng
Time management-cuate.pngpng
_redirects
vite.svgsvg
src/70
assets/1
react.svgsvg
components/30
find-study-rooms/5
BuildingGroup.tsxtsx
FiltersSection.tsxtsx
RoomCard.tsxtsx
SearchSection.tsxtsx
StatsCards.tsxtsx
generate-schedules/9
CartList.tsxtsx
CourseBlock.tsxtsx
CourseCustomizeDialog.tsxtsx
CustomizationForm.tsxtsx
ScheduleCanvas.tsxtsx
SchedulePreview.tsxtsx
ScheduleRankList.tsxtsx
SchedulesList.tsxtsx
SearchSection.tsxtsx
layout/4
AuthButton.tsxtsx
Navbar.tsxtsx
navConfig.tsts
ThemeToggle.tsxtsx
seat-alerts/4
AddSectionForm.tsxtsx
AuthOverlay.tsxtsx
WatchList.tsxtsx
WatchStatus.tsxtsx
self-service-search/3
CourseCard.tsxtsx
FilterSection.tsxtsx
SearchSection.tsxtsx
ui/5
Button.tsxtsx
ConfirmDialog.tsxtsx
Input.tsxtsx
OptionChip.tsxtsx
Tooltip.tsxtsx
contexts/1
AuthContext.tsxtsx
hooks/13
useAdminAuth.tsts
useAuth.tsts
useContributors.tsts
useCourseSearch.tsts
useCourseSearchDebounced.tsts
useCourseSections.tsts
useGenerateCart.tsts
useGenerateRequest.tsts
useNow.tsts
useRoomAvailability.tsts
useTheme.tsts
useTitleBadge.tsts
useWatchedSections.tsts
lib/6
api.tsts
authStorage.tsts
roomUtils.tsts
scheduleExport.tsts
scheduleUtils.tsts
scheduleView.tsts
pages/11
AdminAnalyticsPage.tsxtsx
AdminDashboardPage.tsxtsx
AdminGenerationDetailsPage.tsxtsx
AdminGenerationsPage.tsxtsx
AdminLoginPage.tsxtsx
ContributorsPage.tsxtsx
FindStudyRoomsPage.tsxtsx
GenerateSchedulesPage.tsxtsx
HomePage.tsxtsx
SeatAlertsPage.tsxtsx
SelfServiceSearchPage.tsxtsx
types/5
admin.tsts
course.tsts
generate.tsts
room.tsts
seatAlerts.tsts
App.tsxtsx
index.csscss
main.tsxtsx
.gitignore
eslint.config.jsjs
index.htmlhtml
package-lock.jsonjson
package.jsonjson
README.mdmd
tsconfig.app.jsonjson
tsconfig.jsonjson
tsconfig.node.jsonjson
vite.config.tsts

Screens · شاشات

Scheds as it ships

Captured from the live product. Desktop frames are 1440 wide, phones 390.

The generator with four courses in the cart and every preference exposed
Four courses in, every constraint in reachDesktop · 1440
Self-service search results for CSCI courses, one card per section
Every section, straight from NU self-serviceDesktop · 1440
Available study rooms grouped by building, each with its free blocks for the day
Study rooms with their free blocks for the dayDesktop · 1440
Scheds landing on a phone
Landing on a phonePhone · 390
Résumé