Delivery: a cache class per route and content type, instead of one 60 second window for everything
- Dominant language
- C#
- Stars
- 6
- Forks
- 7
- Avg merge
- 4h 42m
- Merged PRs (30d)
- 307
Description
Every public delivery response gets the same `Cache-Control: public, max-age=60`, set in one place: `barakoCMS/Features/Public/Endpoints.cs:282`. The list, slug and search routes all call it. Only the redirect resolver declares an output cache policy (`barakoCMS/Features/Redirects/ResolveEndpoint.cs:53`). Files and semantic search hardcode their own values (`BarakoCMS.Files/Features/PublicDownload/Endpoint.cs:63`, `BarakoCMS.AI/Features/SemanticSearchEndpoint.cs:99`).
### Why it is too specific
One window fits a blog. A clinic's booking slots (#847) need a read that is fresh to the second, sitting next to a page that could be cached for a day. A school's about page does not change for a year and is still refetched every minute. Location readings (#848) and a barakoPress block that reads live entries (BaryoDev/barakoPress#33) have the same need. One constant cannot express any of that, so each consumer guesses.
### The general concept
The API declares a cache class per route, and per content type where an editor sets one: `long`, `short` or `no-store`, with `stale-while-revalidate` where it fits, written into `Cache-Control`. Every response also names what it was built from as tags (tenant, type, entry ids), which is what #561 asks for. A server output cache keyed by tenant, path and query is invalidated by the same tags. That cache is #562, which sits on 5.0.0 behind #557. It belongs with this change, because the class and the tags are what make it correct.
### Where it lives
Core: public delivery and the content type model. The CDN purge client stays a module, as #561 says. The barakoPress half, honouring the class and purging by tag, is filed on that repository.
### Compatibility
Released. Every route's default class is today's 60 seconds, so a deployment that sets nothing sends the same headers. A class on the content type is an optional field. No HTTP contract break.
### Done when
- A content type set to `no-store` answers its list and slug routes with `Cache-Control: no-store`, with a test that fails before the change.
- A type with no class set still answers `public, max-age=60`.
- Delivery responses carry tenant, type and entry tags (#561), and publishing one entry invalidates a cached list that holds it.
Found in the architecture sweep of 15 September 2026.
Contributor guide
Research direction
Start with barakoCMS/Features/Public/Endpoints.cs:282 and the content type model, then compare the existing policies in ResolveEndpoint.cs:53, BarakoCMS.Files/Features/PublicDownload/Endpoint.cs:63, and BarakoCMS.AI/Features/SemanticSearchEndpoint.cs:99. Done means content types can produce the specified cache headers, default behavior remains public max-age=60, responses carry the required tags, and the stated invalidation behavior is covered by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- api, backend, backend-api-design, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100