About The Project
Users had been requesting recurring events in our agenda app for a while. It's the kind of feature you take for granted in Google Calendar—set a weekly meeting once and forget about it. But behind that simplicity is a real architectural decision that affects how you store, query, and display data.
I was involved in planning how this feature would work and then implementing it across the stack: from database schema to UI components to export functionality.
The Challenge: One Event, Many Occurrences
Our agenda app only supported events with a start and end date. Adding recurrence meant answering a fundamental question: do you store every occurrence in the database?
If someone creates a "weekly team meeting" that repeats for a year, that's 52 records. Multiply that across users and event types, and you're looking at a MongoDB collection that grows fast and becomes harder to query efficiently. We needed a smarter approach.
The Solution: Virtual Expansion
1. Reusing What Already Worked
We already had a pattern for multiday events: store one record in the database, then expand it in the frontend to render across multiple days. I took that same concept and extended it for recurring events.
2. Adopting the RRule Standard
Instead of inventing our own recurrence format, we used the RRule
standard—the same specification behind iCalendar. A weekly Tuesday meeting
gets stored as a single document with a rule like FREQ=WEEKLY;BYDAY=TU. The
frontend reads that rule and expands it into individual occurrences when
rendering the calendar view.
This kept the database lean: one record per recurring event, no matter how many times it repeats.
3. A Deliberate Scope Cut
This approach meant we couldn't support editing single occurrences of a recurring event. If you wanted to cancel one specific Tuesday, you couldn't—you'd have to delete the whole series. We knew this limitation going in.
It was a conscious tradeoff. We could either build a complete system with exception handling (which would take months) or ship something that solved 90% of the use case now. We chose to ship.
What I Built
Beyond the architectural planning, I implemented several pieces of this feature:
- UI Implementation: Translated the full Figma designs into working Vue components, including the recurrence configuration flow.
- Design System Components: Created two new components for our Vue 2 design system—a calendar picker and a time scroll input—that are now reused across the app.
- Export Functionality: Updated our "Export to Calendar" feature so recurring events translated correctly into standard formats that work with Google Calendar, Outlook, and other apps.
Key Results
- Feature Shipped On Time: Users got the recurring events they'd been asking for, delivered within the deadline.
- Database Stayed Clean: The virtual expansion approach avoided bloating our MongoDB collections with duplicate records.
- Reusable Components: The calendar and time scroll inputs became part of our design system, available for future features.
The system isn't perfect—single-occurrence editing is still a gap. But it solved the real problem users had, and it shipped. Sometimes that's the right answer.