API: edge-cacheable headers for global startup endpoints ("Gathering" speedup)

"Gathering the good news…" waits on the home's startup API calls, which were all
DYNAMIC → a round-trip to the residential origin every load (the occasional 2-3s
linger). These responses depend only on the URL, never the session, so they're
safe to share at the edge:
- /api/moods, /api/categories (static config) → public, s-maxage=900
- /api/lanes, /api/families (global, data-derived counts) → public, s-maxage=120
- /api/feed → public, s-maxage=45 ONLY when shareable (no following / prefs /
  exclude); the following feed (reads the session) and personal filters stay
  private, no-store.

Hard personalization boundary, explicit per-endpoint (no blanket /api/* rule).
Pairs with a Cloudflare cache rule (added separately) making these paths
eligible. Tests assert the global endpoints are public+s-maxage and the feed
boundary (default/topic public; following/prefs/exclude private). 227 pytest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-12 04:34:11 -04:00
parent 8435041b14
commit a34a47fe22
2 changed files with 46 additions and 4 deletions
+20
View File
@@ -87,3 +87,23 @@ def test_families_endpoint(client):
names = [f["name"] for f in fams]
assert "Discovery & Wonder" in names
assert all("tags" in f and isinstance(f["tags"], list) for f in fams)
def test_global_endpoints_are_edge_cacheable(client):
# The startup endpoints are identical for every visitor → publicly cacheable
# so "Gathering the good news…" resolves from the edge, not the origin.
for path in ("/api/moods", "/api/categories", "/api/lanes", "/api/families"):
cc = client.get(path).headers.get("cache-control", "")
assert "public" in cc and "s-maxage" in cc, f"{path}: {cc!r}"
def test_feed_cache_boundary(client):
# Shareable (URL-determined) feeds are public; personalized ones are private.
public_cc = client.get("/api/feed").headers.get("cache-control", "")
assert "public" in public_cc and "s-maxage" in public_cc
# topic/tag browse is still shareable (same for everyone)
assert "public" in client.get("/api/feed", params={"topic": "science"}).headers.get("cache-control", "")
# personal filters + the following feed must never be shared across users
assert client.get("/api/feed", params={"following": "true"}).headers.get("cache-control") == "private, no-store"
assert client.get("/api/feed", params={"prefs": json.dumps({"mute_topics": ["science"]})}).headers.get("cache-control") == "private, no-store"
assert client.get("/api/feed", params={"exclude": "1,2"}).headers.get("cache-control") == "private, no-store"