# Template cleanup — turn a production clone into a clean golden VM

Scripts to reset a **clone of VM 105 (logship-production)** into a clean,
data-free template VM. Built 2026-07 for VM 113 `logship-template-2`
(192.168.12.66). Full runbook: see the plan/session notes; short version:

## Order of operations

1. **Clone from PBS backup** (prod untouched), on prox2:
   ```bash
   qmrestore pbs-logyou:backup/vm/105/<latest> 113 --storage Disk1-NVMe --unique 1
   qm set 113 --name logship-template-2 --onboot 0 --protection 0 \
     --ipconfig0 ip=192.168.12.66/24,gw=192.168.12.1
   # read MAC from `qm config 113`, then boot quarantined:
   qm set 113 --net0 virtio=<MAC>,bridge=vmbr1,link_down=1
   qm start 113
   ```
2. **`00-defuse.sh`** — via `qm guest exec` while NIC is down: wipes root
   crontab (DHL crawler! customer reports!), disables postfix, clears
   web-push/chat DBs, removes prod ES bind + data.logship.de hosts entry.
3. **`03-neutralize-env.sh`** — blanks external endpoints/credentials in
   `/opt/erp-nuxt-frontend/.env` (LARAVEL, Sentry, carrier/marketplace
   creds), repoints STRAPIPUBLIC/WEBAUTHN_ORIGIN at the clone IP.
4. Bring NIC up (`qm set 113 --net0 virtio=<MAC>,bridge=vmbr1`), then
   everything else over SSH.
5. **`run-cleanup.sh`** — safety pg_dumps, stops services, runs
   `01-idempiere-truncate.sql` + `02-strapi-truncate.sql`, wipes uploads,
   deletes ES indices, restarts everything, log hygiene.
6. **Review together** the survivor report + row counts before finalizing.
7. Finalize: `rm -rf /root/template-cleanup/backup/`, remove
   `/root/env.production.bak`, clear shell history, `fstrim -a`,
   right-size RAM (`qm set 113 --memory 20480`), shutdown.

## What the iDempiere truncation keeps / deletes

- **Kept:** client 1000000 config (roles, doc types, price list headers,
  taxes, warehouses/locators of org 1000000, `cust_commissiontable`,
  `cust_printer`, `cust_labeltemplate`, `cust_nonworkingdays`,
  `cust_shippingcost_default`), staff users, GardenWorld demo client.
- **Deleted:** all transactional documents of client 1000000 (orders,
  invoices, shipments, payments, fact_acct, stock, requests, …), all
  global log tables, ALL products + business partners of client 1000000
  except rows FK-referenced by kept config, and orgs 1000001+ from every
  table with an `ad_org_id` column.
- Engine: pass-based delete list with FK-retry; rows whose DELETE hits a
  foreign-key violation after convergence are reported as survivors —
  that's the "required by config" set, by construction.

All scripts carry a **production guard** (hostname/IP check) and are
idempotent — safe to re-run after fixing an issue.

Kept in `reference/` (tracked, not built/watched) per repo convention.
