Social guides
Guides

Post search.

Same Postgres FTS shape as user search, this time over post.title (weight A) + post.body (B). Pick relevance ranking or recency ordering with one query param. Drafts, removed, hidden, and expired posts are stripped at the SQL layer.


1

Search by relevance

Default mode. Returns up to limit hits ordered by ts_rank. Title matches are weighted higher than body matches.

bash
curl -H "Authorization: Bearer pcft_live_..." \
  "https://social.productcraft.co/v1/communities/<communityId>/search/posts?q=phase+8&limit=10"

2

Or by recency

Same FTS filter, but ordered by created_at desc among matching rows. Useful when the user is asking “what's the newest mention of X” rather than “the best mention”.

bash
curl -H "Authorization: Bearer pcft_live_..." \
  "https://social.productcraft.co/v1/communities/<communityId>/search/posts?q=phase+8&order=recent"

3

Filter to the requester's view

Without requester_id, only posts with visibility="public" surface — the anonymous-equivalent default. Pass an actor uuid to apply the same block / mute filter that feeds use:

  • Posts authored by anyone the requester has muted / blocked drop out.
  • Posts authored by anyone who has blocked the requester drop out.
  • Visibility filter caveat: the search query stays broad to keep the index effective. A post with visibility="followers" may surface here even when the requester isn't a follower — fetching it via GET /posts/:id?requester_id=... will then return 404. Treat search hits as candidates, not guarantees.

4

Response shape

json
{
  "data": [
    {
      "post": {
        "id": "...",
        "title": "Shipping Phase 8",
        "body": "stories live today",
        "kind": "text",
        "visibility": "public",
        "status": "published",
        "...": "..."
      },
      "rank": 0.6079
    }
  ]
}

Out of scope

Follow-ups

  • Trigram fuzzy matching. Same trade- off as user search; deferred.
  • Cursor pagination. Search returns up to limit in a single call — narrow the query rather than paginate.
  • Cross-community search. Per-community only.

Permissions

PAK scopes

  • GET requires social.list on pcft:agora:community/<communityId>.