Plannr

A syllabus is written for people. Plannr turns it into dates a calendar can hold, and makes the student check every one first.

Product
Plannr's app icon: a gold star above a line drawing of a phone, on navy, with the name PlannrSyllabus to calendar
Platform
iOS · SwiftUI, Python · FastAPI
Status
Free public TestFlight beta
Origin
UCSB CS 148 team project, Winter 2026
Since
Continued alone, Aug – Sep 2026

The document

The dates are already written down. Just not like dates.

Every instructor writes a syllabus their own way, and a term brings a handful of them. Deadlines sit in a table on one page, in a sentence on another, in a phrase that only makes sense next to the start date.

Plannr starts from the document as it is: a PDF with selectable text, or the text pasted in. Scans and photos aren’t supported in the beta yet.

ASTRO 101 · Introduction to the Solar System

Winter 2027 · Lecture M W F 10:00–10:50 AM · Section Thursday 3:00–3:50 PM

Week 1 begins Monday, January 4.

Schedule of graded work

  • Problem Set 1 — due Friday of Week 2Friday of Week 2 is a calculation: the first day of class, plus one week, plus four days.
  • Observation Report 1 — due Wednesday, Week 4
  • Midterm Exam — Friday of Week 5, in class
  • Research paper: proposal — due Monday, February 15
  • Research paper: final draft — due Wednesday of Week 10
  • Final Exam — Friday of finals week, 8:00–11:00 AMFinals week is never stated as a date. Plannr has to work it out, and the student has to check it.

Late work loses 10% per day.

Office hours are by appointment.

Grading: problem sets 30%, observation reports 15%, midterm 20%, paper 15%, final 20%.

Policies, office hours and grading. Plannr is told to leave these alone.

Illustration: a fictitious course, composed from the sample syllabus built into the app. Not a real course document.

The transformation

One document in. A schedule out. The student signs off in the middle.

  1. Syllabus

    Six deadlines, written six different ways: a weekday and a week, a plain date, a phrase like finals week.

    Schedule of graded work

    • — due Friday of Week 2
    • — due Wednesday, Week 4
    • — Friday of Week 5, in class
    • Research paper: proposal — due Monday, February 15
    • Research paper: final draft — due Wednesday of Week 10
    • Final Exam — Friday of finals week, 8:00–11:00 AM

    Trace a deadline. Select a highlighted one to follow it through.

  2. Extract

    Gemini reads the document text and returns each deadline as a record with a title, a date and a type. Friday of Week 2 becomes 2027-01-15. It is told to skip any date it cannot work out.

    • HomeworkProblem Set 1due Friday of Week 2
    • LabObservation Report 1due Wednesday, Week 4
    • ExamMidterm ExamFriday of Week 5, in class
    • HomeworkResearch paper: proposaldue Monday, February 15
    • HomeworkResearch paper: final draftdue Wednesday of Week 10
    • ExamFinal ExamFriday of finals week, 8:00–11:00 AMWorked out, not stated
  3. Review

    Every record lands on a review screen. The student can edit a date, decline an event or accept the lot. Nothing is written to Google Calendar until they press Sync.

    Plannr's review screen for a sample class. A week strip, then event cards for Problem Set 1 and Problem Set 2, each marked Accepted with Edit, Accept and Decline buttons, and a Sync button below.
    The review screen in the current build, on the app's built-in sample course. Every event arrives accepted; each can be edited or declined before Sync.
  4. Calendar

    Accepted events sync to a Google Calendar made for that class, in the class's colour.

    Nothing accepted for the calendar yet.

    The term, weeks 1 to 11, with these dates marked: Problem Set 1, 2027-01-15; Observation Report 1, 2027-01-27; Midterm Exam, 2027-02-05; Research paper: proposal, 2027-02-15; Research paper: final draft, 2027-03-10; Final Exam, 2027-03-19.

    Diagram of the term. Winter 2027, weeks 1 to 11, Monday to Friday. The same six dates, placed.

The product

What the student keeps.

After the sync, Plannr is the view over the term.

  • My Classes

    Every course in one list, each with its own colour and sync status. Classes can be filed into a term.

  • Calendar

    A week or month across every class, filterable by exams, homework, labs and quizzes.

  • Week at a Glance

    What is due this week and next, a weekend preview, and a checkbox for each thing done.

Plannr's Week at a Glance screen, 30 August to 5 September. Tiles show 8 due this week, 11 next week and 0 percent complete. A week strip shows a count on each day that has something due. A weekend preview reads Busy Weekend, 3 assignments due early next week. Upcoming events list Viral Video, for class TMP124, and Week 4 Discussion Peer Responses, tagged Homework.
  • 8 due this week, 11 next. The app itself calls it a heavy week.
  • Each day with something due carries a count.
  • A weekend preview: three assignments due early next week.
Week at a Glance. Captured in the week of 30 Aug 2026 from the developer's own account. Profile photo covered; the course codes are real.
Plannr's My Classes screen, cropped: three classes, TMP124 with 27 events synced, CMPSC 111 with 6, and ENGR 101 with 9, each with its own colour bar and an Active tag, above an Add New Class button.
  • One colour per class. 27 events synced.
My Classes, cropped.

The decisions

What was actually difficult.

Three choices, each made because the calendar isn’t Plannr’s. It’s the student’s.

  • Finding 1

    The student signs off before anything reaches a calendar.

    opt-out, not opt-in

    In the codeCalendarPreviewView.swift ↗

    The constraint
    Extraction is inference. Friday of Week 3 is a calculation, and a calculation can be wrong. A wrong date costs a student a deadline.
    What it does
    Parsed events land on a review screen first. Each can be edited, declined or accepted, and only accepted events are ever sent. The extraction prompt tells the model to skip a date it cannot work out with confidence instead of guessing.
    Where it stops
    Events arrive accepted, so review is opt-out: a student who presses Sync without looking gets what the parser found.
  • Finding 2

    One calendar per class, and Plannr only patches.

    patch, not update

    In the codebackend/app.py, sync_class_calendar ↗

    The constraint
    The calendar it writes to is the student's own. They will add a location, a note, a reminder. A sync must not erase it.
    What it does
    Each class gets a dedicated secondary Google Calendar, found or created by name and coloured to match. Existing events are patched, not replaced, so anything added in Google survives a re-sync. If an event has been deleted in Google, only that one is recreated. Every event carries a private id, so a retried request updates the event it already made instead of duplicating it.
    Where it stops
    Calendars are matched by class name.
  • Finding 3

    A changed syllabus is a diff, not a rebuild.

    identity is title + date

    In the codeEventReconciler.swift ↗

    The constraint
    Professors move deadlines. Uploading the new version must not wipe the student's edits or duplicate the term.
    What it does
    Re-uploads are reconciled against the class's existing events. Two events are the same when their title and date match; a local edit beats the new parse; only the difference is pushed to Google. Every sync is snapshotted, and a class can be restored to any earlier one.
    Where it stops
    A renamed or moved assignment reads as a deletion plus an addition. The code says so itself.

Under the hood

How a syllabus travels.

  1. Syllabus PDF or pasted text, up to 10 MB

  2. The document's text goes to Gemini; structured events come back

    Extraction only. Gemini never touches a calendar.

  3. Events go back to the phone for review

    The server keeps no syllabus and no events.

  4. Accepted events, after the student presses Sync

  5. Insert or patch on the class's own Google Calendar

The phone
Classes, events, review edits and sync snapshots live here.
Plannr's server
A user record and encrypted Google credentials. No syllabi, no events.
Google
Gemini reads the text. Google Calendar holds the result.
A sequence in five steps between the phone, Plannr’s server and Google.

Sign-in is Google OAuth 2.0. The stored refresh tokens are encrypted at rest, the app holds only an opaque session token, and the sign-in callback is bound to the attempt that started it.

Swift · SwiftUI · Python · FastAPI · PostgreSQL · Gemini · Google OAuth 2.0 · Google Calendar API · Render

The receipt

A beta, running, with the code in public.

Checked 23 Sep 2026.

Source
A public repository: 118 commits between 13 Aug and 9 Sep 2026, continuing the team's original code.github.com/m4ttblanke/plannr ↗
Backend
Deployed on Render and redeployed on every push to main. Database migrations run on deploy. Its health check returned 200 with the database ready when checked.The health check ↗
Beta
A free, public TestFlight beta. The invitation is linked from the product page.The product page ↗
Tests
97 backend and 199 iOS test functions. CI is set up to run both suites on every push to main and every pull request.
Crashes
Beta builds report crashes to Sentry.
Payments
A Stripe checkout and webhook path was built and tested, then set aside. The beta is free.

Not on file User counts, revenue, extraction accuracy and Google's OAuth verification are not documented anywhere in the project, so this page does not claim them.

Who built it

The team project
UCSB CS 148, Winter 2026, seven people. Matt was product owner and built Google sign-in, the first Google Calendar sync, the accept and decline controls, exports, guest mode and class editing. Teammates built the first Gemini extraction, the week view and the input handling.The original repository ↗
After the course
Matt continued it alone: hosting and the database, authentication hardening, sync retries and restore, term folders, the product page, and the TestFlight beta.