[Feature][Calendar] Create-for-child from the parent calendar — owner selector in the event modal (follow-up to #788) #790

Closed
opened 2026-07-22 05:36:22 +00:00 by spikerj · 2 comments
Owner

Phase 3 of the family-calendar overlay (#788): let a parent CREATE an event directly on a child's calendar from the parent view.

Backend is nearly free: POST api/calendar/children/{childUserId}/events → CalendarParentalAccess.EnsureOwnerOrParentAsync, build the event with CreatedBy = childUserId (UpdatedBy = the parent), reuse CreateCalendarEventCommand — its UserId => CreatedBy already invalidates the child's cache correctly, and the reminder should schedule for the child.

The real scope is UI: an owner mat-select ("Me" + linked children, colored dots per the #788 palette) in EventModalComponent's create mode, plumbing children into the modal data, and routing save to a new CalendarApiService.createChildEvent. Also decide whether handleDateSelect defaults the owner to "Me" always or remembers the last choice.

Deliberately split out of #788 so the overlay could ship without modal surgery.

Phase 3 of the family-calendar overlay (#788): let a parent CREATE an event directly on a child's calendar from the parent view. Backend is nearly free: `POST api/calendar/children/{childUserId}/events` → `CalendarParentalAccess.EnsureOwnerOrParentAsync`, build the event with `CreatedBy = childUserId` (`UpdatedBy` = the parent), reuse `CreateCalendarEventCommand` — its `UserId => CreatedBy` already invalidates the child's cache correctly, and the reminder should schedule for the child. The real scope is UI: an owner `mat-select` ("Me" + linked children, colored dots per the #788 palette) in `EventModalComponent`'s create mode, plumbing `children` into the modal data, and routing save to a new `CalendarApiService.createChildEvent`. Also decide whether `handleDateSelect` defaults the owner to "Me" always or remembers the last choice. Deliberately split out of #788 so the overlay could ship without modal surgery.
Author
Owner

Audited at file level against origin/master — NOT DONE. Neither half landed.

  • Backend: enumerating every route in SpikerSoft.Api/Domain/Calendar/CalendarController.cs shows [HttpGet("children/{childUserId}/events")] at :326 — the #788 read-side family overlay — and [HttpPost("events")] at :431. There is no POST children/{childUserId}/events. No create-for-child endpoint exists.
  • Angular: git grep -n "createChildEvent" origin/master → zero hits repo-wide.

Worth noting this is not the usual half-shipped cross-repo pattern I've been finding elsewhere in this audit (#894, #663, #645). Both halves are simply absent — the follow-up was filed after #788 shipped and never started.

One thing I did not open: the owner mat-select in EventModalComponent create mode. Since createChildEvent doesn't exist anywhere for a selector to call, there'd be nothing to route to — but treating that as inferred rather than verified.

Remaining: the whole ticket. The read-side overlay from #788 is in place, so the shape is established; this is the write-side counterpart — endpoint with the same household-authorization check :326 uses, service method, and the owner selector gated to a parent's own children.

Related open work worth sequencing against: #876 (ApproveParentalLinkCommandHandler silently resets unlisted FeaturePermissions to false) touches the same parental-permission surface. If create-for-child gains its own permission gate, it should be added after #876 is fixed, or it'll be silently zeroed by the same wholesale-replacement bug.

Audited at file level against `origin/master` — **NOT DONE. Neither half landed.** - **Backend:** enumerating every route in `SpikerSoft.Api/Domain/Calendar/CalendarController.cs` shows `[HttpGet("children/{childUserId}/events")]` at `:326` — the #788 read-side family overlay — and `[HttpPost("events")]` at `:431`. There is **no** `POST children/{childUserId}/events`. No create-for-child endpoint exists. - **Angular:** `git grep -n "createChildEvent" origin/master` → **zero hits** repo-wide. Worth noting this is *not* the usual half-shipped cross-repo pattern I've been finding elsewhere in this audit (#894, #663, #645). Both halves are simply absent — the follow-up was filed after #788 shipped and never started. One thing I did not open: the owner `mat-select` in `EventModalComponent` create mode. Since `createChildEvent` doesn't exist anywhere for a selector to call, there'd be nothing to route to — but treating that as inferred rather than verified. **Remaining:** the whole ticket. The read-side overlay from #788 is in place, so the shape is established; this is the write-side counterpart — endpoint with the same household-authorization check `:326` uses, service method, and the owner selector gated to a parent's own children. Related open work worth sequencing against: **#876** (`ApproveParentalLinkCommandHandler` silently resets unlisted `FeaturePermissions` to false) touches the same parental-permission surface. If create-for-child gains its own permission gate, it should be added after #876 is fixed, or it'll be silently zeroed by the same wholesale-replacement bug.
Author
Owner

Migrated as part of the umbrella-tracker breakup.

This ticket needed changes in more than one repo, so it became one issue per repo:

Verified 2026-08-07. Neither half landed — this is not the usual half-shipped cross-repo
pattern; the follow-up was filed after #788 shipped and never started.

  • Backend spikersoft-backend@98102023: CalendarController.cs:326 has the #788 read route GET children/{childUserId}/events and
    :431 has POST events, but no POST children/{childUserId}/events. Live: POST api.spikersoft.com/api/calendar/children/x/events → 405, confirming the path is GET-only in production.
  • Angular spikersoft-angular@8e5a4048: git grep createChildEvent → zero hits; EventModalComponent (opened at
    calendar.component.ts:203 and :267) has no owner concept.

Status: not started, both halves.

Closing here. Work now lives in the repos that hold the fixes, so fixes #N in a PR will auto-close them on merge. The umbrella tracker keeps cross-repo epics only.

— Opus 5 Agent

Migrated as part of the umbrella-tracker breakup. This ticket needed changes in more than one repo, so it became one issue per repo: - Backend: **spikerj/spikersoft-backend#572** - Angular: **spikerj/spikersoft-angular#684** Verified 2026-08-07. **Neither half landed** — this is not the usual half-shipped cross-repo pattern; the follow-up was filed after #788 shipped and never started. - Backend `spikersoft-backend@98102023`: `CalendarController.cs:326` has the #788 read route `GET children/{childUserId}/events` and `:431` has `POST events`, but no `POST children/{childUserId}/events`. Live: `POST api.spikersoft.com/api/calendar/children/x/events` → **405**, confirming the path is GET-only in production. - Angular `spikersoft-angular@8e5a4048`: `git grep createChildEvent` → zero hits; `EventModalComponent` (opened at `calendar.component.ts:203` and `:267`) has no owner concept. Status: not started, both halves. Closing here. Work now lives in the repos that hold the fixes, so `fixes #N` in a PR will auto-close them on merge. The umbrella tracker keeps cross-repo epics only. — Opus 5 Agent
Sign in to join this conversation.