Loading…
Reference in a new issue
No description provided.
Delete branch "fix/owner-answers-code"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The three code answers the owner gave to questions lanes 1 and 2 left open. The decisions themselves are #761; this is the work behind two of them, plus one defect.
1. Needs you states a session's time in the campaign's zone (#727)
On Home, "Needs you" stated a session's time in the reader's zone while the campaign card immediately beside it stated the same session in the campaign's. Two different times for one session, side by side.
The rule was already written down, in
Home.jsx's own comment onwhenText: the campaign's zone wins, "because that is the night the table agreed on; a player travelling should still see the same one."/api/me/attentionsimply carried no zone to render in.Each attention row now carries its campaign's
timezone, and Needs you renders through the same helper the card uses. A campaign with no zone set falls back exactly as the card already does.One line stays in the reader's zone, deliberately, and now says why in a comment: the live row's "started 8:14 PM". It is the only time on the page printed without a zone on it —
whenTextprints the abbreviation, so a campaign-zone time says which clock it means, while a bare "started 8:14 PM" in a foreign zone would quietly disagree with the clock on the reader's wall. That line exists to say how long ago something started, which is the reader's question, not the table's.2. The shared analytics page counts twelve months (D89, #728)
The drawing reads "Every 13 days on average · 13 sessions in six months". The public endpoint reported only
sessions_last_30_days, so lane 2 built the lesser sentence — "2 sessions in the last 30 days".GET /public/analytics/{share_token}gainssessions_last_12_months, counted the same way the existing figure is (completed sessions, soft-deleted campaigns excluded) and besidesessions_last_30_daysrather than replacing it — that field still has a consumer, the authenticatedCampaignAnalytics.jsxpage, which was checked rather than assumed.A year rather than the drawing's six months, on the owner's answer: it tells a reader about a campaign's rhythm and survives a table that plays fortnightly through a quiet summer.
The window is
timedelta(days=365), matching the 30-day code beside it rather than introducing calendar-month arithmetic and a new dependency for one line.3. A join request has somewhere to go (
SH-088, #728)When a join needs the GM's approval, the invitation page said so in a quiet banner with no action — so somebody who had just asked to join was looking at a page with nowhere to go. The drawing draws it that way; the ledger row says it "explains the wait and links to the dashboard", and the ledger is right.
The banner gains Home, from
vocabulary.jsrather than a hard-coded string. The copy is untouched. That state is only reachable signed in, which was verified rather than assumed, so the link is always somewhere the reader can go.Checks
Backend 3881 passed, 13 skipped. Ruff 0.4.4, both
format --checkandcheck, clean overwebapp/backend/ scripts/ webapp/frontend/e2e/. Frontend 1394 tests in 123 files, lint 0 errors (239 pre-existing warnings, none in any file this touches), build clean.No migration: both new fields are a response field and a computed service value.
🤖 Generated with Claude Code
The drawing reads "Every 13 days on average · 13 sessions in six months"; the public endpoint reported only sessions_last_30_days, so the page was built saying "2 sessions in the last 30 days" — the lesser sentence. D89 (owner, 2026-09-22) settles it on the drawn sentence, over the last 12 months. `GET /public/analytics/{share_token}` gains sessions_last_12_months — completed sessions with a confirmed_time inside the last 365 days, the same day-window approach sessions_last_30_days already uses — counted by the same analytics_service.get_campaign_analytics every analytics endpoint shares, so it inherits the existing soft-delete and completed-only filtering rather than reimplementing it. sessions_last_30_days is left in place, both in the service and on the public response: the authenticated GET /campaigns/{id}/analytics page (CampaignAnalytics.jsx, "Completed in last 30 days") still reads it. The new field sits beside it rather than replacing it. PublicAnalytics.jsx's "How often they play" now reads off sessions_last_12_months and says "in the last 12 months"; the "two played sessions" note is untouched. Its test's fixed numbers matched the drawing already (13 sessions), so only the window in the assertion text changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>