Wang1rrr opened a new pull request, #4869:
URL: https://github.com/apache/rocketmq-dashboard/pull/4869

   ### Which Issue(s) This PR Fixes
   
   - Fixes #4868
   
   ### Brief Description
   
   `POST /api/topics/send` returns `SendMessageVO.sendTime` as a primitive 
`long` of epoch millis (`SendMessageVO.java:30`, set with 
`System.currentTimeMillis()` in all three providers: 
`RocketMQAdminClientImpl.java:555`, `AliyunInstanceProvider.java:483`, 
`TencentInstanceProvider.java:600`), and the AI tool schema already publishes 
it as an integer (`tool-catalog/tools/message.yaml:526`, 
`MessageSendOutput.java:26`).
   
   Three declarations promised an ISO-8601 string instead, and the mock layer 
implemented that promise - so mock mode and real mode returned different shapes 
for the same field, with no test pinning either:
   
   - `docs/api-spec.md` §5.8 field table (`sendTime | string | 发送时间 (ISO 
8601)`) and its response example
   - `web/src/api/metadata.ts:289` `sendTime: string;` on 
`SendTopicMessageResult`
   - `web/src/services/topicService.ts:241` mock branch returning `new 
Date().toISOString()`
   
   This aligns all of them with the server. The direction matters: changing 
`SendMessageVO` to emit a formatted string would break the published tool 
schema and every consumer of `rmq.message.send`, so the declarations move, not 
the wire format.
   
   - `web/src/api/metadata.ts` - `sendTime: number` with a one-line note that 
it mirrors `SendMessageVO.sendTime`
   - `web/src/services/topicService.ts` - mock returns `Date.now()`, so mock 
mode is now interchangeable with the real API for this field
   - `docs/api-spec.md` §5.8 - the field table says `number` / Unix 毫秒时间戳, and 
the example response uses `1783506645123`, which is 
`Date.parse('2026-07-08T10:30:45.123Z')` - the same instant the example already 
showed, so the sample stays semantically identical
   - `web/src/pages/instance/__tests__/TopicPage.test.tsx:188` - the fixture 
that encoded the wrong string shape now uses `Date.parse(...)`
   - `web/src/api/metadata.test.ts` - the pass-through assertion now checks 
`sendTime: 1`, so the API layer pins the numeric shape it was already stubbing
   - `web/src/services/topicService.test.ts` - new case `reports the send time 
as epoch millis, the shape the API returns`
   
   Impact today is latent rather than visible: 
`web/src/pages/instance/topic.tsx:1455` reads only `result.msgId`. What the PR 
removes is the trap - the next caller that renders or formats `sendTime` (the 
obvious next step for a send confirmation) would have been written against a 
string and handed `1783506645123`.
   
   ### How Did You Test This Change?
   
   ```
   cd web
   npx vitest run src/services/topicService.test.ts src/api/metadata.test.ts 
src/pages/instance/__tests__/TopicPage.test.tsx
    Test Files  3 passed (3)
         Tests  47 passed (47)
   
   npx tsc -b            # exit 0
   npx eslint src/api/metadata.ts src/api/metadata.test.ts 
src/services/topicService.ts src/services/topicService.test.ts 
src/pages/instance/__tests__/TopicPage.test.tsx
                         # exit 0, no findings
   npx prettier --check --end-of-line auto <the same five files>
   All matched files use Prettier code style!
   ```
   
   Mutation-checked, because a type-only fix is exactly the kind of change that 
can pass while pinning nothing. Reverting only the mock branch to `new 
Date().toISOString()` (leaving the new test in place) fails the new case and 
nothing else:
   
   ```
   npx vitest run src/services/topicService.test.ts
    FAIL  src/services/topicService.test.ts > topic service mock data > reports 
the send time as epoch millis, the shape the API returns
   AssertionError: expected 'string' to be 'number' // Object.is equality
    Test Files  1 failed (1)
         Tests  1 failed | 8 passed (9)
   ```
   
   Restoring `Date.now()` returns that file to `9 passed (9)`.
   
   Documentation side: `git diff --numstat` is `2 2 docs/api-spec.md` - the two 
`sendTime` lines only, no other section, anchor or index row touched, CRLF 
preserved and no BOM, so the diff carries no whitespace churn. `1783506645123` 
was produced by `Date.parse` on the string the example already contained and 
round-trips back to `2026-07-08T10:30:45.123Z` (asserted in the patch script).
   
   No Java changed, so `mvn test` and the ArchUnit checks are unaffected.
   
   ### Checklist
   
   - [x] One coherent change; unrelated modifications are not bundled in
   - [x] Commit subject follows Conventional Commits (`feat:` / `fix:` / 
`refactor:` / `chore:` / `docs:` / `perf:`)
   - [x] Tests added or updated for non-trivial changes, test methods named 
`...Test` (web: one new vitest case, two fixtures corrected; no Java behaviour 
changed)
   - [x] New UI text has both Chinese and English entries under `web/src/i18n/` 
(no new UI text; the spec edit keeps the document's existing Chinese wording)
   - [x] Architecture constraints stay green (`mvn test` runs the ArchUnit 
checks) - no Java changed
   - [x] New source files carry the ASF license header (no new source files)
   - [x] Documentation touched where behaviour changed (README / `docs/` / 
in-app help) - `docs/api-spec.md` §5.8 corrected in the same change, since the 
wrong contract was documented there too


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to