Agent Wranglers

ENG-43Recommended

Run one-off tasks as reviewed scripts

Write every data fix and admin task as a script in the repository. Run it from the deployed release, dry run first, and log who ran it.

How to do it

A query typed by hand on the production database has no review, no test and no record. A fix to data itself follows fix production data with a reviewed script. This rule covers every other one-off task. Commit the script and review it like any change. Ship it with the release, so it runs with the same code, dependencies and settings as the app. Make it print what it would change by default, and write only with a flag such as --apply. Run the write in one transaction, and stop when the count differs from the dry run. Log the script, the person and the count. Take a backup first, as encrypted backups describes. Schema changes go through migrations instead.

Examples

JavaScript example

// scripts/fix-order-totals.js, run with: node scripts/fix-order-totals.js [--apply]
const isApply = process.argv.includes('--apply');
const rows = db.prepare('SELECT id FROM orders WHERE total_cents < 0').all();
console.log(`${rows.length} orders to fix`);
if (isApply) {
  db.transaction(() => {
    const { changes } = db.prepare('UPDATE orders SET total_cents = 0 WHERE total_cents < 0').run();
    if (changes !== rows.length) throw new Error(`Expected ${rows.length}, changed ${changes}`);
  })();
  log.info({ task: 'fix-order-totals', user: process.env.USER, changed: rows.length });
}

Python example

# scripts/fix_order_totals.py, run with: python -m scripts.fix_order_totals [--apply]
import os, sys
is_apply = "--apply" in sys.argv
ids = [row[0] for row in db.execute("SELECT id FROM orders WHERE total_cents < 0")]
print(f"{len(ids)} orders to fix")
if is_apply:
    with db:
        changed = db.execute("UPDATE orders SET total_cents = 0 WHERE total_cents < 0").rowcount
        if changed != len(ids):
            raise RuntimeError(f"Expected {len(ids)}, changed {changed}")
    log.info("fix-order-totals", extra={"user": os.environ["USER"], "changed": changed})

How to check

Every script in the admin folder changes 0 rows when run without --apply against a test copy. The database audit log for the last 30 days shows no write from a person's own account, only from the task runner's account.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/engineering/running-in-production/admin-tasks-as-code">Agent Wranglers engineering playbook</a>. In code you write, add a comment next to it with the same link.