Skip to content

Common updates to better support Oura and work system#916

Open
darinkrauss wants to merge 1 commit intoBACK-4028-oura-webhook-subscriptions-basefrom
BACK-4028-oura-webhook-subscriptions
Open

Common updates to better support Oura and work system#916
darinkrauss wants to merge 1 commit intoBACK-4028-oura-webhook-subscriptions-basefrom
BACK-4028-oura-webhook-subscriptions

Conversation

@darinkrauss
Copy link
Contributor

  • Update request parsing code to allow parsing of decoded maps with options
  • Add expanded pagination functionality
  • Add direct metadata encoding and decoding
  • Add generic functions to pointer package
  • Add times.TimeRange common structure
  • Add OAuthToken.IsExpired
  • Remove .vscode directory
  • Add various mocks
  • Fix various typos
  • Add and update tests

@darinkrauss darinkrauss requested a review from toddkazakov March 11, 2026 16:19
Copy link
Contributor

@toddkazakov toddkazakov left a comment

Choose a reason for hiding this comment

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

Only nits

return &value
}

func FromAny[T any](value T) *T {
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest renaming this instead of introducing a new function

Suggested change
func From[T any](value T) *T {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Going to leave as-is for now. As I mentioned in Slack, I have an in-progress branch to cleanup the pointer package to consistently use generics. There will be a mass rename.


func DecodeRequestBody(req *http.Request, object interface{}) error {
type DecodeOption struct {
ignoreNotParsed *bool
Copy link
Contributor

Choose a reason for hiding this comment

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

Considering removing the pointer here. I don't thing there is a practical need to distinguish between not set and set to false.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is only an issue if we have multiple DecodeOptions and we list them at the end of a function. For example, Decode(<whatever>, request.IgnoreNotParsed(), request.SomeOtherOption(). When those are merged using request.DecodeOptions the pointer allows the second option to not step on the value of the first option.

times/times.go Outdated

import "time"

func Pin(value time.Time, minimum time.Time, maximum time.Time) time.Time {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe the standard naming for this functionality is Clamp

@darinkrauss darinkrauss changed the base branch from BACK-3960-oura-connection to BACK-4028-oura-webhook-subscriptions-base March 17, 2026 15:50
@darinkrauss darinkrauss force-pushed the BACK-4028-oura-webhook-subscriptions branch 2 times, most recently from b711d7d to c7466f5 Compare March 17, 2026 20:33
- Update request parsing code to allow parsing of decoded maps with options
- Add expanded pagination functionality
- Add direct metadata encoding and decoding
- Add generic functions to pointer package
- Add times.TimeRange common structure
- Add OAuthToken.IsExpired
- Remove .vscode directory
- Add various mocks
- Fix various typos
- Fix intermittent consent test failure
- Add and update tests
@darinkrauss darinkrauss force-pushed the BACK-4028-oura-webhook-subscriptions branch from c7466f5 to 86d60fc Compare March 17, 2026 21:53
@darinkrauss darinkrauss requested a review from Copilot March 18, 2026 06:52
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces shared utilities and developer tooling to better support integrations (e.g., Oura) and “work” system behavior, including improved request decoding, richer pagination helpers, and new common time-range structures. It also adds mocks/tests and cleans up repo-local editor artifacts.

Changes:

  • Expanded request decoding to support decoding from streams and already-decoded objects/arrays, with an option to ignore “not parsed” fields.
  • Added common utilities: times.Clamp, times.TimeRange(+metadata), and generic pointer helpers (From, To, Clone, Equal, DefaultPointer).
  • Added/updated pagination helpers (Collect, First, Process variants), mocks (mockgen), tests, and Ginkgo Makefile/template tooling.

Reviewed changes

Copilot reviewed 52 out of 53 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
work/test/processor.go Adds test Provider and mock metadata helpers for work processors.
work/service/coordinator.go Fixes typo in RegisterProcessorFactories parameter naming.
work/base/processor_factory_test.go Improves test descriptions (“returns an error …”).
work/base/process_result_test.go Refactors gomock controller setup for ProcessResult tests.
times/times.go Adds times.Clamp utility.
times/times_test.go Adds unit tests for times.Clamp.
times/times_suite_test.go Adds Ginkgo suite bootstrap for times package tests.
times/time_range.go Introduces TimeRange + TimeRangeMetadata parsing/validation/helpers.
times/time_range_test.go Adds comprehensive tests for TimeRange and metadata parsing/validation/helpers.
times/test/time_range.go Adds test factories/clone/object builders for time range types.
test/optional.go Adds generic optional/random optional helpers used across tests.
test/int64.go Adjusts random int64 bounds helpers.
test/closer.go Adds ErrorCloser wrapper and supporting ReadCloser types.
summary/summary.go Adds Client interface + go:generate for gomock.
summary/test/summary_mocks.go Adds generated gomock mocks for summary.Client and Summarizer.
store/structured/mongo/test/test.go Improves uniqueness of generated Mongo collection name prefixes.
request/parser.go Adds decode options + stream/object/array decoding and parsing helpers; renames/reshapes decode functions.
request/parser_test.go Adds tests for new decode options; refactors header parsing tests; tweaks loop generation.
request/values_parser.go Simplifies map access for parsed indices.
private/plugin/abbott Updates submodule pointer.
pointer/from.go Adds generic pointer.From.
pointer/from_test.go Adds tests for generic From, FromInt64, FromAny.
pointer/to.go Adds generic pointer.To.
pointer/to_test.go Adds tests for generic To.
pointer/clone.go Adds generic pointer.Clone.
pointer/clone_test.go Adds tests for generic Clone.
pointer/equal.go Adds generic pointer.Equal.
pointer/equal_test.go Adds tests for generic Equal; fixes mislabeled table name.
pointer/default.go Adds DefaultPointer.
pointer/default_test.go Adds tests for generic Default + DefaultPointer; clarifies expectations in existing tests.
page/pagination.go Adds Pager, expands collection helpers (Collect/First/Process) with size variants.
page/pagination_test.go Adds extensive tests for new pagination collection helpers and edge cases.
metadata/metadata.go Updates parsing calls; removes some helpers; adds generic Encode/Decode against map metadata.
metadata/metadata_test.go Adds coverage for MetadataFromMap, plus encode/decode behaviors with decode options.
metadata/test/metadata.go Refactors metadata test factories/cloners/builders using maps.Clone and pointer helpers.
log/test/serializer.go Improves assertion failure output with JSON dumps; adjusts field-join behavior.
devicetokens/devicetokens_test.go Migrates decoding usage to request.DecodeStream.
data/source/service/client/client.go Adds go:generate mockgen directive for Provider.
data/source/service/client/test/client_mocks.go Adds generated gomock for data source client Provider.
data/deduplicator/deduplicator.go Adds go:generate mockgen directives for Factory and Deduplicator.
data/deduplicator/test/deduplicator_mocks.go Adds generated gomock mocks for deduplicator Factory and Deduplicator.
consent/store/mongo/consent_record_repository.go Adjusts aggregation group key and adds explicit sort for deterministic output.
consent/consent_record_test.go Migrates decoding usage to request.DecodeStream.
client/client.go Migrates decoding usage to request.DecodeStream.
auth/token.go Adds OAuthToken.IsExpired.
auth/token_test.go Adds test coverage for IsExpired.
auth/auth_test.go Fixes a typo in test description.
alerts/config_test.go Migrates decoding usage to request.DecodeStream.
Makefile Adds ginkgo repeat/until-fail targets and bootstrapping/generate helpers with templates.
.ginkgo/templates/bootstrap Adds custom Ginkgo bootstrap template.
.ginkgo/templates/generate Adds custom Ginkgo generate template including common imports.
.vscode/launch.json Removes repository-stored VS Code launch configuration.
.gitignore Ignores .vscode directory.
Comments suppressed due to low confidence (5)

work/base/process_result_test.go:1

  • The gomock.Controller created in BeforeEach is not finished/cleaned up anywhere in this test file. This can leak expectations across tests and cause flaky failures. Add DeferCleanup(mockController.Finish) after controller creation (or AfterEach(mockController.Finish)) so mocks are always finalized.
    request/parser_test.go:1
  • This uses Go’s for range <int> form (introduced in Go 1.22). If the repository’s go.mod/CI Go version is < 1.22, this will not compile. Either ensure the project toolchain is pinned to Go 1.22+ or rewrite this loop to a traditional for loops := 0; loops < maxLoops; loops++ { ... } to preserve compatibility.
    request/parser.go:1
  • These error paths drop the underlying err, which makes diagnosing decode failures much harder (especially since callers wrap these messages). Prefer wrapping/attaching the original error so the failure reason (e.g., unsupported type, invalid JSON shape) is preserved.
    test/int64.go:1
  • RandomInt64Maximum() / RandomInt64Minimum() no longer return the true int64 extrema, which makes the names misleading and can break callers that expect full-range bounds. Either restore the original semantics or rename/document these as safe/random-generation bounds (e.g., to avoid overflow during downstream operations).
    test/int64.go:1
  • RandomInt64Maximum() / RandomInt64Minimum() no longer return the true int64 extrema, which makes the names misleading and can break callers that expect full-range bounds. Either restore the original semantics or rename/document these as safe/random-generation bounds (e.g., to avoid overflow during downstream operations).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 11 to 17
func RandomMetadataMap() map[string]any {
return RandomMetadata().AsMap()
datum := map[string]any{}
for range test.RandomIntFromRange(1, 3) {
datum[RandomMetadataKey()] = RandomMetadataValue()
}
return datum
}
Comment on lines +114 to +125
func Decode[T any](ctx context.Context, metadata map[string]any, decodeOptions ...request.DecodeOption) (*T, error) {
if metadata == nil {
return nil, nil
}

object := new(T)
if err := request.DecodeObject(ctx, structure.NewPointerSource(), metadata, object, decodeOptions...); err != nil {
return nil, errors.Wrap(err, "unable to decode metadata")
}

return object, nil
}
Comment on lines +85 to 89
actual, _ := json.MarshalIndent(s.SerializedFields, "", " ")
expected, _ := json.MarshalIndent(joinedContainsFields, "", " ")
panic(fmt.Sprintf("logger does not contain specified message and fields, expected:\n%s\nto contain:\n%s\n", string(actual), string(expected)))
}

}

func (o *OAuthToken) IsExpired() bool {
return o.ExpirationTime.Before(time.Now())
Comment on lines +322 to +328
ginkgo-bootstrap: ginkgo
@echo "ginkgo bootstrap $(TEST_PACKAGE)"
@cd "$(TEST_DIRECTORY)" && \
[ -f "$(TEST_PACKAGE_NAME)_suite_test.go" ] || \
ginkgo bootstrap --template "$(ROOT_DIRECTORY)/.ginkgo/templates/bootstrap"

ginkgo-generate: ginkgo-bootstrap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants