Upload events from an image or file #80

Open
opened 2026-10-03 19:44:44 +00:00 by jalenluorion · 0 comments
Member

Goal
Most club events are announced as flyers or PDFs, not calendar feeds. Letting a manager drop in an image or file and confirm the parsed events makes posting fast enough that clubs will do it.

Current state

  • The upload button in web/src/app/components/Navbar.tsx opens ModalUploadOne.tsx (pick a category you manage), then ModalEventLink.tsx (iCal link) or ModalEventForm.tsx (manual form). Files are not supported.
  • The course agent already calls OpenRouter through api/course_agent/app/services/llm.py (OPENROUTER_API_KEY, OPENROUTER_MODEL).
  • secretspec.toml does not declare OPENROUTER_API_KEY; it still lists OPENAI_API_KEY "for the course agent", which the code no longer reads.

Scope

  • Declare OPENROUTER_API_KEY (and model) in secretspec.toml, required = false, so the API can read it from OpenBao.
  • POST /api/events/parse_upload: accepts an image, PDF or .ics (with a size limit), and checks can_edit_category. Parse .ics with the existing iCal code; send images and PDFs to a vision model with a strict JSON schema (title, start, end, location, description, link). Write nothing to the DB, and do not keep the file.
  • Keep it inside the gunicorn 120s limit (api/app/wsgi.py).
  • Confirm step per the Figma upload flow: an editable list of parsed events, where the user fixes, removes or accepts each one, then saves through the existing create-event path.
  • Add the "Google Calendar link" option to the same modal so all three ways live in one place.
  • Tests with a mocked LLM response.

Done when

  • A manager can upload a flyer, fix the parsed fields and save; the events show on the calendar.
  • Bad files and LLM failures show a clear error.
**Goal** Most club events are announced as flyers or PDFs, not calendar feeds. Letting a manager drop in an image or file and confirm the parsed events makes posting fast enough that clubs will do it. **Current state** - The upload button in `web/src/app/components/Navbar.tsx` opens `ModalUploadOne.tsx` (pick a category you manage), then `ModalEventLink.tsx` (iCal link) or `ModalEventForm.tsx` (manual form). Files are not supported. - The course agent already calls OpenRouter through `api/course_agent/app/services/llm.py` (`OPENROUTER_API_KEY`, `OPENROUTER_MODEL`). - `secretspec.toml` does not declare `OPENROUTER_API_KEY`; it still lists `OPENAI_API_KEY` "for the course agent", which the code no longer reads. **Scope** - [ ] Declare `OPENROUTER_API_KEY` (and model) in `secretspec.toml`, `required = false`, so the API can read it from OpenBao. - [ ] `POST /api/events/parse_upload`: accepts an image, PDF or .ics (with a size limit), and checks `can_edit_category`. Parse .ics with the existing iCal code; send images and PDFs to a vision model with a strict JSON schema (title, start, end, location, description, link). Write nothing to the DB, and do not keep the file. - [ ] Keep it inside the gunicorn 120s limit (`api/app/wsgi.py`). - [ ] Confirm step per the Figma upload flow: an editable list of parsed events, where the user fixes, removes or accepts each one, then saves through the existing create-event path. - [ ] Add the "Google Calendar link" option to the same modal so all three ways live in one place. - [ ] Tests with a mocked LLM response. **Done when** - [ ] A manager can upload a flyer, fix the parsed fields and save; the events show on the calendar. - [ ] Bad files and LLM failures show a clear error.
jalenluorion added this to the Phase 3 milestone 2026-10-03 19:44:44 +00:00
jalenluorion added this to the CMUCal project 2026-10-03 19:45:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ScottyLabs/cal#80
No description provided.