Repository navigation
feat(time): answer the week over the time contract - #154
Merged
Merged
Conversation
Home's This week card needs the week's hours from time. A new internal gRPC contract, bakhyard.time.v1, answers the week of the report time already polls from Jira: no week without Jira, UNAVAILABLE until a read of the worklogs succeeds, and the last good week through failed reads (decision 185).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brief
Goal. The time service answers
TimeService.GetWeek, from the second contract between services,bakhyard.time.v1(plan §4.5). It returns this week's hours against the week's target, for the Home's "This week". home asks for it in the next step.Scope.
proto/bakhyard/time/v1/time.proto:TimeService.GetWeek(NO_SIDE_EFFECTS) returnsGetWeekResponse{week}, andWeek{logged_hours, target_hours}is in hours. The generated Go is ininternal/gen/bakhyard/time/v1.services/time/internal/week:Serveranswers the week from the latest poll to succeed, once the first poll has ended:Unavailablebefore any poll has succeeded;services/time/main.gomounts it on time's router, next toGET /time/report, on the same poller.testing/synctest, and one test throughroutesover gRPC on HTTP/2 without TLS (h2c).home-week, is already a Phase 1 step's (feat(web): show the week's hours on the Home #24), so §8.2 and decision 183 now call ithome-time-week.Out of scope.
time-attention).buf breaking(decision 158).Acceptance criteria.
buf lintandbuf formatpass, andmise run gen:checkpasses with the generated code committed.TimeService/GetWeekover gRPC on h2c on its router, alongsideGET /time/reportand/healthz.GET /time/report'sweek, kept through later failed polls.GetWeekanswers with no week.GetWeekfails withUnavailable.mise run checkpasses and the PR's CI is green.QA
files/qa-time-week/mutate.py):week.go: no nil check; a zero week, orUNAVAILABLE, without Jira; the context's error swallowed, or turned intoUNAVAILABLE; the success check removed, inverted, or replaced by "unavailable after any failure"; another code; another message; logged and target hours swapped, either one missing, or the logged hours as the target;main.go: not mounted; mounted on another mux; the week server without the poller; a poller of its own.TestTimeAnswersTheWeekOfItsReportnow fails when the week and the report come from different reads.live.py, 25 checks, all passed): the service's binary against a stand-in Jira on the loopback, called over gRPC on h2c withbuf curland the repo's schema.{}), andGET /time/reportstill answers 404. Nothing is logged.GET /time/report's week. The Connect protocol over HTTP/1.1 answers the same, as pulls' and todos' handlers do; the gateway doesn't route either. With nothing logged, the week says 0 hours rather than no week.unavailablewith the message, andpoll Jira worklogslogged once.grpc-timeout, the call ends withdeadline_exceeded.go build -overlay) keeps the week of the last read to succeed after a failed read, and answers the new week once a read succeeds again.-race -count=40on the new tests: no failure.UNAVAILABLE, since no read has succeeded; that fits the code's meaning.Review
No blocking findings. Non-blocking:
home-fanout. It becomes true with the next step.Gates
mise run checkpassed locally:gen:check; govulncheck (none);-race, Go coverage 95.9% total (services/time/internal/week100%);tsc, knip,pnpm audit;SonarQube Cloud runs on demand (decision 132).
Merged under the user's standing OK (2026-10-26): merge once CI's
checkis green, and review everything at the end.