Skip to content

feat(competitions): deadline reminders via a saved-competitions calendar feed #210

Description

@AnayDhawan

Blocked by #200 and #201.

Lower priority than the core catalog, higher value than most of the polish. Do it after #201 lands.

Why this and not more countdown polish

Students do not miss competitions because they never heard of them. They miss them because the date passed while they were doing something else. A countdown only helps someone already looking at the page; a reminder reaches someone who is not.

This is the one feature in the vertical that turns a visit into a return visit, and the saves table (#199) already holds exactly the data it needs.

Two delivery paths, in this order

1. Calendar subscription (do this first). An .ics feed at /api/competitions/saved.ics?token=… that a student subscribes to once in Google Calendar or Apple Calendar. No email infrastructure, no sending, no deliverability, no unsubscribe flow, and the reminder lands in the app they already check. Generating iCalendar text is a pure function over the dates.

The token is a per-user opaque value, not the user id and not a JWT. Add a calendar_token column to user_profiles (#203) or a small table. The URL is a bearer credential, so treat it as one: rotatable from the account page, and never logged.

2. Email digest (only if the feed proves wanted). Weekly, listing saved competitions with a deadline in the next 14 days. Needs a sending provider, a scheduled job, unsubscribe handling and a bounce path. That is a real chunk of work and it is not worth starting before anyone asks for it.

Do not build browser push notifications. The PWA service worker exists, but push needs permission prompts, a push service and a subscription store, and it is the most easily ignored of the three.

Acceptance criteria

  • .ics feed validates and imports into Google Calendar and Apple Calendar
  • Feed contains only that user's saved competitions
  • Token is opaque, rotatable, and not derived from the user id
  • An invalid or revoked token returns 404, and does not confirm whether the token ever existed
  • Estimated dates are labelled as approximate in the event title
  • Feed URL is discoverable from /competitions/saved
  • Documented in docs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    competitionsCompetitions catalog verticalgrowthDistribution and tractionowner-yashOwned by Yash

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions