Fase 81.0
organized-app-importer
Backup JSON → roster local con CRDT diff + dry-run + cifrado at-rest
Paquete nuevo jw-meeting-scheduler. Importa el JSON exportado desde organized-app web/desktop a un store SQLite local por congregación. Mapper PersonType → PersonRecord plano: gender derivado de male/female booleans separados, status derivado de publisher_baptized/unbaptized.active, privileges activos sólo, eligible_assignments flattened+deduped, last_updated = max(updatedAt) de los campos Timestamped. Walk recursivo del SchedWeek anidado picking up dict slots {value, type, updatedAt} → AssignmentHistoryEntry con aula auto-detected (suffix _B→aux_class_1, _C→aux_class_2). Pipeline run_import con dry-run flag + compute_person_diff clasifica added/updated/kept_local/unchanged. Cifrado at-rest opt-in con FieldEncryptor + salt PBKDF2 derivada del congregation_id.
Qué se entregó
- load_backup con Pydantic OrganizedAppBackup envelope + lista PersonType del schema F51.
- map_person: gender derivado de booleans separados male/female, status de publisher_baptized/unbaptized.active + statusHistory, privileges activos sólo (end_date vacía o futura), eligible_assignments flattened+deduped por sorted(value).
- slugify_person_id con NFD strip diacritics + intra-word decoration strip (Juan Pérez → juan-perez, O'Connor → oconnor).
- map_schedule_week walk recursivo del dict tree picking up slots {value, type, updatedAt}, aula auto-detected del field suffix.
- SchedulerStore SQLite con índice compuesto (person_id, assignment_code, meeting_date DESC) para rotation queries rápidas.
- CRDT guard en upsert_person: si existing.last_updated ≥ rec.last_updated, no escribe (local newer wins).
- record_history con INSERT OR IGNORE por entry_id (idempotente).
- FieldEncryptor wrapper con salt b'jw-meeting-scheduler/v1:' + congregation_id → mismo passphrase + distinto cong = keys distintas (verificado en tests con Fernet InvalidToken).
- run_import pipeline con dry-run flag + ImportDiff (added/updated/kept_local/unchanged) renderizado en Rich table.
- jw scheduler import --backup --congregation [--dry-run] [--passphrase] CLI completo.
- 26 tests scheduler (5 models + 3 crypto + 4 loader + 5 person_mapper + 4 schedule_mapper + 7 store + 4 diff + 4 pipeline) + 2 CLI tests.
- Guía docs/guias/meeting-scheduler-import.md con quickstart + recetas de cifrado.