network/scripts/complete_pre_2026_work_orders.py
2026-07-19 14:42:02 -05:00

87 lines
2.7 KiB
Python

"""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()