erplibre/script/todo
Mathieu Benoit 37c63af7e2 [ADD] migration: brancher les deux réparations qui ne tournaient jamais
fix_duplicate_index et restore_config_defaults étaient écrits, éprouvés,
et absents du pilote. Chaque migration refabriquait donc ses index
redondants et reperdait sa liste de prix.

Mesuré sur DEUX chaînes 12 → 18 indépendantes, même base source : 68
relations orphelines, 9 langues au drapeau NULL, une liste de prix
absente, 376 paires d'index en double — les mêmes nombres des deux côtés.
Ce n'est pas un accident d'exécution, c'est le chemin lui-même.

Les index à partir du palier 17 : avant, la convention n'a pas changé.
Les réglages au DERNIER palier : l'outil charge le registre, et seul
l'état final compte. Les deux en wait_at_error=False — avec --apply, le
code 1 dit « il en reste », pas « je suis tombé », et cela n'arrête pas
six paliers.

--- EN ---

fix_duplicate_index and restore_config_defaults were written, proven, and
absent from the driver. Every migration therefore rebuilt its redundant
indexes and lost its default pricelist again.

Measured on TWO independent 12 → 18 chains from the same source: 68
orphan relations, 9 languages with a NULL flag, one missing pricelist,
376 duplicate index pairs — the same numbers on both. Not a fluke of one
run: the path itself.

Indexes from step 17 onward: before that the convention had not changed.
Config defaults at the LAST step: the tool loads the registry, and only
the final state matters. Both with wait_at_error=False — with --apply,
exit 1 means "some remain", not "I crashed", and that must not halt six
steps.

Assisted-by: Claude Opus 5
2026-08-25 03:28:39 -04:00
..
mail [ADD] mail: read and send email from the TODO CLI 2026-08-16 03:56:34 -04:00
auto_ask.py [ADD] migration: announce the countdown, and cycle three panel states 2026-08-22 07:23:59 -04:00
database_manager.py [ADD] analyse: inspect an Odoo database without restoring it 2026-08-10 03:10:50 -04:00
deploy_form_extras.py [REF] déploiement : un seul socle pour ce qui décrit le système invité 2026-08-25 03:28:39 -04:00
deploy_form_lib.py [FIX] proxmox : viser la bonne machine, et dire la vérité sur le disque 2026-08-25 03:28:39 -04:00
deploy_form_plan.py [REF] todo : un fichier par sujet, un socle par formulaire 2026-08-25 03:16:07 -04:00
kdbx_manager.py [FIX] security: the KeePass password leaves the command line too 2026-08-23 02:11:50 -04:00
logo_ascii.txt [IMP] bot assistant TODO 2025-04-27 02:40:20 -04:00
migration_form.py [ADD] migration: offer « go back to a step » on the resume screen 2026-08-22 07:23:59 -04:00
migration_stats.py [ADD] migration: see and repair the website COW views 2026-08-10 03:10:50 -04:00
migration_status.py [ADD] migration state: read the server log so nobody has to 2026-08-22 07:23:59 -04:00
migration_status_tui.py [FIX] migration state: open the quality screen in its own process 2026-08-22 07:23:59 -04:00
proxmox_deploy_form.py [REF] déploiement : un seul socle pour ce qui décrit le système invité 2026-08-25 03:28:39 -04:00
proxmox_menu.py [REF] déploiement : un seul socle pour ce qui décrit le système invité 2026-08-25 03:28:39 -04:00
qemu_access.py [REF] todo : un fichier par sujet, un socle par formulaire 2026-08-25 03:16:07 -04:00
qemu_deploy.py [REF] déploiement : un seul socle pour ce qui décrit le système invité 2026-08-25 03:28:39 -04:00
qemu_deploy_form.py [REF] déploiement : un seul socle pour ce qui décrit le système invité 2026-08-25 03:28:39 -04:00
qemu_hardware.py [ADD] qemu : régler le mode CPU, les écrans et le réseau d'une VM 2026-08-23 02:07:42 -04:00
qemu_install.py [REF] déploiement : un seul socle pour ce qui décrit le système invité 2026-08-25 03:28:39 -04:00
qemu_install_monitor.py [FIX] proxmox : six défauts trouvés par un audit, pas à l'usage 2026-08-25 03:28:39 -04:00
qemu_manage.py [FIX] qemu : un alias ssh et une adresse ne se jugent pas sur le nom 2026-08-25 03:19:18 -04:00
qemu_menu.py [FIX] todo : nettoyer ce que le découpage a laissé derrière 2026-08-25 03:17:13 -04:00
README.base.md [ADD] proxmox : un écran pour déployer sur un hôte distant 2026-08-25 03:17:13 -04:00
README.fr.md [ADD] proxmox : un écran pour déployer sur un hôte distant 2026-08-25 03:17:13 -04:00
README.md [ADD] proxmox : un écran pour déployer sur un hôte distant 2026-08-25 03:17:13 -04:00
source_todo.sh [ADD] install: mise as Python provider, pyenv as fallback 2026-08-16 23:33:49 -04:00
textual_setup.py [ADD] todo: install Textual on demand 2026-08-07 03:22:26 -04:00
todo.json [ADD] todo: QEMU/KVM menu 2026-08-07 03:22:26 -04:00
todo.py [ADD] analyse: l'état d'une instance, lu pour l'usage qu'on en fait 2026-08-25 03:28:39 -04:00
todo_example.json [UPD] TODO: simplify code by reusing method and support same command 2025-04-28 00:35:27 -04:00
todo_file_browser.py [FIX] todo: test menu, file browser and KeePass refusals 2026-08-16 03:56:34 -04:00
todo_i18n.py [ADD] migration: brancher les deux réparations qui ne tournaient jamais 2026-08-25 03:28:39 -04:00
todo_prefs.py [ADD] mail: read and send email from the TODO CLI 2026-08-16 03:56:34 -04:00
todo_telemetry.py [FIX] todo : rendre au découpage ses colonnes de télémétrie 2026-08-25 03:19:18 -04:00
todo_upgrade.py [ADD] migration: brancher les deux réparations qui ne tournaient jamais 2026-08-25 03:28:39 -04:00
version_manager.py [IMP] script: update copyright year to 2026 2026-03-11 23:16:05 -04:00

TODO is an assistant robot to use ERPLibre Execute it with ./script/todo/todo.py or make todo.

For a new project, copy todo_example.json to private/todo/todo_override.json | private/todo/todo_override_private.json and edit it.

The mail/ package is the mail client reachable from Assistant > Mail: several IMAP/SMTP accounts, a local cache, and a Textual TUI. See ../../doc/EMAIL.md.

Where the code lives

todo.py carries the menus and the general helpers. Everything around a single subject sits in its own file, and the whole thing is assembled by mixins on the TODO class — one file, one subject, its header states its boundary.

File What it owns
todo.py the menus, the configuration, the general helpers
qemu_menu.py the QEMU/KVM menu, the image catalogue, the statistics
qemu_deploy.py deciding then running a deployment
qemu_install.py the recipes run inside a VM
qemu_manage.py lifecycle, disks, hardware, cleanup, addresses
qemu_access.py SSH, tunnels, consoles, Android emulator
proxmox_menu.py the same, on a REMOTE Proxmox VE host

The two deployment forms — libvirt here, Proxmox over there — ask the same questions, so they share a foundation rather than each holding a copy:

File What it owns
deploy_form_lib.py pure logic (sizes, plan, totals, spec), the shared CSS, the resource-row factory, the progress view
deploy_form_plan.py the plan's gestures: overrides, locks, copies, renaming, free values
qemu_deploy_form.py what QEMU/KVM adds: desktops, tools, branches, install profiles
proxmox_deploy_form.py what Proxmox adds: host, storage, bridge, VMID, address

A form inherits PlanMixin and provides three hooks: which presets each resource offers, the name a VM would fall back to, and what a lock freezes. test_todo_deploy_form_lib.py fails if a form redefines a gesture the foundation already carries — that is what keeps the architecture from drifting back into two copies.