Skip to content

Commit

Permalink
summary stats rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
Roukoswarf committed Jan 13, 2025
1 parent 10dc8b0 commit e2d477d
Show file tree
Hide file tree
Showing 389 changed files with 5,991 additions and 85,361 deletions.
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.CGMStats, *types.GlucoseBucket, types.CGMStats, types.GlucoseBucket], error)
GetBGMSummary(ctx context.Context, id string) (*types.Summary[*types.BGMStats, *types.GlucoseBucket, types.BGMStats, types.GlucoseBucket], error)
GetContinuousSummary(ctx context.Context, id string) (*types.Summary[*types.ContinuousStats, *types.ContinuousBucket, types.ContinuousStats, types.ContinuousBucket], error)
UpdateCGMSummary(ctx context.Context, id string) (*types.Summary[*types.CGMStats, *types.GlucoseBucket, types.CGMStats, types.GlucoseBucket], error)
UpdateBGMSummary(ctx context.Context, id string) (*types.Summary[*types.BGMStats, *types.GlucoseBucket, types.BGMStats, types.GlucoseBucket], error)
UpdateContinuousSummary(ctx context.Context, id string) (*types.Summary[*types.ContinuousStats, *types.ContinuousBucket, types.ContinuousStats, 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.CGMStats, *types.GlucoseBucket, types.CGMStats, 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.CGMStats, *types.GlucoseBucket, types.CGMStats, 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.BGMStats, *types.GlucoseBucket, types.BGMStats, 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.BGMStats, *types.GlucoseBucket, types.BGMStats, 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.ContinuousStats, *types.ContinuousBucket, types.ContinuousStats, 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.ContinuousStats, *types.ContinuousBucket, types.ContinuousStats, 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.CGMStats, *types.GlucoseBucket, types.CGMStats, 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.CGMStats, *types.GlucoseBucket, types.CGMStats, 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.BGMStats, *types.GlucoseBucket, types.BGMStats, 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.BGMStats, *types.GlucoseBucket, types.BGMStats, 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.ContinuousStats, *types.ContinuousBucket, types.ContinuousStats, 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.ContinuousStats, *types.ContinuousBucket, types.ContinuousStats, 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.CGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/bgm/:userId", GetSummary[*types.BGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/continuous/:userId", GetSummary[*types.ContinuousStats, *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.CGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Post("/v1/summaries/bgm/:userId", UpdateSummary[*types.BGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Post("/v1/summaries/continuous/:userId", UpdateSummary[*types.ContinuousStats, *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.CGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/outdated/bgm", GetOutdatedUserIDs[*types.BGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/outdated/continuous", GetOutdatedUserIDs[*types.ContinuousStats, *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.CGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/migratable/bgm", GetMigratableUserIDs[*types.BGMStats, *types.GlucoseBucket], api.RequireAuth),
dataService.Get("/v1/summaries/migratable/continuous", GetMigratableUserIDs[*types.ContinuousStats, *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[A types.StatsPt[T, P, B], P types.BucketDataPt[B], T types.Stats, 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[A, P](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.GetTypeString[A, P](), 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[A types.StatsPt[T, P, B], P types.BucketDataPt[B], T types.Stats, 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[A, P](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[A types.StatsPt[T, P, B], P types.BucketDataPt[B], T types.Stats, 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[A, P](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[A types.StatsPt[T, P, B], P types.BucketDataPt[B], T types.Stats, 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[A, P](dataServiceContext.SummarizerRegistry())
userIDs, err := summarizer.GetMigratableUserIDs(ctx, pagination)
if err != nil {
responder.Error(http.StatusInternalServerError, err)
Expand Down
13 changes: 12 additions & 1 deletion data/service/context/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Standard struct {
dataStore dataStore.Store
dataRepository dataStore.DataRepository
summaryRepository dataStore.SummaryRepository
bucketsRepository dataStore.BucketsRepository
summarizerRegistry *summary.SummarizerRegistry
summaryReporter *reporters.PatientRealtimeDaysReporter
syncTaskStore syncTaskStore.Store
Expand Down Expand Up @@ -126,6 +127,9 @@ func (s *Standard) Close() {
if s.summaryReporter != nil {
s.summaryReporter = nil
}
if s.bucketsRepository != nil {
s.bucketsRepository = nil
}
if s.alertsRepository != nil {
s.alertsRepository = nil
}
Expand Down Expand Up @@ -163,7 +167,7 @@ func (s *Standard) SummaryRepository() dataStore.SummaryRepository {

func (s *Standard) SummarizerRegistry() *summary.SummarizerRegistry {
if s.summarizerRegistry == nil {
s.summarizerRegistry = summary.New(s.SummaryRepository().GetStore(), s.DataRepository())
s.summarizerRegistry = summary.New(s.SummaryRepository().GetStore(), s.BucketsRepository().GetStore(), s.DataRepository())
}
return s.summarizerRegistry
}
Expand All @@ -175,6 +179,13 @@ func (s *Standard) SummaryReporter() *reporters.PatientRealtimeDaysReporter {
return s.summaryReporter
}

func (s *Standard) BucketsRepository() dataStore.BucketsRepository {
if s.bucketsRepository == nil {
s.bucketsRepository = s.dataStore.NewBucketsRepository()
}
return s.bucketsRepository
}

func (s *Standard) SyncTaskRepository() syncTaskStore.SyncTaskRepository {
if s.syncTasksRepository == nil {
s.syncTasksRepository = s.syncTaskStore.NewSyncTaskRepository()
Expand Down
Loading

0 comments on commit e2d477d

Please sign in to comment.