feat(user) map embedded users as compact users in comments, ratings, tags and meal plan shares (spec 003) #60

Merged
araemer merged 5 commits from 003-compact-user-in-embedded-dtos into stage 2026-10-11 06:17:23 +00:00
Owner

Spec 003: docs/features/003-compact-user-in-embedded-dtos.md (recipe-platform#22). Plan: docs/plans/003-compact-user-in-embedded-dtos.md. Contract PR: recipe-platform#46.

What was implemented

Plan step Result
1. Contract pin contract.ref → 0f2e4006995362d60686ce328c1edbb292188ed3
2. Models CommentModel, RatingModel, TagModel, MealPlanShareModel: embedded user is a CompactUserModel; JSDoc updated there and in CompactUserModel, UserDisplayModel
3. Mappers CommentMapper, RatingMapper, TagMapper, MealPlanShareMapper map the embedded user through compactUserMapper; nothing else in the mapping bodies changed. After the review, mapDtoToModel in CommentMapper and RatingMapper also got a method JSDoc
4. Mapper tests compact fixtures, a toEqual test on the whole mapped user, and a new "drops email and role if the backend still sends them" test in each of the four files
5. MealPlanRestResource.ts two stale comments on saveMealPlanShare corrected, no code change
6. docs/architecture.md five rows of the mapper table in section 4.5

No component, hook, context, route or DTO file changed. No type error appeared outside the files the plan names.

Deviations from the plan

None.

Judgment calls

  • API_BASE constant in the four test files. None of them had one; each got the same documented constant that CompactUserMapper.test.ts uses, instead of the literal URL.
  • TagMapper.test.ts fixture. The user constant moved from inside one test to the top of its describe block, because the new "drops email and role" test needs it too.
  • RatingMapper.test.ts fixture. Keeps the user name bob; the first name is Bob rather than the plan's example Anna.
  • Commits. The pin is its own commit (the build fails at that commit by design, as the plan says); models, mappers, tests and architecture.md are one commit; the comment fix is a third; the JSDoc from the review is a fourth.

Verification

  • npm run build: passes.
  • npm run lint: 0 errors, 2 warnings, both in src/contexts/MealPlanDayProvider.tsx, which this branch does not touch.
  • npm run test: 39 files, 403 tests, all pass.
  • Plan's grep checks: no UserModel, userMapper or UserDto left in the four models and four mappers; userMapper only in UserMapper.ts.
  • UI (/verify-ui), logged in as the admin test account (recipe detail also as user, see below), against the local backend on its 003-compact-user-in-embedded-dtos branch. All five viewports per screen (desktop 1920x1080, tablet 1280x800 and 800x1280, phone 400x890 and 890x400); no console errors.
    • Recipe detail ("Aioli ohne Ei"): comment and rating by Anna Admin show her photo avatar and full name. As the user test account (desktop viewport): the same, without edit or delete controls. A temporary comment by the test admin showed initials "CP" and "Claude Playwright-Admin"; it was deleted afterwards.
    • Tag management: "Erstellt von" shows "Anna Admin" for the three tags with a creator and "—" for the other 35; sorting by that column works in both directions.
    • Meal plan share dialog: on a temporary plan, adding a share with the user test account and changing its permission both showed avatar initials and "Claude Playwright-User" afterwards. The plan was deleted afterwards.
    • Network: the recipe, enriched tag and meal plan load responses carry id, userName, firstName, lastName, avatarUrl for embedded users, no email or role.

Review (review-implementation)

No blocking findings. Three minor ones:

  1. mapDtoToModel in CommentMapper and RatingMapper had no method JSDoc: fixed.
  2. No comment or rating author with a user name only (no first or last name) was seen in the UI, because none exists among the data the test accounts may touch: accepted by the user. CompactUserMapper.test.ts covers the mapping, and getUserDisplayName is untouched.
  3. The share dialog was seen only with an initials avatar, not with a photo, because that would mean sharing a plan with a real user's account: accepted by the user. The photo avatar was seen through the same mapper on the recipe detail.

Still open:

  • The pro role was not checked; nothing in the change depends on the role, and tag management is admin-only.
  • CI contract_pin stays red until recipe-platform#46 is merged, then it has to be re-run.

🤖 Generated with Claude Code

Spec 003: [docs/features/003-compact-user-in-embedded-dtos.md](https://git.raemer.net/araemer/recipe-platform/src/branch/main/docs/features/003-compact-user-in-embedded-dtos.md) (recipe-platform#22). Plan: [docs/plans/003-compact-user-in-embedded-dtos.md](https://git.raemer.net/araemer/recipe-app/src/branch/003-compact-user-in-embedded-dtos/docs/plans/003-compact-user-in-embedded-dtos.md). Contract PR: recipe-platform#46. ## What was implemented | Plan step | Result | |---|---| | 1. Contract pin | `contract.ref` → `0f2e4006995362d60686ce328c1edbb292188ed3` | | 2. Models | `CommentModel`, `RatingModel`, `TagModel`, `MealPlanShareModel`: embedded user is a `CompactUserModel`; JSDoc updated there and in `CompactUserModel`, `UserDisplayModel` | | 3. Mappers | `CommentMapper`, `RatingMapper`, `TagMapper`, `MealPlanShareMapper` map the embedded user through `compactUserMapper`; nothing else in the mapping bodies changed. After the review, `mapDtoToModel` in `CommentMapper` and `RatingMapper` also got a method JSDoc | | 4. Mapper tests | compact fixtures, a `toEqual` test on the whole mapped user, and a new "drops email and role if the backend still sends them" test in each of the four files | | 5. `MealPlanRestResource.ts` | two stale comments on `saveMealPlanShare` corrected, no code change | | 6. `docs/architecture.md` | five rows of the mapper table in section 4.5 | No component, hook, context, route or DTO file changed. No type error appeared outside the files the plan names. ## Deviations from the plan None. ## Judgment calls - **`API_BASE` constant in the four test files.** None of them had one; each got the same documented constant that `CompactUserMapper.test.ts` uses, instead of the literal URL. - **`TagMapper.test.ts` fixture.** The `user` constant moved from inside one test to the top of its `describe` block, because the new "drops email and role" test needs it too. - **`RatingMapper.test.ts` fixture.** Keeps the user name `bob`; the first name is `Bob` rather than the plan's example `Anna`. - **Commits.** The pin is its own commit (the build fails at that commit by design, as the plan says); models, mappers, tests and `architecture.md` are one commit; the comment fix is a third; the JSDoc from the review is a fourth. ## Verification - `npm run build`: passes. - `npm run lint`: 0 errors, 2 warnings, both in `src/contexts/MealPlanDayProvider.tsx`, which this branch does not touch. - `npm run test`: 39 files, 403 tests, all pass. - Plan's grep checks: no `UserModel`, `userMapper` or `UserDto` left in the four models and four mappers; `userMapper` only in `UserMapper.ts`. - **UI (`/verify-ui`)**, logged in as the `admin` test account (recipe detail also as `user`, see below), against the local backend on its `003-compact-user-in-embedded-dtos` branch. All five viewports per screen (desktop 1920x1080, tablet 1280x800 and 800x1280, phone 400x890 and 890x400); no console errors. - **Recipe detail** ("Aioli ohne Ei"): comment and rating by Anna Admin show her photo avatar and full name. As the `user` test account (desktop viewport): the same, without edit or delete controls. A temporary comment by the test admin showed initials "CP" and "Claude Playwright-Admin"; it was deleted afterwards. - **Tag management**: "Erstellt von" shows "Anna Admin" for the three tags with a creator and "—" for the other 35; sorting by that column works in both directions. - **Meal plan share dialog**: on a temporary plan, adding a share with the `user` test account and changing its permission both showed avatar initials and "Claude Playwright-User" afterwards. The plan was deleted afterwards. - **Network**: the recipe, enriched tag and meal plan load responses carry `id, userName, firstName, lastName, avatarUrl` for embedded users, no `email` or `role`. ## Review (`review-implementation`) No blocking findings. Three minor ones: 1. `mapDtoToModel` in `CommentMapper` and `RatingMapper` had no method JSDoc: fixed. 2. No comment or rating author with a user name only (no first or last name) was seen in the UI, because none exists among the data the test accounts may touch: accepted by the user. `CompactUserMapper.test.ts` covers the mapping, and `getUserDisplayName` is untouched. 3. The share dialog was seen only with an initials avatar, not with a photo, because that would mean sharing a plan with a real user's account: accepted by the user. The photo avatar was seen through the same mapper on the recipe detail. Still open: - The `pro` role was not checked; nothing in the change depends on the role, and tag management is admin-only. - CI `contract_pin` stays red until recipe-platform#46 is merged, then it has to be re-run. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
docs(plan) add the implementation plan for spec 003
Some checks failed
/ contract_pin (pull_request) Has been cancelled
/ test (pull_request) Has been cancelled
f6dbd7b416
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chore(contract) pin the spec 003 contract commit
Some checks failed
/ test (pull_request) Failing after 45s
/ contract_pin (pull_request) Failing after 3s
6ce0c8a8ee
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
refactor(users) map embedded users of comments, ratings, tags and meal plan shares as compact users
Some checks failed
/ test (pull_request) Has been cancelled
/ contract_pin (pull_request) Has been cancelled
9c2b4d5c8e
The contract now types createdByUser and sharedWithUser as CompactUserDto.
The four mappers go through compactUserMapper and the models hold a
CompactUserModel, so an email or role cannot reach a model even if a
backend still sends them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(meal-plan) correct the comments on the share response in saveMealPlanShare
Some checks failed
/ test (pull_request) Successful in 1m5s
/ contract_pin (pull_request) Failing after 3s
c49bdf0281
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
araemer changed title from WIP: feat(user) map embedded users as compact users in comments, ratings, tags and meal plan shares (spec 003) to feat(user) map embedded users as compact users in comments, ratings, tags and meal plan shares (spec 003) 2026-10-04 06:52:25 +00:00
docs(mappers) document mapDtoToModel of the comment and rating mappers
All checks were successful
/ test (pull_request) Successful in 1m4s
/ contract_pin (pull_request) Successful in 2s
4393357805
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
araemer merged commit f1cba9025c into stage 2026-10-11 06:17:23 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
araemer/recipe-app!60
No description provided.