Skip to content

fix(i18n/notifications): localize collab notification titles + storage objects; wire the notifications REST routes#3354

Merged
os-zhuang merged 2 commits into
mainfrom
claude/unread-message-i18n-status-a089f9
Jul 20, 2026
Merged

fix(i18n/notifications): localize collab notification titles + storage objects; wire the notifications REST routes#3354
os-zhuang merged 2 commits into
mainfrom
claude/unread-message-i18n-status-a089f9

Conversation

@baozhoutao

@baozhoutao baozhoutao commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Fixes #3353.

One user report on a zh-CN workspace — a sys_file "repro.png" assigned to you
notification 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 the
    raw 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 / mentionedYouAnonymous templates
    (en / zh-CN / ja-JP / es-ES), the object named by its translated label
    (objects.{name}.label → authored def label → API name), and the locale
    resolved 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-storagesys_file / sys_upload_session shipped
    with 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 via
    i18n.loadTranslations on kernel: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 handleNotification dispatch branch and discovery entry but
    no server.<verb>() mount in dispatcher-plugin, so only the cloud hosts'
    hono catch-all reached it — the standalone / os dev server 404'd every
    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 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:

  • Title i18n — the materialized inbox row reads 系统文件 "repro.png" 已分配给你
    (translated label + template), confirmed in the DB and via GET /api/v1/notifications.
  • Detail page i18n — the sys_file detail page renders fully in Chinese:
    breadcrumb 系统文件, status pipeline 待上传 / 已提交 / 已删除, fields 文件 ID / 作用域: 附件 /
    访问控制: 私有 / 所有者 ID.
  • Mark-read persists — clicking "全部标记为已读" fired POST /api/v1/notifications/read/all → 200,
    20 receipts flipped delivered → read server-side, and the bell badge stayed
    cleared 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

@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 20, 2026 7:46am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/plugin-audit, @objectstack/runtime, packages/services.

23 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/api/index.mdx (via @objectstack/runtime)
  • content/docs/api/wire-format.mdx (via @objectstack/runtime)
  • content/docs/automation/hook-bodies.mdx (via @objectstack/runtime)
  • content/docs/automation/webhooks.mdx (via packages/services)
  • content/docs/concepts/north-star.mdx (via packages/runtime)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/runtime)
  • content/docs/deployment/index.mdx (via @objectstack/runtime)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-audit, @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx (via @objectstack/runtime)
  • content/docs/deployment/vercel.mdx (via @objectstack/runtime)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-audit)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/runtime)
  • content/docs/kernel/runtime-services/audit-service.mdx (via packages/services)
  • content/docs/kernel/runtime-services/index.mdx (via packages/services)
  • content/docs/kernel/runtime-services/settings-service.mdx (via packages/services)
  • content/docs/permissions/authentication.mdx (via @objectstack/runtime)
  • content/docs/permissions/authorization.mdx (via packages/runtime)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-audit, @objectstack/runtime, packages/services)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/runtime)
  • content/docs/protocol/kernel/i18n-standard.mdx (via packages/services)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/runtime)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/runtime)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-audit, @objectstack/runtime)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang merged commit ee0a499 into main Jul 20, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/unread-message-i18n-status-a089f9 branch July 20, 2026 07:58
baozhoutao and others added 2 commits July 20, 2026 02:51
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

中文工作区:分配类站内消息未国际化,且未读状态无法清除

2 participants