Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BACK-2638] Move Summary buckets to collection and unify datastructure #763

Open
wants to merge 23 commits into
base: alex/version-updates
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ dist: jammy
language: go

go:
- 1.23.4
- 1.24.0

services:
- docker
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.auth
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Development
FROM golang:1.23.4-alpine AS development
FROM golang:1.24.0-alpine AS development
WORKDIR /go/src/github.com/tidepool-org/platform
RUN apk --no-cache update && \
apk --no-cache upgrade && \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.blob
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Development
FROM golang:1.23.4-alpine AS development
FROM golang:1.24.0-alpine AS development
WORKDIR /go/src/github.com/tidepool-org/platform
RUN apk --no-cache update && \
apk --no-cache upgrade && \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.data
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Development
FROM golang:1.23.4-alpine AS development
FROM golang:1.24.0-alpine AS development
WORKDIR /go/src/github.com/tidepool-org/platform
RUN apk --no-cache update && \
apk --no-cache upgrade && \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.migrations
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Development
FROM golang:1.23.4-alpine AS development
FROM golang:1.24.0-alpine AS development
WORKDIR /go/src/github.com/tidepool-org/platform
RUN apk --no-cache update && \
apk --no-cache upgrade && \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.prescription
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Development
FROM golang:1.23.4-alpine AS development
FROM golang:1.24.0-alpine AS development
WORKDIR /go/src/github.com/tidepool-org/platform
RUN apk --no-cache update && \
apk --no-cache upgrade && \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.task
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Development
FROM golang:1.23.4-alpine AS development
FROM golang:1.24.0-alpine AS development
WORKDIR /go/src/github.com/tidepool-org/platform
RUN apk --no-cache update && \
apk --no-cache upgrade && \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.tools
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Development
FROM golang:1.23.4-alpine AS development
FROM golang:1.24.0-alpine AS development
WORKDIR /go/src/github.com/tidepool-org/platform
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.9/community' >> /etc/apk/repositories && \
echo 'http://dl-cdn.alpinelinux.org/alpine/v3.9/main' >> /etc/apk/repositories && \
Expand Down
50 changes: 18 additions & 32 deletions data/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ type Client interface {

DestroyDataForUserByID(ctx context.Context, userID string) error

GetCGMSummary(ctx context.Context, id string) (*types.Summary[*types.CGMStats, types.CGMStats], error)
GetBGMSummary(ctx context.Context, id string) (*types.Summary[*types.BGMStats, types.BGMStats], error)
GetContinuousSummary(ctx context.Context, id string) (*types.Summary[*types.ContinuousStats, types.ContinuousStats], error)
UpdateCGMSummary(ctx context.Context, id string) (*types.Summary[*types.CGMStats, types.CGMStats], error)
UpdateBGMSummary(ctx context.Context, id string) (*types.Summary[*types.BGMStats, types.BGMStats], error)
UpdateContinuousSummary(ctx context.Context, id string) (*types.Summary[*types.ContinuousStats, types.ContinuousStats], error)
GetCGMSummary(ctx context.Context, id string) (*types.Summary[*types.CGMPeriods, *types.GlucoseBucket, types.CGMPeriods, types.GlucoseBucket], error)
GetBGMSummary(ctx context.Context, id string) (*types.Summary[*types.BGMPeriods, *types.GlucoseBucket, types.BGMPeriods, types.GlucoseBucket], error)
GetContinuousSummary(ctx context.Context, id string) (*types.Summary[*types.ContinuousPeriods, *types.ContinuousBucket, types.ContinuousPeriods, types.ContinuousBucket], error)
UpdateCGMSummary(ctx context.Context, id string) (*types.Summary[*types.CGMPeriods, *types.GlucoseBucket, types.CGMPeriods, types.GlucoseBucket], error)
UpdateBGMSummary(ctx context.Context, id string) (*types.Summary[*types.BGMPeriods, *types.GlucoseBucket, types.BGMPeriods, types.GlucoseBucket], error)
UpdateContinuousSummary(ctx context.Context, id string) (*types.Summary[*types.ContinuousPeriods, *types.ContinuousBucket, types.ContinuousPeriods, types.ContinuousBucket], error)
GetOutdatedUserIDs(ctx context.Context, t string, pagination *page.Pagination) (*types.OutdatedSummariesResponse, error)
GetMigratableUserIDs(ctx context.Context, t string, pagination *page.Pagination) ([]string, error)
BackfillSummaries(ctx context.Context, t string) (int, error)
}

type ClientImpl struct {
Expand Down Expand Up @@ -132,7 +131,7 @@ func (c *ClientImpl) GetDataSet(ctx context.Context, id string) (*data.DataSet,
return dataSet, nil
}

func (c *ClientImpl) GetCGMSummary(ctx context.Context, userId string) (*types.Summary[*types.CGMStats, types.CGMStats], error) {
func (c *ClientImpl) GetCGMSummary(ctx context.Context, userId string) (*types.Summary[*types.CGMPeriods, *types.GlucoseBucket, types.CGMPeriods, types.GlucoseBucket], error) {
if ctx == nil {
return nil, errors.New("context is missing")
}
Expand All @@ -141,7 +140,7 @@ func (c *ClientImpl) GetCGMSummary(ctx context.Context, userId string) (*types.S
}

url := c.client.ConstructURL("v1", "summaries", "cgm", userId)
summary := &types.Summary[*types.CGMStats, types.CGMStats]{}
summary := &types.Summary[*types.CGMPeriods, *types.GlucoseBucket, types.CGMPeriods, types.GlucoseBucket]{}
if err := c.client.RequestData(ctx, http.MethodGet, url, nil, nil, summary); err != nil {
if request.IsErrorResourceNotFound(err) {
return nil, nil
Expand All @@ -152,7 +151,7 @@ func (c *ClientImpl) GetCGMSummary(ctx context.Context, userId string) (*types.S
return summary, nil
}

func (c *ClientImpl) GetBGMSummary(ctx context.Context, userId string) (*types.Summary[*types.BGMStats, types.BGMStats], error) {
func (c *ClientImpl) GetBGMSummary(ctx context.Context, userId string) (*types.Summary[*types.BGMPeriods, *types.GlucoseBucket, types.BGMPeriods, types.GlucoseBucket], error) {
if ctx == nil {
return nil, errors.New("context is missing")
}
Expand All @@ -161,7 +160,7 @@ func (c *ClientImpl) GetBGMSummary(ctx context.Context, userId string) (*types.S
}

url := c.client.ConstructURL("v1", "summaries", "bgm", userId)
summary := &types.Summary[*types.BGMStats, types.BGMStats]{}
summary := &types.Summary[*types.BGMPeriods, *types.GlucoseBucket, types.BGMPeriods, types.GlucoseBucket]{}
if err := c.client.RequestData(ctx, http.MethodGet, url, nil, nil, summary); err != nil {
if request.IsErrorResourceNotFound(err) {
return nil, nil
Expand All @@ -172,7 +171,7 @@ func (c *ClientImpl) GetBGMSummary(ctx context.Context, userId string) (*types.S
return summary, nil
}

func (c *ClientImpl) GetContinuousSummary(ctx context.Context, userId string) (*types.Summary[*types.ContinuousStats, types.ContinuousStats], error) {
func (c *ClientImpl) GetContinuousSummary(ctx context.Context, userId string) (*types.Summary[*types.ContinuousPeriods, *types.ContinuousBucket, types.ContinuousPeriods, types.ContinuousBucket], error) {
if ctx == nil {
return nil, errors.New("context is missing")
}
Expand All @@ -181,7 +180,7 @@ func (c *ClientImpl) GetContinuousSummary(ctx context.Context, userId string) (*
}

url := c.client.ConstructURL("v1", "summaries", "continuous", userId)
summary := &types.Summary[*types.ContinuousStats, types.ContinuousStats]{}
summary := &types.Summary[*types.ContinuousPeriods, *types.ContinuousBucket, types.ContinuousPeriods, types.ContinuousBucket]{}
if err := c.client.RequestData(ctx, http.MethodGet, url, nil, nil, summary); err != nil {
if request.IsErrorResourceNotFound(err) {
return nil, nil
Expand All @@ -192,7 +191,7 @@ func (c *ClientImpl) GetContinuousSummary(ctx context.Context, userId string) (*
return summary, nil
}

func (c *ClientImpl) UpdateCGMSummary(ctx context.Context, userId string) (*types.Summary[*types.CGMStats, types.CGMStats], error) {
func (c *ClientImpl) UpdateCGMSummary(ctx context.Context, userId string) (*types.Summary[*types.CGMPeriods, *types.GlucoseBucket, types.CGMPeriods, types.GlucoseBucket], error) {
if ctx == nil {
return nil, errors.New("context is missing")
}
Expand All @@ -201,7 +200,7 @@ func (c *ClientImpl) UpdateCGMSummary(ctx context.Context, userId string) (*type
}

url := c.client.ConstructURL("v1", "summaries", "cgm", userId)
summary := &types.Summary[*types.CGMStats, types.CGMStats]{}
summary := &types.Summary[*types.CGMPeriods, *types.GlucoseBucket, types.CGMPeriods, types.GlucoseBucket]{}
if err := c.client.RequestData(ctx, http.MethodPost, url, nil, nil, summary); err != nil {
if request.IsErrorResourceNotFound(err) {
return nil, nil
Expand All @@ -212,7 +211,7 @@ func (c *ClientImpl) UpdateCGMSummary(ctx context.Context, userId string) (*type
return summary, nil
}

func (c *ClientImpl) UpdateBGMSummary(ctx context.Context, userId string) (*types.Summary[*types.BGMStats, types.BGMStats], error) {
func (c *ClientImpl) UpdateBGMSummary(ctx context.Context, userId string) (*types.Summary[*types.BGMPeriods, *types.GlucoseBucket, types.BGMPeriods, types.GlucoseBucket], error) {
if ctx == nil {
return nil, errors.New("context is missing")
}
Expand All @@ -221,7 +220,7 @@ func (c *ClientImpl) UpdateBGMSummary(ctx context.Context, userId string) (*type
}

url := c.client.ConstructURL("v1", "summaries", "bgm", userId)
summary := &types.Summary[*types.BGMStats, types.BGMStats]{}
summary := &types.Summary[*types.BGMPeriods, *types.GlucoseBucket, types.BGMPeriods, types.GlucoseBucket]{}
if err := c.client.RequestData(ctx, http.MethodPost, url, nil, nil, summary); err != nil {
if request.IsErrorResourceNotFound(err) {
return nil, nil
Expand All @@ -232,7 +231,7 @@ func (c *ClientImpl) UpdateBGMSummary(ctx context.Context, userId string) (*type
return summary, nil
}

func (c *ClientImpl) UpdateContinuousSummary(ctx context.Context, userId string) (*types.Summary[*types.ContinuousStats, types.ContinuousStats], error) {
func (c *ClientImpl) UpdateContinuousSummary(ctx context.Context, userId string) (*types.Summary[*types.ContinuousPeriods, *types.ContinuousBucket, types.ContinuousPeriods, types.ContinuousBucket], error) {
if ctx == nil {
return nil, errors.New("context is missing")
}
Expand All @@ -241,7 +240,7 @@ func (c *ClientImpl) UpdateContinuousSummary(ctx context.Context, userId string)
}

url := c.client.ConstructURL("v1", "summaries", "continuous", userId)
summary := &types.Summary[*types.ContinuousStats, types.ContinuousStats]{}
summary := &types.Summary[*types.ContinuousPeriods, *types.ContinuousBucket, types.ContinuousPeriods, types.ContinuousBucket]{}
if err := c.client.RequestData(ctx, http.MethodPost, url, nil, nil, summary); err != nil {
if request.IsErrorResourceNotFound(err) {
return nil, nil
Expand All @@ -252,19 +251,6 @@ func (c *ClientImpl) UpdateContinuousSummary(ctx context.Context, userId string)
return summary, nil
}

func (c *ClientImpl) BackfillSummaries(ctx context.Context, typ string) (int, error) {
var count int
url := c.client.ConstructURL("v1", "summaries", "backfill", typ)

ctxWithTimeout, cancel := context.WithTimeout(ctx, ExtendedTimeout)
defer cancel()
if err := c.client.RequestData(ctxWithTimeout, http.MethodPost, url, nil, nil, &count); err != nil {
return count, errors.Wrap(err, "backfill request returned an error")
}

return count, nil
}

func (c *ClientImpl) GetOutdatedUserIDs(ctx context.Context, typ string, pagination *page.Pagination) (*types.OutdatedSummariesResponse, error) {
if ctx == nil {
return nil, errors.New("context is missing")
Expand Down
68 changes: 21 additions & 47 deletions data/service/api/v1/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,21 @@ import (

func SummaryRoutes() []dataService.Route {
return []dataService.Route{
dataService.Get("/v1/summaries/cgm/:userId", GetSummary[types.CGMStats, *types.CGMStats], api.RequireAuth),
dataService.Get("/v1/summaries/bgm/:userId", GetSummary[types.BGMStats, *types.BGMStats], api.RequireAuth),
dataService.Get("/v1/summaries/continuous/:userId", GetSummary[types.ContinuousStats, *types.ContinuousStats], api.RequireAuth),
dataService.Get("/v1/summaries/cgm/:userId", GetSummary[*types.CGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/bgm/:userId", GetSummary[*types.BGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/continuous/:userId", GetSummary[*types.ContinuousPeriods, *types.ContinuousBucket], api.RequireAuth),

dataService.Post("/v1/summaries/cgm/:userId", UpdateSummary[types.CGMStats, *types.CGMStats], api.RequireAuth),
dataService.Post("/v1/summaries/bgm/:userId", UpdateSummary[types.BGMStats, *types.BGMStats], api.RequireAuth),
dataService.Post("/v1/summaries/continuous/:userId", UpdateSummary[types.ContinuousStats, *types.ContinuousStats], api.RequireAuth),
dataService.Post("/v1/summaries/cgm/:userId", UpdateSummary[*types.CGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Post("/v1/summaries/bgm/:userId", UpdateSummary[*types.BGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Post("/v1/summaries/continuous/:userId", UpdateSummary[*types.ContinuousPeriods, *types.ContinuousBucket], api.RequireAuth),

dataService.Post("/v1/summaries/backfill/cgm", BackfillSummaries[types.CGMStats, *types.CGMStats], api.RequireAuth),
dataService.Post("/v1/summaries/backfill/bgm", BackfillSummaries[types.BGMStats, *types.BGMStats], api.RequireAuth),
dataService.Post("/v1/summaries/backfill/continuous", BackfillSummaries[types.ContinuousStats, *types.ContinuousStats], api.RequireAuth),
dataService.Get("/v1/summaries/outdated/cgm", GetOutdatedUserIDs[*types.CGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/outdated/bgm", GetOutdatedUserIDs[*types.BGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/outdated/continuous", GetOutdatedUserIDs[*types.ContinuousPeriods, *types.ContinuousBucket], api.RequireAuth),

dataService.Get("/v1/summaries/outdated/cgm", GetOutdatedUserIDs[types.CGMStats, *types.CGMStats], api.RequireAuth),
dataService.Get("/v1/summaries/outdated/bgm", GetOutdatedUserIDs[types.BGMStats, *types.BGMStats], api.RequireAuth),
dataService.Get("/v1/summaries/outdated/continuous", GetOutdatedUserIDs[types.ContinuousStats, *types.ContinuousStats], api.RequireAuth),

dataService.Get("/v1/summaries/migratable/cgm", GetMigratableUserIDs[types.CGMStats, *types.CGMStats], api.RequireAuth),
dataService.Get("/v1/summaries/migratable/bgm", GetMigratableUserIDs[types.BGMStats, *types.BGMStats], api.RequireAuth),
dataService.Get("/v1/summaries/migratable/continuous", GetMigratableUserIDs[types.ContinuousStats, *types.ContinuousStats], api.RequireAuth),
dataService.Get("/v1/summaries/migratable/cgm", GetMigratableUserIDs[*types.CGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/migratable/bgm", GetMigratableUserIDs[*types.BGMPeriods, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/migratable/continuous", GetMigratableUserIDs[*types.ContinuousPeriods, *types.ContinuousBucket], api.RequireAuth),

dataService.Get("/v1/clinics/:clinicId/reports/realtime", GetPatientsWithRealtimeData, api.RequireAuth),
}
Expand All @@ -66,7 +62,7 @@ func CheckPermissions(ctx context.Context, dataServiceContext dataService.Contex
return true
}

func GetSummary[T types.Stats, A types.StatsPt[T]](dataServiceContext dataService.Context) {
func GetSummary[PP types.PeriodsPt[P, PB, B], PB types.BucketDataPt[B], P types.Periods, B types.BucketData](dataServiceContext dataService.Context) {
ctx := dataServiceContext.Request().Context()
res := dataServiceContext.Response()
req := dataServiceContext.Request()
Expand All @@ -79,12 +75,12 @@ func GetSummary[T types.Stats, A types.StatsPt[T]](dataServiceContext dataServic
return
}

summarizer := summary.GetSummarizer[A](dataServiceContext.SummarizerRegistry())
summarizer := summary.GetSummarizer[PP, PB](dataServiceContext.SummarizerRegistry())
userSummary, err := summarizer.GetSummary(ctx, id)
if err != nil {
responder.Error(http.StatusInternalServerError, err)
} else if userSummary == nil {
responder.Error(http.StatusNotFound, fmt.Errorf("no %s summary found for user %s", types.GetTypeString[A](), id))
responder.Error(http.StatusNotFound, fmt.Errorf("no %s summary found for user %s", types.GetType[PP, PB](), id))
} else {
responder.Data(http.StatusOK, userSummary)
}
Expand Down Expand Up @@ -133,7 +129,7 @@ func GetPatientsWithRealtimeData(dataServiceContext dataService.Context) {
responder.Data(http.StatusOK, response)
}

func UpdateSummary[T types.Stats, A types.StatsPt[T]](dataServiceContext dataService.Context) {
func UpdateSummary[PP types.PeriodsPt[P, PB, B], PB types.BucketDataPt[B], P types.Periods, B types.BucketData](dataServiceContext dataService.Context) {
ctx := dataServiceContext.Request().Context()
res := dataServiceContext.Response()
req := dataServiceContext.Request()
Expand All @@ -146,7 +142,7 @@ func UpdateSummary[T types.Stats, A types.StatsPt[T]](dataServiceContext dataSer
return
}

summarizer := summary.GetSummarizer[A](dataServiceContext.SummarizerRegistry())
summarizer := summary.GetSummarizer[PP, PB](dataServiceContext.SummarizerRegistry())
userSummary, err := summarizer.UpdateSummary(ctx, id)
if err != nil {
responder.Error(http.StatusInternalServerError, err)
Expand All @@ -155,29 +151,7 @@ func UpdateSummary[T types.Stats, A types.StatsPt[T]](dataServiceContext dataSer
}
}

func BackfillSummaries[T types.Stats, A types.StatsPt[T]](dataServiceContext dataService.Context) {
ctx := dataServiceContext.Request().Context()
res := dataServiceContext.Response()
req := dataServiceContext.Request()

responder := request.MustNewResponder(res, req)

if details := request.GetAuthDetails(ctx); !details.IsService() {
dataServiceContext.RespondWithError(service.ErrorUnauthorized())
return
}

summarizer := summary.GetSummarizer[A](dataServiceContext.SummarizerRegistry())
status, err := summarizer.BackfillSummaries(ctx)
if err != nil {
responder.Error(http.StatusInternalServerError, err)
return
}

responder.Data(http.StatusOK, status)
}

func GetOutdatedUserIDs[T types.Stats, A types.StatsPt[T]](dataServiceContext dataService.Context) {
func GetOutdatedUserIDs[PP types.PeriodsPt[P, PB, B], PB types.BucketDataPt[B], P types.Periods, B types.BucketData](dataServiceContext dataService.Context) {
ctx := dataServiceContext.Request().Context()
res := dataServiceContext.Response()
req := dataServiceContext.Request()
Expand All @@ -195,7 +169,7 @@ func GetOutdatedUserIDs[T types.Stats, A types.StatsPt[T]](dataServiceContext da
return
}

summarizer := summary.GetSummarizer[A](dataServiceContext.SummarizerRegistry())
summarizer := summary.GetSummarizer[PP, PB](dataServiceContext.SummarizerRegistry())
response, err := summarizer.GetOutdatedUserIDs(ctx, pagination)
if err != nil {
responder.Error(http.StatusInternalServerError, err)
Expand All @@ -205,7 +179,7 @@ func GetOutdatedUserIDs[T types.Stats, A types.StatsPt[T]](dataServiceContext da
responder.Data(http.StatusOK, response)
}

func GetMigratableUserIDs[T types.Stats, A types.StatsPt[T]](dataServiceContext dataService.Context) {
func GetMigratableUserIDs[PP types.PeriodsPt[P, PB, B], PB types.BucketDataPt[B], P types.Periods, B types.BucketData](dataServiceContext dataService.Context) {
ctx := dataServiceContext.Request().Context()
res := dataServiceContext.Response()
req := dataServiceContext.Request()
Expand All @@ -223,7 +197,7 @@ func GetMigratableUserIDs[T types.Stats, A types.StatsPt[T]](dataServiceContext
return
}

summarizer := summary.GetSummarizer[A](dataServiceContext.SummarizerRegistry())
summarizer := summary.GetSummarizer[PP, PB](dataServiceContext.SummarizerRegistry())
userIDs, err := summarizer.GetMigratableUserIDs(ctx, pagination)
if err != nil {
responder.Error(http.StatusInternalServerError, err)
Expand Down
Loading