# topology_api/routes/snapshot.py from datetime import datetime from flask import Blueprint, request, jsonify from topology_api.queries.snapshot_queries import ( resolve_snapshot_time, fetch_snapshot, fetch_layout, fetch_missions, ) snapshot_bp = Blueprint("snapshot", __name__) def _parse_iso_timestamp(value): if value is None: return None try: parsed = datetime.fromisoformat(value.replace("Z", "+00:00")) except ValueError: return None if parsed.tzinfo is None: return None return parsed.isoformat() @snapshot_bp.route("/api/v1/bases//missions") def get_missions(base_code): if base_code != "guanghan": return jsonify({ "error": "base_not_found", "message": f"Base '{base_code}' not found.", }), 404 return jsonify({"missions": fetch_missions(base_code)}) @snapshot_bp.route("/api/v1/bases//snapshot") def get_snapshot(base_code): if base_code != "guanghan": return jsonify({ "error": "base_not_found", "message": f"Base '{base_code}' not found. Only 'guanghan' is available.", }), 404 requested_mission = request.args.get("mission") requested_at = request.args.get("at") normalized_at = _parse_iso_timestamp(requested_at) if requested_at is not None and normalized_at is None: return jsonify({ "error": "invalid_time", "message": ( "Parameter 'at' must be an ISO 8601 timestamp with a timezone." ), }), 400 snapshot_at, anchor_source = resolve_snapshot_time( requested_mission=requested_mission, requested_at=normalized_at, ) if anchor_source == "mission_not_found": return jsonify({ "error": "mission_not_found", "message": f"Mission '{requested_mission}' not found.", }), 404 if anchor_source == "mission_has_no_timed_event": return jsonify({ "error": "mission_has_no_timed_event", "message": f"Mission '{requested_mission}' has no timed events.", }), 409 if anchor_source == "no_events": return jsonify({ "base": {"code": "guanghan", "name": "广寒基地"}, "query": { "requestedAt": requested_at, "requestedMission": requested_mission, "snapshotAt": None, "anchorSource": "no_events", }, "components": [], "connections": [], }) data = fetch_snapshot(snapshot_at) layout = fetch_layout() return jsonify({ "base": data["base"], "query": { "requestedAt": requested_at, "requestedMission": requested_mission, "snapshotAt": snapshot_at, "anchorSource": anchor_source, }, "components": data["components"], "connections": data["connections"], "layout": layout, })