Skip to content

Define and enforce a privacy-conscious profile indexability policy for sitemap.ts #19

Description

@chonilius

Problem

src/app/robots.ts and src/app/sitemap.ts exist, implying the app is meant to be publicly indexable — makes sense for /reputation/[handle] (public contributor profiles) and /issues (public bounty board) to drive discovery/SEO for a marketplace product. But /reputation/[handle] renders real usernames, avatar URLs, GitHub organizations, and lifetime earnings figures pulled via fetchReputationByUsername. If sitemap.ts enumerates every known handle (likely, to be useful for SEO) by calling the backend for a full user list, this creates a public, crawlable, permanently-indexed-by-search-engines directory of exactly who's earning what on the platform tied to their real GitHub identity — a privacy/doxxing-adjacent concern for contributors who may not have anticipated their MergeFi earnings being one Google search away from their real name, and a strategic problem if sitemap.ts calls the live backend at build/request time with no pagination or rate limiting, since a large user base could make sitemap generation slow or produce a sitemap exceeding the 50,000-URL/50MB per-file limit search engines enforce.

Why this is hard

  • Requires reading sitemap.ts to determine its actual current data source (mock data only? live backend list?) and how it paginates (or doesn't) — undocumented currently.
  • This is as much a product/privacy policy decision as an engineering one: should earnings be public at all, should indexability be opt-in per contributor, should the sitemap only include handles who've explicitly enabled a "public profile" flag (does AuthUser/backend even support such a flag today — check the backend or flag as a needed cross-repo addition)? You need to make and justify a reasonable default given no explicit product spec exists, then implement it.
  • If opting toward "indexable by default," at minimum the lifetime-earnings figure and any other sensitive-feeling fields need a considered decision on whether they belong in SEO-crawlable server-rendered HTML at all, versus client-fetched-and-gated — this affects src/app/reputation/[handle]/page.tsx's rendering strategy, not just the sitemap.
  • Sitemap generation for a potentially large user base needs to respect the sitemap size/count limits with a sitemap index file if the user count could exceed single-file limits, and must not hammer the backend on every crawler request — needs appropriate caching/revalidation given Next.js 16's route handler caching model for sitemap.ts.

Scope

  • Determine and document a privacy-conscious default for profile indexability (with a plan for an explicit opt-out or opt-in flag, coordinating the needed backend field if it doesn't exist).
  • Update sitemap.ts to respect that policy, paginate/chunk correctly for scale, and cache appropriately rather than hitting the backend on every crawl.
  • Review robots.ts to ensure it doesn't inadvertently block or allow indexing inconsistently with the sitemap policy.
  • Add a noindex fallback path for any profile page that shouldn't be crawlable per the policy, enforced via response headers/metadata, not just omission from the sitemap (omission alone doesn't prevent direct-URL indexing).

Acceptance criteria

  • The chosen indexability policy is documented and implemented consistently across sitemap.ts, robots.ts, and per-page metadata.
  • Sitemap generation is proven to scale (tested against a large mock user list) without exceeding size limits or excessive backend load.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26help wantedExtra attention is neededsecuritySecurity-related issuevery hardVery difficult task, expert-level effort required

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions