5d5ce65e88
Backend (server/main.py): - EventIn.rrule + emision/parseo de RRULE en el VCALENDAR. - calendar() expande las series recurrentes a sus ocurrencias dentro de [from,to] (compone expand_rrule del registry); helpers _expand_event_occurrences / _occurrence_clone preservan hora local, offset y duracion por ocurrencia. - POST /api/calendars: crea una coleccion de calendario nueva (compone dav_make_calendar); invalida la cache de colecciones. Frontend: - EventModal: controles de repeticion (frecuencia, intervalo, BYDAY para semanal, fin por N veces / hasta fecha); parseRrule/buildRrule; aviso 'afecta a la serie'. - CalendarView: vista Lista/Agenda (eventos por dia, click para editar, nuevo evento), linea roja de hora actual (refresco cada 60s, solo columna de hoy), boton Nuevo calendario (modal nombre/color), indicador de recurrencia (IconRepeat). - api.ts/calendar.ts: rrule/recurring/occurrence en los tipos, createCalendar, helpers nowLinePct/slugifyCalendar. Verificado: tsc -b + vite build limpios; smoke backend (FREQ=WEEKLY;COUNT=3 -> 3 ocurrencias con hora/offset/duracion correctas); render en navegador (vista Lista, Nuevo calendario, Nuevo evento, selectores presentes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>