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)
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.
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.
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.
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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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)
BookAccess.IsInLibrarynested a child'sApprovedBookIdsallow-list inside aPublic && Availableconjunction, and parent uploads are permanentlyVisibility="Private"(no code path ever makes them Public). So the parental allow-list could only narrow the public catalog — never grant a private upload.Bookafter staff approve it, so a parent couldn't even see their own upload to share it.Fix (spikersoft-backend + spikersoft-angular, PRs linked below)
Availablebook 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.PUT/DELETE /api/profile/parental/children/{childUserId}/approved-books/{bookId}) mutates onlyApprovedBookIds, 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)
Verification
SpikerSoft.UnitTests.slnfgreen (incl. new BookAccess household matrix, self-approve, grant auth/grantability, permissions no-clobber).test/lint/typecheckgreen (parent-dashboard grant tests added).Verified complete: feature landed in BOTH repos — backend PR #432 + angular PR #454 ('parents can share/grant their uploaded books with their children'). Closing.