Backend (server/main.py):
- GET /api/calendars: lista las colecciones de calendario bajo el calendar-home
con nombre y color (compone dav_list_calendars del registry).
- GET /api/calendar?cal=&from=&to=: eventos de una colección concreta (caché por
colección validada por ctag). dtstart/dtend ahora en ISO con offset + tz
original + all_day; parseo robusto de TZID/UTC/todo-el-día con zoneinfo.
- POST/PUT/DELETE /api/event[/<uid>]: CRUD de VEVENT contra Xandikos (fuente de
verdad). Construye el VCALENDAR (con VTIMEZONE para zonas con DST), reutiliza el
UID al editar (idempotente), trata 404 del DELETE como idempotente, invalida la
caché de la colección tras escribir.
Frontend:
- CalendarView reescrita: conmutador Mes/Semana/Día con rejilla horaria propia
(Mantine + dayjs, sin react-big-calendar para evitar fricción con React 19),
mini-calendario de navegación, selector de calendario (con color), selector de
zona horaria que recoloca los eventos, colores por evento (del VEVENT o del
calendario).
- EventModal: alta/edición/borrado con summary, inicio/fin, todo-el-día, TZ,
calendario, color, ubicación y descripción. Fechas en formato local 24h.
- calendar.ts: helpers de TZ (dayjs utc+timezone), posicionado por hora, semana
empezando en lunes, locale es. api.ts: tipos y funciones de eventos/calendarios.
Verificado: ciclo real crear→editar→borrar contra Xandikos (cero residuo),
render del calendario en navegador (React 19 + Mantine v9 montan), pnpm build
verde, 40 tests verdes (+ smoke gateado). MKCALENDAR queda fuera (documentado).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Frontend web de lectura del vault osint + agenda/calendario Xandikos.
- Stack: React 19 + Vite 6 + TypeScript + Mantine v9 (React 19 obligatorio para
que Mantine v9 monte). Grafo con sigma v3 + graphology + forceatlas2 en web
worker. Markdown con react-markdown, calendario con @mantine/dates.
- AppShell con navbar de 4 secciones + botón global de refresco (POST /api/refresh).
- GraphView: force-directed, color por tipo, tamaño por grado, panel lateral con
toggles de tipo + dangling + buscador (centra el nodo). Guard de WebGL: si el
navegador no lo expone, avisa en vez de crashear.
- TablesView: una pestaña por tipo, tabla ordenable/filtrable con columnas del
frontmatter. Click en fila -> ficha.
- NodeCard (modal): frontmatter clave-valor (fechas europeas), cuerpo Markdown,
galería de imágenes con lightbox, PDFs/docs como enlace, wikilinks navegables.
- ContactsView: agenda con buscador + detalle (teléfonos, correos, bloque osint,
nota). CalendarView: mini-calendario con días marcados + eventos agrupados por
día (hora local).
- Vite proxya /api -> 127.0.0.1:8470. Verificado end-to-end contra el backend
real: 1199 nodos / 618 aristas, 539 personas en tabla, 1064 contactos, 98
eventos; grafo renderiza con WebGL y NodeCard abre con frontmatter+body.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>