Skip to content

fix(gui): render dashboard log timestamps in server timezone - #790

Closed
Wibias wants to merge 1 commit into
lidge-jun:devfrom
Wibias:fix/725-log-timezone
Closed

fix(gui): render dashboard log timestamps in server timezone#790
Wibias wants to merge 1 commit into
lidge-jun:devfrom
Wibias:fix/725-log-timezone

Conversation

@Wibias

@Wibias Wibias commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #725

Renders dashboard log timestamps in the server timezone.

Stack

Stacks on #784 (fix/726-log-paginationdev). Land the pagination PR first, then retarget this PR to dev if needed.

Test plan

  • bun run typecheck
  • bun run test

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Wibias, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5f77218a-334d-4a5f-9374-589fb098fbaf

📥 Commits

Reviewing files that changed from the base of the PR and between c777c8e and fd43fcb.

📒 Files selected for processing (4)
  • gui/src/pages/Logs.tsx
  • src/server/management/config-routes.ts
  • src/server/management/logs-usage-routes.ts
  • tests/management-api-logs-metrics.test.ts

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c36cc46ba8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread gui/src/pages/Logs.tsx Outdated
Comment thread gui/src/pages/Logs.tsx Outdated
@Wibias
Wibias force-pushed the fix/725-log-timezone branch from c36cc46 to 616eaa0 Compare July 30, 2026 22:44
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

⚠️ Wrong target branch

This pull request currently targets fix/726-log-pagination, but pull requests must target one of dev or dev2-go.

@Wibias Please retarget this PR to dev. Most contributions go to dev first; use dev2-go only for scoped Go native-port work. main receives only release promotions. See our Contributing guide for details. Thanks! 🙏

Its title has been prefixed with [WRONG BRANCH].

This pull request is being kept as a draft automatically. Once every issue above is resolved, it will be marked ready for review again.

@github-actions github-actions Bot changed the title fix(gui): render dashboard log timestamps in server timezone [WRONG BRANCH] fix(gui): render dashboard log timestamps in server timezone Jul 30, 2026
@github-actions
github-actions Bot marked this pull request as draft July 30, 2026 22:45
@Wibias
Wibias force-pushed the fix/725-log-timezone branch from 616eaa0 to 58662bb Compare July 30, 2026 22:55
@Wibias
Wibias marked this pull request as ready for review July 30, 2026 22:56
@Wibias Wibias changed the title [WRONG BRANCH] fix(gui): render dashboard log timestamps in server timezone fix(gui): render dashboard log timestamps in server timezone Jul 30, 2026
@github-actions github-actions Bot added the bug Something isn't working label Jul 30, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58662bb2ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/enforce-pr-target.yml Outdated
@Wibias

Wibias commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

[shipping-github] Status

Not merge-ready yet. This PR is intentionally stacked on fix/726-log-pagination (#784).

enforce-target currently fails with wrong base because that check runs from dev until the stacked-base allowlist from #784 lands. Cross-platform CI may not fully run while that gate is red.

Next: merge #784 to dev first, then re-run checks on this PR (keep the stack). Do not retarget to dev prematurely — this change depends on the paginated /api/logs envelope from #726/#784.

Return server timeZone from /api/logs, validate client ICU support, cache the timezone with log rows, and tolerate legacy array responses.
@Wibias
Wibias force-pushed the fix/725-log-timezone branch from 58662bb to fd43fcb Compare July 31, 2026 00:20
@Wibias
Wibias changed the base branch from fix/726-log-pagination to dev July 31, 2026 00:20
@Wibias

Wibias commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: approve-comment

lidge-jun added a commit that referenced this pull request Jul 31, 2026
The user's constraint is that their GUI layout must not change. #790's
direction is right and its defect is real -- dashboard timestamps render
in browser-local time -- but it carries two problems, and only one was
about layout.

It rewrites /api/logs from an array to a {timeZone, logs} envelope while
leaving four array consumers unfixed, and the single test it touches
accepts both shapes, so it passes with the production change reverted.

The narrower path already exists inside that same PR: it adds timeZone to
/api/settings and then never uses it, carrying the same value over two
routes. SettingsData already flows through the GUI, so the fix needs no
new fetch, no session-cache schema change, and no /api/logs change --
only a timezone argument threaded into two formatters at two call sites.

Records the RangeError guard (an ICU-unknown zone would otherwise kill the
row render), the browser-TZ != server-TZ test that #790's version could
not fail on, and the grep that proves no JSX or CSS moved.
lidge-jun added a commit that referenced this pull request Jul 31, 2026
)

A proxy running in KST viewed from a UTC browser reported every request
nine hours off: `formatLogTimestamp` and `formatLogDateTime` called
`toLocaleTimeString(localeTag)` with no zone, so the viewer's machine
decided what time the server logged something.

The zone rides on `/api/settings`, which is already an object and already
flows through the GUI. PR #790 fixed the same defect by rewriting
`/api/logs` from a bare array into a `{timeZone, logs}` envelope -- while
leaving four suites that read that response as an array untouched
(server-auth:1623, claude-native-passthrough:119,
openai-provider-option-e2e:489, server-403-permission-e2e:86). It also
added a session-cache schema that accepts both the old and new shapes.
Curiously that PR already added `timeZone` to `/api/settings` and then
never read it, carrying one value over two routes.

Layout is untouched, which was the constraint here. The GUI diff is two
call sites gaining a third argument; every `className`, element and
stylesheet is byte-identical. `git diff -- gui/` filtered for
className/element/style changes returns the two timestamp lines and
nothing else.

The formatters swallow `RangeError`: a zone string this browser's ICU
build does not know would otherwise take the whole row render down, and a
timestamp in the wrong zone beats an empty log list. The fetch is a
one-shot on mount rather than part of the 2s log poll, since the server's
zone cannot change while the page is open, and an older proxy without the
field simply keeps browser-local formatting.

Tests, both verified by ablation rather than assumed:

- removing `timeZone` from /api/settings fails the settings test (4/1)
- dropping the formatter argument fails the rendering test (4/1)

That second one is the case #790's own test could not catch: it compared
the response to itself and passed with the production change reverted. The
new test fixes 00:30 UTC and asserts Seoul reads 9:30 while UTC reads
12:30, so an ignored argument shows up as a wrong hour. There is also a
test asserting /api/logs is still a bare array, placed at the source so
the contract fails here rather than in four unrelated suites.

The detail dialog gets the same zone; leaving it on browser time would put
two different times for one request on screen at once.

Co-authored-by: Wibias <37517432+Wibias@users.noreply.github.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Closing — the defect is real and now fixed on codex/260731-pr-merge-round as a6d472e3f, but by a narrower route than this branch takes. Two reasons, and only the second is about preference.

The /api/logs contract. This PR turns the response from a bare array into {timeZone, logs}. Four suites read that response as an array and none of them are updated here:

  • tests/server-auth.test.ts:1623
  • tests/claude-native-passthrough.test.ts:119
  • tests/openai-provider-option-e2e.test.ts:489
  • tests/server-403-permission-e2e.test.ts:86

Related: the one test this PR does change (tests/management-api-logs-metrics.test.ts:16-20) accepts both the array and the envelope, so it passes with the production change reverted — it cannot fail on the behavior it ships with.

The zone was already available. This PR adds timeZone to /api/settings (src/server/management/config-routes.ts:113) and then never reads it, carrying the same value over two routes. SettingsData already flows through the GUI, so /api/settings alone is enough and /api/logs never has to change.

What landed instead, keeping your Intl.DateTimeFormat().resolvedOptions().timeZone approach and your acceptClientTimeZone guard in spirit:

  • timeZone on /api/settings only; /api/logs still returns an array, with a test asserting that at the source
  • Logs.tsx threads the zone into the two formatters — two call sites gain a third argument, no JSX/CSS change, no session-cache schema change
  • RangeError is swallowed so a zone the browser's ICU build lacks falls back to browser-local rather than killing the row render
  • the regression test fixes 00:30 UTC and asserts Seoul reads 9:30 while UTC reads 12:30, so a dropped argument surfaces as a wrong hour; verified by ablation in both directions

The branch is staging: it merges into dev and ships once the in-flight optimization work there lands. Credit preserved via Co-authored-by on the commit. Thanks — the diagnosis and the settings-route idea both came from here.

@lidge-jun lidge-jun closed this Jul 31, 2026
lidge-jun added a commit that referenced this pull request Jul 31, 2026
Selection rule is narrow on purpose: an entry must trace to a triage
row and must not be waiting on maintainer approval or third-party
evidence. That is what keeps the list short -- most open PRs are
blocked by approval, not by code.

F1 is first because three other stream items sit on it.
closeCurrentToolCall() at bridge.ts:378-417 hardcodes
status: "completed", and both failure paths call it unconditionally
(:776 on adapter error, :835 on implicit EOF). So a stream that ends
in failure still hands the client a completed tool call, with
response.failed arriving afterward. That is why the adapter-side
attempt at #658 was reverted in 95d8ed7, and it is what PR #781
already fixes with failCurrentToolCall().

F2 must not land before F1. Relaxing EOF without a cancel path would
let a truncated tool call through as success.

Also recorded: bridge.ts:436-441 still says it synthesizes
response.completed, but :838 emits response.incomplete. The comment
outlived the code.

Three tests already on dev would survive reverting the behavior they
claim to cover. With #790 and #758 last round, that is a pattern
rather than three accidents, so it gets its own issue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants