import datetime def _now() -> str: return datetime.datetime.now(datetime.timezone.utc).isoformat() def approve(store, cluster_id, name=None) -> None: c = store.get_cluster(cluster_id) decided = (name or "").strip() or c.suggested_name store.update_cluster(cluster_id, status="approved", decided_name=decided, reviewed_at=_now()) def mark_non_trip(store, cluster_id) -> None: store.update_cluster(cluster_id, status="non_trip", reviewed_at=_now()) def skip(store, cluster_id) -> None: store.update_cluster(cluster_id, status="skipped", reviewed_at=_now()) def split(store, cluster_id, boundary_immich_id): return store.split_cluster(cluster_id, boundary_immich_id) def merge(store, cluster_id_a, cluster_id_b): return store.merge_clusters(cluster_id_a, cluster_id_b) def set_member(store, cluster_id, immich_id, included: bool) -> None: store.set_member_inclusion(cluster_id, immich_id, included) def approve_high_confidence(store, threshold: float = 0.75) -> int: count = 0 for c in store.all_clusters(): if c.status == "pending" and c.kind_guess == "trip" and c.confidence >= threshold: approve(store, c.id) count += 1 return count