fix(i18n/notifications): localize collab notification titles + storage objects; wire the notifications REST routes#3354
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 23 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…translation bundle
Fixes three symptoms observed on a zh-CN workspace:
- the bell title 'sys_file "repro.png" assigned to you' was a hardcoded
English literal built from the raw object API name — assignment and
@mention titles now resolve through i18n (messages.assignedToYou /
mentionedYou / mentionedYouAnonymous) in the RECIPIENT's locale, with the
object named by its translated label (objects.{name}.label → def label →
API name); every step degrades best-effort to English.
- sys_file / sys_upload_session had no translation bundle, so the file
detail page (labels + Pending Upload / Committed / Deleted status
pipeline) rendered English on every locale — service-storage now ships
its own ADR-0029 D8 bundle (en / zh-CN / ja-JP / es-ES) loaded on
kernel:ready, mirroring service-messaging.
(The third symptom — unread state never clearing — is an objectui fix:
the console wrote sys_notification_receipt via the generic data API,
which ADR-0103 made read-only; it must use POST /api/v1/notifications/read.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
handleNotification (GET /notifications, POST /notifications/read[/all]) and its discovery entry existed, but dispatcher-plugin never registered server.<verb>() mounts for them — so only the cloud hosts' hono catch-all reached the handler; the standalone / `os dev` server 404'd every /api/v1/notifications* request. That was the real reason unread notifications never cleared: the console's direct sys_notification_receipt write is rejected by ADR-0103's engine-owned gate, and this REST fallback — the intended path — was unreachable. Mounting the three routes makes mark-read persist in every deployment. Guarded by the dispatcher-plugin route-registration regression test. Verified end-to-end in the showcase example: POST /notifications/read/all → 200, receipts flip delivered→read server-side, and the bell badge stays cleared across the inbox poll (previously it flipped every row back to unread). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Jul 20, 2026
…d + Console) Continues the v16 page from the latest front/back-end code. Since the rc.0 cut, 9 backend changesets landed and the objectui pin advanced 94d4876 -> af1b0db (objectui objectstack-ai#2706-objectstack-ai#2736). Sourced from each repo's own changesets. - Retitles the now-stale 'pending the next console pin' subsection: those 4 frontend items (objectui#2701/objectstack-ai#2706/objectstack-ai#2707/objectstack-ai#2708) are now bundled as the pin advanced; points to the new running section. - Adds a 'Landed since 16.0.0-rc.0' section: - Breaking/behavior: aiStudio/aiSeat alias removal (objectstack-ai#3308); date-arithmetic now a build-time error (objectstack-ai#3306); checkboxes per-option visibleWhen + string option matching (objectstack-ai#3350). - New backend: formula null-guard/floor/ceil (objectstack-ai#3306); engine-owned managedBy bucket (ADR-0103 addendum, objectstack-ai#3343); approvals viewer gating (objectstack-ai#3344) + decision attachments (objectstack-ai#3332); discovery transactionalBatch bit (objectstack-ai#3298); action resultDialog i18n (objectstack-ai#3347); collab-notification/storage localization + wired notifications REST routes (objectstack-ai#3354). - Console (now bundled): option-widget visibleWhen parity, approvals-inbox server-viewer gating + composer retirement, related-list pagination, inline-analytics renderer retirement, authenticated api-fetch threading, result-dialog i18n, engine-owned bucket UI, write-failure surfacing. - Adds aiStudio/aiSeat and date-arithmetic to the upgrade checklist; updates the Console-section intro for the advanced pin. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AHVoqyH9VAjmbyMN1Ri2jf
This was referenced Jul 20, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3353.
One user report on a zh-CN workspace — a
sys_file "repro.png" assigned to younotification that was English, opened an English detail page, and never cleared
its unread state — turned out to be three distinct gaps. This PR carries the
two framework-side fixes plus the route wiring that makes the objectui mark-read
fix reachable; the console change ships in objectstack-ai/objectui#2743.
Changes
@objectstack/plugin-audit— assignment (collab.assignment) and @mention(
collab.mention) bell titles were hardcoded English literals built from theraw object API name. They now resolve through the i18n service with the same
key shapes as the activity summaries (framework#3039): new
messages.assignedToYou/mentionedYou/mentionedYouAnonymoustemplates(en / zh-CN / ja-JP / es-ES), the object named by its translated label
(
objects.{name}.label→ authored def label → API name), and the localeresolved for the recipient. Best-effort throughout: no locale / no i18n /
key miss degrades to the English literal (which now also prefers the authored
object label over the API name).
@objectstack/service-storage—sys_file/sys_upload_sessionshippedwith no translation bundle, so the file detail page (field labels + the
Pending Upload / Committed / Deleted status pipeline) rendered English on every
locale. The service now ships its own ADR-0029 D8 bundle (en / zh-CN / ja-JP /
es-ES,
src/translations+scripts/i18n-extract.config.ts) loaded viai18n.loadTranslationsonkernel:ready, matching service-messaging.@objectstack/runtime— the in-app notifications REST surface(
GET /api/v1/notifications,POST /api/v1/notifications/read[/all];ADR-0030) had its
handleNotificationdispatch branch and discovery entry butno
server.<verb>()mount indispatcher-plugin, so only the cloud hosts'hono catch-all reached it — the standalone /
os devserver 404'd everyrequest. That was the real reason unread notifications never cleared: the
console's direct
sys_notification_receiptwrite is rejected by ADR-0103'sengine-owned gate, and this REST fallback was unreachable. The three routes
are now mounted explicitly, guarded by the route-registration regression test.
Verification (showcase, real browser)
Booted the showcase example, drove a real assignment through the messaging
pipeline, and drove the console (objectui HMR build) as a real user:
系统文件 "repro.png" 已分配给你(translated label + template), confirmed in the DB and via
GET /api/v1/notifications.sys_filedetail page renders fully in Chinese:breadcrumb 系统文件, status pipeline 待上传 / 已提交 / 已删除, fields 文件 ID / 作用域: 附件 /
访问控制: 私有 / 所有者 ID.
POST /api/v1/notifications/read/all → 200,20 receipts flipped
delivered → readserver-side, and the bell badge stayedcleared across the inbox poll (previously every row flipped back to unread).
Unit tests: plugin-audit 45/45, runtime 193/193 (incl. new route-registration
assertions), service-storage 99/99.
🤖 Generated with Claude Code