Skip to content

FE-1566: Create avatar links in the web of the image they point at - #9499

Open
claude[bot] wants to merge 3 commits into
mainfrom
claude/fe-1566-avatar-link-in-image-web
Open

FE-1566: Create avatar links in the web of the image they point at#9499
claude[bot] wants to merge 3 commits into
mainfrom
claude/fe-1566-avatar-link-in-image-web

Conversation

@claude

@claude claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Requested by Ciaran Morinan · Slack thread

Before: an organization's avatar is visible only to the person who uploaded it. Every other member of the organization sees the empty "Click to upload" dropzone on the organization's settings page, and no image next to the organization's name elsewhere in the app.

After: every member of the organization sees the avatar. Avatars uploaded before this change are repaired the next time the API starts.

How: the avatar's Image File entity is created in the organization's web, but the Has Avatar link to it was created with no webId. $webId is optional in the createEntity mutation, so apps/hash-api/src/graphql/resolvers/knowledge/entity/entity.ts:115 fell back to webId ?? user.accountId and the link landed in the uploading user's own web, where no other member of the organization holds a role. apps/hash-frontend/src/shared/file-upload-context.tsx:497 now passes the web of the file entity the link points at, so the link is created in the same web as the image. The links already stored are repaired by 031-move-avatar-links-to-image-web.migration.ts, which walks every user and organization web as that web's machine actor, and for each Has Avatar link whose right entity sits in another web creates a replacement in that other web with the same left entity, right entity, properties and public-view policy, then archives the original. A link that already has a replacement is archived without a second replacement being created, so an interrupted run leaves no duplicate behind and the migration is safe to re-run.

🔗 Related links

🔍 What does this change?

  • apps/hash-frontend/src/shared/file-upload-context.tsx:497 passes webId to the createEntity mutation for the link entity, taken from the file entity the link points at.
  • apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/031-move-avatar-links-to-image-web.migration.ts runs the repair for the Has Avatar link type.
  • apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/util/relocate-links.ts holds the repair itself, and util.ts exports relocateLinksToRightEntityWeb, which iterates the webs. Both take the link type as a parameter, so a second link type can reuse them.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

The resolver default is unchanged: entity.ts:115 still assigns a link entity to user.accountId when the caller omits webId. Only the avatar call site passes a webId, so any other caller that omits one still creates its link in the acting user's web.

🐾 Next steps

Suggested follow-ups, none of them in this PR:

  • Default a link entity's webId to the left entity's web in entity.ts:115, which would cover every caller that omits it.
  • Repair a Has Avatar link's public-view policy from the UI. org-form.tsx and use-update-profile-avatar.tsx omit linkedEntityData when the profile already has an avatar, so file-upload-context.tsx:412 returns before any link work and replacing an avatar cannot add a policy the link is missing.
  • Apply the public grant when makePublic is true and an existing file entity is updated. apps/hash-api/src/graph/knowledge/system-types/file.ts:247 and :435 attach it only on the create branch. Passing makePublic: true from use-update-profile-avatar.tsx:42, as org-form.tsx:152 does, would match the two call sites.
  • Log a warning in apps/hash-frontend/src/lib/user-and-org.ts:194 and :204 instead of skipping an unreadable avatar link silently.

🛡 What tests cover this?

No automated tests. ESLint and oxfmt were run against the four files and are clean. tsc --noEmit and the unit tests could not be run in the environment this branch was written in: both need the generated types from @blockprotocol/type-system, which come from a wasm-pack and cargo-insta build driven by mise, and the downloads for those tools are blocked there. CI covers both.

❓ How to test this?

  1. As user A, create an organization and upload an avatar for it.
  2. Invite user B to the organization and accept the invitation.
  3. As user B, open the organization's settings page and confirm the avatar is shown.
  4. To check the migration, run yarn workspace @apps/hash-api start:migrate twice against a database holding an avatar link created before this branch. The first run moves the link into the image's web; the second makes no further change.

The web the link is created in decides who can see it. Deriving it from the
uploaded file entity keeps a link in the same web as the image it points at.
Each link outside the web of the image it points at is archived and replaced
by a link in that web, carrying the same endpoints, properties and public
visibility. A link which already has a replacement is only archived, so the
migration is safe to re-run.
@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

4 Skipped Deployments
Project Deployment Actions Updated
hash Ignored Ignored Preview Sep 3, 2026 10:12am UTC
hashdotdesign-tokens Ignored Ignored Preview Sep 3, 2026 10:12am UTC
petrinaut Skipped Skipped Sep 3, 2026 10:12am UTC
petrinaut-docs Skipped Skipped Sep 3, 2026 10:12am UTC

Request Review

@claude claude Bot assigned CiaranMn Sep 2, 2026
@github-actions github-actions Bot added area/apps > hash* Affects HASH (a `hash-*` app) area/apps > hash-api Affects the HASH API (app) type/eng > frontend Owned by the @frontend team type/eng > backend Owned by the @backend team area/apps labels Sep 2, 2026
@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.03%. Comparing base (27b32c4) to head (832ccbb).
⚠️ Report is 22 commits behind head on main.

Files with missing lines Patch % Lines
...ns/031-move-avatar-links-to-image-web.migration.ts 0.00% 37 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9499   +/-   ##
=======================================
  Coverage   61.03%   61.03%           
=======================================
  Files        1449     1450    +1     
  Lines      144693   144755   +62     
  Branches     6692     6700    +8     
=======================================
+ Hits        88307    88356   +49     
- Misses      55282    55291    +9     
- Partials     1104     1108    +4     
Flag Coverage Δ
apps.hash-api 15.33% <0.00%> (+0.64%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@claude
claude Bot marked this pull request as ready for review September 2, 2026 13:18
@claude
claude Bot requested a review from CiaranMn September 2, 2026 13:18
@cursor

cursor Bot commented Sep 2, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
One-time graph migration archives and recreates link entities across webs with policy copying; incorrect logic could break avatar visibility or leave duplicates, though the replacement check limits that risk.

Overview
Has Avatar links were ending up in the uploading user's web when createEntity omitted webId, so other org members could not see organization avatars. File upload link creation now passes webId taken from the right-hand file entity, so new avatar links live in the same web as the image.

A startup migration 031 repairs existing links: for each user/org web it finds misplaced Has Avatar links (right entity in another web), creates a replacement in the image's web with the same endpoints, properties, draft state, and public-view policy when applicable, then archives the original. It runs per-web as each web's machine actor and skips creating a second replacement if one already exists, so re-runs stay safe.

Reviewed by Cursor Bugbot for commit 832ccbb. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel
vercel Bot temporarily deployed to Preview – petrinaut-docs September 3, 2026 10:12 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut September 3, 2026 10:12 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash* Affects HASH (a `hash-*` app) area/apps > hash-api Affects the HASH API (app) area/apps type/eng > backend Owned by the @backend team type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants