Guía
Importar un backup de organized-app
Esta guía cubre F81.0: cómo poblar el store del scheduler a partir
de un backup JSON exportado desde la web app organized-app.
Requisitos
uv sync --all-packagescorrido al menos una vez.- Backup JSON exportado de organized-app (Settings → Backup → Export).
- (opcional)
JW_PRIVACY_KEYexportada o--passphraselisto.
Comando
# Dry-run: muestra qué cambiaría sin tocar el store
uv run jw scheduler import \
--backup ~/Downloads/organized-backup.json \
--congregation kingdom-hall-central \
--dry-run
# Import real
uv run jw scheduler import \
--backup ~/Downloads/organized-backup.json \
--congregation kingdom-hall-central \
--passphrase "correct-horse-battery-staple"
Qué pasa por dentro
- Lee el JSON con
jw_meeting_scheduler.importer.loader.load_backup. - Por cada
PersonTypecorremap_person→PersonRecord. - Calcula diff vs el store (
compute_person_diff):- added: el slug no existía.
- updated: el slug existía con
last_updatedanterior. - kept_local: el slug existía con
last_updatedposterior → no se sobrescribe (CRDT respect). - unchanged: timestamps iguales.
- Si no es dry-run, upserta personas y luego por cada
SchedWeekejecutamap_schedule_week→AssignmentHistoryEntry[]y los inserta conINSERT OR IGNORE(idempotente porentry_id).
Ubicación del store
~/.jw-agent-toolkit/congregations/<congregation_id>/scheduler.db.
Override con env var JW_MEETING_SCHED_HOME.
Cifrado
display_name_ciphered se cifra con
jw_core.privacy.encryption.FieldEncryptor. Llave en orden:
--passphrase→ derivada vía PBKDF2-HMAC-SHA256 (200k iters) con salt"jw-meeting-scheduler/v1:<congregation_id>".JW_PRIVACY_KEY(urlsafe base64 32 bytes).- Sin llave → no-op + warning (cleartext en disco).
Re-import
Repetir el comando es seguro. CRDT por last_updated y INSERT OR IGNORE
por entry_id garantizan que no se duplica ni se machaca ediciones manuales.
F81.1 — Edición manual del roster
# Listar
uv run jw scheduler people list --congregation kingdom-hall-central
# Editar privilegios + asignaciones elegibles
uv run jw scheduler person edit juan-perez \
--congregation kingdom-hall-central \
--add-privilege ms \
--add-eligible MM_TGWTalk \
--add-eligible MM_BibleReading
# Quitar
uv run jw scheduler person edit juan-perez \
--congregation kingdom-hall-central \
--remove-privilege ms \
--remove-eligible 100 # MM_BibleReading por código numérico
# Cambiar status
uv run jw scheduler person edit juan-perez \
--congregation kingdom-hall-central \
--set-status irregular
# Historial de asignaciones (most recent first)
uv run jw scheduler history --person juan-perez --congregation kingdom-hall-central
Cada edición toca last_updated con datetime.now(UTC) para respetar
el CRDT: un re-import posterior de organized-app con last_updated
anterior no machaca la edición manual.
F81.2 — YAML de restricciones por congregación
# Crear template comentado en ~/.jw-agent-toolkit/congregations/<id>/constraints.yaml
uv run jw scheduler constraints init --congregation kingdom-hall-central
# Reemplazar el existente
uv run jw scheduler constraints init --congregation kingdom-hall-central --force
# Validar tras editar a mano
uv run jw scheduler constraints lint --congregation kingdom-hall-central
# Mostrar en tablas Rich (key fields + gap_minimum_days + weights)
uv run jw scheduler constraints show --congregation kingdom-hall-central
AssignmentConstraints (Pydantic strict):
congregation_id: regex^[a-z0-9_-]{3,64}$.gap_minimum_days: dict[AssignmentCode, int]— rotación mínima por código (default 60 days bible_reading, 90 speaker, 45 student parts). Hard floor en el solver F81.3.max_assignments_per_month: int ∈ [1, 10](default 3).pair_experienced_with_novice: bool(defaulttrue).require_brother_for_reading: bool(defaulttrue).allow_overlapping_assistant_in_aula: bool(defaultfalse).languages_active: list[str](≥1, default["en"]).aulas_active: list[str](subset demain_hall/aux_class_1/aux_class_2).weights: dict[str, float]— pesos del objective CP-SAT (no negativos).
Próximos pasos (F81.3+)
- Solver CP-SAT con
jw scheduler suggest --week ...(F81.3). - Agente
assignment_generatorcon@fidelity_wrap(F81.4). - REST endpoints
/api/v1/scheduler/{suggest,confirm}(F81.5). - Tauri UI con override slot por slot (F81.6).
Editar esta página en docs/guias/meeting-scheduler-import.md