ScheduleAI
Scheduling looks simple until constraints interact — then a timetable can appear valid while still breaking the rules that matter.
A conversational scheduling assistant that turns a student's messages into constraints, while a separate rule-based engine builds and validates the actual timetable, so the schedule it returns is always conflict-free.
What I built
- Built the chat interface and the extraction step that turns messages into structured constraints.
- Designed the rule engine that places courses, checks for conflicts, and explains why a slot was rejected.
- Deployed it on Vercel with a custom domain, and resolved the production issues (DNS, config) that only showed up after launch.
- Reused the same model-extracts, engine-decides split to build this portfolio's own meeting scheduler.
Key decision
The model's job stops at turning messages into structured constraints. A rule-based layer does placement, validation, and conflict detection, so every schedule returned is provably free of time clashes and honors the hard rules. The conversation is the interface; correctness is not the model's responsibility. Object-oriented constraint and validator types are reusable across the general-user, student, and admin modes.
What this project taught me
- Building and deploying it pushed me to separate the conversational experience from the rules that decide whether a schedule is valid. Input validation and conflict detection have to stay predictable even if a model is eventually doing the understanding.
- Deployment made configuration, failure states, and validation matter far more than they do when an app only runs locally.
- This portfolio's Contact page now runs a scheduling assistant built on the same split: Claude Sonnet turns a recruiter's message into constraints, and a deterministic engine generates real meeting slots from my availability and re-validates the chosen one on confirm. The model never invents a time, following the same principle as ScheduleAI, narrowed to booking one call.
The full reasoning
The problem, options, and constraints
Problem
Every semester, students rebuild a timetable by hand: preferred times, which professor, no clashes, requirements met. It's a constraint problem solved with a spreadsheet and trial and error, and one missed conflict often isn't caught until it's too late to change sections.
Observation
Scheduling looks simple until several constraints interact: availability, conflicts, invalid inputs, and different preferences can quickly produce a schedule that looks valid but isn't.
The question
Could I make scheduling conversational and easy for the user while keeping the actual scheduling rules deterministic and reliable?
User need
A student needs to state preferences conversationally, trust that the result has no time clashes and respects the hard rules, and sync it to a calendar they already use. Separately, administrators want anonymised demand data to plan how many sections to open.
Constraints
- Solo build; frontend-first prototype
- Scheduling logic has to be explainable: a student should see why a slot was rejected
- Free hosting (Vercel)
- One core serving three audiences: general users, students, administrators
Options considered
| Option | Trade-off |
|---|---|
| Let the model produce the whole schedule directly | Fast to demo, but no guarantee the output is conflict-free or respects hard constraints, and no explanation for what it did |
| Model extracts constraints; a rule-based engine builds and validates the schedule | More to build, but the timetable is verifiably valid and the model only does the part it's good at: understanding the sentence |
Architecture
Chat message
--> extract structured constraints { times, days, professors, hard vs soft }
--> rule engine: place courses, run conflict detection, reject on overlap or hard-rule break
--> timetable state (updates continuously — no separate 'generate' step)
--> Google Calendar / in-app calendar sync
--> admin view: anonymised, aggregated demandTry it live
The deployed app, running here. Talk to the assistant and build a timetable. No sign-in needed to look around.
This page explains the why. GitHub has the proof of what was built.
View full repository