Commit Graph

4 Commits

Author SHA1 Message Date
egutierrez 3063d3c44f feat(scans): persistencia de escaneos de red + POST /api/scan
Tabla network_scans (migración 005, schema main, lleva note_path) que otras
herramientas pueblan vía HTTP con escaneos de reconocimiento (whois/rdap/dns/
nmap/traceroute/ping). Endpoint POST /api/scan: id determinista
<target_slug>:<scan_type>:<YYYYMMDD-HHMM> derivado de scan_ts, idempotente por
id (duckdb_upsert ON CONFLICT DO UPDATE) bajo el lock single-writer del service.
summary (dict) se serializa a JSON.

network_scans no se deriva de notas: ni ingest_vault ni ingest_dav la tocan, así
que un re-ingest del vault no la trunca (test lo verifica).

Tests: inserción + id derivado, idempotencia mismo-minuto, validación de campos
requeridos (422), y no-truncado por ingest del vault.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 13:13:36 +02:00
egutierrez d7c28c8f55 feat(db): migracion 004 — columna import_key + indice para imports idempotentes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 11:47:48 +02:00
egutierrez 63f37257cd feat: DuckDB como fuente de verdad (multi-valor, ownership selectivo, escritura, libretas)
F1 — migraciones: 002_multivalue (persons +telefonos/emails/direcciones/extra_fm JSON,
backfill desde singulares con to_json) + 003_addressbooks (tabla addressbooks + seed
idempotente de la libreta por defecto). Conteos intactos (697/1065/98).

F2 — ingest_vault selectivo (anti-pisado): personas que ya existen en DB solo actualizan
note_path + extra_fm vía duckdb_upsert(update_cols=...), NO pisan los campos OWNED por la
DB; personas nuevas = bootstrap completo. _link_contacts enlaza por listas telefonos[]/
emails[] además del singular. ingest_dav itera todas las libretas de la tabla addressbooks.

F3 — escritura estructurada (server/writes.py + endpoints en main.py): CRUD
/api/person|contact|event, /api/addressbook, /api/calendar, /api/person/{slug}/render
(DB→nota preservando la prosa del cuerpo), /api/push/dav (reconcilia DB→Xandikos). El push
DAV y el render ocurren fuera de la transacción de escritura para no bloquear la DB con
latencia de red. registry_bridge.py importa las funciones nuevas; app.md actualizado.

Verificado: 18 tests verdes; ownership probado sobre datos reales (un centinela DB-owned
sobrevivió a POST /api/ingest/vault sobre las 697 fichas); person CRUD + materialización
de la ficha .md en vivo, con cleanup sin residuo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 00:44:02 +02:00
agent 2716edd5a0 feat: initial scaffold of osint_db (DuckDB source-of-truth service) 2026-06-13 00:02:41 +02:00