feat: POST /api/push/dav-bulk — push masivo por disco + 1 commit (segundos vs minutos)
Vía rápida DB→Xandikos para operaciones masivas: genera todos los vCards de agenda desde DuckDB a un tmpdir, rsync de golpe al working tree de la colección en magnus (excluyendo .git/.xandikos), UN solo git commit, y 1 PROPFIND para capturar todos los etags en batch. ~0.5s vs ~6min del push HTTP (que hace N PUTs + N PROPFINDs + N commits). El push HTTP push_all_dav se mantiene como fallback (y para CalDAV). Config DAV_BULK_SSH_HOST/REMOTE_DIR. 22 tests verdes.
This commit is contained in:
@@ -131,7 +131,36 @@ Health check: `curl http://127.0.0.1:8771/api/health`.
|
||||
| POST/PUT/DELETE | `/api/event[/{uid}]` | CRUD de eventos CalDAV. Push `caldav_put_event`/`dav_delete_resource` |
|
||||
| POST | `/api/addressbook` | `{slug, display_name?, description?, color?}` → `dav_make_addressbook` + INSERT en `addressbooks` |
|
||||
| POST | `/api/calendar` | `{slug, display_name?, color?}` → `dav_make_calendar` (paridad) |
|
||||
| POST | `/api/push/dav` | reconcilia en bloque: recorre `contacts` y `events` de la DB y los empuja a Xandikos (PUT, sin borrar). Útil tras la migración |
|
||||
| POST | `/api/push/dav` | reconcilia en bloque por HTTP: recorre `contacts` y `events` de la DB y los empuja a Xandikos (1 PUT + 1 PROPFIND + 1 commit git por recurso, sin borrar). Fallback cuando no hay SSH al host de Xandikos |
|
||||
| POST | `/api/push/dav-bulk` | vía RÁPIDA del push de **contactos** por DISCO: genera todos los `.vcf` en un tmpdir local y hace **1 rsync + 1 commit + 1 PROPFIND** contra el working tree git que Xandikos sirve. Reconcilia ~1000 contactos en <1s en vez de ~6 min. Requiere SSH por clave |
|
||||
|
||||
### `/api/push/dav` (HTTP) vs `/api/push/dav-bulk` (disco)
|
||||
|
||||
Ambos vuelcan los contactos de la DB a Xandikos, pero por mecanismos distintos:
|
||||
|
||||
| | `/api/push/dav` (HTTP) | `/api/push/dav-bulk` (disco) |
|
||||
|---|---|---|
|
||||
| Mecanismo | N PUT WebDAV (uno por contacto) | 1 rsync de todos los `.vcf` a la vez |
|
||||
| PROPFIND | 1 por contacto (lee el etag tras cada PUT) | 1 al final, lee todos los etags de golpe |
|
||||
| Commits git en el remoto | N (Xandikos commitea cada PUT) | 1 (`git add -A && commit` único) |
|
||||
| Coste para ~1000 contactos | ~6 min (≥1 PROPFIND completo/contacto) | <1s (dominado por 2-3 round-trips SSH) |
|
||||
| Eventos CalDAV | sí (también empuja `events`) | no (solo `contacts`) |
|
||||
| Borra huérfanos remotos | no | sí — `rsync --delete` deja la colección `.vcf` == DB |
|
||||
| Requisitos | red HTTPS a Xandikos + `pass` | SSH por clave al host + `rsync` ambos lados |
|
||||
|
||||
**Usa `/api/push/dav-bulk`** para reconciliar en bloque (tras una migración o un
|
||||
ingest masivo) cuando hay SSH al host de Xandikos: es el camino normal por
|
||||
rapidez. **Usa `/api/push/dav`** como fallback cuando no hay SSH, o cuando
|
||||
también necesitas empujar eventos CalDAV.
|
||||
|
||||
Cómo lo ve Xandikos: sirve cada colección desde el working tree de un repo git y
|
||||
calcula el ctag desde el HEAD. El push por disco escribe los `.vcf` directamente
|
||||
en ese working tree y hace un único commit; Xandikos ve el nuevo HEAD en el
|
||||
siguiente request (nuevo ctag → DAVx5 detecta el cambio). El rsync sincroniza
|
||||
SOLO los `*.vcf` (`--include='*.vcf' --exclude='*'`), preservando `.git/`,
|
||||
`.xandikos` (tipo de colección) y `push-subscriptions.json` (suscripciones
|
||||
WebDAV-Push). Config del host/working tree: `DAV_BULK_SSH_HOST` /
|
||||
`DAV_BULK_REMOTE_DIR` en `server/config.py`.
|
||||
|
||||
Queries con nombre incluidas: `personas_por_contexto`, `personas_recientes`,
|
||||
`eventos_proximos`, `contactos_sin_nota`, `stats_personas`,
|
||||
|
||||
Reference in New Issue
Block a user