from pathlib import Path ROOT = Path(__file__).resolve().parents[1] HEADER = ROOT / "Source" / "AgrarianGame" / "AgrarianWeatherProviderSubsystem.h" CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianWeatherProviderSubsystem.cpp" TDD = ROOT / "Docs" / "TechnicalDesignDocument.md" ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md" EXPECTED = { HEADER: [ "FAgrarianCachedWeatherSnapshot", "WeatherSnapshotCacheTtlSeconds", "ServerWeatherSnapshotCache", "TryApplyCachedSnapshot", "HasFreshCachedSnapshot", "ClearWeatherSnapshotCache", ], CPP: [ "TryApplyCachedSnapshot(TileId, TEXT(\"open-meteo\"), GameState)", "TryApplyCachedSnapshot(TileId, TEXT(\"noaa-nws\"), GameState)", "void UAgrarianWeatherProviderSubsystem::CacheSnapshot", "FString UAgrarianWeatherProviderSubsystem::MakeCacheKey", "CacheSnapshot(Snapshot, WeatherSnapshotCacheTtlSeconds);", "return ApplySnapshotToGameState(CachedSnapshot->Snapshot, GameState);", ], TDD: [ "Real-weather snapshots are cached server-side", "Clients never call Open-Meteo or NOAA/NWS directly", "ServerWeatherSnapshotCache", ], ROADMAP: [ "[x] Cache real-weather snapshots server-side so clients never call public weather APIs directly.", ], } def main() -> None: missing = [] for path, snippets in EXPECTED.items(): text = path.read_text(encoding="utf-8") for snippet in snippets: if snippet not in text: missing.append(f"{path.relative_to(ROOT)}: {snippet}") if missing: raise RuntimeError("Weather snapshot cache verification failed: " + "; ".join(missing)) print("Agrarian weather snapshot cache verification complete.") if __name__ == "__main__": main()