[{'Text': 'Edited /Users/peterdonaghey/Projects/point-topic-mcp/_explore_gbs.py:\n\n```diff\n@@ -1,0 +1,160 @@\n+"""Explore GBS MongoDB data shapes - temporary exploration script."""\n+import json\n+import os\n+import subprocess\n+import sys\n+\n+URI = os.environ["PT_RESEARCH_DATABASE_URI"]\n+\n+def run_js(js, timeout=30):\n+    uri = URI\n+    if os.environ.get("PT_RESEARCH_TLS_SKIP_VERIFY", "").strip() in ("1", "true", "yes"):\n+        sep = "&" if "?" in uri else "?"\n+        uri = f"{uri}{sep}tlsAllowInvalidCertificates=true"\n+    r = subprocess.run(\n+        ["mongosh", uri, "--eval", js, "--quiet"],\n+        capture_output=True, text=True, timeout=timeout,\n+    )\n+    if r.returncode != 0:\n+        raise RuntimeError(f"FAIL: {r.stderr or r.stdout}")\n+    return r.stdout.strip()\n+\n+# 1. GlobalVariables\n+print("=== GlobalVariables ===")\n+gv_raw = run_js("EJSON.stringify(db.GlobalVariables.findOne({isCurrent: true}))")\n+print(gv_raw[:2000])\n+gv = json.loads(gv_raw)\n+current_period = gv.get("currentStatsPeriod", "UNKNOWN")\n+print(f"\\nCurrent period: {current_period}")\n+\n+# 2. Operator counts\n+print("\\n=== Operator counts ===")\n+total_ops = run_js("db.Operator.countDocuments()")\n+print(f"Total operators: {total_ops}")\n+countries = json.loads(run_js("EJSON.stringify(db.Operator.distinct(\'country\'))"))\n+print(f"Countries ({len(countries)}): {countries[:10]}{\'...\' if len(countries) > 10 else \'\'}")\n+\n+# 3. UK operator count\n+uk_ops = run_js("db.Operator.countDocuments({country: \'United Kingdom\'})")\n+print(f"UK operators: {uk_ops}")\n+\n+# 4. Sample operator (UK)\n+print("\\n=== Sample UK operator ===")\n+sample_uk = json.loads(run_js("EJSON.stringify(db.Operator.findOne({country: \'United Kingdom\'}))"))\n+print(json.dumps({k: v for k, v in sample_uk.items() if k != \'_id\'}, indent=2)[:1000])\n+\n+# 5. Statistics - distinct values\n+print("\\n=== Statistics distinct values ===")\n+periods = json.loads(run_js("EJSON.stringify(db.Statistics.distinct(\'period\'))"))\n+print(f"Periods: {sorted(periods)}")\n+states = json.loads(run_js("EJSON.stringify(db.Statistics.distinct(\'state\'))"))\n+print(f"States: {states}")\n+channels = json.loads(run_js("EJSON.stringify(db.Statistics.distinct(\'channel\'))"))\n+print(f"Channels: {channels}")\n+domains = json.loads(run_js("EJSON.stringify(db.Statistics.distinct(\'domain\'))"))\n+print(f"Domains: {domains}")\n+types = json.loads(run_js("EJSON.stringify(db.Statistics.distinct(\'type\'))"))\n+print(f"Types: {types}")\n+\n+# 6. Sample statistic\n+print("\\n=== Sample statistic ===")\n+sample_stat = json.loads(run_js("EJSON.stringify(db.Statistics.findOne())"))\n+print(json.dumps({k: v for k, v in sample_stat.items() if k != \'_id\'}, indent=2)[:1500])\n+\n+# 7. Coverage stats for current period\n+print(f"\\n=== Coverage for {current_period} ===")\n+count_stats = run_js(f"db.Statistics.countDocuments({{period: \'{current_period}\'}})")\n+print(f"Total stats records: {count_stats}")\n+ops_with_data = json.loads(\n+    run_js(f"EJSON.stringify(db.Statistics.distinct(\'operatorId\', {{period: \'{current_period}\'}}))")\n+)\n+print(f"Unique operators with data: {len(ops_with_data)}")\n+\n+# 8. Previous period\n+all_periods = sorted(periods)\n+if len(all_periods) >= 2:\n+    prev = all_periods[-2]\n+    pcount = run_js(f"db.Statistics.countDocuments({{period: \'{prev}\'}})")\n+    pops = json.loads(\n+        run_js(f"EJSON.stringify(db.Statistics.distinct(\'operatorId\', {{period: \'{prev}\'}}))")\n+    )\n+    print(f"\\nPrevious period ({prev}): {pcount} records, {len(pops)} operators with data")\n+\n+# 9. State distribution for current period\n+print(f"\\n=== State distribution for {current_period} ===")\n+state_counts = run_js(f"""\n+  EJSON.stringify(\n+    db.Statistics.aggregate([\n+      {{$match: {{period: \'{current_period}\'}}}},\n+      {{$group: {{_id: \'$state\', count: {{$sum: 1}}}}}}\n+    ]).toArray()\n+  )\n+""")\n+print(state_counts)\n+\n+# 10. Tech distribution\n+print("\\n=== Tech distribution ===")\n+techs = json.loads(run_js("EJSON.stringify(db.Statistics.distinct(\'tech\'))"))\n+print(f"Techs: {techs}")\n+\n+# 11. Test batched query: get all stats for all UK operators in current period\n+print(f"\\n=== BATCHED: All stats for {current_period} ===")\n+# First get all UK operator IDs\n+uk_ops_raw = json.loads(\n+    run_js("EJSON.stringify(db.Operator.find({country: \'United Kingdom\'}, {_id: 1}).toArray())")\n+)\n+uk_ids = [op[\'_id\'][\'$oid\'] for op in uk_ops_raw]\n+print(f"Total UK operators: {len(uk_ids)}")\n+\n+# Batched query: all stats for these operators in current period\n+oid_list = json.dumps([f"ObjectId(\'{oid}\')" for oid in uk_ids])\n+batched_js = f"""\n+  const ids = [{\',\'.join(f"ObjectId(\'{oid}\')" for oid in uk_ids)}];\n+  EJSON.stringify(\n+    db.Statistics.find({{\n+      operatorId: {{$in: ids}},\n+      period: \'{current_period}\'\n+    }}).toArray()\n+  )\n+"""\n+batched_raw = run_js(batched_js, timeout=60)\n+batched_stats = json.loads(batched_raw) if batched_raw else []\n+print(f"Batched stats returned: {len(batched_stats)} records")\n+if batched_stats:\n+    print(f"Sample: {json.dumps(batched_stats[0], indent=2)[:500]}")\n+\n+# 12. Operator coverage summary (has_data / no_data)\n+print(f"\\n=== Operator coverage summary for {current_period} ===")\n+# Which UK operators have data?\n+ops_with_data_set = set(s.get(\'operatorId\', {}).get(\'$oid\', \'\') for s in batched_stats)\n+coverage = []\n+for op in uk_ops_raw:\n+    oid = op[\'_id\'][\'$oid\']\n+    has_data = oid in ops_with_data_set\n+    coverage.append((oid, has_data))\n+\n+with_data = sum(1 for _, h in coverage if h)\n+without_data = sum(1 for _, h in coverage if not h)\n+print(f"With data: {with_data}, Without data: {without_data}")\n+\n+# 13. Per-operator record count for current period\n+print(f"\\n=== Per-operator record counts (top 20) ===")\n+from collections import Counter\n+op_stat_counts = Counter()\n+for s in batched_stats:\n+    oid = s.get(\'operatorId\', {}).get(\'$oid\', \'\')\n+    op_stat_counts[oid] += 1\n+\n+# Get operator names\n+name_map = {}\n+for op in uk_ops_raw:\n+    oid = op[\'_id\'][\'$oid\']\n+    op_data = json.loads(\n+        run_js(f"EJSON.stringify(db.Operator.findOne({{_id: ObjectId(\'{oid}\')}}, {{name: 1}}))")\n+    )\n+    name_map[oid] = op_data.get(\'name\', \'UNKNOWN\')\n+\n+for oid, count in op_stat_counts.most_common(20):\n+    print(f"  {name_map.get(oid, oid)[:30]:30s} {count} records")\n+\n+print("\\n=== DONE ===")\n\n```'}]