iamnbutler/shelfgoblinPublic

Shelf Goblin — discover LitRPG audiobooks, follow series, and track your library.

Move the age gate to a real settings page #3

Mergediamnbutlermerged 1 commit intomainfromrefs/pull/3/head
  1. IA

    Follow-up to #2. The age gate shipped inside the content-filter popover, which was wrong twice over.

    ## It was in the wrong place

    A date of birth sat next to "hide harem", behind a button labelled **Filters**, and disappeared entirely on the My library tab. Content filters are per-browse controls; an attested date of birth is account state that syncs to D1. They do not belong together.

    Settings is now its own view (`?view=settings`), reached from the account controls in the header rather than the browse nav — it is not a browsing destination. Sections: **Account**, **Your library**, **Date of birth**. It renders ahead of the catalog loading/error gates, since none of it depends on the catalog.

    ## It advertised what it was for

    This is the substantive fix. The purpose of the gate is that **a reader who has not set a date of birth should never learn from the app that adult content exists in it** — not from the browse surfaces, and not from a "confirm your age to unlock…" prompt either. The previous copy did exactly that, with an "Adult content" heading and an explanation of what confirming would reveal.

    Now:

    - The **Date of birth** section says only what the date is used for. It does not mention adult content, 18+, or what confirming would change. - The **Adult content** section renders only when `verifiedAdult`. A reader with no date, or a date under 18, sees no trace of it — not a disabled control, not an explanation of what they are missing. - The under-18 branch was removed rather than reworded. Telling a minor "18+ titles stay hidden until you are old enough" is still telling them the feature exists. - Confirm and remove toasts were reworded for the same reason; they previously read "…you can now turn on 18+ content" and "…adult content is hidden again".

    A scan of `+page.svelte` confirms no adult wording outside the `verifiedAdult` block reaches user-visible text — the remaining matches are identifiers and code comments, plus the opt-in toast, which is only reachable from the checkbox inside that block. Two tests were added asserting the data layer reports a locked gate identically for "no claim" and "minor", so the two states are indistinguishable from outside.

    ## Also

    Importing a backup is disabled until the catalog has loaded. An import matched against an empty catalog skips work-id re-homing (`rehomeOrphans` returns early on an empty catalog), which would strand reading progress under ids the current catalog no longer mints.

    ## Verification

    Isolated worktree of this commit, so unrelated uncommitted work in the dev tree could not influence the result:

    - `npm test` — 53 files / 1274 tests passing - `npm run check` — 354 files, 0 errors, 0 warnings - `npm run build` — succeeds

    The dev tree currently shows 2 failures in `scripts/backend/quality/pipeline.test.ts`. That is another session's in-progress quality lane, still untracked and **not** in this PR, along with `scripts/backend/migrations/013_*.sql`, `014_*.sql`, `docs/quality-benchmarks.md`, `scripts/backend/catalog/reader-evidence.ts` and the `pipeline:quality` line in `package.json`.

  2. iamnbutlermerged 24556aa576c0last month on GitHub

  3. iamnbutlerclosedlast month on GitHub

  4. iamnbutlerhead-ref-deletedlast month on GitHub