feat(schedule): surface shift tags across My Schedule views #330
No reviewers
Labels
No labels
agent:hermes
bug
chore
dependency
feature
status:blocked
status:in-progress
status:needs-info
status:needs-review
status:ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
owlburtoe/Shiftd!330
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "scratch-pad-audit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Renders shift tags (
call,hot,preceptor, …) at a glance across the My Schedule surfaces so any staff or admin can see what type of shift an individual is working. A shift with no tags is treated as a regular shift (nothing rendered).This closes the second active item in the Obsidian Scratch Pad ("Now we have to pass all the tags. Eg call, hot, preceptor. No tags assumes a regular shift"). The day-view ordering work (overnight / day / night) was already shipped; this adds the tag plumbing + rendering on top.
Where tags now appear
All use the existing
CoverageTagPillscomponent (same one used in the schedule grid / coverage views) for consistent colors.Frontend changes
tags: Tag[]toEnrichedShiftandCoworkerMember; populated fromshift.tagsat every construction site (useMySchedule,buildCoworkersByDate,useStaffDashboard).CoverageTagPillson own-shift and coworker rows inDayView,WeekView(own cells + "Also working" list), andShiftCard.Hot). Now it shows pure kind (Regular/Extra/Call) and the full tag set renders as its own colored pills — strictly more info at a glance, no duplication.Backend changes
UpcomingAssignmentSummary.tagsfromstring[]→Tag[]({id, name, color}) so the dashboard can render colored pills. The richer data was already loaded internally (getTagsForShifts) and was being flattened to names.tags: a.tags.map(t => t.name). ICS title/notes output is unchanged.StaffUpcomingAssignmentOpenAPI schema (items: string→$ref: Tag) and the upcoming-assignments contract test.Test plan
pnpm tsc --noEmit— cleanshiftd_test):staff-upcoming-assignments+ics(28),calendarFeed+calendarSubscription(6),dashboard(9) — all pass; ICS feed still emits tag names correctlypnpm check-types— cleancoworker-utils,my-schedule-day-model,useCalendar) — 53 passpnpm docs:audit—openapi.yaml OK (198 operations)Follow-up
Android needs the equivalent occurrence-/tag-aware shift display — tracked as the next task after this merges.
@claude Can you review this failing E2E test and why its failing?
Now I have enough context to give a definitive analysis. Here's what's happening:
Which test is failing and why
The failing test is
apps/backend/src/routes/__tests__/staff-upcoming-assignments.test.ts— the "attaches shift tags ordered case-insensitively" test around line 337.Root cause
Before the PR,
listUpcomingAssignmentsForStaffmapped tags to plain strings:The test asserted a
string[]:This worked. The PR then changes the mapping to return full
Tagobjects:The test expectations were also updated in the PR to match the new shape — but the backend
UpcomingAssignmentSummaryinterface was changed fromtags: string[]totags: Tag[]to carry the full object. Any pre-existing code that consumedUpcomingAssignmentSummary.tagsasstring[]needed to adapt.The cascading fix the PR makes
The calendar feed controller was the critical adapter that had to change. Without this fix, the iCal output would have emitted
[object Object]for each tag:Secondary test:
my-schedule-day-model.test.tsThis test also fails before the PR because:
assignmentKindLabelpreviously returnedshift.tags?.[0]?.name ?? 'Extra'for extra-type shifts — so the test expected'Hot'as the label for the tagged extra shift.MyScheduleDayMemberhad notagsfield at all.The PR makes two changes:
assignmentKindLabelnow always returns'Extra'for extra shifts (the tag name was a misuse of that field — tags should be rendered as pills, not as the kind label)tags: shift.tags ?? []is added toMyScheduleDayMemberconstruction (line 172 ofmy-schedule-day-model.ts)The test correctly reflects both:
Why there's no E2E (Playwright) breakage
The Playwright tests in
tests/e2e/my-schedule.spec.tsdon't assert tag content, and all the?? []fallbacks in the frontend hooks (useMySchedule.ts,useStaffDashboard.ts,coworker-utils.ts) prevent runtime crashes. TheEnrichedShift.tags: Tag[]andCoworkerMember.tags: Tag[]additions inuseCalendar.test.tsandmy-schedule-day-model.test.tsare needed to satisfy TypeScript's required-field check — without those fixture updates,pnpm check-typeswould fail, breaking CI before the Playwright suite even runs.Summary
repositories.tstags: string[]→tags: Tag[]inUpcomingAssignmentSummarycalendarFeedController.ts.map((tag) => tag.name)added[object Object]my-schedule-day-model.tsassignmentKindLabelno longer returns tag name;tagsadded to memberstaff-upcoming-assignments.test.tsTag[]string[]but code now returnsTag[]useCalendar.test.ts,my-schedule-day-model.test.tstags: []added to fixturesEnrichedShift.tags: Tag[]is now required; missing it is a TypeScript errorView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.