"""Mark every non-completed work order created before 2026-01-01 UTC as COMPLETED. Usage: GAIIA_KEY=... uv run --project /Users/graham/dev/network/gaiia \ python /Users/graham/dev/network/scripts/complete_pre_2026_work_orders.py """ from __future__ import annotations from datetime import datetime, timezone from gaiia import GaiiaClient from gaiia.errors import GaiiaMutationError CUTOFF = datetime(2026, 1, 1, tzinfo=timezone.utc) LIST_Q = """ query Q($after: String) { workOrders( first: 100 after: $after filter: { status: { notIn: [COMPLETED] } } ) { nodes { id readableId status createdAt workType { name } } pageInfo { hasNextPage endCursor } } } """ UPDATE_M = """ mutation U($i: UpdateWorkOrderInput!) { updateWorkOrder(input: $i) { workOrder { id status } errors { code message } } } """ def parse_dt(s: str) -> datetime: # Gaiia returns ISO 8601 UTC, e.g. "2025-08-12T14:33:01.123Z" return datetime.fromisoformat(s.replace("Z", "+00:00")) def main() -> None: with GaiiaClient(timezone="America/Chicago") as g: targets: list[dict] = [] skipped_repo = 0 for wo in g.iter_nodes(LIST_Q, "workOrders"): if parse_dt(wo["createdAt"]) >= CUTOFF: continue wt = (wo.get("workType") or {}).get("name") or "" if "repo" in wt.lower(): skipped_repo += 1 print(f" SKIP repo #{wo['readableId']:<8} workType={wt!r} ({wo['createdAt']})") continue targets.append(wo) print(f"Found {len(targets)} non-completed work orders created before {CUTOFF.date()} " f"(skipped {skipped_repo} repo-typed).") ok = 0 failed: list[tuple[dict, str]] = [] for wo in targets: try: res = g.mutate( UPDATE_M, "updateWorkOrder", {"i": {"id": wo["id"], "status": "COMPLETED"}}, ) new_status = res["workOrder"]["status"] ok += 1 print(f" #{wo['readableId']:<8} {wo['status']:<12} -> {new_status} ({wo['createdAt']})") except GaiiaMutationError as e: failed.append((wo, str(e))) print(f" #{wo['readableId']:<8} FAILED: {e}") except Exception as e: # noqa: BLE001 failed.append((wo, repr(e))) print(f" #{wo['readableId']:<8} ERROR: {e!r}") print(f"\nDone. {ok}/{len(targets)} updated. {len(failed)} failed.") if failed: for wo, err in failed: print(f" #{wo['readableId']} {wo['id']} {err}") if __name__ == "__main__": main()