Public read-only JSON API for publicly visible stories - #2196
Open
maebeale wants to merge 11 commits into
Open
Conversation
Consumers (e.g. the marketing site) need to pull stories without a login. Expose only publicly-visible stories, each carrying its featured and publicly_featured flags, with an optional publicly_featured filter. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
maebeale
marked this pull request as ready for review
August 14, 2026 13:47
The endpoint should simply expose every publicly visible + published story with its featured/publicly_featured flags, not filter by them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give API consumers the full tag set, split by taxonomy: categories keyed by their category-type label, plus the flat sector list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Untagged stories dropped the key entirely (empty jbuilder block); assign the grouped hash directly so consumers can iterate tags.categories unconditionally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e_url Nest featured and publicly_featured under a "flags" object and remove the redundant published field (always true) and the external-link fields. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lead with title, author, organization, url, flags, tags, body; trailing identifiers/media/timestamps follow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Only publicly_featured is public-facing; drop featured from flags. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The slug/url already carry the id, and show resolves by it — no need for a top-level id field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The url already provides the canonical link; drop the redundant slug. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
It's another story tag, so group it with categories and sectors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both index and show now return only published + publicly_visible + publicly_featured stories, so the per-record publicly_featured flag is redundant and removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 suggested review level: 3 Read 📖 small contained new endpoint; main thing to verify is the public-visibility scoping
What
/api/v1/stories(index) and/api/v1/stories/:id(show).published AND publicly_visible AND publicly_featured).title,author,organization,url,tags(windows_type+categoriesgrouped by category-type label +sectors),body,image_url/thumbnail_url, timestamps.per_pagecapped (default 25, max 100), with paginationmeta.Why
Notes
Story.publicly_featuredand layersStoryPolicyviaauthorized_scope, so the public floor holds regardless of caller.author_credit, honoring each story's privacy preference (never raw PII).