Skip to content

Releases

v0.21.0 - Stay on top

Choose a tag to compare

@kapildev333 kapildev333 released this 10 Oct 01:40
c318008

Highlights

  • Members see what is due across their sections in an Upcoming panel on My sections: open quizzes and due assignments they have not submitted, with staff seeing submission counts (roadmap R1).
  • In-app notifications with a bell and unread count: new announcements, new quizzes and assignments, released scores and posted final grades, with mark-read and mark-all; announcement mail keeps flowing per post and each member can opt out of it (R2).
  • A private calendar feed per member: section meetings and quiz and assignment deadlines as an iCal link for Google, Apple or Outlook Calendar, created once, rotatable and revocable (R3).
  • Every date and time shows in the university's time zone and locale, with the zone named when it differs from the browser's, and quiz and assignment windows are entered in campus time (R4).
  • Two new Playwright files cover notifications, Upcoming, the calendar feed lifecycle and the time-zone display.

What's Changed

Changes

  • P21-L2: migration 0012, in-app notifications (producers, routes), announcement-mail opt-out by @kapildev333 in #196
  • P21-L3: Upcoming, calendar feed with rotatable tokens, ICS writer, campus timezone and locale on /me by @kapildev333 in #197
  • P21-L4: header bell with unread count, notifications page, announcement-mail opt-out by @kapildev333 in #199
  • P21-L5: Upcoming panel, Calendar feed dialog, campus time zone and locale in the web app by @kapildev333 in #201
  • P21-L6: e2e for notifications, Upcoming, calendar feed and campus time zone by @kapildev333 in #202

Full Changelog: v0.19.0...v0.21.0

v0.19.0 - Quiz and assignment follow-ups

Choose a tag to compare

@kapildev333 kapildev333 released this 09 Oct 16:07
5dfde8a

Highlights

  • Staff can fix an answer key after students have started: saving the questions regrades every submitted attempt, keeps points a reviewer set by hand, and records a regrade per attempt in the audit log (Spec 12).
  • A quiz can limit each attempt to a number of minutes inside its window; the countdown shows the attempt's own deadline and the server submits the attempt when it passes.
  • An assignment can accept late submissions until a second date with a flat percentage penalty; late work is marked, the raw grade stays on the submission and the penalised score goes to the gradebook, and students see both once released.
  • The API server bounds how long a client may take to send a request (UNICOURSE_READ_TIMEOUT, default 30 s) while uploads get their own longer deadline (UNICOURSE_UPLOAD_TIMEOUT, default 10 min); a timed-out read is logged as 499.
  • Three new end-to-end cases cover the time limit, the regrade and the late penalty.

What's Changed

Changes

  • P19-L6: server read timeouts (UNICOURSE_READ_TIMEOUT, UNICOURSE_UPLOAD_TIMEOUT), 499 on a timed-out read by @kapildev333 in #176
  • P19-L2: migration 0011, assessment time limit / late window / penalty fields, effective-deadline SQL, timed-quiz questions gate by @kapildev333 in #179
  • P19-L5: late submissions with a penalty (late window, late flag, penalised gradebook score) by @kapildev333 in #180
  • P19-L4: per-attempt time limit (effective deadline on save, submit and the sweeper; Attempt.deadlineAt) by @kapildev333 in #181
  • P19-L3: regrade submitted attempts after an answer-key change (ids on questions, manual marks kept and capped) by @kapildev333 in #183
  • P19-L7: web for Spec 12 - time limit, regrade editor mode, late submissions with penalty by @kapildev333 in #184
  • P19-L8: e2e E-QUIZ-11 (time limit), E-QUIZ-12 (regrade), E-ASG-09 (late penalty) by @kapildev333 in #186

Full Changelog: v0.18.0...v0.19.0

v0.18.0 - Quizzes and assignments

Choose a tag to compare

@kapildev333 kapildev333 released this 09 Oct 01:08
e0e3be0

Highlights

  • Staff create quizzes on a section: multiple-choice and fill-in-the-blank questions with points, a description, a weight in the gradebook and an open-to-close window (Spec 11).
  • Students take a quiz on one page with autosave and a countdown; at the close the server submits whatever was saved, grades it automatically and writes the score into the gradebook, so a student who stops mid-quiz still gets what they earned.
  • Instructors and TAs review every attempt per question, adjust points, add feedback and release scores; until release students see only that they submitted, afterwards their score, feedback and the correct answers.
  • Staff create assignments with a start date, a due date, a description and maximum points; students submit text and up to ten files, replace them until the due date, and staff grade with points and feedback that appear once released.
  • Quizzes and assignments are gradebook columns, so running grades, finalization, GPA and My grades work unchanged; the demo university seeds an open quiz with attempts and a graded assignment.
  • Two new Playwright files assert the whole flow end to end, including the automatic submission at the close and tenant isolation; 106 cases run on npm run e2e.

What's Changed

Changes

  • P18-L3: migration 0010, assessment kinds, window and dueOn, UpsertScore, MyAssessment.kind by @kapildev333 in #163
  • P18-L5: internal/assignment - submissions, files, grading; content upload/download exports; prune-files by @kapildev333 in #165
  • P18-L4: internal/quiz - questions, auto-grading, attempts, sweeper, review; quiz contract by @kapildev333 in #166
  • P18-L6 (a+b): web quizzes - tabs, list, window dialog, question editor, take page, results; D144 gradebook edits by @kapildev333 in #168
  • P18-L6c: web review-attempts page (table, in-place review, release) by @kapildev333 in #169
  • P18-L7: web assignments - list, student submission page, grading page; typed My grades links by @kapildev333 in #170
  • P18-L8a: demo seed - one open quiz with attempts and a review, one assignment with submissions and a grade on CS101 by @kapildev333 in #172
  • P18-L8b: e2e quizzes.spec.ts and assignments.spec.ts (Spec 11 §1 criterion, 18 cases) by @kapildev333 in #173

Full Changelog: v0.17.0...v0.18.0

v0.17.0 - Backlog completion

Choose a tag to compare

@kapildev333 kapildev333 released this 08 Oct 22:57
7782d5f

Highlights

  • Sign-in rate limits live in Postgres, so several API processes share one count per address and per email (Spec 10 B1); the e2e harness can raise the per-IP limit for repeated local runs.
  • Mail delivery runs on configurable sender goroutines (UNICOURSE_OUTBOX_SENDERS), the client address is read from Forwarded as well as X-Forwarded-For, IPv4-mapped prefixes match, and a malformed UNICOURSE_WEB_ORIGIN refuses startup (B2, B5, B10).
  • Department, term and course pickers search as you type (q on the three lists), so universities beyond 200 rows stay usable (B3).
  • create-university runs as a confined unicourse_platform role that cannot migrate or reach an existing university (B4, D133, D135).
  • The upload limit comes from UNICOURSE_MAX_UPLOAD_BYTES, the allowed types and limit are published at GET /api/v1/upload-policy and the web reads them; uploads show byte-level progress; routes are code-split (B7, B9, B13).
  • seed-demo --fixture <path> loads any dataset described by docs/seed/fixture.schema.json; make dev brings up Postgres, migrations, the demo and both dev servers; the screenshot script seeds through seed-demo (B8).
  • Meetings in one section may not overlap; copy fixes for the section Remove dialog, course conflicts, department-admin controls and the audit filter; invitation 409 messages no longer reveal membership state (B6, B12); CI checks the two-origin dev sign-in flow (B11).

What's Changed

Changes

  • P17-L9a: route code splitting, index chunk 546 kB to 293 kB by @kapildev333 in #147
  • P17-L5: overlapping meetings rule (D131), generic invitation 409 (D132), F4 F5 F6 F10 by @kapildev333 in #149
  • P17-L8: seed-demo --fixture, fixture schema, make dev, screens via seed-demo by @kapildev333 in #150
  • P17-L10: CI dev-setup job checks the two-origin sign-in flow (B11) by @kapildev333 in #151
  • P17-L3: outbox senders, Forwarded header and IPv4-mapped prefixes, WEB_ORIGIN validation, upload limit config by @kapildev333 in #152
  • P17-L2: sign-in rate limits in Postgres (rate_buckets, migration 0008) by @kapildev333 in #153
  • P17-L7: unicourse_platform role for create-university, migration 0009 (D133, D135) by @kapildev333 in #155
  • P17-L6: q on departments and terms, picker search, overlap rule in the contract by @kapildev333 in #156
  • P17-L4: upload limit from the environment, GET /upload-policy, web reads the policy (after #156) by @kapildev333 in #157
  • P17-L2b: UNICOURSE_SIGNIN_IP_LIMIT; e2e raises the per-IP limit by @kapildev333 in #158
  • P17-L9b: XHR upload progress with a native progress element, router pending component and intent preload (after #157) by @kapildev333 in #159

Full Changelog: v0.16.0...v0.17.0

v0.16.0 - End-to-end coverage

Choose a tag to compare

@kapildev333 kapildev333 released this 08 Oct 03:21
7d00aff

Highlights

  • Every user-visible flow, for every role, now has a Playwright case that runs on npm run e2e and in CI: 89 cases across 11 files, designed from a catalogue of 112 IDs that maps the specs, the README personas and the UI to tests (Spec 9, catalogue).
  • The demo dataset is guarded: every README persona signs in and sees exactly what the persona table promises (Spec 7).
  • Sign-in, admin, courses and sections, grading, catalog and schedule, and section content each have their own spec file, so a regression names the role, the page and the expected copy.
  • Accessibility is checked on every page and dialog per role in light and dark with axe (WCAG 2.x A and AA); no serious or critical violation today.
  • Invited adjuncts and visiting TAs whose email domain belongs to no university can sign in again after accepting their invitation (Spec 1 §5, D128).
  • The e2e harness takes a port (UNICOURSE_E2E_PORT), seeds through seed-demo or the HTTP API, and npm run e2e -- <file> runs one file.

What's Changed

Changes

  • P16-L2: e2e harness (port, shared helpers, seed-demo), demo.spec.ts persona smoke, CI e2e timeout 30 by @kapildev333 in #135
  • P16-L5: courses.spec.ts, 12 cases (courses, sections, imports, staff, roster, Participants) by @kapildev333 in #139
  • P16-L7: catalog.spec.ts, 8 cases (Catalog, My sections, schedule, phone agenda) by @kapildev333 in #136
  • P16-L6: grades.spec.ts, 12 cases (assessments, scores, publish, finalize, scale, permissions) by @kapildev333 in #137
  • P16-L4: admin.spec.ts, 11 cases incl. audit log filters and entries by @kapildev333 in #141
  • P16-L8: content-edit.spec.ts, 9 cases (announcements, weeks, materials, uploads, access) by @kapildev333 in #138
  • P16-L3: auth.spec.ts, 14 cases (E-AUTH-11 fixme pending P16-F1) by @kapildev333 in #140
  • P16-F1: accepted outside-domain invitees can sign in again (D128); E-AUTH-11 passes by @kapildev333 in #142
  • P16-L9: a11y.spec.ts axe sweep per role in light and dark (D125) by @kapildev333 in #144

Full Changelog: v0.14.1...v0.16.0

v0.14.1 - Sign-in from the dev setup

Choose a tag to compare

@kapildev333 kapildev333 released this 07 Oct 23:55
21269fd

Highlights

Patch: signing in from the README development setup (API on 8080, web dev server on 5173) now lands in the app. The magic-link confirmation page allowed form submissions to its own origin only, and the browser applied that rule to the redirect into the web app, so users stayed on the confirmation page with a session already set. Single-origin deployments were unaffected.

What's Changed

Changes

  • P15-L1: allow the web origin in the sign-in confirm page's form-action CSP (sign-in from the README dev setup) by @kapildev333 in #130

Full Changelog: v0.14.0...v0.14.1

v0.14.0 - Backlog sweep

Choose a tag to compare

@kapildev333 kapildev333 released this 07 Oct 22:47
f9bc9c7

Highlights

Phase 14, the backlog sweep: every defect and bounded improvement carried in PLAN.md since Phase 0 is fixed; what remains is gated on a trigger. Every decision to date is confirmed.

  • Participants tab. Each section's staff editor and roster moved from Home to a Participants tab (Home keeps the title band, description and meeting times); every member sees staff with role badges, the roster stays with those allowed to see it.
  • Account menu. The header shows your name; the account dialog sets your display name and, on phones, holds Sign out so the header stays one row.
  • Gradebook and My grades. The gradebook sits under the section band and tabs; "(n missing)" is labelled against the Finalize count; Finalize-disabled reasons follow the design; a same-letter override keeps its recorded points; My grades shows how many assessments are not yet published; the sticky Student cell no longer takes the row hover.
  • Admin. The Audit log gains a Target column and a true total ("Showing 50 of 100 changes"); admin tabs use the shared page header; catalog and course lists are in code order; one primary "New section" on an empty term; sign-in rate-limit copy says an hour.
  • Operations. A client disconnect mid-request is logged as an abort, not a 500; expired sign-in mails are given up unsent; seed-demo --reset removes the old files directory; prune-files clears day-old temporary uploads; the gradebook export honours Accept q-values.
  • Dependencies. React 19, Vite 8, Vitest 5, jsdom 30 and @types/node 26; local development needs Node 22.22.2 or newer. ESLint stays at 9 until its accessibility plugin supports 10.
  • Process. GitHub Releases per phase (this is the second), generated notes without chore PRs, the capture script covers the section Home and Materials pages.

Specs: https://github.com/kapildev333/unicourse/tree/main/docs/specs. Plan and decisions: https://github.com/kapildev333/unicourse/blob/main/PLAN.md.

What's Changed

Changes

  • P14-L1c: RemoveUniversity on seed --reset, .tmp pruning in prune-files, CSV writer error check by @kapildev333 in #122
  • P14-L1a: client aborts logged as 499, expired sign-in mail given up, audit-log total by @kapildev333 in #123
  • P14-L4: Participants tab, single New section on an empty term, e2e local year, Home and Materials captures by @kapildev333 in #124
  • P14-L1b: catalog ordering, override keeps points, Accept q-values, real authz fixtures, unpublishedCount by @kapildev333 in #125
  • P14-L2: TextLink, PageHeader levels, Account menu with display name, Audit log Target and total, rate-limit copy by @kapildev333 in #126
  • P14-L3: gradebook under the section band, hover band fix, missing-count label, Finalize reasons, My grades unpublished count by @kapildev333 in #127
  • P14-L5: React 19, Vite 8, Vitest 5, jsdom 30, @types/node 26; Node floor 22.22.2 by @kapildev333 in #128

Full Changelog: v0.12.0...v0.14.0

v0.12.0 - Baseline: Specs 1 to 8

Choose a tag to compare

@kapildev333 kapildev333 released this 07 Oct 21:22
5185d77

Highlights

Baseline release: everything built through Phase 12 (Specs 1 to 8), as the product stands on 2026-10-07.

  • A university in minutes. unicourse-admin create-university sets up a tenant with its own allowed email domains, timezone and first admin; unicourse-admin seed-demo loads the Northfield University demo (four departments, five courses, staff, rosters, grades, announcements and materials) for trying every role (Spec 1, Spec 7).
  • Sign in by magic link, Google or Microsoft, with per-university roles: admin, department admin, instructor, TA, student (Spec 1).
  • Catalog and sections. Departments, terms, courses and sections with weekly meeting times and rooms; CSV imports for courses, sections and rosters; instructors and TAs assigned per section (Spec 1, Spec 2).
  • My sections and schedule. Students and staff see their sections per term as cards or as a weekly timetable with a Today marker and clash detection (Spec 2).
  • Grading. Weighted assessments, score entry and CSV import, running percent and letter, a per-university editable grade scale, finalisation with overrides and a reason, and GPA on My grades (Spec 4).
  • Section content. Each section has a home page, announcements emailed to the roster, and weekly materials with file upload and safe download, for instructors and TAs alike (Spec 6).
  • A professional light and dark UI, benchmarked screen by screen and improved across Phases 8 and 9, usable at phone width (Spec 3, Spec 5).
  • For developers. A root README that goes from clone to a signed-in demo, an OpenAPI 3.1 contract checked in CI, a generated Postman collection with a local environment, and an admin CLI with migrations and file pruning (Spec 7, Spec 8).

Specs: docs/specs/. Plan and decisions: PLAN.md.

What's Changed

Changes

  • P0-L1: API skeleton and httpx by @kapildev333 in #6
  • P0-L3: web skeleton and API client by @kapildev333 in #7
  • P0-L4: openapi.json contract, route registry and contract test by @kapildev333 in #9
  • P0-L2: schema, RLS, pg, testdb, audit by @kapildev333 in #10
  • P2-L1: csvimport engine by @kapildev333 in #13
  • P1-L1a: auth primitives (sessions, magic links, mailer, limiter) by @kapildev333 in #14
  • P1-L4: web sign-in and admin console by @kapildev333 in #16
  • P1-L1b/c: sign-in, OIDC, auth handlers and wiring by @kapildev333 in #17
  • P1-L2a/b: authz, tenant pipeline, departments and terms API by @kapildev333 in #18
  • P2-L2a: courses and sections API by @kapildev333 in #19
  • P2-L3: web courses, sections, staffing, roster import, my sections by @kapildev333 in #21
  • P1-L2c: memberships, invitations and audit-log route by @kapildev333 in #22
  • P1-L3: unicourse-admin CLI (migrate, create-university) by @kapildev333 in #23
  • P2-L2b: section staff, enrollments and my-sections API by @kapildev333 in #27
  • P1-L5: audit invitation acceptance at sign-in by @kapildev333 in #29
  • P2-L2c: CSV imports for courses, sections and rosters by @kapildev333 in #30
  • P3-L1: serve the web app from the API, end-to-end staffing flow, CI e2e job by @kapildev333 in #31
  • P5-L1a: section meetings in the API, catalog filters by @kapildev333 in #38
  • P5-L1b: catalog reads for members, pendingStaff masking, import meetings column by @kapildev333 in #39
  • P5-L2: student schedule grid, catalog, meetings editor by @kapildev333 in #41
  • P4-L1: mail outbox, sent after commit by an in-process sender by @kapildev333 in #43
  • P5-L3: e2e for overlapping meetings, schedule clashes and catalog clash note by @kapildev333 in #44
  • P4-L5a: cancel a pending staff assignment, exact-case JSON keys by @kapildev333 in #46
  • P4-L3: trusted-proxy client address, OIDC start rate limit by @kapildev333 in #47
  • P4-L5b: cancel a pending staff invitation from the staff editor, two catalog/dialog fixes by @kapildev333 in #48
  • P4-L2: database role split - owner migrates, the API role cannot disable RLS by @kapildev333 in #50
  • P6-L1: UI foundation - tokens for light and dark, DM Sans, Lucide, theme switch, Udemy top bar with search, shared components, literal-colour gate by @kapildev333 in #56
  • P6-L2: entry pages on the Udemy foundation (sign-in, magic link sent, no access, root redirect) by @kapildev333 in #59
  • P6-L3: My sections and Catalog as card grids, schedule on tokens by @kapildev333 in #60
  • P6-L5: admin area on the Udemy foundation (tabs, tables, dialogs) by @kapildev333 in #62
  • P7-L1a: grading schema, contract, grade scale, assessments, scores by @kapildev333 in #66
  • P6-L4: courses area on the Udemy foundation (lists, section detail band, roster, dialogs, editors) by @kapildev333 in #63
  • P7-L1b: gradebook, finalize with credits snapshot, GPA by @kapildev333 in #68
  • P7-L1c: scores CSV import, gradebook CSV export by @kapildev333 in #70
  • P7-L2: grading web - gradebook, My grades with GPA, grade scale editor by @kapildev333 in #71
  • P7-L3: e2e for grading - assessments, scores, finalize, GPA by @kapildev333 in #72
  • P8-L1: Playwright screen-capture project for the UI/UX benchmark by @kapildev333 in #75
  • P8-L2: reference pack for the UI/UX benchmark (Dribbble shots described from images) by @kapildev333 in #76
  • P8-L3: Spec 5 UI/UX benchmark and its Phase 9 plan by @kapildev333 in #78
  • P9-L1a: shared components for Phase 9 (Table stack, Loading variants, Card footer, Dialog close, SegmentedControl, Disclosure, line-control) by @kapildev333 in #82
  • P9-L1b: shell at phone width, current nav item, / shortcut, no-access page, capture width assertion by @kapildev333 in #85
  • P9-L8: display names (invitation name, roster import fill, sign-in fill, PATCH /me) by @kapildev333 in #84
  • P10-L1a: section content API foundation (migration, blob, description, announcements, mail, contract) by @kapildev333 in #87
  • P9-L4: admin tables stack on phones, term status, audit labels and disclosure, titled banners by @kapildev333 in #89
  • P9-L2: phone agenda, Today marker, merged meetings, Catalog filters and badges, My sections controls by @kapildev333 in #90
  • P10-L1b: weeks, materials upload and download, blob cleanup after commit, prune-files by @kapildev333 in #91
  • P9-L3: courses, sections and dialogs for phones; empty states; staff cells; Edit section by @kapildev333 in #93
  • P9-L5: gradebook, finalize preview, assessment dialog, My grades and grade scale for phones and clarity by @kapildev333 in #94
  • P10-L2: section tabs, Home description, Announcements and Materials pages by @kapildev333 in #97
  • P10-L3: Spec 6 end-to-end criterion (content.spec.ts with generated fixtures) by @kapildev333 in #100
  • P9-L1c: ButtonLink, ListCount, quiet row actions, Table clipping, sized inputs, gradebook Student column by @kapildev333 in #99
  • P9-L6: one sign-in field, resend and last-used, one search, middle-dot separators, e2e selectors per §5.7 by @kapildev333 in #102
  • P9-L9: Phase 9 closing audit (after scores, remaining findings, taste-skill pass) by @kapildev333 in #103
  • P9-L10a: stacked phone rows, table style bugs, Admin heading, Audit log cards on phones, neutral Close and badges, copy by @kapildev333 in #107
  • P9-L10b: schedule Today marker and time line, finalize preview and grade scale stacked on phones, My grades hint, capture seed names by @kapildev333 in #106
  • P11-L1: unicourse-admin seed-demo, embedded demo fixture through the real handlers by @kapildev333 in #111
  • P11-L2: root README, eight light and...
Read more