feat(feedback): capture the browser UTC offset; Filed time in three zones
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 55s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m20s
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 55s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m20s
The account time zone defaults to UTC until a player saves a profile, so a report's Filed time could only render in UTC even for a player clearly in another zone. Capture the client's detected "±HH:MM" offset (browser_tz) with each submission and show the Filed time in three zones in the operator console — UTC, the browser offset detected at submit, and the sender's saved profile zone — each shown "N/A" when not known, so the operator can tell what is certainly known from what is merely defaulted. - Thread browser_tz through the fbs envelope (+ Go/TS codegen), the gateway transcode + backend client, and the backend feedback service/store; add the column via migration 00004 (additive, image-rollback-safe). - Fix fmtTimeIn to resolve "±HH:MM" offsets via account.ResolveZone; time.LoadLocation alone silently fell back to UTC for offset zones, which is the second reason a "+02:00" sender showed only UTC. - Update ARCHITECTURE/FUNCTIONAL(+ru) docs and the feedback integration test.
This commit is contained in:
@@ -1151,8 +1151,8 @@ Players reach the operators through a **Feedback** screen (Settings → Info, re
|
||||
only). A message (≤1024 runes) plus an optional single attachment is stored in
|
||||
`feedback_messages`; the sender's IP (gateway-forwarded, as for chat), the submitting
|
||||
**channel** (telegram/ios/android/web, client-reported and validated), the **client app version**
|
||||
(`__APP_VERSION__`, the build a report was sent from) and a snapshot of the sender's interface
|
||||
language are recorded. The domain is `internal/feedback` (store + service), modelled on the admin
|
||||
(`__APP_VERSION__`, the build a report was sent from), the client's **detected UTC offset** at
|
||||
submit (`browser_tz`, `±HH:MM`) and a snapshot of the sender's interface language are recorded. The domain is `internal/feedback` (store + service), modelled on the admin
|
||||
chat-moderation surface.
|
||||
|
||||
**Anti-spam.** A player with an unreviewed message (`read_at IS NULL`) cannot submit another; the
|
||||
@@ -1162,7 +1162,8 @@ rate limit — there is no separate per-user feedback limiter.
|
||||
**Operator review** happens in the server-rendered console (`/_gm/feedback`): an
|
||||
unread / read / archived queue with per-user search (the `/users` glob masks), a detail card
|
||||
(user content rendered as auto-escaped `html/template` text; it shows the channel, interface
|
||||
language and app version, and the filed time in UTC plus the sender's time zone), and the read /
|
||||
language and app version, and the filed time in three zones — UTC, the browser offset detected at
|
||||
submit, and the sender's saved profile zone, each `N/A` when not known), and the read /
|
||||
reply / archive / delete / delete-all actions — each marks the message read; merely opening the
|
||||
detail does not.
|
||||
The attachment is served from `/_gm/feedback/:id/attachment` with `X-Content-Type-Options:
|
||||
|
||||
Reference in New Issue
Block a user