Files
osint_web/frontend
egutierrez 5d5ce65e88 feat(calendar): recurrencia (RRULE), multi-agenda, vista lista y linea de ahora
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>
2026-06-12 23:30:14 +02:00
..

Frontend de osint_web

Frontend web local del explorador OSINT. Lee el backend FastAPI (../server/main.py, escucha solo en 127.0.0.1:8470) y ofrece cinco vistas de lectura sobre el vault de Obsidian osint + la agenda/calendario del servidor Xandikos.

Stack

  • React 19 + Vite 6 + TypeScript + Mantine v9. Mantine v9 exige React 19 (con React 18 compila pero no monta — error "s is not a function"); por eso el package.json pina React 19. Iconos de @tabler/icons-react. Theming con createTheme() (src/theme.ts), sin Tailwind ni CSS variables custom (regla frontend_theming.md).
  • Grafo: sigma (v3) + graphology + graphology-layout-forceatlas2 (las únicas deps fuera de Mantine; KISS). Layout force-directed en un web worker (no bloquea la UI con 1199 nodos), pausable.
  • Markdown de las fichas con react-markdown. Calendario con @mantine/dates (que usa dayjs).
  • Vite proxya /apihttp://127.0.0.1:8470 en dev (sobrescribible con VITE_API_BASE).

Vistas

Vista Archivo Endpoint(s) Qué muestra
Grafo src/views/GraphView.tsx GET /api/graph, GET /api/search sigma.js force-directed; color por tipo, tamaño por grado; panel lateral con toggles de tipos + dangling + buscador (centra el nodo). Click en nodo → ficha. Layout pausable + reset de cámara.
Tablas src/views/TablesView.tsx GET /api/graph, GET /api/nodes?tipo= una pestaña por tipo real; Table Mantine con columnas deducidas del frontmatter, ordenable y filtrable. Click en fila → ficha.
Ficha src/views/NodeCard.tsx GET /api/node/<slug>, GET /api/attachment modal: frontmatter clave-valor (fechas europeas DD/MM/AAAA), cuerpo Markdown, galería de imágenes con lightbox, documentos/PDFs como enlace, wikilinks navegables.
Contactos src/views/ContactsView.tsx GET /api/contacts agenda: lista + buscador (nombre/alias/tel/email); detalle con teléfonos, correos, bloque osint (dni/país/sexo…) y nota.
Calendario src/views/CalendarView.tsx GET /api/calendar mini-calendario @mantine/dates con punto en días con eventos + lista de eventos del mes/día agrupados por fecha (hora local, lugar, descripción).

Botón global Refrescar (header) → POST /api/refresh + recarga de la vista activa.

Arrancar (dev)

Necesitas backend + frontend a la vez:

# Terminal 1 — backend (escucha solo en 127.0.0.1)
cd projects/osint/apps/osint_web
.venv/bin/python server/main.py --vault /home/enmanuel/Obsidian/osint --port 8470

# Terminal 2 — frontend
cd projects/osint/apps/osint_web/frontend
pnpm install        # primera vez
pnpm dev            # http://127.0.0.1:5173

Abrir http://127.0.0.1:5173. El proxy de Vite reenvía /api al backend, así que no hay que tocar CORS. Solo localhost (datos sensibles del vault: DNIs, fotos).

Build

cd projects/osint/apps/osint_web/frontend
pnpm install
pnpm build          # tsc -b && vite build → dist/

Gotcha pnpm 10/11 (esbuild)

pnpm bloquea por seguridad los scripts de build de dependencias. esbuild (el bundler nativo de Vite) necesita su postinstall. El pnpm-workspace.yaml lo permite con allowBuilds: { esbuild: true }. Si pnpm build falla con "esbuild ... was not found", ejecuta pnpm rebuild esbuild.

Notas

  • Grafo sin WebGL: si el navegador no expone WebGL (headless sin GPU), la vista Grafo muestra un aviso en vez de crashear; el resto de la app sigue funcionando.
  • Contactos/Calendario dependen del servidor Xandikos: si no responde, esas dos vistas muestran un aviso naranja y el grafo/tablas siguen operativos (offline).
  • Las fechas se presentan en europeo (src/format.ts): ISO de Obsidian 2026-06-0707/06/2026; iCal 20220829T133000Z → hora local 15:30.