Problem
handleServeImage in apps/api/src/media/serve.ts sets Cache-Control: private, max-age=300 for every response, regardless of the row's visibility. Two consequences:
- Public images cannot be CDN-cached. Every fetch hits the API → S3 chain even when the image is open to the world.
- Visibility transitions leave stale state in browser caches. If an image flips from public to private (or to deleted), browsers can still serve the cached bytes for up to 5 minutes; if it flips from private to public, public viewers get cached 404s for up to 5 minutes.
Suggested fix
Have findViewableImage also return visibility, then branch in handleServeImage:
public → Cache-Control: public, max-age=<N>
unlisted → Cache-Control: private, max-age=<N> (link-keepers shouldn't be cached by shared intermediaries)
private / shared → Cache-Control: private, max-age=<N>
Open question: pick N. The current 5 minutes is fine for private; public might want longer (an hour?) but it interacts with how aggressive we want the "go private" propagation to be.
Problem
handleServeImageinapps/api/src/media/serve.tssetsCache-Control: private, max-age=300for every response, regardless of the row'svisibility. Two consequences:Suggested fix
Have
findViewableImagealso returnvisibility, then branch inhandleServeImage:public→Cache-Control: public, max-age=<N>unlisted→Cache-Control: private, max-age=<N>(link-keepers shouldn't be cached by shared intermediaries)private/shared→Cache-Control: private, max-age=<N>Open question: pick
N. The current 5 minutes is fine for private; public might want longer (an hour?) but it interacts with how aggressive we want the "go private" propagation to be.