Child's own profile drops 5 granted permissions — ProfileMapper.ToDto maps only 8 of 13 FeaturePermissions fields (child sees "Blog posting isn't turned on" despite parent grant) #736

Closed
opened 2026-07-20 15:51:27 +00:00 by spikerj · 1 comment
Owner

Symptom

toddcan opens blog-create and gets "Blog posting isn't turned on / Ask a parent to enable blog posting in your parental control settings" — even though spikerj granted it. Verified in the live cluster: toddcan's ParentalControls.Permissions.BlogPosting = true in Mongo. The grant is fine.

Root cause

ProfileMapper.ToDto (SpikerSoft.Business/Domain/Profile/DTOs/ProfileDtos.cs ~line 357) builds the child's own profile response with a hand-rolled FeaturePermissionsDto that maps only 8 of the 13 fields — omitting InfoVault, BlogPosting, ParentPreApprovesBlogPosts, Photography, PhotoLocationSharing. Those come back as DTO defaults, so the child's own GetProfile always reports blogPosting=false (and photography=false, etc.) regardless of what the parent granted.

Frontend gates that read the child's own profile are all affected:

  • blog-create.ts:105 → the reported blocked message
  • reading-journey canBlogAboutBooks (#719) → blog-about-book button stays disabled
  • any photography gating reading the child's own permissions.photography

The server-side hard gates are NOT affected (DeterminePostStatus reads the DB entity directly), so this is a pure display/UX block — the child is told the permission is off when it's on.

This is the third mapper of the same family: the #729 clobber fix (PR #432) brought FeaturePermissionsDto, the GetChildren read mapper, and UpdateChildPermissionsCommandHandler into 13-field lockstep, but missed ProfileMapper.ToDto.

Fix

Map all 13 fields in ProfileMapper.ToDto; add a mapper pin test alongside the existing round-trip test so all THREE permission mappers stay in lockstep with the entity.

## Symptom toddcan opens blog-create and gets **"Blog posting isn't turned on / Ask a parent to enable blog posting in your parental control settings"** — even though spikerj granted it. Verified in the live cluster: toddcan's `ParentalControls.Permissions.BlogPosting = true` in Mongo. The grant is fine. ## Root cause `ProfileMapper.ToDto` (`SpikerSoft.Business/Domain/Profile/DTOs/ProfileDtos.cs` ~line 357) builds the child's own profile response with a hand-rolled `FeaturePermissionsDto` that maps only **8 of the 13** fields — omitting `InfoVault`, `BlogPosting`, `ParentPreApprovesBlogPosts`, `Photography`, `PhotoLocationSharing`. Those come back as DTO defaults, so the child's own GetProfile always reports `blogPosting=false` (and `photography=false`, etc.) regardless of what the parent granted. Frontend gates that read the child's own profile are all affected: - `blog-create.ts:105` → the reported blocked message - reading-journey `canBlogAboutBooks` (#719) → blog-about-book button stays disabled - any photography gating reading the child's own `permissions.photography` The server-side hard gates are NOT affected (`DeterminePostStatus` reads the DB entity directly), so this is a pure display/UX block — the child is told the permission is off when it's on. This is the third mapper of the same family: the #729 clobber fix (PR #432) brought `FeaturePermissionsDto`, the GetChildren read mapper, and `UpdateChildPermissionsCommandHandler` into 13-field lockstep, but missed `ProfileMapper.ToDto`. ## Fix Map all 13 fields in `ProfileMapper.ToDto`; add a mapper pin test alongside the existing round-trip test so all THREE permission mappers stay in lockstep with the entity.
Author
Owner

Resolved in spikersoft-backend PR #435 (merged to master 2026-07-20 15:58Z). ProfileMapper.ToDto now maps all 13 FeaturePermissions fields (was 8 — BlogPosting, Photography, PhotoLocationSharing, InfoVault, ParentPreApprovesBlogPosts were dropped), with a pin test where every value is the opposite of its DTO default so a dropped mapping can't pass. Once the API deploy rolls, toddcan's blog-create unblocks with no data changes (BlogPosting=true was already in his profile). Closing.

Resolved in spikersoft-backend PR #435 (merged to `master` 2026-07-20 15:58Z). `ProfileMapper.ToDto` now maps all 13 FeaturePermissions fields (was 8 — BlogPosting, Photography, PhotoLocationSharing, InfoVault, ParentPreApprovesBlogPosts were dropped), with a pin test where every value is the opposite of its DTO default so a dropped mapping can't pass. Once the API deploy rolls, toddcan's blog-create unblocks with no data changes (`BlogPosting=true` was already in his profile). Closing.
Sign in to join this conversation.