Reading journey: let parents share their uploaded books with their children #729

Closed
opened 2026-07-20 02:58:03 +00:00 by spikerj · 1 comment
Owner

Problem

In the reading journey a parent can upload a book, but there is no way to make that uploaded book available to their children — the uploaded book never appears in the per-child "approved books" grant list, and even if its id were added, the child still couldn't read it.

Root cause (two structural layers + a latent bug)

  1. Read gate. BookAccess.IsInLibrary nested a child's ApprovedBookIds allow-list inside a Public && Available conjunction, and parent uploads are permanently Visibility="Private" (no code path ever makes them Public). So the parental allow-list could only narrow the public catalog — never grant a private upload.
  2. Upload moderation. An uploaded book only becomes a real, grantable Book after staff approve it, so a parent couldn't even see their own upload to share it.
  3. Latent data-loss bug (found while tracing): the child-permissions DTO/handler/read-mapper round-tripped only 8 of 13 permission fields, so every per-child save silently reset Photography / PhotoLocationSharing / InfoVault / Blog.

Fix (spikersoft-backend + spikersoft-angular, PRs linked below)

  • Household read branch: a child may read an Available book their linked parent uploaded once the parent grants it (parent ownership and explicit per-child grant both required; a third party's private book is never reachable). Verified by a BookAccess test matrix.
  • Self-approve family uploads: a reading-journey (personal/family) upload skips staff moderation and processes immediately. The automated security scan still runs; nothing becomes Public. Scope was kept narrow — only the reading-journey dialog opts in; the book-shelf dialog stays staff-moderated.
  • Grant picker now lists the public catalog plus the parent's own uploads (processed only), labelled "Your upload".
  • Narrow grant endpoint (PUT/DELETE /api/profile/parental/children/{childUserId}/approved-books/{bookId}) mutates only ApprovedBookIds, validates the parent may grant the book, and preserves sibling permissions — also fixing the pre-existing clobber for the full-permissions endpoint.

Decisions (confirmed with the requester)

  • Bypass staff moderation for family/personal uploads.
  • Fix the permissions-clobber bug as part of this work.

Verification

  • Backend: full SpikerSoft.UnitTests.slnf green (incl. new BookAccess household matrix, self-approve, grant auth/grantability, permissions no-clobber).
  • Frontend: affected test/lint/typecheck green (parent-dashboard grant tests added).
  • Remaining: manual parent→child E2E with seeded accounts (upload → processes without staff → grant → child reads → revoke → 404) before release.
## Problem In the reading journey a parent can upload a book, but there is no way to make that uploaded book available to their children — the uploaded book never appears in the per-child "approved books" grant list, and even if its id were added, the child still couldn't read it. ## Root cause (two structural layers + a latent bug) 1. **Read gate.** `BookAccess.IsInLibrary` nested a child's `ApprovedBookIds` allow-list *inside* a `Public && Available` conjunction, and parent uploads are permanently `Visibility="Private"` (no code path ever makes them Public). So the parental allow-list could only *narrow the public catalog* — never grant a private upload. 2. **Upload moderation.** An uploaded book only becomes a real, grantable `Book` after **staff** approve it, so a parent couldn't even see their own upload to share it. 3. **Latent data-loss bug** (found while tracing): the child-permissions DTO/handler/read-mapper round-tripped only 8 of 13 permission fields, so every per-child save silently reset Photography / PhotoLocationSharing / InfoVault / Blog. ## Fix (spikersoft-backend + spikersoft-angular, PRs linked below) - **Household read branch**: a child may read an `Available` book their **linked parent** uploaded once the parent grants it (parent ownership **and** explicit per-child grant both required; a third party's private book is never reachable). Verified by a BookAccess test matrix. - **Self-approve family uploads**: a reading-journey (personal/family) upload skips **staff** moderation and processes immediately. The automated **security scan** still runs; nothing becomes Public. Scope was kept narrow — only the reading-journey dialog opts in; the book-shelf dialog stays staff-moderated. - **Grant picker** now lists the public catalog **plus the parent's own uploads** (processed only), labelled "Your upload". - **Narrow grant endpoint** (`PUT/DELETE /api/profile/parental/children/{childUserId}/approved-books/{bookId}`) mutates only `ApprovedBookIds`, validates the parent may grant the book, and **preserves sibling permissions** — also fixing the pre-existing clobber for the full-permissions endpoint. ## Decisions (confirmed with the requester) - Bypass staff moderation for family/personal uploads. - Fix the permissions-clobber bug as part of this work. ## Verification - Backend: full `SpikerSoft.UnitTests.slnf` green (incl. new BookAccess household matrix, self-approve, grant auth/grantability, permissions no-clobber). - Frontend: affected `test`/`lint`/`typecheck` green (parent-dashboard grant tests added). - Remaining: manual parent→child E2E with seeded accounts (upload → processes without staff → grant → child reads → revoke → 404) before release.
Author
Owner

Verified complete: feature landed in BOTH repos — backend PR #432 + angular PR #454 ('parents can share/grant their uploaded books with their children'). Closing.

Verified complete: feature landed in BOTH repos — backend PR #432 + angular PR #454 ('parents can share/grant their uploaded books with their children'). Closing.
Sign in to join this conversation.